You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2011/05/11 20:50:41 UTC
svn commit: r1102017 - in /couchdb/branches/1.1.x: ./ THANKS
etc/default/couchdb share/server/util.js share/www/script/test/design_docs.js
Author: davisp
Date: Wed May 11 18:50:41 2011
New Revision: 1102017
URL: http://svn.apache.org/viewvc?rev=1102017&view=rev
Log:
Fix circular imports in CommonJS modules.
Backport of 1102006 from trunk.
Modified:
couchdb/branches/1.1.x/ (props changed)
couchdb/branches/1.1.x/THANKS
couchdb/branches/1.1.x/etc/default/couchdb (props changed)
couchdb/branches/1.1.x/share/server/util.js
couchdb/branches/1.1.x/share/www/script/test/design_docs.js
Propchange: couchdb/branches/1.1.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed May 11 18:50:41 2011
@@ -6,4 +6,4 @@
/couchdb/branches/list-iterator:782292-784593
/couchdb/branches/tail_header:775760-778477
/couchdb/tags/0.10.0:825400
-/couchdb/trunk:1045203,1064417,1081107-1083320,1083714,1095523,1095557,1095569,1095581,1096098,1097300,1099479
+/couchdb/trunk:1045203,1064417,1081107-1083320,1083714,1095523,1095557,1095569,1095581,1096098,1097300,1099479,1102006
Modified: couchdb/branches/1.1.x/THANKS
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/THANKS?rev=1102017&r1=1102016&r2=1102017&view=diff
==============================================================================
--- couchdb/branches/1.1.x/THANKS (original)
+++ couchdb/branches/1.1.x/THANKS Wed May 11 18:50:41 2011
@@ -79,5 +79,7 @@ suggesting improvements or submitting ch
* Tim Smith <ti...@couchbase.com>
* Sam Bisbee <sa...@sbisbee.com>
* Nathan Vander Wilt <na...@yahoo.com>
+ * Caolan McMahon <ca...@googlemail.com>
+
For a list of authors see the `AUTHORS` file.
Propchange: couchdb/branches/1.1.x/etc/default/couchdb
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed May 11 18:50:41 2011
@@ -6,5 +6,5 @@
/couchdb/branches/list-iterator/etc/default/couchdb:782292-784593
/couchdb/branches/tail_header/etc/default/couchdb:775760-778477
/couchdb/tags/0.10.0/etc/default/couchdb:825400
-/couchdb/trunk/etc/default/couchdb:1045203,1064417,1081107-1083320,1083714,1095523,1095557,1095569,1095581,1096098,1097300,1099479
+/couchdb/trunk/etc/default/couchdb:1045203,1064417,1081107-1083320,1083714,1095523,1095557,1095569,1095581,1096098,1097300,1099479,1102006
/incubator/couchdb/trunk/etc/default/couchdb:642419-694440
Modified: couchdb/branches/1.1.x/share/server/util.js
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/share/server/util.js?rev=1102017&r1=1102016&r2=1102017&view=diff
==============================================================================
--- couchdb/branches/1.1.x/share/server/util.js (original)
+++ couchdb/branches/1.1.x/share/server/util.js Wed May 11 18:50:41 2011
@@ -31,16 +31,16 @@ var resolveModule = function(names, mod,
}
return resolveModule(names, {
id : mod.id.slice(0, mod.id.lastIndexOf('/')),
- parent : mod.parent.parent.parent,
- current : mod.parent.parent.current
+ parent : mod.parent.parent,
+ current : mod.parent.current
});
} else if (n == '.') {
if (!mod.parent) {
throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(mod.current)];
}
return resolveModule(names, {
- parent : mod.parent.parent,
- current : mod.parent.current,
+ parent : mod.parent,
+ current : mod.current,
id : mod.id
});
} else if (root) {
@@ -66,17 +66,28 @@ var Couch = {
try {
if (sandbox) {
if (ddoc) {
+ if (!ddoc._module_cache) {
+ ddoc._module_cache = {};
+ }
var require = function(name, module) {
module = module || {};
- var newModule = resolveModule(name.split('/'), module, ddoc);
- var s = "function (module, exports, require) { " + newModule.current + " }";
- try {
- var func = sandbox ? evalcx(s, sandbox) : eval(s);
- func.apply(sandbox, [newModule, newModule.exports, function(name) {return require(name, newModule)}]);
- } catch(e) {
- throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()];
+ var newModule = resolveModule(name.split('/'), module.parent, ddoc);
+ if (!ddoc._module_cache.hasOwnProperty(newModule.id)) {
+ // create empty exports object before executing the module,
+ // stops circular requires from filling the stack
+ ddoc._module_cache[newModule.id] = {};
+ var s = "function (module, exports, require) { " + newModule.current + " }";
+ try {
+ var func = sandbox ? evalcx(s, sandbox) : eval(s);
+ func.apply(sandbox, [newModule, newModule.exports, function(name) {
+ return require(name, newModule);
+ }]);
+ } catch(e) {
+ throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()];
+ }
+ ddoc._module_cache[newModule.id] = newModule.exports;
}
- return newModule.exports;
+ return ddoc._module_cache[newModule.id];
}
sandbox.require = require;
}
Modified: couchdb/branches/1.1.x/share/www/script/test/design_docs.js
URL: http://svn.apache.org/viewvc/couchdb/branches/1.1.x/share/www/script/test/design_docs.js?rev=1102017&r1=1102016&r2=1102017&view=diff
==============================================================================
--- couchdb/branches/1.1.x/share/www/script/test/design_docs.js (original)
+++ couchdb/branches/1.1.x/share/www/script/test/design_docs.js Wed May 11 18:50:41 2011
@@ -49,7 +49,48 @@ couchTests.design_docs = function(debug)
whynot : "exports.test = require('../stringzone'); " +
"exports.foo = require('whatever/stringzone');",
upper : "exports.testing = require('./whynot').test.string.toUpperCase()+" +
- "module.id+require('./whynot').foo.string"
+ "module.id+require('./whynot').foo.string",
+ circular_one: "require('./circular_two'); exports.name = 'One';",
+ circular_two: "require('./circular_one'); exports.name = 'Two';"
+ },
+ // paths relative to parent
+ idtest1: {
+ a: {
+ b: {d: "module.exports = require('../c/e').id;"},
+ c: {e: "exports.id = module.id;"}
+ }
+ },
+ // multiple paths relative to parent
+ idtest2: {
+ a: {
+ b: {d: "module.exports = require('../../a/c/e').id;"},
+ c: {e: "exports.id = module.id;"}
+ }
+ },
+ // paths relative to module
+ idtest3: {
+ a: {
+ b: "module.exports = require('./c/d').id;",
+ c: {
+ d: "module.exports = require('./e');",
+ e: "exports.id = module.id;"
+ }
+ }
+ },
+ // paths relative to module and parent
+ idtest4: {
+ a: {
+ b: "module.exports = require('../a/./c/d').id;",
+ c: {
+ d: "module.exports = require('./e');",
+ e: "exports.id = module.id;"
+ }
+ }
+ },
+ // paths relative to root
+ idtest5: {
+ a: "module.exports = require('whatever/idtest5/b').id;",
+ b: "exports.id = module.id;"
}
},
views: {
@@ -134,6 +175,25 @@ couchTests.design_docs = function(debug)
(function() {
var lib = require('whatever/commonjs/upper');
return JSON.stringify(this);
+ }).toString(),
+ circular_require:
+ (function() {
+ return require('whatever/commonjs/circular_one').name;
+ }).toString(),
+ idtest1: (function() {
+ return require('whatever/idtest1/a/b/d');
+ }).toString(),
+ idtest2: (function() {
+ return require('whatever/idtest2/a/b/d');
+ }).toString(),
+ idtest3: (function() {
+ return require('whatever/idtest3/a/b');
+ }).toString(),
+ idtest4: (function() {
+ return require('whatever/idtest4/a/b');
+ }).toString(),
+ idtest5: (function() {
+ return require('whatever/idtest5/a');
}).toString()
}
}; // designDoc
@@ -174,6 +234,52 @@ couchTests.design_docs = function(debug)
T(xhr.status == 200);
TEquals("javascript", JSON.parse(xhr.responseText).language);
+ // test circular commonjs dependencies
+ xhr = CouchDB.request(
+ "GET",
+ "/test_suite_db/_design/test/_show/circular_require"
+ );
+ TEquals(200, xhr.status);
+ TEquals("One", xhr.responseText);
+
+ // Test that changes to the design doc properly invalidate cached modules:
+
+ // update the designDoc and replace
+ designDoc.whatever.commonjs.circular_one = "exports.name = 'Updated';"
+ T(db.save(designDoc).ok);
+
+ // request circular_require show function again and check the response has
+ // changed
+ xhr = CouchDB.request(
+ "GET",
+ "/test_suite_db/_design/test/_show/circular_require"
+ );
+ TEquals(200, xhr.status);
+ TEquals("Updated", xhr.responseText);
+
+
+ // test module id values are as expected:
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/idtest1");
+ TEquals(200, xhr.status);
+ TEquals("whatever/idtest1/a/c/e", xhr.responseText);
+
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/idtest2");
+ TEquals(200, xhr.status);
+ TEquals("whatever/idtest2/a/c/e", xhr.responseText);
+
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/idtest3");
+ TEquals(200, xhr.status);
+ TEquals("whatever/idtest3/a/c/e", xhr.responseText);
+
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/idtest4");
+ TEquals(200, xhr.status);
+ TEquals("whatever/idtest4/a/c/e", xhr.responseText);
+
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/idtest5");
+ TEquals(200, xhr.status);
+ TEquals("whatever/idtest5/b", xhr.responseText);
+
+
var prev_view_sig = db.designInfo("_design/test").view_index.signature;
var prev_view_size = db.designInfo("_design/test").view_index.disk_size;