2012-01-26 2 views
3

Я использую Cradle для хранения объектов в CouchDB с моего сервера 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 
+0

Мне было бы интересно иметь модуль, который бы сохранил ссылки функций на db, и вы могли бы вызвать их при их извлечении. Что-то вроде dnode делает. – fent

ответ

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

+0

Спасибо, Ray, это ответ, к сожалению, я не мог заставить ваш модуль работать, поэтому я закончил загрузку и ./ вместо этого потребовал, чтобы этот файл получил функцию «продлить» ... https://raw.github.com /DracoBlue/spludo/master/core/util.js –

+0

@MichaelDausmann вы могли бы выделить, какая часть его не работает? Я исправлю это, если вы откроете отчет об ошибке на pd. – Raynos

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() 
Смежные вопросы