简体   繁体   English

node.js可以像CouchApp那样执行从CouchDB中提取的JavaScript函数吗? 怎么样?

[英]Can node.js execute JavaScript functions pulled from CouchDB like CouchApp does? How?

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. 快速概述是这样的:对于我的Web应用程序,我可以使用CouchApp和CouchDB视图等编写我的大部分功能。我喜欢CouchApp的功能,它通过复制将我的代码推送到服务器 - 这使得部署周期非常容易。

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. 但是,要做一些在couchdb中不支持的任意工作并解决一些限制,我需要在CouchDB前放置一个Web平台。 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. 我正在考虑在node.js中构建它,因为它使用JavaScript,我想继续将代码推送到数据库的简单部署方法。

Here's how i imagine it working: - I write a web server/service in node.js using the normal method and the node command to start it. 以下是我想象它的工作方式: - 我使用普通方法和node命令在node.js中编写Web服务器/服务来启动它。 - this sevice connects to couch db and gets a virtual list and a URL mapping list. - 此服务连接到沙发数据库并获取虚拟列表和URL映射列表。 This list is stored in redis for quick lookup. 此列表存储在redis中以便快速查找。 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. - 服务器获取处理程序 - 它只是一个文档,它可以是设计文档或couchdb中的任意json文档。 And then executes that handler to handle the request, as if I'd writte the handler as part of node js. 然后执行该处理程序来处理请求,就像我将处理程序写为节点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? 所以问题是,如何以文本形式获取包含JavaScript函数的子数据结构,并执行该函数?

This may be blindingly obvious, but i come from a compiled background, so normally there would be a compilation step here that makes this pretty much impossible. 这可能是非常明显的,但我来自编译后的背景,所以通常会有一个编译步骤,这使得这几乎不可能。

So, what I'm thinking is in pseudo code: Var string thecode = getValueForMapKey(handlerFunctionIWant); 所以,我在想的是伪代码:Var string thecode = getValueForMapKey(handlerFunctionIWant); somehowmagicallyexecute(thecode) somehowmagicallyexecute(导出代码)

Is there an exec or run function that will do the magical execution step above in JavaScript? 是否有一个exec或run函数可以在JavaScript中执行上面的魔术执行步骤?

It will run in the node.js context. 它将在node.js上下文中运行。

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. 它与调用新函数的范围相同,因此您可以访问cradle,或者您可以需要其他库,这些库将被加载,就好像它是该作用域中的anon函数一样。

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. eval(handlerFunctionIwant)是执行它的调用。 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. 我不清楚这是否会在可以访问其他javescript资源的上下文中对其进行评估,例如node.js的其余部分或对couchdb库的访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM