Как я могу вызвать функции для документов, извлеченных из CouchDB? - PullRequest
3 голосов
/ 26 января 2012

Я использую Cradle для хранения объектов в CouchDB с моего сервера Node.js. Объекты содержат функции ....

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 ]

2 голосов
/ 26 января 2012

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

0 голосов
/ 04 мая 2014

Есть способ сохранить функции в CouchDB: как вложения .

Определите ваши функции в отдельном файле .js (например, набор функций, которыми вы хотите поделиться на нескольких серверах или экземплярах приложения).

/ модули / 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()
...