不要怂,就是干,撸起袖子干!

Commit 05068524 by sdepold

Merge branch 'master' of https://github.com/megshark/sequelize into megshark-master

2 parents 232b93ef 0ccbc17e
...@@ -3,3 +3,4 @@ test*.js ...@@ -3,3 +3,4 @@ test*.js
.DS_STORE .DS_STORE
node_modules node_modules
config config
npm-debug.log
...@@ -11,22 +11,16 @@ module.exports = (function() { ...@@ -11,22 +11,16 @@ module.exports = (function() {
var customEventEmitter = new Utils.CustomEventEmitter(function() { var customEventEmitter = new Utils.CustomEventEmitter(function() {
var where = {} var where = {}
where[self.__factory.identifier] = self.instance.id //fully qualify
where[self.__factory.connectorModel.tableName+"."+self.__factory.identifier] = self.instance.id
var primaryKeys = Utils._.keys(self.__factory.connectorModel.rawAttributes) var primaryKeys = Utils._.keys(self.__factory.connectorModel.rawAttributes)
, foreignKey = primaryKeys.filter(function(pk) { return pk != self.__factory.identifier })[0] , foreignKey = primaryKeys.filter(function(pk) { return pk != self.__factory.identifier })[0]
self.__factory.connectorModel.findAll({where: where}).success(function(associatedObjects) { where[self.__factory.connectorModel.tableName+"."+foreignKey] = {join: self.__factory.target.tableName+".id"}
var ids = associatedObjects.map(function(obj) { return obj[foreignKey] }) self.__factory.target.findAllJoin(self.__factory.connectorModel.tableName, {where: where})
.on('success', function(objects) { customEventEmitter.emit('success', objects) })
if (ids.length == 0) { .on('failure', function(err){ customEventEmitter.emit('failure', err) })
customEventEmitter.emit('success', [])
} else {
self.__factory.target.findAll({where: 'id in (' + ids.join(", ") + ')'})
.success(function(objects) { customEventEmitter.emit('success', objects) })
.error(function(err){ customEventEmitter.emit('failure', err) })
}
})
}) })
return customEventEmitter.run() return customEventEmitter.run()
......
...@@ -11,7 +11,7 @@ module.exports = (function() { ...@@ -11,7 +11,7 @@ module.exports = (function() {
this.options = options this.options = options
this.isSelfAssociation = (this.source.tableName == this.target.tableName) this.isSelfAssociation = (this.source.tableName == this.target.tableName)
this.associationAccessor = this.combinedName = Utils.combineTableNames( this.associationAccessor = this.combinedName = this.options.joinTableName || Utils.combineTableNames(
this.source.tableName, this.source.tableName,
this.isSelfAssociation ? (this.options.as || this.target.tableName) : this.target.tableName this.isSelfAssociation ? (this.options.as || this.target.tableName) : this.target.tableName
) )
...@@ -37,7 +37,7 @@ module.exports = (function() { ...@@ -37,7 +37,7 @@ module.exports = (function() {
if (this.isSelfAssociation || multiAssociation) { if (this.isSelfAssociation || multiAssociation) {
// remove the obsolete association identifier from the source // remove the obsolete association identifier from the source
if(this.isSelfAssociation) { if(this.isSelfAssociation) {
this.foreignIdentifier = (this.options.as || this.target.tableName) + 'Id' this.foreignIdentifier = Utils._.underscoredIf((this.options.as || this.target.tableName) + 'Id', this.options.underscored)
} else { } else {
this.foreignIdentifier = this.target.associations[this.associationAccessor].identifier this.foreignIdentifier = this.target.associations[this.associationAccessor].identifier
delete this.source.attributes[this.foreignIdentifier] delete this.source.attributes[this.foreignIdentifier]
...@@ -48,7 +48,7 @@ module.exports = (function() { ...@@ -48,7 +48,7 @@ module.exports = (function() {
combinedTableAttributes[this.identifier] = {type:DataTypes.INTEGER, primaryKey: true} combinedTableAttributes[this.identifier] = {type:DataTypes.INTEGER, primaryKey: true}
combinedTableAttributes[this.foreignIdentifier] = {type:DataTypes.INTEGER, primaryKey: true} combinedTableAttributes[this.foreignIdentifier] = {type:DataTypes.INTEGER, primaryKey: true}
this.connectorModel = this.source.modelFactoryManager.sequelize.define(this.combinedName, combinedTableAttributes) this.connectorModel = this.source.modelFactoryManager.sequelize.define(this.combinedName, combinedTableAttributes, this.options)
if(!this.isSelfAssociation) this.target.associations[this.associationAccessor].connectorModel = this.connectorModel if(!this.isSelfAssociation) this.target.associations[this.associationAccessor].connectorModel = this.connectorModel
this.connectorModel.sync() this.connectorModel.sync()
......
...@@ -94,13 +94,14 @@ module.exports = (function() { ...@@ -94,13 +94,14 @@ module.exports = (function() {
selectQuery: function(tableName, options) { selectQuery: function(tableName, options) {
options = options || {} options = options || {}
options.table = Utils.addTicks(tableName) options.table = Array.isArray(tableName) ? tableName.map(function(tbl){return Utils.addTicks(tbl)}).join(", ") : Utils.addTicks(tableName)
options.attributes = options.attributes && options.attributes.map(function(attr){ options.attributes = options.attributes && options.attributes.map(function(attr){
if(Array.isArray(attr) && attr.length == 2) if(Array.isArray(attr) && attr.length == 2)
return [attr[0], Utils.addTicks(attr[1])].join(' as ') return [attr[0], Utils.addTicks(attr[1])].join(' as ')
else else
return Utils.addTicks(attr) return attr.indexOf(Utils.TICK_CHAR)<0 ? Utils.addTicks(attr) : attr
}).join(", ") }).join(", ")
options.attributes = options.attributes || '*' options.attributes = options.attributes || '*'
var query = "SELECT <%= attributes %> FROM <%= table %>" var query = "SELECT <%= attributes %> FROM <%= table %>"
...@@ -240,16 +241,22 @@ module.exports = (function() { ...@@ -240,16 +241,22 @@ module.exports = (function() {
hashToWhereConditions: function(hash) { hashToWhereConditions: function(hash) {
return Utils._.map(hash, function(value, key) { return Utils._.map(hash, function(value, key) {
var _key = Utils.addTicks(key) //handle qualified key names
var _key = key.split('.').map(function(col){return Utils.addTicks(col)}).join(".")
, _value = null , _value = null
if(Array.isArray(value)) { if(Array.isArray(value)) {
_value = "(" + Utils._.map(value, function(subvalue) { _value = "(" + Utils._.map(value, function(subvalue) {
return Utils.escape(subvalue); return Utils.escape(subvalue);
}).join(',') + ")" }).join(',') + ")"
return [_key, _value].join(" IN ") return [_key, _value].join(" IN ")
} else { }
else if ((value) && (typeof value == 'object')) {
//using as sentinel for join column => value
_value = value.join.split('.').map(function(col){return Utils.addTicks(col)}).join(".")
return [_key, _value].join("=")
} else {
_value = Utils.escape(value) _value = Utils.escape(value)
return (_value == 'NULL') ? _key + " IS NULL" : [_key, _value].join("=") return (_value == 'NULL') ? _key + " IS NULL" : [_key, _value].join("=")
} }
......
...@@ -27,6 +27,8 @@ module.exports = (function() { ...@@ -27,6 +27,8 @@ module.exports = (function() {
console.log('Executing: ' + this.sql) console.log('Executing: ' + this.sql)
this.client.query(this.sql, function(err, results, fields) { this.client.query(this.sql, function(err, results, fields) {
//allow clients to listen to sql to do their own logging or whatnot
self.emit('sql', self.sql)
err ? onFailure.call(self, err) : onSuccess.call(self, results, fields) err ? onFailure.call(self, err) : onSuccess.call(self, results, fields)
}).setMaxListeners(100) }).setMaxListeners(100)
......
...@@ -90,6 +90,14 @@ module.exports = (function() { ...@@ -90,6 +90,14 @@ module.exports = (function() {
return this.QueryInterface.select(this, this.tableName, options) return this.QueryInterface.select(this, this.tableName, options)
} }
//right now, the caller (has-many-double-linked) is in charge of the where clause
ModelFactory.prototype.findAllJoin = function(joinTableName, options) {
optcpy = Utils._.clone(options)
optcpy.attributes = optcpy.attributes || [Utils.addTicks(this.tableName)+".*"]
return this.QueryInterface.select(this, [this.tableName, joinTableName], optcpy)
}
ModelFactory.prototype.find = function(options) { ModelFactory.prototype.find = function(options) {
if([null, undefined].indexOf(options) > -1) { if([null, undefined].indexOf(options) > -1) {
var NullEmitter = require("./emitters/null-emitter") var NullEmitter = require("./emitters/null-emitter")
......
...@@ -26,8 +26,9 @@ var Utils = module.exports = { ...@@ -26,8 +26,9 @@ var Utils = module.exports = {
addEventEmitter: function(_class) { addEventEmitter: function(_class) {
util.inherits(_class, require('events').EventEmitter) util.inherits(_class, require('events').EventEmitter)
}, },
TICK_CHAR: '`',
addTicks: function(s) { addTicks: function(s) {
return '`' + Utils.removeTicks(s) + '`' return Utils.TICK_CHAR + Utils.removeTicks(s) + Utils.TICK_CHAR
}, },
removeTicks: function(s) { removeTicks: function(s) {
return s.replace("`", "") return s.replace("`", "")
......
...@@ -29,4 +29,4 @@ ...@@ -29,4 +29,4 @@
"node": ">=0.4.6" "node": ">=0.4.6"
}, },
"license": "MIT" "license": "MIT"
} }
\ No newline at end of file
...@@ -92,6 +92,7 @@ describe('HasMany', function() { ...@@ -92,6 +92,7 @@ describe('HasMany', function() {
}) })
}) })
}) })
}) })
describe('bi-directional', function() { describe('bi-directional', function() {
......
module.exports = { module.exports = {
username: "root", username: "meg",
password: null, password: "meg",
database: 'sequelize_test', database: 'test',
host: '127.0.0.1', host: '127.0.0.1',
rand: function() { rand: function() {
return parseInt(Math.random() * 999) return parseInt(Math.random() * 999)
......
...@@ -7,8 +7,9 @@ describe('HasMany', function() { ...@@ -7,8 +7,9 @@ describe('HasMany', function() {
beforeEach(function() { Helpers.sync() }) beforeEach(function() { Helpers.sync() })
afterEach(function() { Helpers.drop() }) afterEach(function() { Helpers.drop() })
var User = sequelize.define('User' + Math.random(), { name: Sequelize.STRING }) //prevent periods from occurring in the table name since they are used to delimit (table.column)
, Task = sequelize.define('Task' + Math.random(), { name: Sequelize.STRING }) var User = sequelize.define('User' + Math.ceil(Math.random()*10000000), { name: Sequelize.STRING })
, Task = sequelize.define('Task' + Math.ceil(Math.random()*10000000), { name: Sequelize.STRING })
, users = null , users = null
, tasks = null , tasks = null
......
...@@ -24,6 +24,20 @@ describe('Associations', function() { ...@@ -24,6 +24,20 @@ describe('Associations', function() {
}) })
}) })
}) })
describe('when join table name is specified', function() {
var Table2 = sequelize.define('ms_table1', {foo: Sequelize.STRING})
, Table1 = sequelize.define('ms_table2', {foo: Sequelize.STRING})
Table1.hasMany(Table2, {joinTableName: 'table1_to_table2'})
Table2.hasMany(Table1, {joinTableName: 'table1_to_table2'})
it("should not use a combined name", function() {
expect(sequelize.modelFactoryManager.getModel('ms_table1sms_table2s')).toBeUndefined()
})
it("should use the specified name", function() {
expect(sequelize.modelFactoryManager.getModel('table1_to_table2')).toBeDefined()
})
})
}) })
}) })
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!