admin管理员组

文章数量:1317898

The quick overview is this: for my web app I can write most of my functionality using CouchApp and CouchDB views, etc. I love the feature of CouchApp that pushes my code up to the server via replication- this makes the deployment cycle very easy.

However, to do some arbitrary work not supported in couchdb and works around a few limitations, I need to put a web platform in front of CouchDB. I'm considering building this in node.js because it uses JavaScript and I want to continue the easy deployment method of pushing code into the database.

Here's how i imagine it working: - I write a web server/service in node.js using the normal method and the node mand to start it. - this sevice connects to couch db and gets a virtual list and a URL mapping list. This list is stored in redis for quick lookup. This list will tell the server, when it gets a request, based on host and path, etc, which handler is to be run. - the server fetches the handler- which is just a document, it could be a design document or an arbitrary json document in couchdb. And then executes that handler to handle the request, as if I'd writte the handler as part of node js.

So the question is, how to get a son data structure that contains a JavaScript function in it, in text form, and execute that function?

This may be blindingly obvious, but i e from a piled background, so normally there would be a pilation step here that makes this pretty much impossible.

So, what I'm thinking is in pseudo code: Var string thecode = getValueForMapKey(handlerFunctionIWant); somehowmagicallyexecute(thecode)

Is there an exec or run function that will do the magical execution step above in JavaScript?

The quick overview is this: for my web app I can write most of my functionality using CouchApp and CouchDB views, etc. I love the feature of CouchApp that pushes my code up to the server via replication- this makes the deployment cycle very easy.

However, to do some arbitrary work not supported in couchdb and works around a few limitations, I need to put a web platform in front of CouchDB. I'm considering building this in node.js because it uses JavaScript and I want to continue the easy deployment method of pushing code into the database.

Here's how i imagine it working: - I write a web server/service in node.js using the normal method and the node mand to start it. - this sevice connects to couch db and gets a virtual list and a URL mapping list. This list is stored in redis for quick lookup. This list will tell the server, when it gets a request, based on host and path, etc, which handler is to be run. - the server fetches the handler- which is just a document, it could be a design document or an arbitrary json document in couchdb. And then executes that handler to handle the request, as if I'd writte the handler as part of node js.

So the question is, how to get a son data structure that contains a JavaScript function in it, in text form, and execute that function?

This may be blindingly obvious, but i e from a piled background, so normally there would be a pilation step here that makes this pretty much impossible.

So, what I'm thinking is in pseudo code: Var string thecode = getValueForMapKey(handlerFunctionIWant); somehowmagicallyexecute(thecode)

Is there an exec or run function that will do the magical execution step above in JavaScript?

Share Improve this question asked Sep 15, 2010 at 20:18 JimJim 553 bronze badges 3
  • Interesting idea -- pulling code from couchdb on the fly -- did you ever go ahead with it? – Nick Perkins Commented Jun 13, 2011 at 4:39
  • I have seen people do this successfully. With this technique, you can deploy simultaneous CouchDB and Node.js upgrades. – JasonSmith Commented Feb 1, 2012 at 3:08
  • Normally if the javascript does not change, you put the code in _attachments/script and load it using <script src="…"></script>. If it changes you can create an ordinary document (outside of the design doc), and fetch it also, with a script tag. To be dynamic, you can load several files and only execute the one you need. Only do ajax, eval, db.get etc if you have to. – ctrl-alt-delor Commented Mar 17, 2014 at 10:32
Add a ment  | 

2 Answers 2

Reset to default 11

It will run in the node.js context.

You can also use it in node, like this, as a dynamic function:

var cradle = require('cradle');
var db = new(cradle.Connection)().database('db_name');

db.get('_design/node%2Fyour_code', function (err, doc) {
  if (!err){
    var your_code = new Function(doc['arguments'].join(','), doc.code);
    your_code("cool", "also cool");
  }else{
    console.error('error:', err);
  }
});

make your docs look like this:

{
   "_id": "_design/node/your_code",
   "arguments": [
       "nameOfArg1",
       "nameOfArg2"
   ],
   "code": "console.log('arg1', nameOfArg1); console.log('arg2', nameOfArg2);"
}

It's in the same scope as where the new Function is called, so you have access to cradle, or you can require other libs, which will be loaded as if it was an anon function in that scope.

Put it in a design doc, then only admin can make changes, out of the box.

Here is a nicer, but similar approach:

// Format, in db:
doc = {
   "_id": "_design/node",
   "your_function_name": {
       "arguments": [
           "nameOfArg1",
           "nameOfArg2"
       ],
       "code": "console.log('arg1', nameOfArg1); console.log('arg2', nameOfArg2);"
   },
   "your_other_function_name": {
       "arguments": [
           "name"
       ],
       "code": "console.log('hello', name, 'how\\'s it going, bro?');"
   }
};


var cradle = require('cradle');
var db = new(cradle.Connection)().database('db_name');

function run_from_db(name, args){
  db.get('_design/node', function (err, doc) {
    if (!err){
      if (doc[name] !== undefined){
        var fn = new Function(doc[name]['arguments'].join(','), doc[name].code);
        fn.apply(fn, args);
      }else{
        console.error("could not find", name, "in _design/node");
      }
    }else{
      console.error(err);
    }
  });
}


run_from_db('your_other_function_name', ['konsumer']);

this will output:

hello konsumer how's it going, bro?

eval(handlerFunctionIwant) is the call to execute it. You need to make sure that there's no way for hackers to inject code into that string, of course.

It is not clear to me if this will evaluate it in a context that has access to other javescript resources, such as the rest of node.js or access to your couchdb library.

本文标签: Can nodejs execute JavaScript functions pulled from CouchDB like CouchApp does HowStack Overflow