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

Commit 89cdf3a9 by Mick Hansen

Merge branch 'master' of github.com:sequelize/sequelize

2 parents 92bdd72f bdd547d0
......@@ -295,6 +295,7 @@ HasMany.prototype.get = function(instances, options) {
where[association.foreignKey] = {
$in: values
};
delete options.groupedLimit;
}
} else {
where[association.foreignKey] = instance.get(association.source.primaryKeyAttribute, {raw: true});
......
......@@ -30,7 +30,14 @@ Query.prototype.run = function(sql, parameters) {
var self = this;
this.sql = sql;
this.sequelize.log('Executing (' + (this.connection.uuid || 'default') + '): ' + this.sql, this.options);
//do we need benchmark for this query execution
var benchmark = this.sequelize.options.benchmark || this.options.benchmark;
if (!benchmark) {
this.sequelize.log('Executing (' + (this.connection.uuid || 'default') + '): ' + this.sql, this.options);
} else {
var queryBegin = Date.now();
}
var promise = new Utils.Promise(function(resolve, reject) {
// TRANSACTION SUPPORT
......@@ -63,6 +70,11 @@ Query.prototype.run = function(sql, parameters) {
var results = [];
var request = new self.connection.lib.Request(self.sql, function(err) {
if (benchmark) {
self.sequelize.log('Executed (' + (self.connection.uuid || 'default') + '): ' + self.sql + ' in ' + (Date.now() - queryBegin) + 'ms', self.options);
}
if (err) {
err.sql = sql;
reject(self.formatError(err));
......
......@@ -26,10 +26,22 @@ Query.prototype.run = function(sql, parameters) {
var self = this;
this.sql = sql;
this.sequelize.log('Executing (' + (this.connection.uuid || 'default') + '): ' + this.sql, this.options);
//do we need benchmark for this query execution
var benchmark = this.sequelize.options.benchmark || this.options.benchmark;
if (!benchmark) {
this.sequelize.log('Executing (' + (this.connection.uuid || 'default') + '): ' + this.sql, this.options);
} else {
var queryBegin = Date.now();
}
var promise = new Utils.Promise(function(resolve, reject) {
self.connection.query(self.sql, function(err, results) {
if (benchmark) {
self.sequelize.log('Executed (' + (self.connection.uuid || 'default') + '): ' + self.sql + ' in ' + (Date.now() - queryBegin) + 'ms', self.options);
}
if (err) {
err.sql = sql;
......
......@@ -62,7 +62,14 @@ Query.prototype.run = function(sql, parameters) {
, query = ((parameters && parameters.length) ? this.client.query(this.sql, parameters) : this.client.query(this.sql))
, rows = [];
this.sequelize.log('Executing (' + (this.client.uuid || 'default') + '): ' + this.sql, this.options);
//do we need benchmark for this query execution
var benchmark = this.sequelize.options.benchmark || this.options.benchmark;
if (!benchmark) {
this.sequelize.log('Executing (' + (this.client.uuid || 'default') + '): ' + this.sql, this.options);
} else {
var queryBegin = Date.now();
}
var promise = new Promise(function(resolve, reject) {
query.on('row', function(row) {
......@@ -82,6 +89,11 @@ Query.prototype.run = function(sql, parameters) {
});
query.on('end', function(result) {
if (benchmark) {
self.sequelize.log('Executed (' + (self.client.uuid || 'default') + '): ' + self.sql + ' in ' + (Date.now() - queryBegin) + 'ms', self.options);
}
if (receivedError) {
return;
}
......
......@@ -84,7 +84,14 @@ Query.prototype.run = function(sql, parameters) {
this.sql = sql;
}
this.sequelize.log('Executing (' + (this.database.uuid || 'default') + '): ' + this.sql, this.options);
//do we need benchmark for this query execution
var benchmark = this.sequelize.options.benchmark || this.options.benchmark;
if (!benchmark) {
this.sequelize.log('Executing (' + (this.database.uuid || 'default') + '): ' + this.sql, this.options);
} else {
var queryBegin = Date.now();
}
promise = new Promise(function(resolve) {
var columnTypes = {};
......@@ -95,6 +102,11 @@ Query.prototype.run = function(sql, parameters) {
} else {
resolve(new Promise(function(resolve, reject) {
var afterExecute = function(err, results) {
if (benchmark) {
self.sequelize.log('Executed (' + (self.database.uuid || 'default') + '): ' + self.sql + ' in ' + (Date.now() - queryBegin) + 'ms', self.options);
}
if (err) {
err.sql = self.sql;
reject(self.formatError(err));
......
......@@ -480,7 +480,7 @@ Instance.prototype._setInclude = function(key, value, options) {
* This error will have a property for each of the fields for which validation failed, with the error message for that field.
*
* @param {Object} [options]
* @param {Object} [options.fields] An optional array of strings, representing database columns. If fields is provided, only those columns will be validated and saved.
* @param {string[]} [options.fields] An optional array of strings, representing database columns. If fields is provided, only those columns will be validated and saved.
* @param {Boolean} [options.silent=false] If true, the updatedAt timestamp will not be updated.
* @param {Boolean} [options.validate=true] If false, validations won't be run.
* @param {Function} [options.logging=false] A function that gets executed while running the query to log the sql.
......
......@@ -81,7 +81,8 @@ var url = require('url')
* @param {Boolean} [options.quoteIdentifiers=true] Set to `false` to make table names and attributes case-insensitive on Postgres and skip double quoting of them.
* @param {String} [options.transactionType='DEFERRED'] Set the default transaction type. See `Sequelize.Transaction.TYPES` for possible options. Sqlite only.
* @param {String} [options.isolationLevel='REPEATABLE_READ'] Set the default transaction isolation level. See `Sequelize.Transaction.ISOLATION_LEVELS` for possible options.
* @param {Boolean} [options.typeValidation=false] Run built in type validators on insert and update, e.g. validate that arguments passed to integer fields are integer-like
* @param {Boolean} [options.typeValidation=false] Run built in type validators on insert and update, e.g. validate that arguments passed to integer fields are integer-like.
* @param {Boolean} [options.benchmark=false] Print query execution time in milliseconds when logging SQL.
*/
/**
......@@ -147,7 +148,8 @@ var Sequelize = function(database, username, password, options) {
transactionType: Transaction.TYPES.DEFERRED,
isolationLevel: Transaction.ISOLATION_LEVELS.REPEATABLE_READ,
databaseVersion: 0,
typeValidation: false
typeValidation: false,
benchmark: false
}, options || {});
if (this.options.dialect === 'postgresql') {
......
......@@ -185,8 +185,9 @@ Transaction.prototype.commit = function() {
.finally(function() {
self.finished = 'commit';
if (!self.parent) {
self.cleanup();
return self.cleanup();
}
return null;
});
};
......@@ -212,8 +213,9 @@ Transaction.prototype.rollback = function() {
.finally(function() {
self.finished = 'rollback';
if (!self.parent) {
self.cleanup();
return self.cleanup();
}
return null;
});
};
......@@ -241,6 +243,7 @@ Transaction.prototype.prepareEnvironment = function() {
if (self.sequelize.constructor.cls) {
self.sequelize.constructor.cls.set('transaction', self);
}
return null;
});
};
......
......@@ -38,7 +38,7 @@
"generic-pool": "2.3.0",
"inflection": "^1.6.0",
"lodash": "^3.9.3",
"moment": "^2.11.0",
"moment": "^2.11.1",
"moment-timezone": "^0.5.0",
"node-uuid": "~1.4.4",
"semver": "^5.0.1",
......
......@@ -116,6 +116,100 @@ describe(Support.getTestDialectTeaser('HasMany'), function() {
});
});
it('should fetch multiple layers of associations with limit and order with separate=true', function () {
var User = this.sequelize.define('User', {})
, Task = this.sequelize.define('Task', {
title: DataTypes.STRING
})
, SubTask = this.sequelize.define('SubTask', {
title: DataTypes.STRING
});
User.Tasks = User.hasMany(Task, {as: 'tasks'});
Task.SubTasks = Task.hasMany(SubTask, {as: 'subtasks'});
return this.sequelize.sync({force: true}).then(function() {
return Promise.join(
User.create({
tasks: [
{title: 'b', subtasks: [
{title:'c'},
{title:'a'}
]},
{title: 'd'},
{title: 'c', subtasks: [
{title:'b'},
{title:'a'},
{title:'c'}
]},
{title: 'a', subtasks: [
{title:'c'},
{title:'a'},
{title:'b'}
]}
]
}, {
include: [{association: User.Tasks, include: [Task.SubTasks]}]
}),
User.create({
tasks: [
{title: 'a', subtasks: [
{title:'b'},
{title:'a'},
{title:'c'}
]},
{title: 'c', subtasks: [
{title:'a'}
]},
{title: 'b', subtasks: [
{title:'a'},
{title:'b'}
]}
]
}, {
include: [{association: User.Tasks, include: [Task.SubTasks]}]
})
);
}).then(function(users) {
return User.findAll(
{
include: [{
association: User.Tasks,
limit: 2,
order: [['title', 'ASC']],
separate: true,
as: 'tasks',
include: [{association: Task.SubTasks, order: [['title', 'DESC']], separate: true, as: 'subtasks'}]
}]
}).then(function(users) {
expect(users[0].tasks.length).to.equal(2);
expect(users[0].tasks[0].title).to.equal('a');
expect(users[0].tasks[0].subtasks.length).to.equal(3);
expect(users[0].tasks[0].subtasks[0].title).to.equal('c');
expect(users[0].tasks[0].subtasks[1].title).to.equal('b');
expect(users[0].tasks[0].subtasks[2].title).to.equal('a');
expect(users[0].tasks[1].title).to.equal('b');
expect(users[0].tasks[1].subtasks.length).to.equal(2);
expect(users[0].tasks[1].subtasks[0].title).to.equal('c');
expect(users[0].tasks[1].subtasks[1].title).to.equal('a');
expect(users[1].tasks.length).to.equal(2);
expect(users[1].tasks[0].title).to.equal('a');
expect(users[1].tasks[0].subtasks.length).to.equal(3);
expect(users[1].tasks[0].subtasks[0].title).to.equal('c');
expect(users[1].tasks[0].subtasks[1].title).to.equal('b');
expect(users[1].tasks[0].subtasks[2].title).to.equal('a');
expect(users[1].tasks[1].title).to.equal('b');
expect(users[1].tasks[1].subtasks.length).to.equal(2);
expect(users[1].tasks[1].subtasks[0].title).to.equal('b');
expect(users[1].tasks[1].subtasks[1].title).to.equal('a');
});
});
});
it('should fetch associations for multiple instances with limit and order and a belongsTo relation', function () {
var User = this.sequelize.define('User', {})
, Task = this.sequelize.define('Task', {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!