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

Commit 5dfd4c86 by Sascha Depold

first preps for prefetching associated objects

1 parent 1cd32292
......@@ -102,6 +102,8 @@ module.exports = (function() {
}
DAOFactory.prototype.find = function(options) {
// no options defined?
// return an emitter which emits null
if([null, undefined].indexOf(options) > -1) {
return new Utils.CustomEventEmitter(function(emitter) {
setTimeout(function() { emitter.emit('success', null) }, 10)
......@@ -121,6 +123,14 @@ module.exports = (function() {
})
options = { where: where }
} else if((typeof options === 'object') && (options.hasOwnProperty('include'))) {
var includes = options.include
options.include = {}
includes.forEach(function(daoName) {
options.include[daoName] = this.daoFactoryManager.getDAO(daoName)
}.bind(this))
}
options.limit = 1
......
......@@ -94,21 +94,30 @@ module.exports = (function() {
},
selectQuery: function(tableName, options) {
var query = "SELECT <%= attributes %> FROM <%= table %>"
options = options || {}
options.table = Array.isArray(tableName) ? tableName.map(function(tbl){return Utils.addTicks(tbl)}).join(", ") : 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){
if(Array.isArray(attr) && attr.length == 2)
return [attr[0], Utils.addTicks(attr[1])].join(' as ')
else
return attr.indexOf(Utils.TICK_CHAR)<0 ? Utils.addTicks(attr) : attr
return attr.indexOf(Utils.TICK_CHAR) < 0 ? Utils.addTicks(attr) : attr
}).join(", ")
options.attributes = options.attributes || '*'
var query = "SELECT <%= attributes %> FROM <%= table %>"
if (options.include) {
var tableNames = []
for (var daoName in options.include) {
tableNames.push(Utils.addTicks(options.include[daoName].tableName))
}
options.table = [options.table].concat(tableNames).join(', ')
}
if(options.where) {
options.where = QueryGenerator.getWhereConditions(options.where)
options.where = QueryGenerator.getWhereConditions(options.where, tableName)
query += " WHERE <%= where %>"
}
......@@ -122,8 +131,11 @@ module.exports = (function() {
}
if(options.limit) {
if(options.offset) query += " LIMIT <%= offset %>, <%= limit %>"
else query += " LIMIT <%= limit %>"
if(options.offset) {
query += " LIMIT <%= offset %>, <%= limit %>"
} else {
query += " LIMIT <%= limit %>"
}
}
query += ";"
......@@ -235,16 +247,18 @@ module.exports = (function() {
return Utils._.template(sql)({ tableName: tableName, indexName: indexName })
},
getWhereConditions: function(smth) {
getWhereConditions: function(smth, tableName) {
var result = null
if(Utils.isHash(smth)) {
smth = Utils.prependTableNameToHash(tableName, smth)
result = QueryGenerator.hashToWhereConditions(smth)
} else if(typeof smth === 'number') {
result = Utils.addTicks('id') + "=" + Utils.escape(smth)
} else if(typeof smth === "string") {
} else if (typeof smth === 'number') {
smth = Utils.prependTableNameToHash(tableName, { id: smth })
result = QueryGenerator.hashToWhereConditions(smth)
} else if (typeof smth === "string") {
result = smth
} else if(Array.isArray(smth)) {
} else if (Array.isArray(smth)) {
result = Utils.format(smth)
}
......@@ -257,18 +271,21 @@ module.exports = (function() {
var _key = key.split('.').map(function(col){return Utils.addTicks(col)}).join(".")
, _value = null
if(Array.isArray(value)) {
if (Array.isArray(value)) {
// is value an array?
_value = "(" + Utils._.map(value, function(subvalue) {
return Utils.escape(subvalue);
}).join(',') + ")"
return [_key, _value].join(" IN ")
}
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 {
} else if ((value) && (typeof value == 'object')) {
// is value an 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)
return (_value == 'NULL') ? _key + " IS NULL" : [_key, _value].join("=")
}
......
......@@ -33,12 +33,18 @@ module.exports = (function() {
bindClient.call(this)
if(this.options.logging !== false)
if(this.options.logging !== false) {
this.options.logging('Executing: ' + this.sql)
}
this.client.query(this.sql, function(err, results, fields) {
self.emit('sql', self.sql)
err ? onFailure.call(self, err) : onSuccess.call(self, results, fields)
if (err) {
onFailure.call(self, err)
} else {
onSuccess.call(self, results, fields)
}
}).setMaxListeners(100)
return this
......
......@@ -128,6 +128,24 @@ var Utils = module.exports = {
}
return result
},
prependTableNameToHash: function(tableName, hash) {
if (tableName) {
var _hash = {}
for (var key in hash) {
if (key.indexOf('.') === -1) {
_hash[tableName + '.' + key] = hash[key]
} else {
_hash[key] = hash[key]
}
}
return _hash
} else {
return hash
}
}
}
......
......@@ -41,16 +41,16 @@ describe('QueryGenerator', function() {
expectation: "SELECT `id`, `name` FROM `myTable`;"
}, {
arguments: ['myTable', {where: {id: 2}}],
expectation: "SELECT * FROM `myTable` WHERE `id`=2;"
expectation: "SELECT * FROM `myTable` WHERE `myTable`.`id`=2;"
}, {
arguments: ['myTable', {where: {name: 'foo'}}],
expectation: "SELECT * FROM `myTable` WHERE `name`='foo';"
expectation: "SELECT * FROM `myTable` WHERE `myTable`.`name`='foo';"
}, {
arguments: ['myTable', {where: {name: "foo';DROP TABLE myTable;"}}],
expectation: "SELECT * FROM `myTable` WHERE `name`='foo\\';DROP TABLE myTable;';"
expectation: "SELECT * FROM `myTable` WHERE `myTable`.`name`='foo\\';DROP TABLE myTable;';"
}, {
arguments: ['myTable', {where: 2}],
expectation: "SELECT * FROM `myTable` WHERE `id`=2;"
expectation: "SELECT * FROM `myTable` WHERE `myTable`.`id`=2;"
}, {
arguments: ['foo', { attributes: [['count(*)', 'count']] }],
expectation: 'SELECT count(*) as `count` FROM `foo`;'
......@@ -206,7 +206,7 @@ describe('QueryGenerator', function() {
// Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly
var context = test.context || {options: {}};
var conditions = QueryGenerator[suiteTitle].apply(context, test.arguments)
expect(conditions).toEqual(test.expectation)
})
})
......
......@@ -360,28 +360,34 @@ dialects.forEach(function(dialect) {
})
})
it('=>fetches associated objects for 1:1 associations', function(done) {
it('//fetches associated objects for 1:1 associations', function(done) {
var Task = this.sequelize.define('Task', {
title: Sequelize.STRING
})
this.User.hasOne(Task)
Task.belongsTo(this.User)
var User = this.sequelize.define('UserWithName', {
name: Sequelize.STRING
})
User.hasOne(Task)
Task.belongsTo(User)
this.sequelize.sync({ force: true }).success(function() {
Task.create({ title: 'task' }).success(function(task) {
this.user.setTask(task).success(function() {
this.User.find({
where: { id: 1 },
include: 'Task'
}).success(function(user) {
expect(user.task).toBeDefined()
expect(user.task).toEqual(task)
done()
}.bind(this))
}.bind(this))
}.bind(this))
}.bind(this))
User.create({ name: 'barfooz' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) {
user.setTask(task).success(function() {
User.find({
where: { 'UserWithNames.id': 1 },
include: [ 'Task' ]
}).success(function(user) {
expect(user.task).toBeDefined()
expect(user.task).toEqual(task)
done()
})
}) //- setTask
}) //- Task.create
}) //- User.create
}) //- sequelize.sync
})
})
})
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!