sequelize
Advanced tools
Comparing version 1.6.0-alpha-3 to 1.6.0-beta-1
@@ -5,2 +5,4 @@ # v1.6.0 # | ||
- [BUG] fixed wrong version in sequelize binary | ||
- [BUG] local options have higher priority than global options (thanks to guersam) | ||
- [BUG] fixed where clause when passing an empty array (thanks to kbackowski) | ||
- [FEATURE] added association prefetching for find and findAll | ||
@@ -10,3 +12,7 @@ - [FEATURE] it's now possible to use callbacks of async functions inside migrations (thanks to mphilpot) | ||
- [FEATURE] Migrations now understand NODE_ENV (thanks to gavri) | ||
- [FEATURE] | ||
- [FEATURE] Performance improvements (thanks to Mick-Hansen and janmeier from innofluence) | ||
- [FEATURE] Model.find and Model.findAll can now take a String with an ID. (thanks to ghernandez345) | ||
- [FEATURE] Compatibility for JSON-like strings in Postgres (thanks to aslakhellesoy) | ||
- [FEATURE] honor maxConcurrentQueries option (thanks to dchester) | ||
- [FEATURE] added support for stored procedures (inspired by wuyuntao) | ||
@@ -13,0 +19,0 @@ # v1.5.0 # |
@@ -28,2 +28,6 @@ var Utils = require("./../utils") | ||
Utils._.defaults(this.source.rawAttributes, newAttributes) | ||
// Sync attributes to DAO proto each time a new assoc is added | ||
this.target.DAO.prototype.attributes = Object.keys(this.target.DAO.prototype.rawAttributes); | ||
return this | ||
@@ -37,3 +41,3 @@ } | ||
obj[accessor] = function() { | ||
var id = obj[self.identifier] | ||
var id = this[self.identifier] | ||
return self.target.find(id) | ||
@@ -50,6 +54,6 @@ } | ||
obj[accessor] = function(associatedObject) { | ||
obj[self.identifier] = associatedObject ? associatedObject.id : null | ||
this[self.identifier] = associatedObject ? associatedObject.id : null | ||
// passes the changed field to save, so only that field get updated. | ||
return obj.save([ self.identifier ]) | ||
return this.save([ self.identifier ]) | ||
} | ||
@@ -56,0 +60,0 @@ |
@@ -29,3 +29,3 @@ var Utils = require('./../utils') | ||
options.where = options.where ? Utils.merge(options.where, where) : where | ||
Utils._.extend(options.where, where) | ||
} else { | ||
@@ -32,0 +32,0 @@ options.where = where; |
@@ -14,3 +14,3 @@ var Utils = require('./../utils') | ||
options.where = options.where ? Utils.merge(options.where, where) : where | ||
options.where = options.where ? Utils._.extend(options.where, where) : where | ||
return this.__factory.target.findAll(options) | ||
@@ -17,0 +17,0 @@ } |
@@ -71,2 +71,6 @@ var Utils = require("./../utils") | ||
// Sync attributes to DAO proto each time a new assoc is added | ||
this.target.DAO.prototype.attributes = Object.keys(this.target.DAO.prototype.rawAttributes); | ||
this.source.DAO.prototype.attributes = Object.keys(this.source.DAO.prototype.rawAttributes); | ||
return this | ||
@@ -73,0 +77,0 @@ } |
@@ -34,2 +34,5 @@ var Utils = require("./../utils") | ||
// Sync attributes to DAO proto each time a new assoc is added | ||
this.target.DAO.prototype.attributes = Object.keys(this.target.DAO.prototype.rawAttributes); | ||
return this | ||
@@ -42,3 +45,3 @@ } | ||
obj[this.accessors.get] = function() { | ||
var id = obj.id | ||
var id = this.id | ||
, where = {} | ||
@@ -58,4 +61,5 @@ | ||
obj[this.accessors.set] = function(associatedObject) { | ||
var instance = this; | ||
return new Utils.CustomEventEmitter(function(emitter) { | ||
obj[self.accessors.get]().success(function(oldObj) { | ||
instance[self.accessors.get]().success(function(oldObj) { | ||
if(oldObj) { | ||
@@ -67,3 +71,3 @@ oldObj[self.identifier] = null | ||
if(associatedObject) { | ||
associatedObject[self.identifier] = obj.id | ||
associatedObject[self.identifier] = instance.id | ||
associatedObject | ||
@@ -70,0 +74,0 @@ .save() |
@@ -13,2 +13,6 @@ var Utils = require("./../utils") | ||
this.associations[association.associationAccessor] = association.injectAttributes() | ||
association.injectGetter(this.DAO.prototype); | ||
association.injectSetter(this.DAO.prototype); | ||
return this | ||
@@ -21,2 +25,6 @@ } | ||
this.associations[association.associationAccessor] = association.injectAttributes() | ||
association.injectGetter(this.DAO.prototype); | ||
association.injectSetter(this.DAO.prototype); | ||
return this | ||
@@ -29,2 +37,6 @@ } | ||
this.associations[association.associationAccessor] = association.injectAttributes() | ||
association.injectGetter(this.DAO.prototype); | ||
association.injectSetter(this.DAO.prototype); | ||
return this | ||
@@ -31,0 +43,0 @@ } |
var Utils = require("./utils") | ||
, DAO = require("./dao") | ||
, DataTypes = require("./data-types") | ||
, Util = require('util') | ||
@@ -44,13 +45,17 @@ module.exports = (function() { | ||
Object.defineProperty(DAOFactory.prototype, 'primaryKeyCount', { | ||
get: function() { return Utils._.keys(this.primaryKeys).length } | ||
}) | ||
DAOFactory.prototype.init = function(daoFactoryManager) { | ||
var self = this; | ||
Object.defineProperty(DAOFactory.prototype, 'hasPrimaryKeys', { | ||
get: function() { return this.primaryKeyCount > 0 } | ||
}) | ||
DAOFactory.prototype.init = function(daoFactoryManager) { | ||
this.daoFactoryManager = daoFactoryManager | ||
this.primaryKeys = {}; | ||
Utils._.each(this.attributes, function(dataTypeString, attributeName) { | ||
if((attributeName != 'id') && (dataTypeString.indexOf('PRIMARY KEY') !== -1)) { | ||
self.primaryKeys[attributeName] = dataTypeString | ||
} | ||
}) | ||
this.primaryKeyCount = Utils._.keys(this.primaryKeys).length; | ||
this.options.hasPrimaryKeys = this.hasPrimaryKeys = this.primaryKeyCount > 0; | ||
addDefaultAttributes.call(this) | ||
@@ -60,2 +65,37 @@ addOptionalClassMethods.call(this) | ||
// DAO prototype | ||
this.DAO = function() { | ||
DAO.apply(this, arguments); | ||
}; | ||
Util.inherits(this.DAO, DAO); | ||
this.DAO.prototype.rawAttributes = this.rawAttributes; | ||
if (this.options.instanceMethods) { | ||
Utils._.each(this.options.instanceMethods, function(fct, name) { | ||
self.DAO.prototype[name] = fct | ||
}) | ||
} | ||
this.DAO.prototype.attributes = Object.keys(this.DAO.prototype.rawAttributes); | ||
this.DAO.prototype.booleanValues = []; | ||
this.DAO.prototype.defaultValues = {}; | ||
this.DAO.prototype.validators = {}; | ||
Utils._.each(this.rawAttributes, function (definition, name) { | ||
if(((definition === DataTypes.BOOLEAN) || (definition.type === DataTypes.BOOLEAN))) { | ||
self.DAO.prototype.booleanValues.push(name); | ||
} | ||
if(definition.hasOwnProperty('defaultValue')) { | ||
self.DAO.prototype.defaultValues[name] = function() { | ||
return Utils.toDefaultValue(definition.defaultValue); | ||
} | ||
} | ||
if (definition.hasOwnProperty('validate')) { | ||
self.DAO.prototype.validators[name] = definition.validate; | ||
} | ||
}); | ||
this.DAO.prototype.__factory = this; | ||
this.DAO.prototype.hasDefaultValues = !Utils._.isEmpty(this.DAO.prototype.defaultValues); | ||
return this | ||
@@ -65,3 +105,3 @@ } | ||
DAOFactory.prototype.sync = function(options) { | ||
options = Utils.merge(options || {}, this.options) | ||
options = Utils._.extend({}, this.options, options || {}) | ||
@@ -96,5 +136,8 @@ var self = this | ||
DAOFactory.prototype.findAll = function(options) { | ||
var hasJoin = false; | ||
if ((typeof options === 'object') && (options.hasOwnProperty('include'))) { | ||
var includes = options.include | ||
hasJoin = true; | ||
options.include = {} | ||
@@ -107,3 +150,3 @@ | ||
return this.QueryInterface.select(this, this.tableName, options) | ||
return this.QueryInterface.select(this, this.tableName, options, { type: 'SELECT', hasJoin: hasJoin }) | ||
} | ||
@@ -116,9 +159,10 @@ | ||
return this.QueryInterface.select(this, [this.tableName, joinTableName], optcpy) | ||
return this.QueryInterface.select(this, [this.tableName, joinTableName], optcpy, { type: 'SELECT' }) | ||
} | ||
DAOFactory.prototype.find = function(options) { | ||
var hasJoin = false; | ||
// no options defined? | ||
// return an emitter which emits null | ||
if([null, undefined].indexOf(options) > -1) { | ||
if([null, undefined].indexOf(options) !== -1) { | ||
return new Utils.CustomEventEmitter(function(emitter) { | ||
@@ -129,17 +173,29 @@ setTimeout(function() { emitter.emit('success', null) }, 10) | ||
var primaryKeys = this.primaryKeys; | ||
// options is not a hash but an id | ||
if(typeof options === 'number') { | ||
options = { where: options } | ||
} else if (Utils.argsArePrimaryKeys(arguments, this.primaryKeys)) { | ||
var where = {} | ||
, self = this | ||
} else if (Utils._.size(primaryKeys) && Utils.argsArePrimaryKeys(arguments, primaryKeys)) { | ||
var where = {} | ||
, self = this | ||
, keys = Utils._.keys(primaryKeys) | ||
Utils._.each(arguments, function(arg, i) { | ||
var key = Utils._.keys(self.primaryKeys)[i] | ||
where[key] = arg | ||
}) | ||
Utils._.each(arguments, function(arg, i) { | ||
var key = keys[i] | ||
where[key] = arg | ||
}) | ||
options = { where: where } | ||
} else if((typeof options === 'object') && (options.hasOwnProperty('include'))) { | ||
options = { where: where } | ||
} else if ((typeof options === 'string') && (parseInt(options, 10).toString() === options)) { | ||
var parsedId = parseInt(options, 10); | ||
if(!Utils._.isFinite(parsedId)) { | ||
throw new Error('Invalid argument to find(). Must be an id or an options object.') | ||
} | ||
options = { where: parsedId } | ||
} else if ((typeof options === 'object') && (options.hasOwnProperty('include'))) { | ||
var includes = options.include | ||
hasJoin = true; | ||
@@ -155,3 +211,3 @@ options.include = {} | ||
return this.QueryInterface.select(this, this.tableName, options, { plain: true }) | ||
return this.QueryInterface.select(this, this.tableName, options, { plain: true, type: 'SELECT', hasJoin: hasJoin }) | ||
} | ||
@@ -183,41 +239,9 @@ | ||
DAOFactory.prototype.build = function(values, options) { | ||
var instance = new DAO(values, Utils._.extend(this.options, this.attributes, { hasPrimaryKeys: this.hasPrimaryKeys })) | ||
, self = this | ||
options = options || {} | ||
instance.__factory = this | ||
Utils._.each(this.attributes, function(definition, name) { | ||
//transform integer 0,1 into boolean | ||
if((definition.indexOf(DataTypes.BOOLEAN) !== -1) && (typeof instance[name] === "number")) { | ||
instance[name] = (instance[name] !== 0) | ||
} | ||
var self = this | ||
, instance = new this.DAO(values, this.options) | ||
//add default attributes | ||
if(typeof instance[name] === 'undefined') { | ||
var value = null | ||
instance.isNewRecord = options.hasOwnProperty('isNewRecord') ? options.isNewRecord : true | ||
if(self.rawAttributes.hasOwnProperty(name) && self.rawAttributes[name].hasOwnProperty('defaultValue')) { | ||
value = Utils.toDefaultValue(self.rawAttributes[name].defaultValue) | ||
} | ||
instance[name] = value | ||
instance.addAttribute(name, value) | ||
} | ||
// add validation | ||
if (self.rawAttributes.hasOwnProperty(name) && self.rawAttributes[name].hasOwnProperty('validate')) { | ||
instance.setValidators(name, self.rawAttributes[name].validate) | ||
} | ||
}) | ||
Utils._.each(this.options.instanceMethods || {}, function(fct, name) { instance[name] = fct }) | ||
Utils._.each(this.associations, function(association) { | ||
association.injectGetter(instance) | ||
association.injectSetter(instance) | ||
}) | ||
instance.isNewRecord = options.hasOwnProperty('isNewRecord') ? options.isNewRecord : true | ||
instance.selectedValues = values | ||
return instance | ||
@@ -230,13 +254,2 @@ } | ||
DAOFactory.prototype.__defineGetter__('primaryKeys', function() { | ||
var result = {} | ||
Utils._.each(this.attributes, function(dataTypeString, attributeName) { | ||
if((attributeName != 'id') && (dataTypeString.indexOf('PRIMARY KEY') > -1)) { | ||
result[attributeName] = dataTypeString | ||
} | ||
}) | ||
return result | ||
}) | ||
// private | ||
@@ -243,0 +256,0 @@ |
var Utils = require("./utils") | ||
, Mixin = require("./associations/mixin") | ||
, Validator = require("validator") | ||
, DataTypes = require("./data-types") | ||
module.exports = (function() { | ||
var DAO = function(values, options) { | ||
this.attributes = [] | ||
this.validators = {} // holds validation settings for each attribute | ||
this.__factory = null // will be set in DAO.build | ||
this.__options = Utils._.extend({ | ||
underscored: false, | ||
hasPrimaryKeys: false, | ||
timestamps: true, | ||
paranoid: false | ||
}, options || {}) | ||
var self = this; | ||
this.__options = options; | ||
this.hasPrimaryKeys = options.hasPrimaryKeys; | ||
this.selectedValues = values; | ||
initAttributes.call(this, values) | ||
if (this.hasDefaultValues) { | ||
Utils._.each(this.defaultValues, function (value, name) { | ||
if(typeof self[name] === 'undefined') { | ||
self.addAttribute(name, value()); | ||
} | ||
}) | ||
} | ||
if (this.booleanValues.length) { | ||
this.booleanValues.forEach(function (name) { | ||
//transform integer 0,1 into boolean | ||
self[name] = !!self[name]; | ||
}); | ||
} | ||
} | ||
@@ -151,3 +162,3 @@ Utils._.extend(DAO.prototype, Mixin.prototype) | ||
// extra args | ||
fn_args = details.hasOwnProperty("args") ? details.args : [] | ||
fn_args = details.hasOwnProperty("args") ? details.args : details | ||
if (!Utils._.isArray(fn_args)) | ||
@@ -246,3 +257,2 @@ fn_args = [fn_args] | ||
this[attribute] = value | ||
this.attributes.push(attribute) | ||
} | ||
@@ -270,3 +280,3 @@ | ||
// a newly created dao has no id | ||
var defaults = this.__options.hasPrimaryKeys ? {} : { id: null } | ||
var defaults = this.hasPrimaryKeys ? {} : { id: null } | ||
@@ -282,7 +292,9 @@ if(this.__options.timestamps) { | ||
for (var attr in defaults) { | ||
var value = defaults[attr] | ||
if (Utils._.size(defaults)) { | ||
for (var attr in defaults) { | ||
var value = defaults[attr] | ||
if(!this.hasOwnProperty(attr)) { | ||
this.addAttribute(attr, Utils.toDefaultValue(value)) | ||
if(!this.hasOwnProperty(attr)) { | ||
this.addAttribute(attr, Utils.toDefaultValue(value)) | ||
} | ||
} | ||
@@ -292,6 +304,3 @@ } | ||
/* Add the instance methods to DAO */ | ||
Utils._.extend(DAO.prototype, Mixin.prototype) | ||
return DAO | ||
})() |
@@ -72,2 +72,4 @@ var Utils = require('../../utils') | ||
result = data | ||
} else if (isCallQuery.call(this)) { | ||
result = data[0] | ||
} | ||
@@ -142,8 +144,3 @@ | ||
} else { | ||
var regExp = new RegExp("^" + daoFactory.tableName + "\\.") | ||
, match = attribute.match(regExp) | ||
if (!!match) { | ||
tableName = daoFactory.tableName | ||
} | ||
if (attribute.indexOf(daoFactory.tableName+".") === 0) tableName = daoFactory.tableName; | ||
} | ||
@@ -208,3 +205,3 @@ }) | ||
var isSelectQuery = function() { | ||
return (this.sql.toLowerCase().indexOf('select') === 0) | ||
return this.options.type === 'SELECT'; | ||
} | ||
@@ -217,7 +214,7 @@ | ||
var handleSelectQuery = function(results) { | ||
var result = null | ||
var result = null, self = this; | ||
if (this.options.raw) { | ||
result = results | ||
} else if (queryResultHasJoin.call(this, results)) { | ||
} else if (this.options.hasJoin === true) { | ||
result = prepareJoinData.call(this, results) | ||
@@ -281,3 +278,11 @@ result = groupDataByCalleeFactory.call(this, result).map(function(result) { | ||
var isCallQuery = function() { | ||
var result = false | ||
result = result || (this.sql.toLowerCase().indexOf('call') === 0) | ||
return result | ||
} | ||
/** | ||
@@ -284,0 +289,0 @@ The function takes the result of the query execution and groups |
@@ -17,2 +17,4 @@ var mysql = require("mysql") | ||
this.poolCfg = this.config.pool | ||
this.pendingQueries = 0; | ||
this.useQueue = config.queue !== undefined ? config.queue : true; | ||
@@ -51,37 +53,65 @@ var self = this | ||
Utils._.extend(ConnectorManager.prototype, require("../connector-manager").prototype) | ||
Utils._.extend(ConnectorManager.prototype, require("../connector-manager").prototype); | ||
var isConnecting = false | ||
var isConnecting = false; | ||
ConnectorManager.prototype.query = function(sql, callee, options) { | ||
if(!this.isConnected && !this.pool) this.connect() | ||
if (!this.isConnected && !this.pool) this.connect(); | ||
var queueItem = { | ||
query: new Query(this.client, this.sequelize, callee, options || {}), | ||
sql: sql | ||
if (this.useQueue) { | ||
var queueItem = { | ||
query: new Query(this.client, this.sequelize, callee, options || {}), | ||
sql: sql | ||
}; | ||
enqueue.call(this, queueItem); | ||
return queueItem.query; | ||
} | ||
enqueue.call(this, queueItem) | ||
var self = this, query = new Query(this.client, this.sequelize, callee, options || {}); | ||
this.pendingQueries++; | ||
return queueItem.query | ||
} | ||
query.done(function() { | ||
self.pendingQueries--; | ||
if (self.pool) self.pool.release(query.client); | ||
else { | ||
if (self.pendingQueries === 0) { | ||
setTimeout(function() { | ||
self.pendingQueries === 0 && self.disconnect.call(self); | ||
}, 100); | ||
} | ||
} | ||
}); | ||
if (!this.pool) query.run(sql); | ||
else { | ||
this.pool.acquire(function(err, client) { | ||
if (err) return query.emit('error', err); | ||
query.client = client; | ||
query.run(sql); | ||
return; | ||
}); | ||
} | ||
return query; | ||
}; | ||
ConnectorManager.prototype.connect = function() { | ||
var self = this | ||
var self = this; | ||
// in case database is slow to connect, prevent orphaning the client | ||
if (this.isConnecting || this.pool) { | ||
return | ||
return; | ||
} | ||
connect.call(self, function(err, client) { | ||
self.client = client | ||
return | ||
}) | ||
return | ||
} | ||
self.client = client; | ||
return; | ||
}); | ||
return; | ||
}; | ||
ConnectorManager.prototype.disconnect = function() { | ||
if (this.client) | ||
disconnect.call(this, this.client) | ||
return | ||
} | ||
if (this.client) disconnect.call(this, this.client); | ||
return; | ||
}; | ||
@@ -92,4 +122,7 @@ | ||
var disconnect = function(client) { | ||
var self = this | ||
var self = this; | ||
if (!this.useQueue) this.client = null; | ||
client.end(function() { | ||
if (!self.useQueue) return client.destroy(); | ||
var intervalObj = null | ||
@@ -166,6 +199,5 @@ var cleanup = function () { | ||
for(var i = 0; i < count; i++) { | ||
var queueItem = this.queue[0] | ||
var queueItem = this.queue.shift(); | ||
if(queueItem) { | ||
enqueue.call(this, queueItem) | ||
this.queue = without(this.queue, queueItem) | ||
} | ||
@@ -217,4 +249,2 @@ } | ||
return ConnectorManager | ||
})() | ||
})() |
@@ -161,3 +161,3 @@ var Utils = require("../../utils") | ||
query += Utils.addTicks(association.identifier) + '=' | ||
query += Utils.addTicks(table) + '.' + Utils.addTicks('id') | ||
query += Utils.addTicks(association.associationType === 'BelongsTo' ? tableName : dao.tableName) + '.' + Utils.addTicks('id') | ||
} | ||
@@ -344,3 +344,3 @@ | ||
// is value an array? | ||
if(value.length == 0) { value = [null] } | ||
_value = "(" + value.map(function(subValue) { | ||
@@ -347,0 +347,0 @@ return Utils.escape(subValue); |
@@ -19,3 +19,2 @@ var Utils = require("../../utils") | ||
Utils.inherit(Query, AbstractQuery) | ||
Query.prototype.run = function(sql) { | ||
@@ -37,3 +36,2 @@ this.sql = sql | ||
}.bind(this)).setMaxListeners(100) | ||
return this | ||
@@ -40,0 +38,0 @@ } |
@@ -13,14 +13,25 @@ var Utils = require("../../utils") | ||
quoteChar = quoteChar || '"' | ||
return s.split('.').map(function(e) { return quoteChar + String(e) + quoteChar }).join('.') | ||
return removeQuotes(s, quoteChar) | ||
.split('.') | ||
.map(function(e) { return quoteChar + String(e) + quoteChar }) | ||
.join('.') | ||
} | ||
function pgEscape(s) { | ||
s = Utils.escape(s) | ||
function pgEscape(val) { | ||
if (val === undefined || val === null) { | ||
return 'NULL'; | ||
} | ||
if (typeof s == 'string') { | ||
// http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS | ||
s = s.replace(/\\'/g, "''") | ||
switch (typeof val) { | ||
case 'boolean': return (val) ? 'true' : 'false'; | ||
case 'number': return val+''; | ||
} | ||
return s | ||
if (val instanceof Date) { | ||
val = pgSqlDate(val); | ||
} | ||
// http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS | ||
val = val.replace(/'/g, "''"); | ||
return "'"+val+"'"; | ||
} | ||
@@ -138,2 +149,3 @@ | ||
for (var attributeName in attributes) { | ||
var definition = attributes[attributeName] | ||
var attrSql = '' | ||
@@ -181,5 +193,6 @@ | ||
var query = "SELECT <%= attributes %> FROM <%= table %>" | ||
, table = null | ||
options = options || {} | ||
options.table = Array.isArray(tableName) ? tableName.map(function(t){return addQuotes(t);}).join(", ") : addQuotes(tableName) | ||
options.table = table = Array.isArray(tableName) ? tableName.map(function(t){return addQuotes(t);}).join(", ") : addQuotes(tableName) | ||
options.attributes = options.attributes && options.attributes.map(function(attr){ | ||
@@ -197,15 +210,38 @@ if(Array.isArray(attr) && attr.length == 2) { | ||
if (options.include) { | ||
var tableNames = [options.table] | ||
, optAttributes = [options.table + '.*'] | ||
var optAttributes = [options.table + '.*'] | ||
for (var daoName in options.include) { | ||
if (options.include.hasOwnProperty(daoName)) { | ||
var dao = options.include[daoName] | ||
, _tableName = Utils.addTicks(dao.tableName) | ||
var dao = options.include[daoName] | ||
, daoFactory = dao.daoFactoryManager.getDAO(tableName, { | ||
attribute: 'tableName' | ||
}) | ||
, _tableName = addQuotes(dao.tableName) | ||
, association = dao.getAssociation(daoFactory) | ||
tableNames.push(_tableName) | ||
if (association.connectorDAO) { | ||
var foreignIdentifier = Utils._.keys(association.connectorDAO.rawAttributes).filter(function(attrName) { | ||
return (!!attrName.match(/.+Id$/) || !!attrName.match(/.+_id$/)) && (attrName !== association.identifier) | ||
})[0] | ||
query += ' LEFT OUTER JOIN ' + addQuotes(association.connectorDAO.tableName) + ' ON ' | ||
query += addQuotes(association.connectorDAO.tableName) + '.' | ||
query += addQuotes(foreignIdentifier) + '=' | ||
query += addQuotes(table) + '.' + addQuotes('id') | ||
query += ' LEFT OUTER JOIN ' + addQuotes(dao.tableName) + ' ON ' | ||
query += addQuotes(dao.tableName) + '.' | ||
query += addQuotes('id') + '=' | ||
query += addQuotes(association.connectorDAO.tableName) + '.' + addQuotes(association.identifier) | ||
} else { | ||
query += ' LEFT OUTER JOIN ' + addQuotes(dao.tableName) + ' ON ' | ||
query += addQuotes(association.associationType === 'BelongsTo' ? dao.tableName : tableName) + '.' | ||
query += addQuotes(association.identifier) + '=' | ||
query += addQuotes(association.associationType === 'BelongsTo' ? tableName : dao.tableName) + '.' + addQuotes('id') | ||
} | ||
optAttributes = optAttributes.concat( | ||
Utils._.keys(dao.attributes).map(function(attr) { | ||
var identifier = [_tableName, Utils.addTicks(attr)] | ||
return identifier.join('.') + ' AS ' + Utils.addTicks(identifier.join('.')) | ||
var identifier = [_tableName, addQuotes(attr)] | ||
return identifier.join('.') + ' AS "' + removeQuotes(identifier.join('.')) + '"' | ||
}) | ||
@@ -216,4 +252,3 @@ ) | ||
options.table = tableNames.join(', ').replace(/`/g, '"') | ||
options.attributes = optAttributes.join(', ').replace(/`/g, '"') | ||
options.attributes = optAttributes.join(', ') | ||
} | ||
@@ -272,3 +307,3 @@ | ||
values: Utils._.values(attrValueHash).map(function(value){ | ||
return pgEscape((value instanceof Date) ? pgSqlDate(value) : value) | ||
return pgEscape(value) | ||
}).join(",") | ||
@@ -283,3 +318,3 @@ } | ||
var query = "UPDATE <%= table %> SET <%= values %> WHERE <%= where %>" | ||
var query = "UPDATE <%= table %> SET <%= values %> WHERE <%= where %> RETURNING *" | ||
, values = [] | ||
@@ -289,3 +324,3 @@ | ||
var value = attrValueHash[key] | ||
values.push(addQuotes(key) + "=" + pgEscape((value instanceof Date) ? pgSqlDate(value) : value)) | ||
values.push(addQuotes(key) + "=" + pgEscape(value)) | ||
} | ||
@@ -409,2 +444,3 @@ | ||
if(Array.isArray(value)) { | ||
if(value.length == 0) { value = [null] } | ||
_value = "(" + value.map(function(subValue) { | ||
@@ -411,0 +447,0 @@ return pgEscape(subValue); |
@@ -78,2 +78,8 @@ var Utils = require("../../utils") | ||
} else if (this.send('isUpdateQuery')) { | ||
for (var key in rows[0]) { | ||
if (rows[0].hasOwnProperty(key)) { | ||
this.callee[key] = rows[0][key] | ||
} | ||
} | ||
this.emit('success', this.callee) | ||
@@ -80,0 +86,0 @@ } else { |
@@ -8,3 +8,3 @@ var Utils = require('./utils') | ||
this.QueryGenerator = require('./dialects/' + this.sequelize.options.dialect + '/query-generator') | ||
this.QueryGenerator.options = this.sequelize.options; | ||
this.QueryGenerator.options = this.sequelize.options; | ||
} | ||
@@ -212,3 +212,3 @@ Utils.addEventEmitter(QueryInterface) | ||
var sql = self.QueryGenerator.selectQuery(tableName, options) | ||
, qry = self.sequelize.query(sql, null, { plain: true, raw: true }) | ||
, qry = self.sequelize.query(sql, null, { plain: true, raw: true, type: 'SELECT' }) | ||
@@ -277,3 +277,3 @@ qry | ||
emitter.emit('sql', sql) | ||
}) | ||
}); | ||
}).run() | ||
@@ -280,0 +280,0 @@ } |
@@ -39,3 +39,4 @@ var Utils = require("./utils") | ||
logging: console.log, | ||
omitNull: false | ||
omitNull: false, | ||
queue: true | ||
}, options || {}) | ||
@@ -55,3 +56,5 @@ | ||
pool : this.options.pool, | ||
protocol: this.options.protocol | ||
protocol: this.options.protocol, | ||
queue : this.options.queue, | ||
maxConcurrentQueries: this.options.maxConcurrentQueries | ||
} | ||
@@ -93,6 +96,14 @@ | ||
options = options || {} | ||
if(this.options.define) { | ||
options = Sequelize.Utils.merge(options, this.options.define) | ||
var globalOptions = this.options | ||
if(globalOptions.define) { | ||
options = Utils._.extend({}, globalOptions.define, options) | ||
Utils._(['classMethods', 'instanceMethods']).each(function(key) { | ||
if(globalOptions.define[key]) { | ||
options[key] = options[key] || {} | ||
Utils._.extend(options[key], globalOptions.define[key]) | ||
} | ||
}) | ||
} | ||
options.omitNull = this.options.omitNull | ||
options.omitNull = globalOptions.omitNull | ||
@@ -123,6 +134,14 @@ var factory = new DAOFactory(daoName, attributes, options) | ||
Sequelize.prototype.query = function(sql, callee, options) { | ||
options = (arguments.length === 3) ? options : { raw: true } | ||
if (arguments.length === 3) { | ||
options = options | ||
} else if (arguments.length === 2) { | ||
options = {} | ||
} else { | ||
options = { raw: true } | ||
} | ||
options = Utils._.extend(Utils._.clone(this.options.query), options) | ||
options = Utils._.extend(options, { | ||
logging: this.options.hasOwnProperty('logging') ? this.options.logging : console.log | ||
logging: this.options.hasOwnProperty('logging') ? this.options.logging : console.log, | ||
type: (sql.toLowerCase().indexOf('select') === 0) ? 'SELECT' : false | ||
}) | ||
@@ -137,3 +156,3 @@ | ||
if(this.options.sync) { | ||
options = Sequelize.Utils.merge(options, this.options.sync) | ||
options = Utils._.extend({}, this.options.sync, options) | ||
} | ||
@@ -140,0 +159,0 @@ |
@@ -70,11 +70,13 @@ var mysql = require("mysql") | ||
var result = (args.length == Utils._.keys(primaryKeys).length) | ||
Utils._.each(args, function(arg) { | ||
if(result) { | ||
if(['number', 'string'].indexOf(typeof arg) > -1) | ||
result = true | ||
else | ||
result = (arg instanceof Date) | ||
if (result) { | ||
Utils._.each(args, function(arg) { | ||
if(result) { | ||
if(['number', 'string'].indexOf(typeof arg) !== -1) | ||
result = true | ||
else | ||
result = (arg instanceof Date) | ||
} | ||
}) | ||
} | ||
}) | ||
} | ||
return result | ||
@@ -94,9 +96,2 @@ }, | ||
merge: function(a, b){ | ||
for(var key in b) { | ||
a[key] = b[key] | ||
} | ||
return a | ||
}, | ||
removeCommentsFromFunctionString: function(s) { | ||
@@ -103,0 +98,0 @@ s = s.replace(/\s*(\/\/.*)/g, '') |
{ | ||
"name": "sequelize", | ||
"description": "Multi dialect ORM for Node.JS", | ||
"version": "1.6.0-alpha-3", | ||
"version": "1.6.0-beta-1", | ||
"author": "Sascha Depold <sascha@depold.com>", | ||
@@ -6,0 +6,0 @@ "contributors": [ |
@@ -33,28 +33,30 @@ # Sequelize # | ||
## Collaboration ## | ||
## Collaboration 2.0 ## | ||
I'm glad to get pull request if any functionality is missing or something is buggy. But _please_ ... run the tests before you send me the pull request. | ||
Now if you want to contribute but don't really know where to begin | ||
don't worry, the steps below will guide you to have a sequelize | ||
contributor's environment running in a couple minutes. | ||
Still interested? Coolio! Here is how to get started: | ||
### 1. Prepare the environment ### | ||
### 1. Prepare your environment ### | ||
All the following steps consider you already have [npm](http://npmjs.org/) installed in your [node.js version 0.4.6 or higher](https://github.com/sdepold/sequelize/blob/master/package.json#L30) | ||
Here comes a little surprise: You need [Node.JS](http://nodejs.org). In order to be | ||
a productive developer, I would recommend the latest v0.8 (or a stable 0.9 if | ||
already out). Also I usually recommend [NVM](https://github.com/creationix/nvm). | ||
#### 1.1 MySQL and other external dependencies #### | ||
Once Node.JS is installed on your computer, you will also have access to the lovely | ||
Node Package Manager (NPM). | ||
Contributing to sequelize requires you to have | ||
[MySQL](http://www.mysql.com/) up and running in your local | ||
environment. The reason for that is that we have test cases that runs | ||
against an actual MySQL server and make sure everything is always | ||
working. | ||
### 2. Database... Come to me! ### | ||
That is also one of the reasons your features must come with tests: | ||
let's make sure sequelize will stay awesome as more features are added | ||
as well as that fixed bugs will never come back. | ||
First class citizen of Sequelize was MySQL. Over time, Sequelize began to | ||
become compatible to SQLite and PostgreSQL. In order to provide a fully | ||
featured pull request, you would most likely want to install of them. Give | ||
it a try, it's not that hard. | ||
Well, after installing **MySQL** you also need to create the sequelize test database: | ||
If you are too lazy or just don't know how to get this work, | ||
feel free to join the IRC channel (freenode@#sequelizejs). | ||
For MySQL and PostgreSQL you'll need to create a DB called `sequelize_test`. | ||
For MySQL this would look like this: | ||
```console | ||
@@ -69,7 +71,8 @@ $ echo "CREATE DATABASE sequelize_test;" | mysql -uroot | ||
**AND ONE LAST THING:** Sequelize also supports SQLite. So this should be working | ||
on your machine as well :) | ||
**AND ONE LAST THING:** Once `npm install` worked for you (see below), you'll | ||
get SQLite tests for free :) | ||
### 2. Install the dependencies ### | ||
### 3. Install the dependencies ### | ||
Just "cd" into sequelize directory and run `npm install`, see an example below: | ||
@@ -82,21 +85,40 @@ | ||
### 3. Run the tests ### | ||
### 4. Run the tests ### | ||
In order to run the tests you got to run `jasmine-node` against the `spec` directory. | ||
By the way, [there](https://github.com/sdepold/sequelize/tree/master/spec) is where | ||
you will write new tests if that's the case. | ||
Right now, the test base is split into the `spec` folder (which contains the | ||
lovely [BusterJS](http://busterjs.org) tests) and the `spec-jasmine` folder | ||
(which contains the ugly and awkward node-jasmine based tests). A main goal | ||
is to get rid of the jasmine tests! | ||
All you need is to run `./node_modules/.bin/jasmine-node spec/`, | ||
although this is kinda long and boring, so we configures a NPM task | ||
and made that less laborious to you :) | ||
As you might haven't installed all of the supported SQL dialects, here is how | ||
to run the test suites for your development environment: | ||
```console | ||
$ # run all tests at once: | ||
$ npm test | ||
$ # run only the jasmine tests (for all dialects): | ||
$ npm run test-jasmine | ||
$ # run all of the buster specs (for all dialects): | ||
$ npm run test-buster | ||
$ # run the buster specs for mysql: | ||
$ npm run test-buster-mysql | ||
$ # run the buster specs for sqlite: | ||
$ npm run test-buster-sqlite | ||
$ # run the buster specs for postgresql: | ||
$ npm run test-buster-postgres | ||
``` | ||
### 4. That's all ### | ||
### 5. That's all ### | ||
Just commit and send pull requests. | ||
Happy hacking and thank you for contributing. | ||
Ah and one last thing: If you think you deserve it, feel free to add yourself to the | ||
`package.json`. Also I always look for projects which are using sequelize. If you have | ||
one of them, drop me a line! | ||
Happy hacking and thank you for contributing | ||
@@ -103,0 +125,0 @@ # Build status |
@@ -65,3 +65,3 @@ var config = require("../config/config") | ||
var task = Task.build({title: 'asd'}) | ||
expect(task['UserId']).toBeNull() | ||
expect(task['UserId']).not.toBeDefined(); | ||
}) | ||
@@ -68,0 +68,0 @@ |
@@ -34,2 +34,26 @@ var config = require("./config/config") | ||
describe('Escaping', function() { | ||
it('is done properly for special characters', function() { | ||
var User = sequelize.define('User', { | ||
bio: Sequelize.TEXT | ||
}, { timestamps: false, logging: false }) | ||
Helpers.async(function(done) { | ||
User.sync({ force: true }).success(done) | ||
}) | ||
Helpers.async(function(done) { | ||
// Ideally we should test more: "\0\n\r\b\t\\\'\"\x1a" | ||
// But this causes sqlite to fail and exits the entire test suite immediately | ||
var bio = dialect + "'\"\n"; // Need to add the dialect here so in case of failure I know what DB it failed for | ||
User.create({ bio: bio }).success(function(u1) { | ||
User.find(u1.id).success(function(u2) { | ||
expect(u2.bio).toEqual(bio) | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
describe('isNewRecord', function() { | ||
@@ -209,3 +233,4 @@ it('returns true for non-saved objects', function() { | ||
User2.create({ username: 'john doe' }).success(function(johnDoe) { | ||
expect(johnDoe.updatedAt).toBeNull() | ||
// sqlite and mysql return undefined, whereas postgres returns null | ||
expect([undefined, null].indexOf(johnDoe.updatedAt)).not.toBe(-1); | ||
done() | ||
@@ -315,5 +340,4 @@ }) | ||
}) | ||
}) | ||
}) |
@@ -210,2 +210,6 @@ var config = require("../config/config") | ||
expectation: "`id` IN (1,2,3)" | ||
}, | ||
{ | ||
arguments: [{ id: [] }], | ||
expectation: "`id` IN (NULL)" | ||
} | ||
@@ -212,0 +216,0 @@ ] |
@@ -122,2 +122,5 @@ var config = require("../config/config") | ||
}, { | ||
arguments: ['mySchema.myTable', {name: JSON.stringify({info: 'Look ma a " quote'})}], | ||
expectation: "INSERT INTO \"mySchema\".\"myTable\" (\"name\") VALUES ('{\"info\":\"Look ma a \\\" quote\"}') RETURNING *;" | ||
}, { | ||
arguments: ['mySchema.myTable', {name: "foo';DROP TABLE mySchema.myTable;"}], | ||
@@ -131,33 +134,33 @@ expectation: "INSERT INTO \"mySchema\".\"myTable\" (\"name\") VALUES ('foo'';DROP TABLE mySchema.myTable;') RETURNING *;" | ||
arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, {id: 2}], | ||
expectation: "UPDATE \"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2" | ||
expectation: "UPDATE \"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2 RETURNING *" | ||
}, { | ||
arguments: ['myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, 2], | ||
expectation: "UPDATE \"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2" | ||
expectation: "UPDATE \"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2 RETURNING *" | ||
}, { | ||
arguments: ['myTable', {bar: 2}, {name: 'foo'}], | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo'" | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo' RETURNING *" | ||
}, { | ||
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {name: 'foo'}], | ||
expectation: "UPDATE \"myTable\" SET \"name\"='foo'';DROP TABLE myTable;' WHERE \"name\"='foo'" | ||
expectation: "UPDATE \"myTable\" SET \"name\"='foo'';DROP TABLE myTable;' WHERE \"name\"='foo' RETURNING *" | ||
}, { | ||
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}], | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2,\"nullValue\"=NULL WHERE \"name\"='foo'" | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2,\"nullValue\"=NULL WHERE \"name\"='foo' RETURNING *" | ||
}, { | ||
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}], | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2,\"nullValue\"=NULL WHERE \"name\"='foo'", | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2,\"nullValue\"=NULL WHERE \"name\"='foo' RETURNING *", | ||
context: {options: {omitNull: false}} | ||
}, { | ||
arguments: ['myTable', {bar: 2, nullValue: null}, {name: 'foo'}], | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo'", | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo' RETURNING *", | ||
context: {options: {omitNull: true}} | ||
}, { | ||
arguments: ['myTable', {bar: 2, nullValue: undefined}, {name: 'foo'}], | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo'", | ||
expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo' RETURNING *", | ||
context: {options: {omitNull: true}} | ||
}, { | ||
arguments: ['mySchema.myTable', {name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55))}, {id: 2}], | ||
expectation: "UPDATE \"mySchema\".\"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2" | ||
expectation: "UPDATE \"mySchema\".\"myTable\" SET \"name\"='foo',\"birthday\"='2011-03-27 10:01:55.0' WHERE \"id\"=2 RETURNING *" | ||
}, { | ||
arguments: ['mySchema.myTable', {name: "foo';DROP TABLE mySchema.myTable;"}, {name: 'foo'}], | ||
expectation: "UPDATE \"mySchema\".\"myTable\" SET \"name\"='foo'';DROP TABLE mySchema.myTable;' WHERE \"name\"='foo'" | ||
expectation: "UPDATE \"mySchema\".\"myTable\" SET \"name\"='foo'';DROP TABLE mySchema.myTable;' WHERE \"name\"='foo' RETURNING *" | ||
} | ||
@@ -239,2 +242,6 @@ ], | ||
expectation: "\"id\" IN (1,2,3)" | ||
}, | ||
{ | ||
arguments: [{ id: [] }], | ||
expectation: "\"id\" IN (NULL)" | ||
} | ||
@@ -241,0 +248,0 @@ ] |
@@ -43,2 +43,31 @@ var config = require("./config/config") | ||
}) | ||
it("overwrites global options", function() { | ||
setup({ define: { collate: 'utf8_general_ci' } }) | ||
var DAO = sequelize.define('foo', {bar: Sequelize.STRING}, {collate: 'utf8_bin'}) | ||
expect(DAO.options.collate).toEqual('utf8_bin') | ||
}) | ||
it("inherits global collate option", function() { | ||
setup({ define: { collate: 'utf8_general_ci' } }) | ||
var DAO = sequelize.define('foo', {bar: Sequelize.STRING}) | ||
expect(DAO.options.collate).toEqual('utf8_general_ci') | ||
}) | ||
it("inherits global classMethods and instanceMethods", function() { | ||
setup({ | ||
define: { | ||
classMethods : { globalClassMethod : function() {} }, | ||
instanceMethods : { globalInstanceMethod : function() {} } | ||
} | ||
}) | ||
var DAO = sequelize.define('foo', {bar: Sequelize.STRING}, { | ||
classMethods : { localClassMethod : function() {} } | ||
}) | ||
expect(typeof DAO.options.classMethods.globalClassMethod).toEqual('function') | ||
expect(typeof DAO.options.classMethods.localClassMethod).toEqual('function') | ||
expect(typeof DAO.options.instanceMethods.globalInstanceMethod).toEqual('function') | ||
}) | ||
}) | ||
@@ -45,0 +74,0 @@ |
@@ -23,4 +23,4 @@ if (typeof require === 'function') { | ||
it('clears the association if null is passed', function(done) { | ||
var User = this.sequelize.define('User', { username: Sequelize.STRING }) | ||
, Task = this.sequelize.define('Task', { title: Sequelize.STRING }) | ||
var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING }) | ||
, Task = this.sequelize.define('TaskXYZ', { title: Sequelize.STRING }) | ||
@@ -32,8 +32,8 @@ Task.belongsTo(User) | ||
Task.create({ title: 'task' }).success(function(task) { | ||
task.setUser(user).success(function() { | ||
task.getUser().success(function(user) { | ||
task.setUserXYZ(user).success(function() { | ||
task.getUserXYZ().success(function(user) { | ||
expect(user).not.toEqual(null) | ||
task.setUser(null).success(function() { | ||
task.getUser().success(function(user) { | ||
task.setUserXYZ(null).success(function() { | ||
task.getUserXYZ().success(function(user) { | ||
expect(user).toEqual(null) | ||
@@ -40,0 +40,0 @@ done() |
@@ -24,4 +24,4 @@ if (typeof require === 'function') { | ||
it('clears the association if null is passed', function(done) { | ||
var User = this.sequelize.define('User', { username: Sequelize.STRING }) | ||
, Task = this.sequelize.define('Task', { title: Sequelize.STRING }) | ||
var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING }) | ||
, Task = this.sequelize.define('TaskXYZ', { title: Sequelize.STRING }) | ||
@@ -31,21 +31,19 @@ User.hasOne(Task) | ||
this.sequelize.sync({ force: true }).success(function() { | ||
setTimeout(function(){ | ||
User.create({ username: 'foo' }).success(function(user) { | ||
Task.create({ title: 'task' }).success(function(task) { | ||
user.setTask(task).success(function() { | ||
user.getTask().success(function(task) { | ||
expect(task).not.toEqual(null) | ||
User.create({ username: 'foo' }).success(function(user) { | ||
Task.create({ title: 'task' }).success(function(task) { | ||
user.setTaskXYZ(task).success(function() { | ||
user.getTaskXYZ().success(function(task) { | ||
expect(task).not.toEqual(null) | ||
user.setTask(null).success(function() { | ||
user.getTask().success(function(task) { | ||
expect(task).toEqual(null) | ||
done() | ||
}) | ||
user.setTaskXYZ(null).success(function() { | ||
user.getTaskXYZ().success(function(task) { | ||
expect(task).toEqual(null) | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}.bind(this), 500) | ||
}) | ||
}) | ||
@@ -52,0 +50,0 @@ }) |
@@ -89,3 +89,3 @@ if(typeof require === 'function') { | ||
expect(Task.build().foo).toEqual(2) | ||
expect(Task.build().bar).toEqual(null) | ||
expect(Task.build().bar).toEqual(undefined) | ||
expect(Task.build().foobar).toEqual('asd') | ||
@@ -304,2 +304,11 @@ expect(Task.build().flag).toEqual(false) | ||
it('returns a single dao given a string id', function(done) { | ||
this.User.find(this.user.id + '').success(function(user) { | ||
expect(Array.isArray(user)).toBeFalsy() | ||
expect(user.id).toEqual(this.user.id) | ||
expect(user.id).toEqual(1) | ||
done() | ||
}.bind(this)) | ||
}) | ||
it("should make aliased attributes available", function(done) { | ||
@@ -369,3 +378,3 @@ this.User.find({ | ||
it('//returns the selected fields as instance.selectedValues', function(done) { | ||
it('returns the selected fields as instance.selectedValues', function(done) { | ||
this.User.create({ | ||
@@ -376,3 +385,3 @@ username: 'JohnXOXOXO' | ||
where: { username: 'JohnXOXOXO' }, | ||
select: ['username'] | ||
attributes: ['username'] | ||
}).success(function(user) { | ||
@@ -424,14 +433,16 @@ expect(user.selectedValues).toEqual({ username: 'JohnXOXOXO' }) | ||
this.User.create({ name: 'barfooz' }).success(function(user) { | ||
this.Task.create({ title: 'task' }).success(function(task) { | ||
user.setTask(task).success(function() { | ||
this.Task.find({ | ||
where: { 'Tasks.id': 1 }, | ||
include: [ 'UserWithName' ] | ||
}).success(function(task) { | ||
expect(task.userWithName).toBeDefined() | ||
expect(task.userWithName.id).toEqual(user.id) | ||
done() | ||
}) | ||
}.bind(this)) //- setTask | ||
}.bind(this)) //- Task.create | ||
this.User.create({ name: 'another user' }).success(function(another_user) { | ||
this.Task.create({ title: 'task' }).success(function(task) { | ||
user.setTask(task).success(function() { | ||
this.Task.find({ | ||
where: { 'Tasks.id': 1 }, | ||
include: [ 'UserWithName' ] | ||
}).success(function(task) { | ||
expect(task.userWithName).toBeDefined() | ||
expect(task.userWithName.id).toEqual(user.id) | ||
done() | ||
}) | ||
}.bind(this)) //- setTask | ||
}.bind(this)) //- Task.create | ||
}.bind(this)) //- User.create | ||
}.bind(this)) //- User.create | ||
@@ -438,0 +449,0 @@ }.bind(this)) //- sequelize.sync |
@@ -120,2 +120,8 @@ if(typeof require === 'function') { | ||
} | ||
, len: { | ||
spec: [2,4], | ||
fail: ["1", "12345"], | ||
pass: ["12", "123", "1234"], | ||
raw: true | ||
} | ||
, isUUID : { | ||
@@ -155,2 +161,7 @@ spec: { args: 4 }, | ||
} | ||
, max : { | ||
spec: 23, | ||
fail: "24", | ||
pass: "23" | ||
} | ||
, min : { | ||
@@ -161,2 +172,7 @@ spec: { args: 23 }, | ||
} | ||
, min : { | ||
spec: 23, | ||
fail: "22", | ||
pass: "23" | ||
} | ||
, isArray : { | ||
@@ -163,0 +179,0 @@ fail: 22, |
@@ -37,22 +37,35 @@ if(typeof require === 'function') { | ||
this.insertQuery = "INSERT INTO " + this.User.tableName + " (username) VALUES ('john')" | ||
this.insertQuery = "INSERT INTO " + this.User.tableName + " (username, createdAt, updatedAt) VALUES ('john', '2012-01-01 10:10:10', '2012-01-01 10:10:10')" | ||
this.User.sync().success(done) | ||
this.User.sync().success(done).error(function(err) { | ||
console(err) | ||
done() | ||
}) | ||
}) | ||
it('//executes a query the internal way', function(done) { | ||
this.sequelize.query(this.insertQuery, null, { raw: true }).success(function(result) { | ||
it('executes a query the internal way', function(done) { | ||
this.sequelize.query(this.insertQuery, null, { raw: true }).success(function(result) { | ||
expect(result).toBeNull() | ||
done() | ||
}) | ||
.error(function(err) { | ||
console.log(err) | ||
expect(err).not.toBeDefined() | ||
done() | ||
}) | ||
}) | ||
it('//executes a query if only the sql is passed', function(done) { | ||
it('executes a query if only the sql is passed', function(done) { | ||
this.sequelize.query(this.insertQuery).success(function(result) { | ||
expect(result).toBeNull() | ||
expect(result).not.toBeDefined() | ||
done() | ||
}) | ||
.error(function(err) { | ||
console.log(err) | ||
expect(err).not.toBeDefined() | ||
done() | ||
}) | ||
}) | ||
it('//executes select queries correctly', function(done) { | ||
it('executes select queries correctly', function(done) { | ||
this.sequelize.query(this.insertQuery).success(function() { | ||
@@ -72,3 +85,27 @@ this.sequelize | ||
}) | ||
it('executes stored procedures', function(done) { | ||
this.sequelize.query(this.insertQuery).success(function() { | ||
this.sequelize.query('DROP PROCEDURE IF EXISTS foo').success(function() { | ||
this.sequelize.query( | ||
"CREATE PROCEDURE foo()\nSELECT * FROM " + this.User.tableName + ";" | ||
).success(function() { | ||
this.sequelize.query('CALL foo()').success(function(users) { | ||
expect(users.map(function(u){ return u.username })).toEqual(['john']) | ||
done() | ||
}) | ||
}.bind(this)) | ||
}.bind(this)) | ||
}.bind(this)) | ||
}) | ||
it('uses the passed DAOFactory', function(done) { | ||
this.sequelize.query(this.insertQuery).success(function() { | ||
this.sequelize.query("SELECT * FROM " + this.User.tableName + ";", this.User).success(function(users) { | ||
expect(users[0].__factory).toEqual(this.User) | ||
done() | ||
}.bind(this)) | ||
}.bind(this)) | ||
}) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
2519484
9041
128