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

Commit 0800fbce by Jan Aagaard Meier

Merge remote-tracking branch 'sdepold/master' into performancecherry

2 parents 8d09ef96 fbd1246a
...@@ -21,4 +21,3 @@ node_js: ...@@ -21,4 +21,3 @@ node_js:
- 0.6 - 0.6
- 0.8 - 0.8
- 0.9 - 0.9
...@@ -6,6 +6,7 @@ var HasManySingleLinked = require("./has-many-single-linked") ...@@ -6,6 +6,7 @@ var HasManySingleLinked = require("./has-many-single-linked")
module.exports = (function() { module.exports = (function() {
var HasMany = function(srcDAO, targetDAO, options) { var HasMany = function(srcDAO, targetDAO, options) {
this.associationType = 'HasMany'
this.source = srcDAO this.source = srcDAO
this.target = targetDAO this.target = targetDAO
this.options = options this.options = options
...@@ -53,6 +54,7 @@ module.exports = (function() { ...@@ -53,6 +54,7 @@ module.exports = (function() {
combinedTableAttributes[this.foreignIdentifier] = {type:DataTypes.INTEGER, primaryKey: true} combinedTableAttributes[this.foreignIdentifier] = {type:DataTypes.INTEGER, primaryKey: true}
this.connectorDAO = this.source.daoFactoryManager.sequelize.define(this.combinedName, combinedTableAttributes, this.options) this.connectorDAO = this.source.daoFactoryManager.sequelize.define(this.combinedName, combinedTableAttributes, this.options)
if(!this.isSelfAssociation) { if(!this.isSelfAssociation) {
this.target.associations[this.associationAccessor].connectorDAO = this.connectorDAO this.target.associations[this.associationAccessor].connectorDAO = this.connectorDAO
} }
......
...@@ -115,9 +115,10 @@ module.exports = (function() { ...@@ -115,9 +115,10 @@ module.exports = (function() {
selectQuery: function(tableName, options) { selectQuery: function(tableName, options) {
var query = "SELECT <%= attributes %> FROM <%= table %>" var query = "SELECT <%= attributes %> FROM <%= table %>"
, table = null
options = options || {} options = options || {}
options.table = Array.isArray(tableName) ? tableName.map(function(tbl){ return Utils.addTicks(tbl) }).join(", ") : Utils.addTicks(tableName) options.table = 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 ')
...@@ -128,25 +129,47 @@ module.exports = (function() { ...@@ -128,25 +129,47 @@ module.exports = (function() {
options.attributes = options.attributes || '*' options.attributes = options.attributes || '*'
if (options.include) { if (options.include) {
var tableNames = [options.table] var optAttributes = [options.table + '.*']
, optAttributes = [options.table + '.*']
for (var daoName in options.include) { for (var daoName in options.include) {
if (options.include.hasOwnProperty(daoName)) { if (options.include.hasOwnProperty(daoName)) {
var dao = options.include[daoName] var dao = options.include[daoName]
, daoFactory = dao.daoFactoryManager.getDAO(tableName, {
attribute: 'tableName'
})
, _tableName = Utils.addTicks(dao.tableName) , _tableName = Utils.addTicks(dao.tableName)
, association = dao.getAssociation(daoFactory)
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 ' + Utils.addTicks(association.connectorDAO.tableName) + ' ON '
query += Utils.addTicks(association.connectorDAO.tableName) + '.'
query += Utils.addTicks(foreignIdentifier) + '='
query += Utils.addTicks(table) + '.' + Utils.addTicks('id')
query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON '
query += Utils.addTicks(dao.tableName) + '.'
query += Utils.addTicks('id') + '='
query += Utils.addTicks(association.connectorDAO.tableName) + '.' + Utils.addTicks(association.identifier)
} else {
query += ' LEFT OUTER JOIN ' + Utils.addTicks(dao.tableName) + ' ON '
query += Utils.addTicks(association.associationType === 'BelongsTo' ? dao.tableName : tableName) + '.'
query += Utils.addTicks(association.identifier) + '='
query += Utils.addTicks(table) + '.' + Utils.addTicks('id')
}
tableNames.push(_tableName)
optAttributes = optAttributes.concat( optAttributes = optAttributes.concat(
Utils._.keys(dao.attributes).map(function(attr) { Utils._.keys(dao.attributes).map(function(attr) {
var identifer = [_tableName, Utils.addTicks(attr)] var identifier = [_tableName, Utils.addTicks(attr)]
return identifer.join('.') + ' AS ' + Utils.addTicks(identifer.join('.')) return identifier.join('.') + ' AS ' + Utils.addTicks(identifier.join('.'))
}) })
) )
} }
} }
options.table = tableNames.join(', ')
options.attributes = optAttributes.join(', ') options.attributes = optAttributes.join(', ')
} }
......
...@@ -202,8 +202,8 @@ module.exports = (function() { ...@@ -202,8 +202,8 @@ module.exports = (function() {
tableNames.push(_tableName) tableNames.push(_tableName)
optAttributes = optAttributes.concat( optAttributes = optAttributes.concat(
Utils._.keys(dao.attributes).map(function(attr) { Utils._.keys(dao.attributes).map(function(attr) {
var identifer = [_tableName, Utils.addTicks(attr)] var identifier = [_tableName, Utils.addTicks(attr)]
return identifer.join('.') + ' AS ' + Utils.addTicks(identifer.join('.')) return identifier.join('.') + ' AS ' + Utils.addTicks(identifier.join('.'))
}) })
) )
} }
......
{ {
"name": "sequelize", "name": "sequelize",
"description": "Multi dialect ORM for Node.JS", "description": "Multi dialect ORM for Node.JS",
"version": "1.6.0-alpha-2", "version": "1.6.0-alpha-3",
"author": "Sascha Depold <sascha@depold.com>", "author": "Sascha Depold <sascha@depold.com>",
"contributors": [ "contributors": [
{ {
......
...@@ -20,20 +20,20 @@ describe("[" + dialect.toUpperCase() + "] BelongsTo", function() { ...@@ -20,20 +20,20 @@ describe("[" + dialect.toUpperCase() + "] BelongsTo", function() {
describe('setAssociation', function() { describe('setAssociation', function() {
it('clears the association if null is passed', function(done) { it('clears the association if null is passed', function(done) {
var User = this.sequelize.define('User', { username: Sequelize.STRING }) var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING })
, Task = this.sequelize.define('Task', { title: Sequelize.STRING }) , Task = this.sequelize.define('TaskXYZ', { title: Sequelize.STRING })
Task.belongsTo(User) Task.belongsTo(User)
this.sequelize.sync({ force: true }).success(function() { this.sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { User.create({ username: 'foo' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) { Task.create({ title: 'task' }).success(function(task) {
task.setUser(user).success(function() { task.setUserXYZ(user).success(function() {
task.getUser().success(function(user) { task.getUserXYZ().success(function(user) {
expect(user).not.toEqual(null) expect(user).not.toEqual(null)
task.setUser(null).success(function() { task.setUserXYZ(null).success(function() {
task.getUser().success(function(user) { task.getUserXYZ().success(function(user) {
expect(user).toEqual(null) expect(user).toEqual(null)
done() done()
}) })
......
...@@ -6,7 +6,7 @@ if (typeof require === 'function') { ...@@ -6,7 +6,7 @@ if (typeof require === 'function') {
} }
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 500 buster.testRunner.timeout = 1500
describe("[" + dialect.toUpperCase() + "] HasOne", function() { describe("[" + dialect.toUpperCase() + "] HasOne", function() {
before(function(done) { before(function(done) {
...@@ -21,20 +21,20 @@ describe("[" + dialect.toUpperCase() + "] HasOne", function() { ...@@ -21,20 +21,20 @@ describe("[" + dialect.toUpperCase() + "] HasOne", function() {
describe('setAssociation', function() { describe('setAssociation', function() {
it('clears the association if null is passed', function(done) { it('clears the association if null is passed', function(done) {
var User = this.sequelize.define('User', { username: Sequelize.STRING }) var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING })
, Task = this.sequelize.define('Task', { title: Sequelize.STRING }) , Task = this.sequelize.define('TaskXYZ', { title: Sequelize.STRING })
User.hasOne(Task) User.hasOne(Task)
this.sequelize.sync({ force: true }).success(function() { this.sequelize.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { User.create({ username: 'foo' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) { Task.create({ title: 'task' }).success(function(task) {
user.setTask(task).success(function() { user.setTaskXYZ(task).success(function() {
user.getTask().success(function(task) { user.getTaskXYZ().success(function(task) {
expect(task).not.toEqual(null) expect(task).not.toEqual(null)
user.setTask(null).success(function() { user.setTaskXYZ(null).success(function() {
user.getTask().success(function(task) { user.getTaskXYZ().success(function(task) {
expect(task).toEqual(null) expect(task).toEqual(null)
done() done()
}) })
......
...@@ -364,13 +364,13 @@ describe("[" + dialect.toUpperCase() + "] DAOFactory", function() { ...@@ -364,13 +364,13 @@ describe("[" + dialect.toUpperCase() + "] DAOFactory", function() {
}) })
}) })
it('//returns the selected fields as instance.selectedValues', function(done) { it('returns the selected fields as instance.selectedValues', function(done) {
this.User.create({ this.User.create({
username: 'JohnXOXOXO' username: 'JohnXOXOXO'
}).success(function() { }).success(function() {
this.User.find({ this.User.find({
where: { username: 'JohnXOXOXO' }, where: { username: 'JohnXOXOXO' },
select: ['username'] attributes: ['username']
}).success(function(user) { }).success(function(user) {
expect(user.selectedValues).toEqual({ username: 'JohnXOXOXO' }) expect(user.selectedValues).toEqual({ username: 'JohnXOXOXO' })
done() done()
...@@ -550,7 +550,7 @@ describe("[" + dialect.toUpperCase() + "] DAOFactory", function() { ...@@ -550,7 +550,7 @@ describe("[" + dialect.toUpperCase() + "] DAOFactory", function() {
}) //- describe: find }) //- describe: find
describe('findAll', function findAll() { describe('findAll', function findAll() {
describe('association fetching', function() { describe('include', function() {
before(function() { before(function() {
this.Task = this.sequelize.define('Task', { this.Task = this.sequelize.define('Task', {
title: Sequelize.STRING title: Sequelize.STRING
...@@ -561,6 +561,34 @@ describe("[" + dialect.toUpperCase() + "] DAOFactory", function() { ...@@ -561,6 +561,34 @@ describe("[" + dialect.toUpperCase() + "] DAOFactory", function() {
}) })
}) })
it('fetches data only for the relevant where clause', function(done) {
this.User.hasOne(this.Task)
this.Task.belongsTo(this.User)
this.sequelize.sync({ force: true }).success(function() {
this.User.create({ name: 'barfooz' }).success(function(user1) {
this.User.create({ name: 'barfooz' }).success(function(user2) {
this.Task.create({ title: 'task' }).success(function(task) {
var where = [Sequelize.Utils.addTicks(this.User.tableName) + ".`id`=?", user1.id]
if (dialect === 'postgres') {
where = ['"' + this.User.tableName + '"."id"=?', user1.id]
}
this.User.findAll({
where: where,
include: [ 'Task' ]
}).success(function(users){
expect(users.length).toEqual(1)
// console.log(users[0])
done()
}.bind(this))
}.bind(this))
}.bind(this))
}.bind(this))
}.bind(this))
})
it('fetches associated objects for 1:1 associations (1st direction)', function(done) { it('fetches associated objects for 1:1 associations (1st direction)', function(done) {
this.User.hasOne(this.Task) this.User.hasOne(this.Task)
this.Task.belongsTo(this.User) this.Task.belongsTo(this.User)
......
...@@ -34,26 +34,39 @@ describe("[" + dialect.toUpperCase() + "] Sequelize", function() { ...@@ -34,26 +34,39 @@ describe("[" + dialect.toUpperCase() + "] Sequelize", function() {
username: Helpers.Sequelize.STRING username: Helpers.Sequelize.STRING
}) })
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) { it('executes a query the internal way', function(done) {
this.sequelize.query(this.insertQuery, null, { raw: true }).success(function(result) { this.sequelize.query(this.insertQuery, null, { raw: true }).success(function(result) {
expect(result).toBeNull() expect(result).toBeNull()
done() 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) { 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() done()
}) })
}) })
it('//executes select queries correctly', function(done) { it('executes select queries correctly', function(done) {
this.sequelize.query(this.insertQuery).success(function() { this.sequelize.query(this.insertQuery).success(function() {
this.sequelize this.sequelize
.query("select * from " + this.User.tableName) .query("select * from " + this.User.tableName)
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!