cormo
Advanced tools
Comparing version 0.2.0 to 0.3.0
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var AdapterBase; | ||
var AdapterBase, async, _bindDomain; | ||
async = require('async'); | ||
_bindDomain = function(fn) { | ||
var d; | ||
if (d = process.domain) { | ||
return d.bind(fn); | ||
} else { | ||
return fn; | ||
} | ||
}; | ||
AdapterBase = (function() { | ||
@@ -54,2 +65,13 @@ | ||
AdapterBase.prototype.createBulk = function(model, data, callback) { | ||
return callback(new Error('not implemented')); | ||
}; | ||
AdapterBase.prototype._createBulkDefault = function(model, data, callback) { | ||
var _this = this; | ||
return async.map(data, function(item, callback) { | ||
return _this.create(model, item, _bindDomain(callback)); | ||
}, callback); | ||
}; | ||
AdapterBase.prototype.update = function(model, data, callback) { | ||
@@ -59,2 +81,6 @@ return callback(new Error('not implemented')); | ||
AdapterBase.prototype.updatePartial = function(model, data, conditions, options, callback) { | ||
return callback(new Error('not implemented')); | ||
}; | ||
AdapterBase.prototype.findById = function(model, id, options, callback) { | ||
@@ -61,0 +87,0 @@ return callback(new Error('not implemented')); |
@@ -257,2 +257,32 @@ // Generated by CoffeeScript 1.4.0 | ||
MongoDBAdapter.prototype.createBulk = function(model, data, callback) { | ||
return this._collection(model).insert(data, { | ||
safe: true | ||
}, function(error, result) { | ||
var ids, key; | ||
if ((error != null ? error.code : void 0) === 11000) { | ||
key = error.err.match(/index: [\w-.]+\$(\w+)_1/); | ||
return callback(new Error('duplicated ' + (key != null ? key[1] : void 0))); | ||
} | ||
if (error) { | ||
return callback(MongoDBAdapter.wrapError('unknown error', error)); | ||
} | ||
error = void 0; | ||
ids = result.map(function(doc) { | ||
var id; | ||
id = doc._id.toString(); | ||
if (id) { | ||
delete data._id; | ||
} else { | ||
error = new Error('unexpected result'); | ||
} | ||
return id; | ||
}); | ||
if (error) { | ||
return callback(error); | ||
} | ||
return callback(null, ids); | ||
}); | ||
}; | ||
MongoDBAdapter.prototype.update = function(model, data, callback) { | ||
@@ -279,2 +309,55 @@ var id; | ||
MongoDBAdapter.prototype._buildUpdateOps = function(schema, update_ops, data, path, object) { | ||
var column, property, value, _results; | ||
_results = []; | ||
for (column in object) { | ||
value = object[column]; | ||
property = schema[path + column]; | ||
if (property) { | ||
if (value != null) { | ||
_results.push(update_ops.$set[path + column] = value); | ||
} else { | ||
_results.push(update_ops.$unset[path + column] = ''); | ||
} | ||
} else if (typeof object[column] === 'object') { | ||
_results.push(this._buildUpdateOps(schema, update_ops, data, path + column + '.', object[column])); | ||
} else { | ||
_results.push(void 0); | ||
} | ||
} | ||
return _results; | ||
}; | ||
MongoDBAdapter.prototype.updatePartial = function(model, data, conditions, options, callback) { | ||
var schema, update_ops; | ||
schema = this._connection.models[model]._schema; | ||
try { | ||
conditions = _buildWhere(schema, conditions); | ||
} catch (e) { | ||
return callback(e); | ||
} | ||
if (!conditions) { | ||
conditions = {}; | ||
} | ||
update_ops = { | ||
$set: {}, | ||
$unset: {} | ||
}; | ||
this._buildUpdateOps(schema, update_ops, data, '', data); | ||
return this._collection(model).update(conditions, update_ops, { | ||
safe: true, | ||
multi: true | ||
}, function(error, count) { | ||
var key; | ||
if ((error != null ? error.code : void 0) === 11001) { | ||
key = error.err.match(/index: [\w-.]+\$(\w+)_1/); | ||
return callback(new Error('duplicated ' + (key != null ? key[1] : void 0))); | ||
} | ||
if (error) { | ||
return callback(MongoDBAdapter.wrapError('unknown error', error)); | ||
} | ||
return callback(null, count); | ||
}); | ||
}; | ||
MongoDBAdapter.prototype.findById = function(model, id, options, callback) { | ||
@@ -281,0 +364,0 @@ var fields, |
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var MySQLAdapter, SQLAdapterBase, async, mysql, tableize, types, _propertyToSQL, _typeToSQL, | ||
var MySQLAdapter, SQLAdapterBase, async, mysql, tableize, types, _, _propertyToSQL, _typeToSQL, | ||
__hasProp = {}.hasOwnProperty, | ||
@@ -22,2 +22,4 @@ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
_ = require('underscore'); | ||
_typeToSQL = function(property) { | ||
@@ -163,6 +165,28 @@ switch (property.type) { | ||
MySQLAdapter.prototype._buildUpdateSetOfColumn = function(property, data, values, fields, places, insert) { | ||
var dbname; | ||
dbname = property.dbname; | ||
if (property.type === types.GeoPoint) { | ||
values.push(data[dbname][0]); | ||
values.push(data[dbname][1]); | ||
if (insert) { | ||
fields.push(dbname); | ||
return places.push('POINT(?,?)'); | ||
} else { | ||
return fields.push(dbname + '=POINT(?,?)'); | ||
} | ||
} else { | ||
values.push(data[dbname]); | ||
if (insert) { | ||
fields.push(dbname); | ||
return places.push('?'); | ||
} else { | ||
return fields.push(dbname + '=?'); | ||
} | ||
} | ||
}; | ||
MySQLAdapter.prototype._buildUpdateSet = function(model, data, values, insert) { | ||
var column, dbname, fields, places, property, schema; | ||
var column, fields, places, property, schema; | ||
schema = this._connection.models[model]._schema; | ||
values = []; | ||
fields = []; | ||
@@ -172,35 +196,34 @@ places = []; | ||
property = schema[column]; | ||
dbname = property.dbname; | ||
if (property.type === types.GeoPoint) { | ||
values.push(data[dbname][0]); | ||
values.push(data[dbname][1]); | ||
if (insert) { | ||
fields.push(dbname); | ||
places.push('POINT(?,?)'); | ||
} else { | ||
fields.push(dbname + '=POINT(?,?)'); | ||
} | ||
} else { | ||
values.push(data[dbname]); | ||
if (insert) { | ||
fields.push(dbname); | ||
places.push('?'); | ||
} else { | ||
fields.push(dbname + '=?'); | ||
} | ||
} | ||
this._buildUpdateSetOfColumn(property, data, values, fields, places, insert); | ||
} | ||
return [values, fields.join(','), places.join(',')]; | ||
return [fields.join(','), places.join(',')]; | ||
}; | ||
MySQLAdapter.prototype._buildPartialUpdateSet = function(model, data, values) { | ||
var column, fields, places, property, schema, value; | ||
schema = this._connection.models[model]._schema; | ||
fields = []; | ||
places = []; | ||
for (column in data) { | ||
value = data[column]; | ||
property = _.find(schema, function(item) { | ||
return item.dbname === column; | ||
}); | ||
this._buildUpdateSetOfColumn(property, data, values, fields, places); | ||
} | ||
return [fields.join(','), places.join(',')]; | ||
}; | ||
MySQLAdapter.prototype.create = function(model, data, callback) { | ||
var fields, places, sql, values, _ref; | ||
_ref = this._buildUpdateSet(model, data, values, true), values = _ref[0], fields = _ref[1], places = _ref[2]; | ||
values = []; | ||
_ref = this._buildUpdateSet(model, data, values, true), fields = _ref[0], places = _ref[1]; | ||
sql = "INSERT INTO " + (tableize(model)) + " (" + fields + ") VALUES (" + places + ")"; | ||
return this._query(sql, values, function(error, result) { | ||
var id; | ||
if (error) { | ||
return _processSaveError(error, callback); | ||
} | ||
if (result != null ? result.insertId : void 0) { | ||
return callback(null, result.insertId); | ||
if (id = result != null ? result.insertId : void 0) { | ||
return callback(null, id); | ||
} else { | ||
@@ -212,5 +235,33 @@ return callback(new Error('unexpected result')); | ||
MySQLAdapter.prototype.createBulk = function(model, data, callback) { | ||
var fields, places, sql, values, | ||
_this = this; | ||
values = []; | ||
fields = void 0; | ||
places = []; | ||
data.forEach(function(item) { | ||
var places_sub, _ref; | ||
_ref = _this._buildUpdateSet(model, item, values, true), fields = _ref[0], places_sub = _ref[1]; | ||
return places.push('(' + places_sub + ')'); | ||
}); | ||
sql = "INSERT INTO " + (tableize(model)) + " (" + fields + ") VALUES " + (places.join(',')); | ||
return this._query(sql, values, function(error, result) { | ||
var id; | ||
if (error) { | ||
return _processSaveError(error, callback); | ||
} | ||
if (id = result != null ? result.insertId : void 0) { | ||
return callback(null, data.map(function(item, i) { | ||
return id + i; | ||
})); | ||
} else { | ||
return callback(new Error('unexpected result')); | ||
} | ||
}); | ||
}; | ||
MySQLAdapter.prototype.update = function(model, data, callback) { | ||
var fields, sql, values, _ref; | ||
_ref = this._buildUpdateSet(model, data, values), values = _ref[0], fields = _ref[1]; | ||
var fields, sql, values; | ||
values = []; | ||
fields = this._buildUpdateSet(model, data, values)[0]; | ||
values.push(data.id); | ||
@@ -226,2 +277,21 @@ sql = "UPDATE " + (tableize(model)) + " SET " + fields + " WHERE id=?"; | ||
MySQLAdapter.prototype.updatePartial = function(model, data, conditions, options, callback) { | ||
var fields, sql, values; | ||
values = []; | ||
fields = this._buildPartialUpdateSet(model, data, values)[0]; | ||
sql = "UPDATE " + (tableize(model)) + " SET " + fields; | ||
if (conditions.length > 0) { | ||
sql += ' WHERE ' + this._buildWhere(conditions, values); | ||
} | ||
return this._query(sql, values, function(error, result) { | ||
if (error) { | ||
return _processSaveError(error, callback); | ||
} | ||
if (!(result != null)) { | ||
return callback(MySQLAdapter.wrapError('unknown error')); | ||
} | ||
return callback(null, result.affectedRows); | ||
}); | ||
}; | ||
MySQLAdapter.prototype.findById = function(model, id, options, callback) { | ||
@@ -228,0 +298,0 @@ var selects, sql, |
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var PostgreSQLAdapter, SQLAdapterBase, async, pg, tableize, types, _propertyToSQL, _typeToSQL, | ||
var PostgreSQLAdapter, SQLAdapterBase, async, pg, tableize, types, _, _propertyToSQL, _typeToSQL, | ||
__hasProp = {}.hasOwnProperty, | ||
@@ -22,2 +22,4 @@ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
_ = require('underscore'); | ||
_typeToSQL = function(property) { | ||
@@ -158,6 +160,17 @@ switch (property.type) { | ||
PostgreSQLAdapter.prototype._buildUpdateSetOfColumn = function(property, data, values, fields, places, insert) { | ||
var dbname; | ||
dbname = property.dbname; | ||
values.push(data[dbname]); | ||
if (insert) { | ||
fields.push(dbname); | ||
return places.push('$' + values.length); | ||
} else { | ||
return fields.push(dbname + '=$' + values.length); | ||
} | ||
}; | ||
PostgreSQLAdapter.prototype._buildUpdateSet = function(model, data, values, insert) { | ||
var column, dbname, fields, places, property, schema; | ||
var column, fields, places, property, schema; | ||
schema = this._connection.models[model]._schema; | ||
values = []; | ||
fields = []; | ||
@@ -167,17 +180,26 @@ places = []; | ||
property = schema[column]; | ||
dbname = property.dbname; | ||
values.push(data[dbname]); | ||
if (insert) { | ||
fields.push(dbname); | ||
places.push('$' + values.length); | ||
} else { | ||
fields.push(dbname + '=$' + values.length); | ||
} | ||
this._buildUpdateSetOfColumn(property, data, values, fields, places, insert); | ||
} | ||
return [values, fields.join(','), places.join(',')]; | ||
return [fields.join(','), places.join(',')]; | ||
}; | ||
PostgreSQLAdapter.prototype._buildPartialUpdateSet = function(model, data, values) { | ||
var column, fields, places, property, schema, value; | ||
schema = this._connection.models[model]._schema; | ||
fields = []; | ||
places = []; | ||
for (column in data) { | ||
value = data[column]; | ||
property = _.find(schema, function(item) { | ||
return item.dbname === column; | ||
}); | ||
this._buildUpdateSetOfColumn(property, data, values, fields, places); | ||
} | ||
return [fields.join(','), places.join(',')]; | ||
}; | ||
PostgreSQLAdapter.prototype.create = function(model, data, callback) { | ||
var fields, places, sql, values, _ref; | ||
_ref = this._buildUpdateSet(model, data, values, true), values = _ref[0], fields = _ref[1], places = _ref[2]; | ||
values = []; | ||
_ref = this._buildUpdateSet(model, data, values, true), fields = _ref[0], places = _ref[1]; | ||
sql = "INSERT INTO " + (tableize(model)) + " (" + fields + ") VALUES (" + places + ") RETURNING id"; | ||
@@ -198,5 +220,34 @@ return this._query(sql, values, function(error, result) { | ||
PostgreSQLAdapter.prototype.createBulk = function(model, data, callback) { | ||
var fields, places, sql, values, | ||
_this = this; | ||
values = []; | ||
fields = void 0; | ||
places = []; | ||
data.forEach(function(item) { | ||
var places_sub, _ref; | ||
_ref = _this._buildUpdateSet(model, item, values, true), fields = _ref[0], places_sub = _ref[1]; | ||
return places.push('(' + places_sub + ')'); | ||
}); | ||
sql = "INSERT INTO " + (tableize(model)) + " (" + fields + ") VALUES " + (places.join(',')) + " RETURNING id"; | ||
return this._query(sql, values, function(error, result) { | ||
var ids; | ||
if (error) { | ||
return _processSaveError(model, error, callback); | ||
} | ||
ids = result != null ? result.rows.map(function(row) { | ||
return row.id; | ||
}) : void 0; | ||
if (ids.length === data.length) { | ||
return callback(null, ids); | ||
} else { | ||
return callback(new Error('unexpected rows')); | ||
} | ||
}); | ||
}; | ||
PostgreSQLAdapter.prototype.update = function(model, data, callback) { | ||
var fields, sql, values, _ref; | ||
_ref = this._buildUpdateSet(model, data, values), values = _ref[0], fields = _ref[1]; | ||
var fields, sql, values; | ||
values = []; | ||
fields = this._buildUpdateSet(model, data, values)[0]; | ||
values.push(data.id); | ||
@@ -212,2 +263,18 @@ sql = "UPDATE " + (tableize(model)) + " SET " + fields + " WHERE id=$" + values.length; | ||
PostgreSQLAdapter.prototype.updatePartial = function(model, data, conditions, options, callback) { | ||
var fields, sql, values; | ||
values = []; | ||
fields = this._buildPartialUpdateSet(model, data, values)[0]; | ||
sql = "UPDATE " + (tableize(model)) + " SET " + fields; | ||
if (conditions.length > 0) { | ||
sql += ' WHERE ' + this._buildWhere(conditions, values); | ||
} | ||
return this._query(sql, values, function(error, result) { | ||
if (error) { | ||
return _processSaveError(model, error, callback); | ||
} | ||
return callback(null, result.rowCount); | ||
}); | ||
}; | ||
PostgreSQLAdapter.prototype.findById = function(model, id, options, callback) { | ||
@@ -214,0 +281,0 @@ var selects, table, |
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var SQLAdapterBase, SQLite3Adapter, async, sqlite3, tableize, types, _propertyToSQL, _typeToSQL, | ||
var SQLAdapterBase, SQLite3Adapter, async, sqlite3, tableize, types, _, _propertyToSQL, _typeToSQL, | ||
__hasProp = {}.hasOwnProperty, | ||
@@ -22,2 +22,4 @@ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
_ = require('underscore'); | ||
_typeToSQL = function(property) { | ||
@@ -143,6 +145,21 @@ switch (property.type) { | ||
SQLite3Adapter.prototype._buildUpdateSetOfColumn = function(property, data, values, fields, places, insert) { | ||
var dbname, _ref; | ||
dbname = property.dbname; | ||
if (property.type === types.Date) { | ||
values.push((_ref = data[dbname]) != null ? _ref.getTime() : void 0); | ||
} else { | ||
values.push(data[dbname]); | ||
} | ||
if (insert) { | ||
fields.push(dbname); | ||
return places.push('?'); | ||
} else { | ||
return fields.push(dbname + '=?'); | ||
} | ||
}; | ||
SQLite3Adapter.prototype._buildUpdateSet = function(model, data, values, insert) { | ||
var column, dbname, fields, places, property, schema, _ref; | ||
var column, fields, places, property, schema; | ||
schema = this._connection.models[model]._schema; | ||
values = []; | ||
fields = []; | ||
@@ -152,21 +169,26 @@ places = []; | ||
property = schema[column]; | ||
dbname = property.dbname; | ||
if (property.type === types.Date) { | ||
values.push((_ref = data[dbname]) != null ? _ref.getTime() : void 0); | ||
} else { | ||
values.push(data[dbname]); | ||
} | ||
if (insert) { | ||
fields.push(dbname); | ||
places.push('?'); | ||
} else { | ||
fields.push(dbname + '=?'); | ||
} | ||
this._buildUpdateSetOfColumn(property, data, values, fields, places, insert); | ||
} | ||
return [values, fields.join(','), places.join(',')]; | ||
return [fields.join(','), places.join(',')]; | ||
}; | ||
SQLite3Adapter.prototype._buildPartialUpdateSet = function(model, data, values) { | ||
var column, fields, places, property, schema, value; | ||
schema = this._connection.models[model]._schema; | ||
fields = []; | ||
places = []; | ||
for (column in data) { | ||
value = data[column]; | ||
property = _.find(schema, function(item) { | ||
return item.dbname === column; | ||
}); | ||
this._buildUpdateSetOfColumn(property, data, values, fields, places); | ||
} | ||
return [fields.join(','), places.join(',')]; | ||
}; | ||
SQLite3Adapter.prototype.create = function(model, data, callback) { | ||
var fields, places, sql, values, _ref; | ||
_ref = this._buildUpdateSet(model, data, values, true), values = _ref[0], fields = _ref[1], places = _ref[2]; | ||
values = []; | ||
_ref = this._buildUpdateSet(model, data, values, true), fields = _ref[0], places = _ref[1]; | ||
sql = "INSERT INTO " + (tableize(model)) + " (" + fields + ") VALUES (" + places + ")"; | ||
@@ -181,5 +203,10 @@ return this._query('run', sql, values, function(error) { | ||
SQLite3Adapter.prototype.createBulk = function(model, data, callback) { | ||
return this._createBulkDefault(model, data, callback); | ||
}; | ||
SQLite3Adapter.prototype.update = function(model, data, callback) { | ||
var fields, sql, values, _ref; | ||
_ref = this._buildUpdateSet(model, data, values), values = _ref[0], fields = _ref[1]; | ||
var fields, sql, values; | ||
values = []; | ||
fields = this._buildUpdateSet(model, data, values)[0]; | ||
values.push(data.id); | ||
@@ -195,2 +222,18 @@ sql = "UPDATE " + (tableize(model)) + " SET " + fields + " WHERE id=?"; | ||
SQLite3Adapter.prototype.updatePartial = function(model, data, conditions, options, callback) { | ||
var fields, sql, values; | ||
values = []; | ||
fields = this._buildPartialUpdateSet(model, data, values)[0]; | ||
sql = "UPDATE " + (tableize(model)) + " SET " + fields; | ||
if (conditions.length > 0) { | ||
sql += ' WHERE ' + this._buildWhere(conditions, values); | ||
} | ||
return this._query('run', sql, values, function(error) { | ||
if (error) { | ||
return _processSaveError(error, callback); | ||
} | ||
return callback(null, this.changes); | ||
}); | ||
}; | ||
SQLite3Adapter.prototype.findById = function(model, id, options, callback) { | ||
@@ -197,0 +240,0 @@ var selects, table, |
231
lib/model.js
// Generated by CoffeeScript 1.4.0 | ||
(function() { | ||
var Model, ModelCallback, ModelQuery, async, inflector, type, value, _, _bindDomain, _getRef, _getValue, _ref, _setValue, | ||
var Model, async, inflector, type, value, _, _bindDomain, _getRef, _getValue, _ref, _setValue, _use, | ||
__hasProp = {}.hasOwnProperty, | ||
@@ -233,55 +233,96 @@ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
Model.createBulk = function(data, callback) { | ||
var records, | ||
_this = this; | ||
if (!Array.isArray(data)) { | ||
return callback(new Error('data is not an array')); | ||
} | ||
records = data.map(function(item) { | ||
return _this.build(item); | ||
}); | ||
return async.forEach(records, function(record, callback) { | ||
return record.validate(callback); | ||
}, function(error) { | ||
if (error) { | ||
return callback(error); | ||
} | ||
records.forEach(function(record) { | ||
return record._runCallbacks('save', 'before'); | ||
}); | ||
records.forEach(function(record) { | ||
return record._runCallbacks('create', 'before'); | ||
}); | ||
return _this._createBulk(records, function(error, records) { | ||
records.forEach(function(record) { | ||
return record._runCallbacks('create', 'after'); | ||
}); | ||
records.forEach(function(record) { | ||
return record._runCallbacks('save', 'after'); | ||
}); | ||
return callback(error, records); | ||
}); | ||
}); | ||
}; | ||
Model._validateColumn = function(data, column, property) { | ||
var last, obj, value, _ref; | ||
_ref = _getRef(data, property.parts), obj = _ref[0], last = _ref[1]; | ||
value = obj[last]; | ||
if (value != null) { | ||
switch (property.type) { | ||
case Model.Number: | ||
value = Number(value); | ||
if (isNaN(value)) { | ||
return "'" + column + "' is not a number"; | ||
} else { | ||
obj[last] = value; | ||
} | ||
break; | ||
case Model.Boolean: | ||
if (typeof value !== 'boolean') { | ||
return "'" + column + "' is not a boolean"; | ||
} | ||
break; | ||
case Model.Integer: | ||
value = Number(value); | ||
if (isNaN(value) || (value >> 0) !== value) { | ||
return "'" + column + "' is not an integer"; | ||
} else { | ||
obj[last] = value; | ||
} | ||
break; | ||
case Model.GeoPoint: | ||
if (!(Array.isArray(value) && value.length === 2)) { | ||
return "'" + column + "' is not a geo point"; | ||
} else { | ||
value[0] = Number(value[0]); | ||
value[1] = Number(value[1]); | ||
} | ||
break; | ||
case Model.Date: | ||
value = new Date(value); | ||
if (isNaN(value.getTime())) { | ||
return "'" + column + "' is not a date"; | ||
} else { | ||
obj[last] = value; | ||
} | ||
} | ||
} else { | ||
if (property.required) { | ||
return "'" + column + "' is required"; | ||
} | ||
} | ||
}; | ||
Model.prototype.validate = function(callback) { | ||
var column, errors, last, obj, property, schema, value, _ref, | ||
var column, ctor, error, errors, property, schema, | ||
_this = this; | ||
this._runCallbacks('validate', 'before'); | ||
errors = []; | ||
schema = this.constructor._schema; | ||
ctor = this.constructor; | ||
schema = ctor._schema; | ||
for (column in schema) { | ||
property = schema[column]; | ||
_ref = _getRef(this, property.parts), obj = _ref[0], last = _ref[1]; | ||
value = obj[last]; | ||
if (value != null) { | ||
switch (property.type) { | ||
case Model.Number: | ||
value = Number(value); | ||
if (isNaN(value)) { | ||
errors.push("'" + column + "' is not a number"); | ||
} else { | ||
obj[last] = value; | ||
} | ||
break; | ||
case Model.Boolean: | ||
if (typeof value !== 'boolean') { | ||
errors.push("'" + column + "' is not a boolean"); | ||
} | ||
break; | ||
case Model.Integer: | ||
value = Number(value); | ||
if (isNaN(value) || (value >> 0) !== value) { | ||
errors.push("'" + column + "' is not an integer"); | ||
} else { | ||
obj[last] = value; | ||
} | ||
break; | ||
case Model.GeoPoint: | ||
if (!(Array.isArray(value) && value.length === 2)) { | ||
errors.push("'" + column + "' is not a geo point"); | ||
} else { | ||
value[0] = Number(value[0]); | ||
value[1] = Number(value[1]); | ||
} | ||
break; | ||
case Model.Date: | ||
value = new Date(value); | ||
if (isNaN(value.getTime())) { | ||
errors.push("'" + column + "' is not a date"); | ||
} else { | ||
obj[last] = value; | ||
} | ||
} | ||
} else { | ||
if (property.required) { | ||
errors.push("'" + column + "' is required"); | ||
} | ||
if (error = ctor._validateColumn(this, column, property)) { | ||
errors.push(error); | ||
} | ||
@@ -317,27 +358,32 @@ } | ||
Model._buildSaveDataColumn = function(data, model, column, property, allow_null) { | ||
var adapter, parts, value; | ||
adapter = this._adapter; | ||
parts = property.parts; | ||
value = _getValue(model, parts); | ||
if (property.type === Model.Object && !adapter.support_object) { | ||
value = JSON.stringify(value); | ||
} else { | ||
value = adapter.valueToDB(value, column, property); | ||
} | ||
if (allow_null || value !== void 0) { | ||
if (adapter.support_nested) { | ||
return _setValue(data, parts, value); | ||
} else { | ||
return data[property.dbname] = value; | ||
} | ||
} | ||
}; | ||
Model.prototype._buildSaveData = function() { | ||
var adapter, column, ctor, data, parts, property, schema, value; | ||
var column, ctor, data, property, schema; | ||
data = {}; | ||
ctor = this.constructor; | ||
schema = ctor._schema; | ||
adapter = ctor._adapter; | ||
for (column in schema) { | ||
property = schema[column]; | ||
parts = property.parts; | ||
value = _getValue(this, parts); | ||
if (property.type === Model.Object && !adapter.support_object) { | ||
value = JSON.stringify(value); | ||
} else { | ||
value = adapter.valueToDB(value, column, property); | ||
} | ||
if (value !== void 0) { | ||
if (adapter.support_nested) { | ||
_setValue(data, parts, value); | ||
} else { | ||
data[property.dbname] = value; | ||
} | ||
} | ||
ctor._buildSaveDataColumn(data, this, column, property); | ||
} | ||
if (this.id != null) { | ||
data.id = adapter.idToDB(this.id); | ||
data.id = ctor._adapter.idToDB(this.id); | ||
} | ||
@@ -358,5 +404,2 @@ return data; | ||
} | ||
if (Object.keys(data).length === 0) { | ||
return callback(new Error('empty data', this)); | ||
} | ||
ctor = this.constructor; | ||
@@ -391,2 +434,37 @@ ctor._connection.log(ctor._name, 'create', data); | ||
Model._createBulk = function(records, callback) { | ||
var data_array, error; | ||
if (this._waitingForConnection(this, this._createBulk, arguments)) { | ||
return; | ||
} | ||
error = void 0; | ||
data_array = records.map(function(record) { | ||
var data; | ||
try { | ||
data = record._buildSaveData(); | ||
} catch (e) { | ||
error = e; | ||
} | ||
return data; | ||
}); | ||
if (error) { | ||
return callback(error, records); | ||
} | ||
this._connection.log(this._name, 'createBulk', data_array); | ||
return this._adapter.createBulk(this._name, data_array, _bindDomain(function(error, ids) { | ||
if (error) { | ||
return callback(error, records); | ||
} | ||
records.forEach(function(record, i) { | ||
return Object.defineProperty(record, 'id', { | ||
configurable: false, | ||
enumerable: true, | ||
writable: false, | ||
value: ids[i] | ||
}); | ||
}); | ||
return callback(null, records); | ||
})); | ||
}; | ||
Model.prototype._update = function(callback) { | ||
@@ -510,14 +588,15 @@ var ctor, data, | ||
ModelQuery = require('./model/query'); | ||
_use = function(file) { | ||
var MixClass; | ||
MixClass = require("./model/" + file); | ||
_.extend(Model, MixClass); | ||
return _.extend(Model.prototype, MixClass.prototype); | ||
}; | ||
_.extend(Model, ModelQuery); | ||
_use('query'); | ||
_.extend(Model.prototype, ModelQuery.prototype); | ||
_use('callback'); | ||
ModelCallback = require('./model/callback'); | ||
_use('timestamp'); | ||
_.extend(Model, ModelCallback); | ||
_.extend(Model.prototype, ModelCallback.prototype); | ||
_ref = require('./types'); | ||
@@ -524,0 +603,0 @@ for (type in _ref) { |
@@ -11,11 +11,8 @@ // Generated by CoffeeScript 1.4.0 | ||
ModelQuery.find = function(id, callback) { | ||
ModelQuery._createQueryAndRun = function(criteria, data, operation, callback) { | ||
var query; | ||
if (this._waitingForConnection(this, this.find, arguments)) { | ||
return; | ||
} | ||
query = new Query(this); | ||
query.find(id); | ||
query[criteria](data); | ||
if (typeof callback === 'function') { | ||
query.exec(callback); | ||
query[operation](callback); | ||
} | ||
@@ -25,58 +22,36 @@ return query; | ||
ModelQuery.where = function(condition, callback) { | ||
var query; | ||
if (this._waitingForConnection(this, this.where, arguments)) { | ||
return; | ||
ModelQuery._createOptionalQueryAndRun = function(criteria, data, operation, callback) { | ||
if (typeof data === 'function') { | ||
return this._createQueryAndRun(criteria, null, operation, data); | ||
} else { | ||
return this._createQueryAndRun(criteria, data, operation, callback); | ||
} | ||
if (typeof condition === 'function') { | ||
callback = condition; | ||
condition = null; | ||
} | ||
query = new Query(this); | ||
query.where(condition); | ||
if (typeof callback === 'function') { | ||
query.exec(callback); | ||
} | ||
return query; | ||
}; | ||
ModelQuery.find = function(id, callback) { | ||
return this._createQueryAndRun('find', id, 'exec', callback); | ||
}; | ||
ModelQuery.findPreserve = function(ids, callback) { | ||
return this._createQueryAndRun('findPreserve', ids, 'exec', callback); | ||
}; | ||
ModelQuery.where = function(condition, callback) { | ||
return this._createOptionalQueryAndRun('where', condition, 'exec', callback); | ||
}; | ||
ModelQuery.select = function(columns, callback) { | ||
var query; | ||
if (this._waitingForConnection(this, this.select, arguments)) { | ||
return; | ||
} | ||
if (typeof columns === 'function') { | ||
callback = columns; | ||
columns = null; | ||
} | ||
query = new Query(this); | ||
query.select(columns); | ||
if (typeof callback === 'function') { | ||
query.exec(callback); | ||
} | ||
return query; | ||
return this._createOptionalQueryAndRun('select', columns, 'exec', callback); | ||
}; | ||
ModelQuery.order = function(orders, callback) { | ||
var query; | ||
if (this._waitingForConnection(this, this.where, arguments)) { | ||
return; | ||
} | ||
if (typeof orders === 'function') { | ||
callback = orders; | ||
orders = null; | ||
} | ||
query = new Query(this); | ||
query.order(orders); | ||
if (typeof callback === 'function') { | ||
query.exec(callback); | ||
} | ||
return query; | ||
return this._createOptionalQueryAndRun('order', orders, 'exec', callback); | ||
}; | ||
ModelQuery.count = function(condition, callback) { | ||
return this._createOptionalQueryAndRun('where', condition, 'count', callback); | ||
}; | ||
ModelQuery.update = function(updates, condition, callback) { | ||
var query; | ||
if (this._waitingForConnection(this, this.count, arguments)) { | ||
return; | ||
} | ||
if (typeof condition === 'function') { | ||
@@ -89,3 +64,3 @@ callback = condition; | ||
if (typeof callback === 'function') { | ||
query.count(callback); | ||
query.update(updates, callback); | ||
} | ||
@@ -96,16 +71,3 @@ return query; | ||
ModelQuery["delete"] = function(condition, callback) { | ||
var query; | ||
if (this._waitingForConnection(this, this["delete"], arguments)) { | ||
return; | ||
} | ||
if (typeof condition === 'function') { | ||
callback = condition; | ||
condition = null; | ||
} | ||
query = new Query(this); | ||
query.where(condition); | ||
if (typeof callback === 'function') { | ||
query["delete"](callback); | ||
} | ||
return query; | ||
return this._createOptionalQueryAndRun('where', condition, 'delete', callback); | ||
}; | ||
@@ -112,0 +74,0 @@ |
@@ -40,2 +40,9 @@ // Generated by CoffeeScript 1.4.0 | ||
Query.prototype.findPreserve = function(ids) { | ||
this._id = _.uniq(ids); | ||
this._find_single_id = false; | ||
this._preserve_order_ids = ids; | ||
return this; | ||
}; | ||
Query.prototype.near = function(target) { | ||
@@ -94,3 +101,7 @@ this._options.near = target; | ||
Query.prototype.exec = function(callback) { | ||
var expected_count; | ||
var expected_count, | ||
_this = this; | ||
if (this._model._waitingForConnection(this, this.exec, arguments)) { | ||
return; | ||
} | ||
if (this._find_single_id && this._conditions.length === 0) { | ||
@@ -141,3 +152,15 @@ this._connection.log(this._name, 'find by id', { | ||
} | ||
return callback(null, records); | ||
if (_this._preserve_order_ids) { | ||
return callback(null, _this._preserve_order_ids.map(function(id) { | ||
var record, _i, _len; | ||
for (_i = 0, _len = records.length; _i < _len; _i++) { | ||
record = records[_i]; | ||
if (record.id === id) { | ||
return record; | ||
} | ||
} | ||
})); | ||
} else { | ||
return callback(null, records); | ||
} | ||
})); | ||
@@ -147,2 +170,5 @@ }; | ||
Query.prototype.count = function(callback) { | ||
if (this._model._waitingForConnection(this, this.count, arguments)) { | ||
return; | ||
} | ||
if (this._id) { | ||
@@ -160,3 +186,52 @@ this._conditions.push({ | ||
Query.prototype._validateAndBuildSaveData = function(errors, data, updates, path, object) { | ||
var column, error, model, property, schema, _results; | ||
model = this._model; | ||
schema = model._schema; | ||
_results = []; | ||
for (column in object) { | ||
property = schema[path + column]; | ||
if (property) { | ||
if (error = model._validateColumn(updates, path + column, property)) { | ||
errors.push(error); | ||
} | ||
_results.push(model._buildSaveDataColumn(data, updates, path + column, property, true)); | ||
} else if (typeof object[column] === 'object') { | ||
_results.push(this._validateAndBuildSaveData(errors, data, updates, path + column + '.', object[column])); | ||
} else { | ||
_results.push(void 0); | ||
} | ||
} | ||
return _results; | ||
}; | ||
Query.prototype.update = function(updates, callback) { | ||
var data, errors; | ||
if (this._model._waitingForConnection(this, this.update, arguments)) { | ||
return; | ||
} | ||
errors = []; | ||
data = {}; | ||
this._validateAndBuildSaveData(errors, data, updates, '', updates); | ||
if (errors.length > 0) { | ||
return callback(new Error(errors.join(','))); | ||
} | ||
if (this._id) { | ||
this._conditions.push({ | ||
id: this._id | ||
}); | ||
delete this._id; | ||
} | ||
this._connection.log(this._name, 'update', { | ||
data: data, | ||
conditions: this._conditions, | ||
options: this._options | ||
}); | ||
return this._adapter.updatePartial(this._name, data, this._conditions, this._options, _bindDomain(callback)); | ||
}; | ||
Query.prototype["delete"] = function(callback) { | ||
if (this._model._waitingForConnection(this, this["delete"], arguments)) { | ||
return; | ||
} | ||
if (this._id) { | ||
@@ -163,0 +238,0 @@ this._conditions.push({ |
{ | ||
"name": "cormo", | ||
"description": "ORM framework for Node.js", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"keywords": [ | ||
@@ -6,0 +6,0 @@ "orm", |
@@ -88,3 +88,3 @@ # About | ||
# create is the same as build and save | ||
User.create { name: 'John Doe', age: 27 }, (error, user4) -> | ||
User.create { name: 'John Doe', age: 27 }, (error, user) -> | ||
console.log error | ||
@@ -135,2 +135,7 @@ ``` | ||
# find multiple ids with same order | ||
User.findPreserve [2,1,2,3], (error, users) -> | ||
# users[0].id is 2 and users[1].id is 1 and users[2].id is 2 and users[3].id is 3 | ||
console.log users | ||
# get count of all records | ||
@@ -146,2 +151,11 @@ # the same as "SELECT COUNT(*) FROM users" | ||
# update records that match conditions | ||
# the same as "UPDATE users SET age=10 WHERE age=27" | ||
User.update { age: 10 }, age: 27, (error, count) -> | ||
console.log count | ||
# using query chain | ||
User.where(age: 27).update age:10, (error, count) -> | ||
console.log count | ||
# delete records that match conditions | ||
@@ -346,1 +360,16 @@ # the same as "DELETE FROM users WHERE age=27" | ||
See [[#Query::near]] for more details. | ||
## Other features | ||
Use [[#ModelTimestamp.timestamps]] to add created_at and updated_at to the table. | ||
```coffeescript | ||
User.timestamps() | ||
``` | ||
Use [[#Model.createBulk]] to create many records at once. | ||
```coffeescript | ||
User.createBulk [ { name: 'John Doe', age: 27 }, { name: 'Bill Smith', age: 45 } ], (error, users) -> | ||
console.log users | ||
``` |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
113862
22
2989
372
3