Comparing version 3.0.2 to 3.0.3
932
lib/model.js
@@ -7,58 +7,9 @@ 'use strict'; | ||
* @author <a href="mailto:plopes@roughcookie.com">Paulo Lopes</a> | ||
* @version 2.0 | ||
* @version 3.0 | ||
*/ | ||
var mongodb = require('mongodb'); | ||
var baseModel = require('./protos/freemodel'); | ||
var schemaModel = require('./protos/schemamodel'); | ||
var embedSchemaModel = require('./protos/embedschemamodel'); | ||
var ObjectID = mongodb.BSONPure.ObjectID; | ||
var objectIdRegExp = /^[0-9a-fA-F]{24}$/; | ||
/** | ||
* Extracts one option from the object and returns it. | ||
* @private | ||
*/ | ||
function extractOption(name, options, defaultValue) { | ||
var option = defaultValue; | ||
if (options) { | ||
if (options.hasOwnProperty(name)) { | ||
option = options[name]; | ||
delete options[name]; | ||
} | ||
} | ||
return option; | ||
} | ||
function extend(obj, proto, deep) { | ||
if (obj !== undefined && obj !== null) { | ||
var key; | ||
var keys = Object.keys(proto); | ||
var kl = keys.length; | ||
while (kl--) { | ||
key = keys[kl]; | ||
if (typeof proto[key] === 'object') { | ||
if (deep && obj.hasOwnProperty(key)) { | ||
// if type is object and obj has it too, recurse | ||
extend(obj[key], proto[key], deep); | ||
} | ||
} else { | ||
if (typeof obj === 'object') { | ||
if (obj[key] === undefined) { | ||
// set it if not defined in the object | ||
if (Array.isArray(obj)) { | ||
var i = obj.length; | ||
while (i--) { | ||
extend(obj[i], proto, deep); | ||
} | ||
} else { | ||
Object.defineProperty(obj, key, {value: proto[key]}); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return obj; | ||
} | ||
/** | ||
* Creates a new Document Model class | ||
@@ -81,876 +32,17 @@ * | ||
var hasSchema = false; | ||
if (schemaDef !== undefined && schemaDef !== null) { | ||
hasSchema = true; | ||
} | ||
/** | ||
* @name Model | ||
* @class Document Model Customized class for a mongodb document schema. | ||
* @param {Object} [json] if provided will update the current instance with the json properties | ||
*/ | ||
var Model = function (json) { | ||
if (hasSchema) { | ||
var filterUndefined = function (target, source) { | ||
if (source !== undefined && source !== null) { | ||
var key, value; | ||
// update new ones | ||
for (key in source) { | ||
if (source.hasOwnProperty(key)) { | ||
value = source[key]; | ||
if (value !== undefined) { | ||
if (typeof value === 'object') { | ||
if (value === null || value instanceof String || value instanceof Number || value instanceof Boolean || value instanceof Date || value instanceof ObjectID) { | ||
target[key] = value; | ||
} else { | ||
if (target[key] === undefined) { | ||
if (Array.isArray(value)) { | ||
target[key] = []; | ||
} else { | ||
target[key] = {}; | ||
} | ||
} | ||
filterUndefined(target[key], value); | ||
} | ||
} else { | ||
target[key] = value; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
filterUndefined(this, json); | ||
} | ||
// inheritance | ||
if (Model.$embeds !== undefined) { | ||
extend(this, Model.$embeds, true); | ||
} | ||
if (Model.onLoad !== undefined) { | ||
Model.onLoad(this); | ||
} | ||
}; | ||
var odm = this; | ||
if (schemaDef !== undefined && schemaDef !== null) { | ||
/** | ||
* schema for embedded objects | ||
* | ||
* @memberOf Model | ||
*/ | ||
Object.defineProperty(Model, '$schema', {value: odm.createSchema(schemaDef)}); | ||
} | ||
/** | ||
* Keep track of embeds (it is similar to prototype) | ||
*/ | ||
Object.defineProperty(Model, '$embeds', {value: {}}); | ||
/** | ||
* Finds one element of this collection by the given query. | ||
* | ||
* @memberOf Model | ||
* @param {Object} query Query object as in mongodb documentation | ||
* @param {Object|Function} [fields] filter fields | ||
* @param {Object|Function} [options] Query options, such as skip, limit, etc | ||
* @param {Function} callback Callback function (error, model) with the result of the operation | ||
*/ | ||
Model.findOne = function (query, fields, options, callback) { | ||
var hasFields = true; | ||
if (callback === undefined) { | ||
if (options === undefined) { | ||
callback = fields; | ||
options = {}; | ||
fields = {}; | ||
hasFields = false; | ||
} else { | ||
callback = options; | ||
options = fields; | ||
fields = {}; | ||
hasFields = false; | ||
} | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot findOne on embedded model'); | ||
} | ||
var wantExtend = extractOption('extend', options, true); | ||
var wantExtendDeep = extractOption('deepExtend', options, true); | ||
var pluck = extractOption('pluck', options); | ||
if (pluck !== undefined) { | ||
// state that we only care about the plucked field | ||
fields[pluck] = true; | ||
hasFields = true; | ||
} | ||
odm.findOne(mongoCollection, query, fields, options, function (err, documentLoaded) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
if (documentLoaded === null) { | ||
return callback(null, null); | ||
} | ||
if (hasFields) { | ||
if (pluck !== undefined) { | ||
documentLoaded = documentLoaded[pluck]; | ||
} | ||
} else { | ||
if (hasSchema && (wantExtend || wantExtendDeep)) { | ||
extend(documentLoaded, Model.prototype, wantExtendDeep); | ||
if (Model.$embeds !== undefined) { | ||
extend(documentLoaded, Model.$embeds, wantExtendDeep); | ||
} | ||
if (Model.onLoad !== undefined) { | ||
Model.onLoad(documentLoaded); | ||
} | ||
} | ||
} | ||
callback(null, documentLoaded); | ||
}); | ||
}; | ||
/** | ||
* Finds one element of this collection given its Id. | ||
* | ||
* @memberOf Model | ||
* @param {ObjectID|String} id Either a ObjectId instance or, the function will try to cast it to ObjectId. | ||
* @param {Object|Function} [fields] filter fields | ||
* @param {Object|Function} [options] Query options, such as skip, limit, etc | ||
* @param {Function} callback Callback function (error, model) with the result of the operation | ||
*/ | ||
Model.findById = function (id, fields, options, callback) { | ||
var hasFields = true; | ||
if (callback === undefined) { | ||
if (options === undefined) { | ||
callback = fields; | ||
options = {}; | ||
fields = {}; | ||
hasFields = false; | ||
} else { | ||
callback = options; | ||
options = fields; | ||
fields = {}; | ||
hasFields = false; | ||
} | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot findById on embedded model'); | ||
} | ||
var wantExtend = extractOption('extend', options, true); | ||
var wantExtendDeep = extractOption('deepExtend', options, true); | ||
var pluck = extractOption('pluck', options); | ||
if (pluck !== undefined) { | ||
// state that we only care about the plucked field | ||
fields[pluck] = true; | ||
hasFields = true; | ||
} | ||
if (id === undefined) { | ||
return callback('undefined id'); | ||
} | ||
var _id; | ||
var includeNotFound = extractOption('includeNotFound', options); | ||
if (id instanceof ObjectID) { | ||
_id = id; | ||
if (mongoCollection !== undefined) { | ||
return schemaModel(odm, mongoCollection, schemaDef); | ||
} else { | ||
if (typeof id === 'string' && id.length === 24 && objectIdRegExp.test(id)) { | ||
_id = ObjectID.createFromHexString(id); | ||
} else { | ||
return callback('invalid object id'); | ||
} | ||
return embedSchemaModel(odm, schemaDef); | ||
} | ||
} | ||
odm.findOne(mongoCollection, {_id: _id}, fields, options, function (err, documentLoaded) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
if (mongoCollection !== undefined) { | ||
return baseModel(odm, mongoCollection); | ||
} | ||
// if we search for an Id and get null it should return right away | ||
if (documentLoaded === null) { | ||
if (includeNotFound) { | ||
return callback(null, null); | ||
} else { | ||
return callback(mongoCollection + ' ' + _id.toHexString() + ' not found'); | ||
} | ||
} | ||
if (hasFields) { | ||
if (pluck !== undefined) { | ||
documentLoaded = documentLoaded[pluck]; | ||
} | ||
} else { | ||
if (hasSchema && (wantExtend || wantExtendDeep)) { | ||
extend(documentLoaded, Model.prototype, wantExtendDeep); | ||
if (Model.$embeds !== undefined) { | ||
extend(documentLoaded, Model.$embeds, wantExtendDeep); | ||
} | ||
if (Model.onLoad !== undefined) { | ||
Model.onLoad(documentLoaded); | ||
} | ||
} | ||
} | ||
callback(null, documentLoaded); | ||
}); | ||
}; | ||
/** | ||
* Free form find in collection. The result is returned as a Array of this model objects. | ||
* | ||
* @memberOf Model | ||
* @param {Object} query MongoDB Query | ||
* @param {Object|Function} [fields] filter the fields to be returned | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error, model) with the result of the operation | ||
*/ | ||
Model.find = function (query, fields, options, callback) { | ||
var hasFields = true; | ||
if (callback === undefined) { | ||
if (options === undefined) { | ||
callback = fields; | ||
options = {}; | ||
fields = {}; | ||
hasFields = false; | ||
} else { | ||
callback = options; | ||
options = fields; | ||
fields = {}; | ||
hasFields = false; | ||
} | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot find on embedded model'); | ||
} | ||
var wantExtend = extractOption('extend', options, true); | ||
var wantExtendDeep = extractOption('deepExtend', options, true); | ||
var pluck = extractOption('pluck', options); | ||
if (pluck !== undefined) { | ||
// state that we only care about the plucked field | ||
fields[pluck] = true; | ||
hasFields = true; | ||
} | ||
odm.find(mongoCollection, query, fields, options, function (err, documentsLoaded) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
var i, len; | ||
if (hasFields) { | ||
if (pluck !== undefined) { | ||
for (i = 0, len = documentsLoaded.length; i < len; i++) { | ||
documentsLoaded[i] = documentsLoaded[i][pluck]; | ||
} | ||
} | ||
} else { | ||
if (hasSchema && (wantExtend || wantExtendDeep)) { | ||
for (i = 0, len = documentsLoaded.length; i < len; i++) { | ||
extend(documentsLoaded[i], Model.prototype, wantExtendDeep); | ||
if (Model.$embeds !== undefined) { | ||
extend(documentsLoaded[i], Model.$embeds, wantExtendDeep); | ||
} | ||
if (Model.onLoad !== undefined) { | ||
Model.onLoad(documentsLoaded[i]); | ||
} | ||
} | ||
} | ||
} | ||
callback(null, documentsLoaded); | ||
}); | ||
}; | ||
/** | ||
* Finds all elements in this collection. | ||
* | ||
* @memberOf Model | ||
* @param {Object|Function} [fields] filter the fields to be returned | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error, model) with the result of the operation | ||
*/ | ||
Model.findAll = function (fields, options, callback) { | ||
Model.find({}, fields, options, callback); | ||
}; | ||
/** | ||
* Loads documents referenced by id/ids. This is a helper function that calls internally find or findById | ||
* with the correct parameters. The order of the return is guaranteed, while with a find it is not. | ||
* | ||
* @memberOf Model | ||
* @param {ObjectID|ObjectID[]} ids single or array of ObjectId objects | ||
* @param {Object|Function} [fields] filter the fields to be returned | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error, model) with the result of the operation | ||
*/ | ||
Model.loadDbRef = function (ids, fields, options, callback) { | ||
var hasFields = true; | ||
if (callback === undefined) { | ||
if (options === undefined) { | ||
callback = fields; | ||
options = {}; | ||
fields = {}; | ||
hasFields = false; | ||
} else { | ||
callback = options; | ||
options = fields; | ||
fields = {}; | ||
hasFields = false; | ||
} | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot loadDbRef on embedded model'); | ||
} | ||
var wantExtend = extractOption('extend', options, true); | ||
var wantExtendDeep = extractOption('deepExtend', options, true); | ||
var pluck = extractOption('pluck', options); | ||
if (pluck !== undefined) { | ||
// state that we only care about the plucked field | ||
fields[pluck] = true; | ||
hasFields = true; | ||
} | ||
// special case when the property does not exist | ||
if (ids === undefined) { | ||
callback(null, []); | ||
} | ||
if (Array.isArray(ids)) { | ||
if (ids.length === 0) { | ||
callback(null, []); | ||
} else { | ||
// convert the orig array to an index | ||
var index = {}; | ||
var i, len; | ||
var idsToFind = []; | ||
for (i = 0, len = ids.length; i < len; i++) { | ||
if (!(ids[i] instanceof ObjectID)) { | ||
return callback('Non ObjectId in the array'); | ||
} | ||
// build index for the missing data | ||
if (index[ids[i].toHexString()] === undefined) { | ||
index[ids[i].toHexString()] = [i]; | ||
idsToFind.push(ids[i]); | ||
} else { | ||
index[ids[i].toHexString()].push(i); | ||
} | ||
} | ||
// no items to search | ||
if (idsToFind.length === 0) { | ||
return callback(null, []); | ||
} | ||
odm.find(mongoCollection, {_id: {'$in': idsToFind}}, fields, options, function (err, documentsLoaded) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
var i, j, lenI, lenJ; | ||
var result = []; | ||
// using the index we have O(2n) complexity | ||
for (i = 0, lenI = documentsLoaded.length; i < lenI; i++) { | ||
var indexes = index[documentsLoaded[i]._id.toHexString()]; | ||
for (j = 0, lenJ = indexes.length; j < lenJ; j++) { | ||
if (hasFields) { | ||
if (pluck !== undefined) { | ||
result[indexes[j]] = documentsLoaded[i][pluck]; | ||
} | ||
} else { | ||
if (hasSchema && (wantExtend || wantExtendDeep)) { | ||
result[indexes[j]] = extend(documentsLoaded[i], Model.prototype, wantExtendDeep); | ||
if (Model.$embeds !== undefined) { | ||
result[indexes[j]] = extend(documentsLoaded[i], Model.$embeds, wantExtendDeep); | ||
} | ||
if (Model.onLoad !== undefined) { | ||
Model.onLoad(documentsLoaded[i]); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
callback(null, result); | ||
}); | ||
} | ||
} else { | ||
Model.findById(ids, options, callback); | ||
} | ||
}; | ||
/** | ||
* Ensure indexes are present | ||
* | ||
* @param fieldOrSpec | ||
* @param [options] | ||
* @param callback | ||
*/ | ||
Model.ensureIndex = function (fieldOrSpec, options, callback) { | ||
if (callback === undefined) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot ensureIndex on embedded model'); | ||
} | ||
var indexFields = Object.keys(fieldOrSpec); | ||
if (indexFields.length === 1) { | ||
var field = indexFields[0]; | ||
// only create special finder if the index is not on a sub document | ||
if (field.indexOf('.') === -1) { | ||
// create special find with cache method | ||
var methodName = 'findBy' + field.substr(0, 1).toUpperCase() + field.substr(1); | ||
Model[methodName] = function (id, fields, options, callback) { | ||
var hasFields = true; | ||
if (callback === undefined) { | ||
if (options === undefined) { | ||
callback = fields; | ||
options = {}; | ||
fields = {}; | ||
hasFields = false; | ||
} else { | ||
callback = options; | ||
options = fields; | ||
fields = {}; | ||
hasFields = false; | ||
} | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot ' + methodName + ' on embedded model'); | ||
} | ||
var wantExtend = extractOption('extend', options, true); | ||
var wantExtendDeep = extractOption('deepExtend', options, true); | ||
var pluck = extractOption('pluck', options); | ||
if (pluck !== undefined) { | ||
// state that we only care about the plucked field | ||
fields[pluck] = true; | ||
hasFields = true; | ||
} | ||
if (id === undefined) { | ||
return callback('undefined id'); | ||
} | ||
var includeNotFound = true; | ||
if (options.unique !== undefined && options.unique === true) { | ||
includeNotFound = false; | ||
} | ||
var query = {}; | ||
query[field] = id; | ||
odm.findOne(mongoCollection, query, fields, options, function (err, documentLoaded) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
// if we search for an Id and get null it should return right away | ||
if (documentLoaded === null) { | ||
if (includeNotFound) { | ||
return callback(null, null); | ||
} else { | ||
return callback(mongoCollection + ' ' + id + ' not found'); | ||
} | ||
} | ||
if (hasFields) { | ||
if (pluck !== undefined) { | ||
documentLoaded = documentLoaded[pluck]; | ||
} | ||
} else { | ||
if (hasSchema && (wantExtend || wantExtendDeep)) { | ||
extend(documentLoaded, Model.prototype, wantExtendDeep); | ||
if (Model.$embeds !== undefined) { | ||
extend(documentLoaded, Model.$embeds, wantExtendDeep); | ||
} | ||
if (Model.onLoad !== undefined) { | ||
Model.onLoad(documentLoaded); | ||
} | ||
} | ||
} | ||
callback(null, documentLoaded); | ||
}); | ||
}; | ||
} | ||
} | ||
odm.collection(mongoCollection, options, function (err, collection) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
collection.ensureIndex(fieldOrSpec, options, callback); | ||
}); | ||
}; | ||
/** | ||
* Verifies if an Object is valid against the configured validator | ||
* | ||
* @param {Boolean} [verbose] | ||
* @return {Boolean|Object} | ||
*/ | ||
Model.prototype.validate = function (verbose) { | ||
if (hasSchema) { | ||
var validation = odm.validate(this, Model.$schema); | ||
if (Array.isArray(validation)) { | ||
if (validation.length > 0) { | ||
if (verbose === true) { | ||
return validation; | ||
} else { | ||
return false; | ||
} | ||
} | ||
} | ||
} | ||
// if no schema, always OK | ||
if (verbose === true) { | ||
return null; | ||
} else { | ||
return true; | ||
} | ||
}; | ||
/** | ||
* Helper to have a short syntax | ||
* | ||
* @return {Boolean} | ||
*/ | ||
Model.prototype.isValid = function () { | ||
return this.validate(); | ||
}; | ||
/** | ||
* Save this object instance to the backend mongodb instance. | ||
* | ||
* @memberOf Model | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error, documentId) with the result of the operation | ||
*/ | ||
Model.prototype.save = function (options, callback) { | ||
if (callback === undefined) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot save on embedded model'); | ||
} | ||
var self = this; | ||
var validation = self.validate(true); | ||
if (validation !== null) { | ||
return callback(validation); | ||
} | ||
odm.save(mongoCollection, self, options, function (err, savedDocument) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
// only inserts have savedDocument | ||
if (self._id === undefined) { | ||
if (savedDocument) { | ||
self._id = savedDocument._id; | ||
} | ||
} | ||
callback(null, self._id); | ||
}); | ||
}; | ||
/** | ||
* Update this object instance to the backend mongodb instance. | ||
* | ||
* @memberOf Model | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error, documentId) with the result of the operation | ||
*/ | ||
Model.prototype.update = function (partUpdate, options, callback) { | ||
if (callback === undefined) { | ||
if (options === undefined) { | ||
callback = partUpdate; | ||
options = {}; | ||
partUpdate = undefined; | ||
} else { | ||
callback = options; | ||
options = {}; | ||
} | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot update on embedded model'); | ||
} | ||
var self = this; | ||
var validation; | ||
if (partUpdate !== undefined) { | ||
var setPath = extractOption('$setpath', partUpdate); | ||
if (setPath) { | ||
if (Array.isArray(setPath)) { | ||
var j, len0; | ||
var path, i, len, result; | ||
for (j = 0, len0 = setPath.length; j < len0; j++) { | ||
if (typeof setPath[j] === 'string') { | ||
path = setPath[j].split('.'); | ||
result = self; | ||
for (i = 0, len = path.length; i < len; i++) { | ||
result = result[path[i]]; | ||
} | ||
if (partUpdate.$set === undefined || partUpdate.$set === null) { | ||
partUpdate.$set = {}; | ||
} | ||
partUpdate.$set[setPath[j]] = result; | ||
} else { | ||
return callback('$setpath only accepts a String path'); | ||
} | ||
} | ||
} else { | ||
if (typeof setPath === 'string') { | ||
path = setPath.split('.'); | ||
result = self; | ||
for (i = 0, len = path.length; i < len; i++) { | ||
result = result[path[i]]; | ||
} | ||
if (partUpdate.$set === undefined || partUpdate.$set === null) { | ||
partUpdate.$set = {}; | ||
} | ||
partUpdate.$set[setPath] = result; | ||
} else { | ||
return callback('$setpath only accepts a String path'); | ||
} | ||
} | ||
validation = self.validate(true); | ||
if (validation !== null) { | ||
return callback(validation); | ||
} | ||
} | ||
} else { | ||
validation = self.validate(true); | ||
if (validation !== null) { | ||
return callback(validation); | ||
} | ||
} | ||
odm.update(mongoCollection, {_id: self._id}, partUpdate !== undefined ? partUpdate : self, options, callback); | ||
}; | ||
/** | ||
* Insert this object instance to the backend mongodb instance. | ||
* | ||
* @memberOf Model | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error, documentId) with the result of the operation | ||
*/ | ||
Model.prototype.insert = function (options, callback) { | ||
if (callback === undefined) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot insert on embedded model'); | ||
} | ||
var self = this; | ||
var validation = self.validate(true); | ||
if (validation !== null) { | ||
return callback(validation); | ||
} | ||
odm.insert(mongoCollection, self, options, callback); | ||
}; | ||
/** | ||
* Remove this object instance from the backend mongodb instance. | ||
* | ||
* @memberOf Model | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error) with the result of the operation | ||
*/ | ||
Model.prototype.remove = function (options, callback) { | ||
if (callback === undefined) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot remove on embedded model'); | ||
} | ||
var self = this; | ||
odm.remove(mongoCollection, {_id: self._id}, options, callback); | ||
}; | ||
Model.prototype.reload = function (callback) { | ||
if (!mongoCollection) { | ||
return callback('Cannot remove on embedded model'); | ||
} | ||
var self = this; | ||
var _id = self._id; | ||
if (!(_id instanceof ObjectID)) { | ||
return callback('cannot reload a non stored model'); | ||
} | ||
Model.findById(_id, function (err, documentLoaded) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
// remove old references | ||
var key; | ||
for (key in self) { | ||
if (self.hasOwnProperty(key)) { | ||
delete self[key]; | ||
} | ||
} | ||
// update new ones | ||
for (key in documentLoaded) { | ||
if (documentLoaded.hasOwnProperty(key)) { | ||
self[key] = documentLoaded[key]; | ||
} | ||
} | ||
callback(null); | ||
}); | ||
}; | ||
/** | ||
* Remove this object instance from the backend mongodb instance. | ||
* | ||
* @memberOf Model | ||
* @param {Object} query Search query of objects to remove | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error) with the result of the operation | ||
*/ | ||
Model.remove = function (query, options, callback) { | ||
if (callback === undefined) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot remove on embedded model'); | ||
} | ||
odm.remove(mongoCollection, query, options, callback); | ||
}; | ||
/** | ||
* Insert this object instance to the backend mongodb instance. | ||
* | ||
* @memberOf Model | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error, documentId) with the result of the operation | ||
*/ | ||
Model.insert = function (document, options, callback) { | ||
if (callback === undefined) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot insert on embedded model'); | ||
} | ||
odm.insert(mongoCollection, document, options, callback); | ||
}; | ||
/** | ||
* Remove this object instance from the backend mongodb instance. | ||
* | ||
* @memberOf Model | ||
* @param {Object} query Search query of objects to remove | ||
* @param {Object|Function} [options] options for the query | ||
* @param {Function} callback Callback function (error) with the result of the operation | ||
*/ | ||
Model.update = function (query, document, options, callback) { | ||
if (callback === undefined) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if (!mongoCollection) { | ||
return callback('Cannot remove on embedded model'); | ||
} | ||
odm.update(mongoCollection, query, document, options, callback); | ||
}; | ||
/** | ||
* Clones the Type prototype to this model class | ||
* @param path {String} Path to be updated | ||
* @param type {Object} Type prototype to be copied | ||
*/ | ||
Model.embeds = function (path, type) { | ||
path = path.split('.'); | ||
var i; | ||
var result = Model.$embeds; | ||
for (i = 0; i < path.length; i++) { | ||
var key = path[i]; | ||
if (!result.hasOwnProperty(key)) { | ||
result[key] = {}; | ||
} | ||
result = result[path[i]]; | ||
} | ||
var protokey; | ||
for (protokey in type.prototype) { | ||
if (type.prototype.hasOwnProperty(protokey)) { | ||
if (protokey !== 'save' && protokey !== 'update' && protokey !== 'insert' && protokey !== 'remove' && protokey !== 'reload') { | ||
result[protokey] = type.prototype[protokey]; | ||
} | ||
} | ||
} | ||
for (protokey in type.$embeds) { | ||
if (type.$embeds.hasOwnProperty(protokey)) { | ||
if (protokey !== 'save' && protokey !== 'update' && protokey !== 'insert' && protokey !== 'remove' && protokey !== 'reload') { | ||
result[protokey] = type.$embeds[protokey]; | ||
} | ||
} | ||
} | ||
}; | ||
return Model; | ||
throw new Error('Cannot instantiate model without schema and collection'); | ||
}; |
@@ -8,3 +8,3 @@ { | ||
], | ||
"version": "3.0.2", | ||
"version": "3.0.3", | ||
"engines": { | ||
@@ -14,4 +14,4 @@ "node": ">=0.4.12" | ||
"dependencies": { | ||
"mongodb": "1.0.2", | ||
"jsonschema": ">= 0.0.3" | ||
"mongodb": "1.1.2", | ||
"jsonschema": "0.0.4" | ||
}, | ||
@@ -18,0 +18,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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
67326
12
2124
1
+ Addedbson@0.1.1(transitive)
+ Addedcommander@0.6.1(transitive)
+ Addeddebug@4.3.7(transitive)
+ Addeddeep-equal@0.0.0(transitive)
+ Addeddiff@1.0.2(transitive)
+ Addedgrowl@1.5.1(transitive)
+ Addedjade@0.26.3(transitive)
+ Addedjsonschema@0.0.4(transitive)
+ Addedmkdirp@0.3.0(transitive)
+ Addedmocha@1.3.2(transitive)
+ Addedmongodb@1.1.2(transitive)
+ Addedms@2.1.3(transitive)
+ Addedshould@0.6.3(transitive)
- Removedbson@0.0.6(transitive)
- Removedjsonschema@1.4.1(transitive)
- Removedmongodb@1.0.2(transitive)
Updatedjsonschema@0.0.4
Updatedmongodb@1.1.2