commit
034bdcac07
220
lib/dao.js
220
lib/dao.js
|
@ -148,7 +148,10 @@ function noCallback(err, result) {
|
|||
* - instance (null or Model)
|
||||
*/
|
||||
DataAccessObject.create = function (data, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
var Model = this;
|
||||
var self = this;
|
||||
|
@ -167,9 +170,9 @@ DataAccessObject.create = function (data, options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
data = data || {};
|
||||
options = options || {};
|
||||
cb = cb || (Array.isArray(data) ? noCallback : utils.createPromiseCallback());
|
||||
|
||||
assert(typeof data === 'object', 'The data argument must be an object or array');
|
||||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
|
@ -276,12 +279,27 @@ DataAccessObject.create = function (data, options, cb) {
|
|||
}, obj, cb);
|
||||
}
|
||||
|
||||
// Does this make any sense? How would chaining be used here? -partap
|
||||
|
||||
// for chaining
|
||||
return obj;
|
||||
return cb.promise || obj;
|
||||
};
|
||||
|
||||
function stillConnecting(dataSource, obj, args) {
|
||||
return dataSource.ready(obj, args);
|
||||
if (typeof args[args.length-1] === 'function') {
|
||||
return dataSource.ready(obj, args);
|
||||
}
|
||||
|
||||
// promise variant
|
||||
var promiseArgs = Array.prototype.slice.call(args);
|
||||
promiseArgs.callee = args.callee
|
||||
var cb = utils.createPromiseCallback();
|
||||
promiseArgs.push(cb);
|
||||
if (dataSource.ready(obj, promiseArgs)) {
|
||||
return cb.promise;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,8 +316,9 @@ function stillConnecting(dataSource, obj, args) {
|
|||
// 'upsert' will be used as the name for strong-remoting to keep it backward
|
||||
// compatible for angular SDK
|
||||
DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) {
|
||||
return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
if (options === undefined && cb === undefined) {
|
||||
|
@ -316,7 +335,7 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
data = data || {};
|
||||
options = options || {};
|
||||
|
||||
|
@ -404,6 +423,7 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
|
|||
});
|
||||
}
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -418,10 +438,19 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
|
|||
* @param {Function} cb Callback called with (err, instance, created)
|
||||
*/
|
||||
DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
assert(arguments.length >= 2, 'At least two arguments are required');
|
||||
if (options === undefined && cb === undefined) {
|
||||
assert(arguments.length >= 1, 'At least one argument is required');
|
||||
if (data === undefined && options === undefined && cb === undefined) {
|
||||
assert(typeof query === 'object', 'Single argument must be data object');
|
||||
// findOrCreate(data);
|
||||
// query will be built from data, and method will return Promise
|
||||
data = query;
|
||||
query = {where: data};
|
||||
} else if (options === undefined && cb === undefined) {
|
||||
if (typeof data === 'function') {
|
||||
// findOrCreate(data, cb);
|
||||
// query will be built from data
|
||||
|
@ -437,7 +466,7 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
query = query || {where: {}};
|
||||
data = data || {};
|
||||
options = options || {};
|
||||
|
@ -466,11 +495,19 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
if (created) {
|
||||
Model.notifyObserversOf('after save', { Model: Model, instance: obj },
|
||||
function(err) {
|
||||
cb(err, obj, created);
|
||||
if (cb.promise) {
|
||||
cb(err, [obj, created]);
|
||||
} else {
|
||||
cb(err, obj, created);
|
||||
}
|
||||
if (!err) Model.emit('changed', obj);
|
||||
});
|
||||
} else {
|
||||
cb(err, obj, created);
|
||||
if (cb.promise) {
|
||||
cb(err, [obj, created]);
|
||||
} else {
|
||||
cb(err, obj, created);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -481,9 +518,10 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
try {
|
||||
this._normalize(query);
|
||||
} catch (err) {
|
||||
return process.nextTick(function () {
|
||||
process.nextTick(function () {
|
||||
cb(err);
|
||||
});
|
||||
return cb.promise;
|
||||
}
|
||||
|
||||
this.applyScope(query);
|
||||
|
@ -521,12 +559,23 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
} else {
|
||||
Model.findOne(query, options, function (err, record) {
|
||||
if (err) return cb(err);
|
||||
if (record) return cb(null, record, false);
|
||||
if (record) {
|
||||
if (cb.promise) {
|
||||
return cb(null, [record, false]);
|
||||
} else {
|
||||
return cb(null, record, false);
|
||||
}
|
||||
}
|
||||
Model.create(data, options, function (err, record) {
|
||||
cb(err, record, record != null);
|
||||
if (cb.promise) {
|
||||
cb(err, [record, record != null]);
|
||||
} else {
|
||||
cb(err, record, record != null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -537,7 +586,10 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
|
|||
* @param {Function} cb Callback function called with (err, exists: Bool)
|
||||
*/
|
||||
DataAccessObject.exists = function exists(id, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
assert(arguments.length >= 1, 'The id argument is required');
|
||||
if (cb === undefined) {
|
||||
|
@ -548,7 +600,7 @@ DataAccessObject.exists = function exists(id, options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
options = options || {};
|
||||
|
||||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
|
@ -559,10 +611,11 @@ DataAccessObject.exists = function exists(id, options, cb) {
|
|||
cb(err, err ? false : count === 1);
|
||||
});
|
||||
} else {
|
||||
return process.nextTick(function() {
|
||||
process.nextTick(function() {
|
||||
cb(new Error('Model::exists requires the id argument'));
|
||||
});
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -580,7 +633,10 @@ DataAccessObject.exists = function exists(id, options, cb) {
|
|||
* @param {Function} cb Callback called with (err, instance)
|
||||
*/
|
||||
DataAccessObject.findById = function find(id, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
assert(arguments.length >= 1, 'The id argument is required');
|
||||
if (cb === undefined) {
|
||||
|
@ -590,18 +646,20 @@ DataAccessObject.findById = function find(id, options, cb) {
|
|||
options = {};
|
||||
}
|
||||
}
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
options = options || {};
|
||||
|
||||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
if (id == null || id === '') {
|
||||
return process.nextTick(function() {
|
||||
process.nextTick(function() {
|
||||
cb(new Error('Model::findById requires the id argument'));
|
||||
});
|
||||
} else {
|
||||
this.findOne(byIdQuery(this, id), options, cb);
|
||||
}
|
||||
this.findOne(byIdQuery(this, id), options, cb);
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -626,7 +684,7 @@ DataAccessObject.findByIds = function(ids, query, options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
options = options || {};
|
||||
query = query || {};
|
||||
|
||||
|
@ -638,7 +696,7 @@ DataAccessObject.findByIds = function(ids, query, options, cb) {
|
|||
var pk = idName(this);
|
||||
if (ids.length === 0) {
|
||||
process.nextTick(function() { cb(null, []); });
|
||||
return;
|
||||
return cb.promise;;
|
||||
}
|
||||
|
||||
var filter = { where: {} };
|
||||
|
@ -647,6 +705,7 @@ DataAccessObject.findByIds = function(ids, query, options, cb) {
|
|||
this.find(filter, options, function(err, results) {
|
||||
cb(err, err ? results : utils.sortObjectsByIds(pk, ids, results));
|
||||
});
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
function convertNullToNotFoundError(ctx, cb) {
|
||||
|
@ -662,7 +721,7 @@ function convertNullToNotFoundError(ctx, cb) {
|
|||
|
||||
// alias function for backwards compat.
|
||||
DataAccessObject.all = function () {
|
||||
DataAccessObject.find.apply(this, arguments);
|
||||
return DataAccessObject.find.apply(this, arguments);
|
||||
};
|
||||
|
||||
var operators = {
|
||||
|
@ -994,7 +1053,10 @@ DataAccessObject._coerce = function (where) {
|
|||
*/
|
||||
|
||||
DataAccessObject.find = function find(query, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
if (options === undefined && cb === undefined) {
|
||||
if (typeof query === 'function') {
|
||||
|
@ -1010,7 +1072,7 @@ DataAccessObject.find = function find(query, options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
query = query || {};
|
||||
options = options || {};
|
||||
|
||||
|
@ -1023,9 +1085,10 @@ DataAccessObject.find = function find(query, options, cb) {
|
|||
try {
|
||||
this._normalize(query);
|
||||
} catch (err) {
|
||||
return process.nextTick(function () {
|
||||
process.nextTick(function () {
|
||||
cb(err);
|
||||
});
|
||||
return cb.promise;
|
||||
}
|
||||
|
||||
this.applyScope(query);
|
||||
|
@ -1073,7 +1136,7 @@ DataAccessObject.find = function find(query, options, cb) {
|
|||
});
|
||||
|
||||
// already handled
|
||||
return;
|
||||
return cb.promise;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1135,6 +1198,7 @@ DataAccessObject.find = function find(query, options, cb) {
|
|||
self.getDataSource().connector.all(self.modelName, query, allCb);
|
||||
});
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1146,7 +1210,10 @@ DataAccessObject.find = function find(query, options, cb) {
|
|||
* @param {Function} cb Callback function called with (err, instance)
|
||||
*/
|
||||
DataAccessObject.findOne = function findOne(query, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
if (options === undefined && cb === undefined) {
|
||||
if (typeof query === 'function') {
|
||||
|
@ -1160,7 +1227,7 @@ DataAccessObject.findOne = function findOne(query, options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
query = query || {};
|
||||
options = options || {};
|
||||
|
||||
|
@ -1173,6 +1240,7 @@ DataAccessObject.findOne = function findOne(query, options, cb) {
|
|||
if (err || !collection || !collection.length > 0) return cb(err, null);
|
||||
cb(err, collection[0]);
|
||||
});
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1190,7 +1258,10 @@ DataAccessObject.findOne = function findOne(query, options, cb) {
|
|||
* @param {Function} [cb] Callback called with (err)
|
||||
*/
|
||||
DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyAll = function destroyAll(where, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
var Model = this;
|
||||
|
||||
|
@ -1206,7 +1277,7 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
where = where || {};
|
||||
options = options || {};
|
||||
|
||||
|
@ -1267,6 +1338,7 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA
|
|||
});
|
||||
}
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
function whereIsEmpty(where) {
|
||||
|
@ -1285,7 +1357,10 @@ function whereIsEmpty(where) {
|
|||
// 'deleteById' will be used as the name for strong-remoting to keep it backward
|
||||
// compatible for angular SDK
|
||||
DataAccessObject.removeById = DataAccessObject.destroyById = DataAccessObject.deleteById = function deleteById(id, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
assert(arguments.length >= 1, 'The id argument is required');
|
||||
if (cb === undefined) {
|
||||
|
@ -1297,15 +1372,16 @@ DataAccessObject.removeById = DataAccessObject.destroyById = DataAccessObject.de
|
|||
}
|
||||
|
||||
options = options || {};
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
|
||||
assert(typeof options === 'object', 'The options argument must be an object');
|
||||
assert(typeof cb === 'function', 'The cb argument must be a function');
|
||||
|
||||
if (id == null || id === '') {
|
||||
return process.nextTick(function() {
|
||||
process.nextTick(function() {
|
||||
cb(new Error('Model::deleteById requires the id argument'));
|
||||
});
|
||||
return cb.promise;
|
||||
}
|
||||
|
||||
var Model = this;
|
||||
|
@ -1316,6 +1392,7 @@ DataAccessObject.removeById = DataAccessObject.destroyById = DataAccessObject.de
|
|||
}
|
||||
if(!err) Model.emit('deleted', id);
|
||||
});
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1333,7 +1410,10 @@ DataAccessObject.removeById = DataAccessObject.destroyById = DataAccessObject.de
|
|||
* @param {Function} cb Callback, called with (err, count)
|
||||
*/
|
||||
DataAccessObject.count = function (where, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
if (options === undefined && cb === undefined) {
|
||||
if (typeof where === 'function') {
|
||||
|
@ -1349,7 +1429,7 @@ DataAccessObject.count = function (where, options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
where = where || {};
|
||||
options = options || {};
|
||||
|
||||
|
@ -1365,9 +1445,10 @@ DataAccessObject.count = function (where, options, cb) {
|
|||
where = removeUndefined(where);
|
||||
where = this._coerce(where);
|
||||
} catch (err) {
|
||||
return process.nextTick(function () {
|
||||
process.nextTick(function () {
|
||||
cb(err);
|
||||
});
|
||||
return cb.promise;
|
||||
}
|
||||
|
||||
var Model = this;
|
||||
|
@ -1376,6 +1457,7 @@ DataAccessObject.count = function (where, options, cb) {
|
|||
where = ctx.query.where;
|
||||
Model.getDataSource().connector.count(Model.modelName, cb, where);
|
||||
});
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1387,7 +1469,10 @@ DataAccessObject.count = function (where, options, cb) {
|
|||
* @param {Function} cb Callback function with err and object arguments
|
||||
*/
|
||||
DataAccessObject.prototype.save = function (options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
var Model = this.constructor;
|
||||
|
||||
if (typeof options === 'function') {
|
||||
|
@ -1395,7 +1480,7 @@ DataAccessObject.prototype.save = function (options, cb) {
|
|||
options = {};
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
options = options || {};
|
||||
|
||||
assert(typeof options === 'object', 'The options argument should be an object');
|
||||
|
@ -1466,6 +1551,7 @@ DataAccessObject.prototype.save = function (options, cb) {
|
|||
}, data, cb);
|
||||
}
|
||||
});
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1486,27 +1572,39 @@ DataAccessObject.prototype.save = function (options, cb) {
|
|||
*/
|
||||
DataAccessObject.update =
|
||||
DataAccessObject.updateAll = function (where, data, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
assert(arguments.length >= 2, 'At least two arguments are required');
|
||||
if (options === undefined && cb === undefined) {
|
||||
assert(arguments.length >= 1, 'At least one argument is required');
|
||||
|
||||
if (data === undefined && options === undefined && cb === undefined && arguments.length === 1) {
|
||||
data = where;
|
||||
where = {};
|
||||
} else if (options === undefined && cb === undefined) {
|
||||
// One of:
|
||||
// updateAll(data, cb)
|
||||
// updateAll(where, data) -> Promise
|
||||
if (typeof data === 'function') {
|
||||
// updateAll(data, cb);
|
||||
cb = data;
|
||||
data = where;
|
||||
where = {};
|
||||
}
|
||||
|
||||
} else if (cb === undefined) {
|
||||
// One of:
|
||||
// updateAll(where, data, options) -> Promise
|
||||
// updateAll(where, data, cb)
|
||||
if (typeof options === 'function') {
|
||||
// updateAll(query, data, cb)
|
||||
cb = options;
|
||||
options = {};
|
||||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
data = data || {};
|
||||
options = options || {};
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
|
||||
assert(typeof where === 'object', 'The where argument must be an object');
|
||||
assert(typeof data === 'object', 'The data argument must be an object');
|
||||
|
@ -1564,6 +1662,7 @@ DataAccessObject.updateAll = function (where, data, options, cb) {
|
|||
});
|
||||
});
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
DataAccessObject.prototype.isNewRecord = function () {
|
||||
|
@ -1589,14 +1688,17 @@ DataAccessObject.prototype._adapter = function () {
|
|||
DataAccessObject.prototype.remove =
|
||||
DataAccessObject.prototype.delete =
|
||||
DataAccessObject.prototype.destroy = function (options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
if (cb === undefined && typeof options === 'function') {
|
||||
cb = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
options = options || {};
|
||||
|
||||
assert(typeof options === 'object', 'The options argument should be an object');
|
||||
|
@ -1650,6 +1752,7 @@ DataAccessObject.prototype.remove =
|
|||
});
|
||||
}, null, cb);
|
||||
}
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1674,7 +1777,7 @@ DataAccessObject.prototype.setAttribute = function setAttribute(name, value) {
|
|||
DataAccessObject.prototype.updateAttribute = function updateAttribute(name, value, cb) {
|
||||
var data = {};
|
||||
data[name] = value;
|
||||
this.updateAttributes(data, cb);
|
||||
return this.updateAttributes(data, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1718,7 +1821,10 @@ DataAccessObject.prototype.unsetAttribute = function unsetAttribute(name, nullif
|
|||
* @param {Function} cb Callback function called with (err, instance)
|
||||
*/
|
||||
DataAccessObject.prototype.updateAttributes = function updateAttributes(data, options, cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
if (options === undefined && cb === undefined) {
|
||||
if (typeof data === 'function') {
|
||||
|
@ -1734,7 +1840,7 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
|
|||
}
|
||||
}
|
||||
|
||||
cb = cb || noCallback;
|
||||
cb = cb || utils.createPromiseCallback();
|
||||
options = options || {};
|
||||
|
||||
assert((typeof data === 'object') && (data !== null),
|
||||
|
@ -1803,6 +1909,7 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
|
|||
}, data, cb);
|
||||
}, data);
|
||||
});
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1812,11 +1919,12 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
|
|||
* @private
|
||||
*/
|
||||
DataAccessObject.prototype.reload = function reload(cb) {
|
||||
if (stillConnecting(this.getDataSource(), this, arguments)) {
|
||||
return;
|
||||
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
|
||||
if (connectionPromise) {
|
||||
return connectionPromise;
|
||||
}
|
||||
|
||||
this.constructor.findById(getIdValue(this.constructor, this), cb);
|
||||
return this.constructor.findById(getIdValue(this.constructor, this), cb);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -59,6 +59,21 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should create instance (promise variant)', function (done) {
|
||||
Person.create({name: 'Anatoliy'})
|
||||
.then (function (p) {
|
||||
p.name.should.equal('Anatoliy');
|
||||
should.exist(p);
|
||||
return Person.findById(p.id)
|
||||
.then (function (person) {
|
||||
person.id.should.eql(p.id);
|
||||
person.name.should.equal('Anatoliy');
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('should instantiate an object', function (done) {
|
||||
var p = new Person({name: 'Anatoliy'});
|
||||
p.name.should.equal('Anatoliy');
|
||||
|
@ -71,6 +86,20 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should instantiate an object (promise variant)', function (done) {
|
||||
var p = new Person({name: 'Anatoliy'});
|
||||
p.name.should.equal('Anatoliy');
|
||||
p.isNewRecord().should.be.true;
|
||||
p.save()
|
||||
.then (function(inst) {
|
||||
inst.isNewRecord().should.be.false;
|
||||
inst.should.equal(p);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
|
||||
});
|
||||
|
||||
it('should return instance of object', function (done) {
|
||||
var person = Person.create(function (err, p) {
|
||||
p.id.should.eql(person.id);
|
||||
|
@ -93,6 +122,19 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should not allow user-defined value for the id of object - create (promise variant)', function (done) {
|
||||
Person.create({id: 123456})
|
||||
.then (function (p) {
|
||||
done(new Error('Person.create should have failed.'));
|
||||
}, function (err) {
|
||||
err.should.be.instanceof(ValidationError);
|
||||
err.statusCode.should.equal(422);
|
||||
err.details.messages.id.should.eql(['can\'t be set']);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('should not allow user-defined value for the id of object - save', function (done) {
|
||||
var p = new Person({id: 123456});
|
||||
p.isNewRecord().should.be.true;
|
||||
|
@ -106,6 +148,21 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should not allow user-defined value for the id of object - save (promise variant)', function (done) {
|
||||
var p = new Person({id: 123456});
|
||||
p.isNewRecord().should.be.true;
|
||||
p.save()
|
||||
.then (function(inst) {
|
||||
done(new Error('save should have failed.'));
|
||||
}, function (err) {
|
||||
err.should.be.instanceof(ValidationError);
|
||||
err.statusCode.should.equal(422);
|
||||
err.details.messages.id.should.eql(['can\'t be set']);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('should work when called without callback', function (done) {
|
||||
Person.afterCreate = function (next) {
|
||||
this.should.be.an.instanceOf(Person);
|
||||
|
@ -131,6 +188,20 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should create instance with blank data (promise variant)', function (done) {
|
||||
Person.create()
|
||||
.then (function (p) {
|
||||
should.exist(p);
|
||||
should.not.exists(p.name);
|
||||
return Person.findById(p.id)
|
||||
.then (function (person) {
|
||||
person.id.should.eql(p.id);
|
||||
should.not.exists(person.name);
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should work when called with no data and callback', function (done) {
|
||||
Person.afterCreate = function (next) {
|
||||
this.should.be.an.instanceOf(Person);
|
||||
|
@ -219,6 +290,7 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('save', function () {
|
||||
|
@ -232,6 +304,16 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should save new object (promise variant)', function (done) {
|
||||
var p = new Person;
|
||||
p.save()
|
||||
.then(function () {
|
||||
should.exist(p.id);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('should save existing object', function (done) {
|
||||
Person.findOne(function (err, p) {
|
||||
should.not.exist(err);
|
||||
|
@ -247,6 +329,22 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should save existing object (promise variant)', function (done) {
|
||||
Person.findOne()
|
||||
.then(function (p) {
|
||||
p.name = 'Fritz';
|
||||
return p.save()
|
||||
.then(function () {
|
||||
return Person.findOne()
|
||||
.then(function (p) {
|
||||
p.name.should.equal('Fritz');
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('should save invalid object (skipping validation)', function (done) {
|
||||
Person.findOne(function (err, p) {
|
||||
should.not.exist(err);
|
||||
|
@ -265,6 +363,29 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should save invalid object (skipping validation - promise variant)', function (done) {
|
||||
Person.findOne()
|
||||
.then(function (p) {
|
||||
p.isValid = function (done) {
|
||||
process.nextTick(done);
|
||||
return false;
|
||||
};
|
||||
p.name = 'Nana';
|
||||
return p.save()
|
||||
.then(function (d) {
|
||||
done(new Error('save should have failed.'));
|
||||
}, function (err) {
|
||||
should.exist(err);
|
||||
p.save({validate: false})
|
||||
.then(function (d) {
|
||||
should.exist(d);
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('should save throw error on validation', function () {
|
||||
Person.findOne(function (err, p) {
|
||||
should.not.exist(err);
|
||||
|
@ -312,7 +433,7 @@ describe('manipulation', function () {
|
|||
person.updateAttribute('name', 'Paul Graham', function (err, p) {
|
||||
should.not.exist(err);
|
||||
Person.all(function (e, ps) {
|
||||
should.not.exist(err);
|
||||
should.not.exist(e);
|
||||
ps.should.have.lengthOf(1);
|
||||
ps.pop().name.should.equal('Paul Graham');
|
||||
done();
|
||||
|
@ -320,12 +441,24 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should update one attribute (promise variant)', function (done) {
|
||||
person.updateAttribute('name', 'Teddy Graham')
|
||||
.then(function (p) {
|
||||
return Person.all()
|
||||
.then(function (ps) {
|
||||
ps.should.have.lengthOf(1);
|
||||
ps.pop().name.should.equal('Teddy Graham');
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should ignore undefined values on updateAttributes', function(done) {
|
||||
person.updateAttributes({'name': 'John', age: undefined},
|
||||
function(err, p) {
|
||||
should.not.exist(err);
|
||||
Person.findById(p.id, function(e, p) {
|
||||
should.not.exist(err);
|
||||
should.not.exist(e);
|
||||
p.name.should.equal('John');
|
||||
p.age.should.equal(15);
|
||||
done();
|
||||
|
@ -338,7 +471,7 @@ describe('manipulation', function () {
|
|||
function(err, p) {
|
||||
should.not.exist(err);
|
||||
Person.findById(p.id, function(e, p) {
|
||||
should.not.exist(err);
|
||||
should.not.exist(e);
|
||||
p.name.should.equal('John');
|
||||
p.age.should.equal(15);
|
||||
done();
|
||||
|
@ -346,6 +479,19 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should allows model instance on updateAttributes (promise variant)', function(done) {
|
||||
person.updateAttributes(new Person({'name': 'Jane', age: undefined}))
|
||||
.then(function(p) {
|
||||
return Person.findById(p.id)
|
||||
.then(function(p) {
|
||||
p.name.should.equal('Jane');
|
||||
p.age.should.equal(15);
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('updateOrCreate', function() {
|
||||
|
@ -404,6 +550,71 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe('findOrCreate', function() {
|
||||
it('should create a record with if new', function(done) {
|
||||
Person.findOrCreate({ name: 'Zed', gender: 'male' },
|
||||
function(err, p, created) {
|
||||
if (err) return done(err);
|
||||
should.exist(p);
|
||||
p.should.be.instanceOf(Person);
|
||||
p.name.should.equal('Zed');
|
||||
p.gender.should.equal('male');
|
||||
created.should.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should find a record if exists', function(done) {
|
||||
Person.findOrCreate(
|
||||
{where: {name: 'Zed'}},
|
||||
{name: 'Zed', gender: 'male'},
|
||||
function(err, p, created) {
|
||||
if (err) return done(err);
|
||||
should.exist(p);
|
||||
p.should.be.instanceOf(Person);
|
||||
p.name.should.equal('Zed');
|
||||
p.gender.should.equal('male');
|
||||
created.should.equal(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a record with if new (promise variant)', function(done) {
|
||||
Person.findOrCreate({ name: 'Jed', gender: 'male' })
|
||||
.then(function(res) {
|
||||
should.exist(res);
|
||||
res.should.be.instanceOf(Array);
|
||||
res.should.have.lengthOf(2);
|
||||
var p = res[0];
|
||||
var created = res[1];
|
||||
p.should.be.instanceOf(Person);
|
||||
p.name.should.equal('Jed');
|
||||
p.gender.should.equal('male');
|
||||
created.should.equal(true);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('should find a record if exists (promise variant)', function(done) {
|
||||
Person.findOrCreate(
|
||||
{where: {name: 'Jed'}},
|
||||
{name: 'Jed', gender: 'male'})
|
||||
.then(function(res) {
|
||||
res.should.be.instanceOf(Array);
|
||||
res.should.have.lengthOf(2);
|
||||
var p = res[0];
|
||||
var created = res[1];
|
||||
p.should.be.instanceOf(Person);
|
||||
p.name.should.equal('Jed');
|
||||
p.gender.should.equal('male');
|
||||
created.should.equal(false);
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('destroy', function () {
|
||||
|
||||
it('should destroy record', function (done) {
|
||||
|
@ -418,6 +629,21 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should destroy record (promise variant)', function (done) {
|
||||
Person.create()
|
||||
.then(function (p) {
|
||||
return p.destroy()
|
||||
.then(function () {
|
||||
return Person.exists(p.id)
|
||||
.then(function (ex) {
|
||||
ex.should.not.be.ok;
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(done);
|
||||
});
|
||||
|
||||
it('should destroy all records', function (done) {
|
||||
Person.destroyAll(function (err) {
|
||||
should.not.exist(err);
|
||||
|
@ -431,6 +657,26 @@ describe('manipulation', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should destroy all records (promise variant)', function (done) {
|
||||
Person.create()
|
||||
.then(function() {
|
||||
return Person.destroyAll()
|
||||
.then(function () {
|
||||
return Person.all()
|
||||
.then(function (ps) {
|
||||
ps.should.have.lengthOf(0);
|
||||
return Person.count()
|
||||
.then(function (count) {
|
||||
count.should.eql(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(done);
|
||||
|
||||
});
|
||||
|
||||
// TODO: implement destroy with filtered set
|
||||
it('should destroy filtered set of records');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue