Comparing version 0.2.2 to 0.2.3
191
lib/model.js
var r = require('rethinkdb'); | ||
var Document = require('./document.js'); | ||
var Query = require('./query.js'); | ||
@@ -98,2 +99,4 @@ function Model(name, schema, settings, thinky) { | ||
if (this.joins[joinKey].type === 'hasOne') { | ||
result[joinKey] = new this.joins[joinKey].model(doc[joinKey], options); | ||
/* | ||
if (options.createJoinedDocuments === true) { | ||
@@ -105,4 +108,11 @@ result[joinKey] = new this.joins[joinKey].model(doc[joinKey], options); | ||
} | ||
*/ | ||
} | ||
else if (this.joins[joinKey].type === 'hasMany') { | ||
result[joinKey] = []; | ||
for(var i=0; i<doc[joinKey].length; i++) { | ||
result[joinKey].push(new this.joins[joinKey].model(doc[joinKey][i], options)); | ||
} | ||
/* | ||
if (options.createJoinedDocuments === true) { | ||
@@ -117,2 +127,3 @@ result[joinKey] = []; | ||
} | ||
*/ | ||
} | ||
@@ -313,2 +324,3 @@ } | ||
//TODO Move in Thinky? | ||
// Execute the query without wrapping the callback | ||
Model.prototype._execute = function(query, callback) { | ||
@@ -329,2 +341,3 @@ var self = this; | ||
// Execute the query with a wrapped callback | ||
Model.prototype.execute = function(query, callback) { | ||
@@ -398,2 +411,28 @@ var self = this; | ||
} | ||
}, | ||
any: function(model, callback) { | ||
return function(error, result) { | ||
if (error) { | ||
callback(error, null); | ||
} | ||
else if (typeof result.toArray === 'function') { | ||
result.toArray( function(error, results) { | ||
if (error) { | ||
callback(error, null); | ||
} | ||
else { | ||
var docs = []; | ||
for(var index=0; index<results.length; index++) { | ||
docs.push(new model(results[index], {saved: true})); | ||
} | ||
callback(null, docs); | ||
} | ||
}); | ||
} | ||
else { | ||
var doc = new model(result, {saved: true}); | ||
callback(null, doc); | ||
} | ||
} | ||
} | ||
@@ -404,147 +443,27 @@ | ||
// TODO: Refactor all queries | ||
Model.prototype.get = function(id, argCallback, options) { | ||
var self = this; | ||
var model = this.getModel(); | ||
var query, callback; | ||
if (Object.prototype.toString.call(id) === '[object Array]') { | ||
var query = r.db(model.thinkyOptions.db).table(model.name); | ||
query = query.getAll.apply(query, id); | ||
callback = self.callbacks.stream(self, argCallback); | ||
} | ||
else { | ||
query = r.db(model.thinkyOptions.db).table(model.name).get(id); | ||
if ((typeof options === 'object') && (options !== null) && (options.getJoin === true)) { | ||
query = this.getJoin(query, model, 'object'); | ||
} | ||
callback = self.callbacks.document(self, argCallback); | ||
} | ||
this._execute.call(self, query, callback); | ||
} | ||
// Chain the query with its joined tables. | ||
// TODO Implement arbitrary functions and hasMany relation | ||
Model.prototype.getJoin = function(query, model, type) { | ||
for(var fieldName in model.joins) { | ||
var otherModel = model.joins[fieldName].model.getModel(); | ||
var joinClause = model.joins[fieldName].joinClause; | ||
var joinType = model.joins[fieldName].type; | ||
if (typeof joinClause === 'object') { | ||
if (type === 'object') { | ||
if (joinType === 'hasOne') { | ||
query = query.do( function(doc) { | ||
return r.db(otherModel.thinkyOptions.db).table(otherModel.name) | ||
.getAll( doc(joinClause["leftKey"]), {index: joinClause["rightKey"]}).coerceTo('array').do( function(stream) { | ||
return r.branch( stream.count().gt(1), | ||
r.error("Found more than one match"), // TODO Improve error | ||
r.branch( stream.count().eq(0), | ||
r.expr(doc), | ||
doc.merge( | ||
r.expr([[fieldName, otherModel.getJoin(stream.nth(0), otherModel, 'object')]]).coerceTo('object') | ||
) | ||
) | ||
) | ||
}); | ||
}); | ||
} | ||
else if (joinType === 'hasMany') { | ||
query = query.do( function(doc) { | ||
return doc(joinClause["leftKey"]).concatMap( function(value) { | ||
return r.db(otherModel.thinkyOptions.db).table(otherModel.name) | ||
.getAll( value, {index: joinClause["rightKey"]}) | ||
}).coerceTo('array').do( function(stream) { | ||
return doc.merge( | ||
r.expr([[fieldName, otherModel.getJoin(stream, otherModel, 'stream')]]).coerceTo('object') | ||
) | ||
}); | ||
}); | ||
} | ||
} | ||
else if (type === 'stream') { | ||
if (joinType === 'hasOne') { | ||
query = query.map( function(doc) { | ||
return r.branch( | ||
doc.hasFields(joinClause["leftKey"]), | ||
r.db(otherModel.thinkyOptions.db).table(otherModel.name) | ||
.getAll( doc(joinClause["leftKey"]), {index: joinClause["rightKey"]}).coerceTo('array').do( function(stream) { | ||
return r.branch( stream.count().gt(1), | ||
r.error("Found more than one match"), // TODO Improve error | ||
r.branch( stream.count().eq(0), | ||
r.expr(doc), | ||
doc.merge( | ||
r.expr([[fieldName, otherModel.getJoin(stream.nth(0), otherModel, 'object')]]).coerceTo('object') | ||
) | ||
) | ||
) | ||
}), | ||
doc) | ||
}); | ||
} | ||
else if (joinType === 'hasMany') { | ||
query = query.map( function(doc) { | ||
return r.branch( | ||
doc.hasFields(joinClause["leftKey"]), | ||
doc(joinClause["leftKey"]).concatMap( function(joinValue) { | ||
return r.db(otherModel.thinkyOptions.db).table(otherModel.name) | ||
.getAll( joinValue, {index: joinClause["rightKey"]} ).coerceTo('array') | ||
}).do( function(stream) { | ||
return doc.merge( | ||
r.expr([[fieldName, otherModel.getJoin(stream, otherModel, 'stream')]]).coerceTo('object') | ||
) | ||
}), | ||
doc) | ||
}); | ||
} | ||
} | ||
} | ||
else if (typeof joinClause === 'function') { // the joinClause is a function | ||
//TODO | ||
} | ||
} | ||
Model.prototype.get = function(id, options, callback) { | ||
var query = new Query(this); | ||
query = query.get(id, options, callback); | ||
return query; | ||
} | ||
Model.prototype.getAll = function(id, index, argCallback, options) { | ||
var self = this; | ||
var model = this.getModel(); | ||
var query, callback; | ||
if (Object.prototype.toString.call(id) === '[object Array]') { | ||
var query = r.db(model.thinkyOptions.db).table(model.name); | ||
var args = []; | ||
for(var i=0; i<id.length; i++) { | ||
args.push(id[i]); | ||
} | ||
args.push({index: index}); | ||
query = query.getAll.apply(query, args); | ||
} | ||
else { | ||
query = r.db(model.thinkyOptions.db).table(model.name).getAll(id, {index: index}) | ||
} | ||
if ((typeof options === 'object') && (options !== null) && (options.getJoin === true)) { | ||
query = this.getJoin(query, model, 'stream'); | ||
} | ||
callback = self.callbacks.stream(self, argCallback); | ||
this._execute.call(self, query, callback); | ||
// Merge getAll in get? | ||
Model.prototype.getAll = function(id, options, callback) { | ||
var query = new Query(this); | ||
query = query.getAll(id, options, callback); | ||
return query; | ||
} | ||
Model.prototype.filter = function(filter, argCallback, options) { | ||
var self = this; | ||
var model = this.getModel(); | ||
var query = r.db(model.thinkyOptions.db).table(model.name).filter(filter) | ||
if ((typeof options === 'object') && (options !== null) && (options.getJoin === true)) { | ||
query = this.getJoin(query, model, 'stream'); | ||
} | ||
var callback = self.callbacks.stream(self, argCallback); | ||
this._execute.call(self, query, callback); | ||
Model.prototype.filter = function(filter, options, callback) { | ||
var query = new Query(this); | ||
query = query.filter(filter, options, callback); | ||
return query; | ||
} | ||
Model.prototype.count = function(argCallback) { | ||
var self = this; | ||
var model = this.getModel(); | ||
var query = r.db(model.thinkyOptions.db).table(model.name).count() | ||
var callback = self.callbacks.value(self, argCallback); | ||
this._execute.call(self, query, callback); | ||
Model.prototype.count = function(callback) { | ||
var query = new Query(this); | ||
query = query.count(callback); | ||
return query; | ||
} | ||
@@ -551,0 +470,0 @@ |
{ | ||
"name": "thinky", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"description": "RethinkDB ORM for Node.js", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -68,2 +68,3 @@ # Thinky | ||
### Roadmap | ||
- Stick closer to the driver -- Things will be chainable | ||
- Add examples on how to use Thinky. | ||
@@ -70,0 +71,0 @@ - Clean/reorganize tests and add more tests. |
@@ -418,3 +418,3 @@ var thinky = require('../lib/index.js'); | ||
it('should retrieve a document in the database', function(done){ | ||
Cat.get(scope.catou.id, function(error, result) { | ||
Cat.get(scope.catou.id, null, function(error, result) { | ||
should(_.isEqual(result, scope.catou)); | ||
@@ -425,3 +425,3 @@ done(); | ||
it('should retrieve documents in the database', function(done){ | ||
Cat.get([scope.catou.id, scope.minou.id], function(error, result) { | ||
Cat.get([scope.catou.id, scope.minou.id], null, function(error, result) { | ||
should.not.exists(error); | ||
@@ -433,2 +433,20 @@ result.should.have.length(2); | ||
}); | ||
//TODO Move this test elsewhere // just testing chaining for now | ||
it('with limit should work', function(done){ | ||
Cat.get([scope.catou.id, scope.minou.id]).skip(1).limit(1, null, function(error, result) { | ||
should.not.exists(error); | ||
result.should.have.length(1); | ||
should((result[0].id === scope.catou.id) || (result[0].id === scope.minou.id)); | ||
done(); | ||
}) | ||
}); | ||
it('should work with manually calling run', function(done){ | ||
Cat.get([scope.catou.id, scope.minou.id]).skip(1).limit(1).run(function(error, result) { | ||
should.not.exists(error); | ||
result.should.have.length(1); | ||
should((result[0].id === scope.catou.id) || (result[0].id === scope.minou.id)); | ||
done(); | ||
}) | ||
}); | ||
}); | ||
@@ -453,3 +471,3 @@ describe('getAll', function() { | ||
it('should retrieve some documents in the database -- single values', function(done){ | ||
Cat.getAll(scope.catou.name, 'name', function(error, result) { | ||
Cat.getAll(scope.catou.name, {index: 'name'}, function(error, result) { | ||
should.not.exist(error); | ||
@@ -461,3 +479,3 @@ should(result.length >= 1); | ||
it('should retrieve some documents in the database -- multiple values', function(done){ | ||
Cat.getAll([scope.catou.name, scope.minou.name], 'name', function(error, result) { | ||
Cat.getAll([scope.catou.name, scope.minou.name], {index: 'name'}, function(error, result) { | ||
should.not.exists(error); | ||
@@ -469,2 +487,3 @@ should(result.length >= 2); | ||
}); | ||
describe('execute', function() { | ||
@@ -480,2 +499,3 @@ it('should be able to execute arbitrary queries', function(done){ | ||
}) | ||
describe('filter', function() { | ||
@@ -500,2 +520,3 @@ var Cat; | ||
Cat.filter(function(doc) { return r.expr([catouCopy.id, minouCopy.id]).contains(doc("id")) }, | ||
null, | ||
function(error, result) { | ||
@@ -510,2 +531,3 @@ should.not.exists(error); | ||
Cat.filter(function(doc) { return true }, | ||
null, | ||
function(error, result) { | ||
@@ -519,2 +541,3 @@ should.not.exists(error); | ||
}); | ||
describe('count', function() { | ||
@@ -524,2 +547,3 @@ it('should return the number of document in the table', function(done){ | ||
Cat.filter(function(doc) { return true }, | ||
null, | ||
function(error, result) { | ||
@@ -537,2 +561,3 @@ should.not.exists(error); | ||
// Testing events | ||
@@ -678,3 +703,3 @@ describe('on', function() { | ||
it('get should be able to get joined documents', function(done) { | ||
var catou = Cat.get(catou_id, function(error, result) { | ||
var catou = Cat.get(catou_id, {getJoin: true}, function(error, result) { | ||
should.not.exist(error); | ||
@@ -687,6 +712,6 @@ should.exist(result.id); | ||
done(); | ||
}, {getJoin: true}) | ||
}) | ||
}); | ||
it('get should be able to get joined documents -- and they should be `saved`', function(done) { | ||
var catou = Cat.get(catou_id, function(error, result) { | ||
var catou = Cat.get(catou_id, {getJoin: true}, function(error, result) { | ||
should(result.getDocument().docSettings.saved, true) | ||
@@ -696,3 +721,3 @@ should(result.owner.getDocument().docSettings.saved, true) | ||
done(); | ||
}, {getJoin: true}) | ||
}) | ||
}); | ||
@@ -724,3 +749,3 @@ it('getAll should work -- nested joins', function(done) { | ||
catou1.save( function(error, result) { | ||
Cat.getAll([catou.id, catou1.id], 'id', function(error, result) { | ||
Cat.getAll([catou.id, catou1.id], {index: 'id', getJoin: true}, function(error, result) { | ||
result.should.have.length(2); | ||
@@ -742,3 +767,3 @@ | ||
}, {getJoin: true}) | ||
}) | ||
}, {saveJoin: true}) | ||
@@ -773,20 +798,22 @@ | ||
catou1.save( function(error, result) { | ||
Cat.filter(function(doc) { return r.expr([catou.id, catou1.id]).contains(doc("id")) }, function(error, result) { | ||
result.should.have.length(2); | ||
Cat.filter(function(doc) { return r.expr([catou.id, catou1.id]).contains(doc("id")) }, | ||
{getJoin: true}, | ||
function(error, result) { | ||
result.should.have.length(2); | ||
should.exist(result[0].id); | ||
should.exist(result[0].idHuman); | ||
should.exist(result[0].owner.id); | ||
should.exist(result[0].owner.idMom); | ||
should.exist(result[0].owner.mom.id); | ||
should.exist(result[0].id); | ||
should.exist(result[0].idHuman); | ||
should.exist(result[0].owner.id); | ||
should.exist(result[0].owner.idMom); | ||
should.exist(result[0].owner.mom.id); | ||
should.exist(result[1].id); | ||
should.exist(result[1].idHuman); | ||
should.exist(result[1].owner.id); | ||
should.exist(result[1].owner.idMom); | ||
should.exist(result[1].owner.mom.id); | ||
should.exist(result[1].id); | ||
should.exist(result[1].idHuman); | ||
should.exist(result[1].owner.id); | ||
should.exist(result[1].owner.idMom); | ||
should.exist(result[1].owner.mom.id); | ||
done(); | ||
}, {getJoin: true}) | ||
done(); | ||
} | ||
) | ||
}, {saveJoin: true}) | ||
@@ -811,2 +838,3 @@ | ||
}); | ||
it('should be able to save the joined doc', function(done) { | ||
@@ -831,3 +859,3 @@ catou = new Cat({name: "Catou"}); | ||
it('get should be able to get joined documents', function(done) { | ||
Cat.get(catou.id, function(error, result) { | ||
Cat.get(catou.id, {getJoin: true}, function(error, result) { | ||
result.taskIds.should.have.length(3); | ||
@@ -842,6 +870,6 @@ should.exist(result.taskIds[0]); | ||
done(); | ||
}, {getJoin: true}) | ||
}) | ||
}); | ||
it('get should be able to get joined documents -- and they should be `saved`', function(done) { | ||
Cat.get(catou.id, function(error, result) { | ||
Cat.get(catou.id, {getJoin: true}, function(error, result) { | ||
should(result.tasks[0].getDocument().docSettings.saved, true); | ||
@@ -851,6 +879,6 @@ should(result.tasks[1].getDocument().docSettings.saved, true); | ||
done(); | ||
}, {getJoin: true}) | ||
}) | ||
}); | ||
it('getAll should work', function(done) { | ||
Cat.getAll([catou.id], 'id', function(error, result) { | ||
Cat.getAll([catou.id], {getJoin: true, index: 'id'}, function(error, result) { | ||
result.should.have.length(1); | ||
@@ -866,19 +894,21 @@ result[0].taskIds.should.have.length(3); | ||
done(); | ||
}, {getJoin: true}) | ||
}) | ||
}); | ||
it('filter should work', function(done) { | ||
Cat.filter(function(doc) { return doc("id").eq(catou.id) }, function(error, result) { | ||
result.should.have.length(1); | ||
result[0].taskIds.should.have.length(3); | ||
should.exist(result[0].taskIds[0]); | ||
should.exist(result[0].taskIds[1]); | ||
should.exist(result[0].taskIds[2]); | ||
should.exist(result[0].tasks[0].id); | ||
should.exist(result[0].tasks[1].id); | ||
should.exist(result[0].tasks[2].id); | ||
catou.tasks.should.have.length(3); | ||
done(); | ||
}, {getJoin: true}) | ||
Cat.filter(function(doc) { return doc("id").eq(catou.id) }, | ||
{getJoin: true}, | ||
function(error, result) { | ||
result.should.have.length(1); | ||
result[0].taskIds.should.have.length(3); | ||
should.exist(result[0].taskIds[0]); | ||
should.exist(result[0].taskIds[1]); | ||
should.exist(result[0].taskIds[2]); | ||
should.exist(result[0].tasks[0].id); | ||
should.exist(result[0].tasks[1].id); | ||
should.exist(result[0].tasks[2].id); | ||
catou.tasks.should.have.length(3); | ||
done(); | ||
} | ||
) | ||
}); | ||
@@ -885,0 +915,0 @@ }) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
235227
44
4741
100