You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by jc...@apache.org on 2010/02/25 02:20:07 UTC

svn commit: r916076 - in /couchdb/trunk/share: server/loop.js server/render.js server/util.js www/script/test/design_docs.js

Author: jchris
Date: Thu Feb 25 01:20:07 2010
New Revision: 916076

URL: http://svn.apache.org/viewvc?rev=916076&view=rev
Log:
commonjs require for show list etc via Mikeal Rogers. closes COUCHDB-658

Modified:
    couchdb/trunk/share/server/loop.js
    couchdb/trunk/share/server/render.js
    couchdb/trunk/share/server/util.js
    couchdb/trunk/share/www/script/test/design_docs.js

Modified: couchdb/trunk/share/server/loop.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/server/loop.js?rev=916076&r1=916075&r2=916076&view=diff
==============================================================================
--- couchdb/trunk/share/server/loop.js (original)
+++ couchdb/trunk/share/server/loop.js Thu Feb 25 01:20:07 2010
@@ -74,7 +74,7 @@
             if (i+1 == funPath.length) {
               fun = point[funPath[i]]
               if (typeof fun != "function") {
-                fun = Couch.compileFunction(fun);
+                fun = Couch.compileFunction(fun, ddoc);
                 // cache the compiled fun on the ddoc
                 point[funPath[i]] = fun
               };

Modified: couchdb/trunk/share/server/render.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/server/render.js?rev=916076&r1=916075&r2=916076&view=diff
==============================================================================
--- couchdb/trunk/share/server/render.js (original)
+++ couchdb/trunk/share/server/render.js Thu Feb 25 01:20:07 2010
@@ -210,6 +210,11 @@
     return s;
   };
 
+  function isDocRequestPath(info) {
+    var path = info.path;
+    return path.length > 5;
+  };
+
   function runShow(fun, ddoc, args) {
     try {
       resetList();
@@ -239,7 +244,7 @@
         throw(["error", "render_error", "undefined response from show function"]);      
       }
     } catch(e) {
-      if(args[0] === null) {
+      if (args[0] === null && isDocRequestPath(args[1])) {
         throw(["error", "not_found", "document not found"]);
       } else {
         renderError(e, fun.toSource());

Modified: couchdb/trunk/share/server/util.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/server/util.js?rev=916076&r1=916075&r2=916076&view=diff
==============================================================================
--- couchdb/trunk/share/server/util.js (original)
+++ couchdb/trunk/share/server/util.js Thu Feb 25 01:20:07 2010
@@ -10,15 +10,66 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
+var resolveModule = function(names, parent, current) {
+  if (names.length == 0) {
+    if (typeof current != "string") {
+      throw ["error","invalid_require_path",
+        'Must require a JavaScript string, not: '+(typeof current)];
+    }
+    return [current, parent];
+  }
+  // we need to traverse the path
+  var n = names.shift();
+  if (n == '..') {
+    if (!(parent && parent.parent)) {
+      throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(current)];
+    }
+    return resolveModule(names, parent.parent.parent, parent.parent);
+  } else if (n == '.') {
+    if (!parent) {
+      throw ["error", "invalid_require_path", 'Object has no parent '+JSON.stringify(current)];
+    }
+    return resolveModule(names, parent.parent, parent);
+  }
+  if (!current[n]) {
+    throw ["error", "invalid_require_path", 'Object has no property "'+n+'". '+JSON.stringify(current)];
+  }
+  var p = current
+  current = current[n];
+  current.parent = p;
+  return resolveModule(names, p, current)
+}
+
 var Couch = {
   // moving this away from global so we can move to json2.js later
   toJSON : function (val) {
     return JSON.stringify(val);
   },
-  compileFunction : function(source) {
+  compileFunction : function(source, ddoc) {    
     if (!source) throw(["error","not_found","missing function"]);
     try {
-      var functionObject = sandbox ? evalcx(source, sandbox) : eval(source);
+      if (sandbox) {
+        if (ddoc) {
+          var require = function(name, parent) {
+            var exports = {};
+            var resolved = resolveModule(name.split('/'), parent, ddoc);
+            var source = resolved[0]; 
+            parent = resolved[1];
+            var s = "function (exports, require) { " + source + " }";
+            try {
+              var func = sandbox ? evalcx(s, sandbox) : eval(s);
+              func.apply(sandbox, [exports, function(name) {return require(name, parent, source)}]);
+            } catch(e) { 
+              throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()]; 
+            }
+            return exports;
+          }
+          sandbox.require = require;
+        }
+        var functionObject = evalcx(source, sandbox);
+      } else {
+        var functionObject = eval(source);
+      }
     } catch (err) {
       throw(["error", "compilation_error", err.toSource() + " (" + source + ")"]);
     };

Modified: couchdb/trunk/share/www/script/test/design_docs.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/design_docs.js?rev=916076&r1=916075&r2=916076&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/design_docs.js (original)
+++ couchdb/trunk/share/www/script/test/design_docs.js Thu Feb 25 01:20:07 2010
@@ -38,6 +38,13 @@
   var designDoc = {
     _id:"_design/test", // turn off couch.js id escaping?
     language: "javascript",
+    whatever : {
+      stringzone : "exports.string = 'plankton';",
+      commonjs : {
+        whynot : "exports.test = require('../stringzone')",
+        upper : "exports.testing = require('./whynot').test.string.toUpperCase()"
+      }
+    },
     views: {
       all_docs_twice: {map: "function(doc) { emit(doc.integer, null); emit(doc.integer, null) }"},
       no_docs: {map: "function(doc) {}"},
@@ -50,9 +57,11 @@
                 reduce:"function (keys, values) { return \"" + makebigstring(16) + "\"; };"}
     },
     shows: {
-      simple: "function() {return 'ok'};"
+      simple: "function() {return 'ok'};",
+      requirey : "function() { var lib = require('whatever/commonjs/upper'); return lib.testing; };"
     }
-  }
+  }; 
+
   var xhr = CouchDB.request("PUT", "/test_suite_db_a/_design/test", {body: JSON.stringify(designDoc)});
   var resp = JSON.parse(xhr.responseText);
   
@@ -74,6 +83,11 @@
   T(xhr.status == 200);
   TEquals("ok", xhr.responseText, 'query server used wrong ddoc');
 
+  // test commonjs require
+  var xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/requirey");
+  T(xhr.status == 200);
+  TEquals("PLANKTON", xhr.responseText);
+
   // test that we get design doc info back
   var dinfo = db.designInfo("_design/test");
   TEquals("test", dinfo.name);