如何调用从CouchDB检索的文档的函数?

时间:2012-01-26 12:36:34

标签: javascript node.js couchdb cradle

我正在使用Cradle从我的Node.js服务器在CouchDB中存储对象。对象包含函数....

function AnObject(a, b){
this.a = a; this.b = b;
this.addparts = function(){return this.a + this.b;};}

var cradle = require('cradle');
var db = new(cradle.Connection)('http://localhost', 5984, {cache: true, raw: false}).database('myDB');

var myObject = new AnObject(1, 2);
console.log("addparts:" + myObject.addparts());
db.save('myObjectId', myObject);

这样工作正常并且文档存储但是当我检索它时,我不能再对返回的文档调用该函数...

db.get('myObjectId', function(err, myRetrievedObject){
console.log("addparts:" + myRetrievedObject.addparts());
});

这失败了(属性不是函数)错误..

node cradle_test

cradle_test.js:21
console.log("addparts:" + myRetrievedObject.addparts());
                                         ^
TypeError: Property 'addparts' of object {"_id":"myObjectId","_rev":"2-83535db5101fedfe30a1548fa2641f29","a":1,"b":2,"addparts":"function (){return this.a + this.b;}"} is not a function

2 个答案:

答案 0 :(得分:2)

CouchDB存储JSON。函数无效JSON。函数永远不会存储在数据库中。

我建议您将这些功能移到原型中。

function AnObject(a, b){
    this.a = a; this.b = b;
}

AnObject.prototype.addparts = function(){
    return this.a + this.b;
};

db.get('myObjectId', function(err, myRetrievedObject){
    var obj = Object.create(AnObject.prototype);
    // for some value of extend ( https://github.com/Raynos/pd#pd.extend )
    extend(obj, myRetrievedObject);
    console.log("addparts:" + obj.addparts());
});

这样您的保存功能就可以使用您的方法对您的对象进行操作。您只需确保将检索到的对象设为AnObject的实例

答案 1 :(得分:0)

有一种方法可以在CouchDB中存储功能:作为附件

在单独的.js文件中定义您的函数 (例如,要在多个服务器或应用程序实例之间共享的一组函数)。

/modules/db.js:

var db = {}

db.insert = function(nanoDb, object, cb){
  //insert new doc
  nanoDb.insert(object, function(err, body, header) {
    if (!err) {
      cb.call(null, {success: true, data: body});

    }else{
      console.log('[insert] ', err.message); 
      cb.call(null, {success: false, error: err.message});
    }
  });
}

db.bulkInsert = function(nanoDb, array, cb){
  //structure for bulk insert
  var data = {
    docs: array
  }
  //insert new doc
  nanoDb.bulk(data, function(err, body, header) {
    if (!err) {
      cb.call(null, {success: true, data: body});

    }else{
      console.log('[bulkInsert] ', err.message); 
      cb.call(null, {success: false, error: err.message});
    }
  });
}

db.bulkDelete = function(nanoDb, array, cb){
  for(i in array){
    array[i]._deleted = true;
  }
  var data = {
    docs: array
  }
  //check if the url exists in the db
  nanoDb.bulk(data, function(err, body) {
    if (!err){  
      cb.call(null, {success: true, data: data});
    }else{
      console.log('[bulkDelete] ', err.message);
      cb.call(null, {success: false, error: err.message});
    }
  });
}

db.view = function(nanoDb, design, view, params, cb){
  nanoDb.view(design, view, params, function(err, body) {
    if (!err){
      var docs = util.extractDocs(body);
      cb.call(null, {success: true, data: docs});
    }else{
      console.log('[view] ', err.message);
      cb.call(null, {success: false, error: err.message});
    }
  });
}

db.search = function(nanoDb, design, index, params, cb){
  nanoDb.search(design, index, params, function(err, body) {
    if (!err) {
      var docs = util.extractDocsSearch(body);
      cb.call(null, {success: true, data: docs});
    }else{
      console.log('[search] ', err.message);
      cb.call(null, {success: false, error: err.message});
    }
  }); 
}

db.follow = function(nanoDb, params){
  var feed = nanoDb.follow(params);
  return feed;
}

module.exports = db;

使用CouchApp将功能部署为附件(在设计文档中):

//your couchapp
var couchapp = require('couchapp')

//url to your database
var url = '...';

//empty design doc (for attachments)
ddoc = {
  _id: '_design/mods'
};

//folder containing .js files
couchapp.loadAttachments(ddoc, './modules/');

//this function uploads your attachments
couchapp.createApp(ddoc, url, function(app) {
  app.push(function(){
    //do something
  });
});

现在,在任何需要的地方获取功能:

//use mikaels request module if you like
var request = require('request');

//tell the app where to get your .js file
//sometimes a good idea to persist these references in memory or even in your couchdb
var fileUrl = '/_design/modules/db.js'

//set this variable in the proper scope
var db;

//we'll use this to 'require' the .js file
var _require = function(src, file) {
  var m = new module.constructor();
  m.paths = module.paths;
  m._compile(src, file);
  return m.exports;
}

request({ url: fileUrl, json: true }, function (err, response, data) {
  if (!err && response.statusCode === 200) {
    //now we assign our required .js file (object w/functions) back into usable form
    //woot woot!
    db = _require(data);
  }else{
    console.log('[request]', err);
  }
});

做点什么!

db.doSomething()