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

Commit 1a81cee9 by Mick Hansen

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

2 parents 82403cfc 65abf5bc
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
- [BUG] Allow logging from individual functions even though the global logging setting is false. Closes [#2571](https://github.com/sequelize/sequelize/issues/2571) - [BUG] Allow logging from individual functions even though the global logging setting is false. Closes [#2571](https://github.com/sequelize/sequelize/issues/2571)
- [BUG] Allow increment/decrement operations when using schemata - [BUG] Allow increment/decrement operations when using schemata
- [INTERNALS] Update `inflection` dependency to v1.5.2 - [INTERNALS] Update `inflection` dependency to v1.5.2
- [REMOVED] Remove query generation syntactic sugar provided by `node-sql`, as well as the dependency on that module
#### Backwards compatability changes #### Backwards compatability changes
- When eager-loading a many-to-many association, the attributes of the through table are now accessible through an attribute named after the through model rather than the through table name singularized. i.e. `Task.find({include: Worker})` where the table name for through model `TaskWorker` is `TableTaskWorkers` used to produce `{ Worker: { ..., TableTaskWorker: {...} } }`. It now produces `{ Worker: { ..., TaskWorker: {...} } }`. Does not affect models where table name is auto-defined by Sequelize, or where table name is model name pluralized. - When eager-loading a many-to-many association, the attributes of the through table are now accessible through an attribute named after the through model rather than the through table name singularized. i.e. `Task.find({include: Worker})` where the table name for through model `TaskWorker` is `TableTaskWorkers` used to produce `{ Worker: { ..., TableTaskWorker: {...} } }`. It now produces `{ Worker: { ..., TaskWorker: {...} } }`. Does not affect models where table name is auto-defined by Sequelize, or where table name is model name pluralized.
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
- Nested HSTORE objects are no longer supported. Use DataTypes.JSON instead. - Nested HSTORE objects are no longer supported. Use DataTypes.JSON instead.
- In PG `where: { arr: [1, 2] }` where the `arr` column is an array will now use strict comparison (`=`) instead of the overlap operator (`&&`). To obtain the old behaviour, use ` where: { arr: { overlap: [1, 2] }}` - In PG `where: { arr: [1, 2] }` where the `arr` column is an array will now use strict comparison (`=`) instead of the overlap operator (`&&`). To obtain the old behaviour, use ` where: { arr: { overlap: [1, 2] }}`
- The default `fields` for `Instance#save` (when not a new record) is now an intersection of the model attributes and the changed attributes making saves more atomic while still allowing only defined attributes. - The default `fields` for `Instance#save` (when not a new record) is now an intersection of the model attributes and the changed attributes making saves more atomic while still allowing only defined attributes.
- Syntactic sugar for query generation was removed. You will no longer be able to call Model.dataset() to generate raw sql queries
# 2.0.0-rc2 # 2.0.0-rc2
- [FEATURE] Added to posibility of using a sequelize object as key in `sequelize.where`. Also added the option of specifying a comparator - [FEATURE] Added to posibility of using a sequelize object as key in `sequelize.where`. Also added the option of specifying a comparator
......
...@@ -33,6 +33,7 @@ AbstractDialect.prototype.supports = { ...@@ -33,6 +33,7 @@ AbstractDialect.prototype.supports = {
'IGNORE': '', 'IGNORE': '',
schemas: false, schemas: false,
transactions: true, transactions: true,
migrations: true,
constraints: { constraints: {
restrict: true restrict: true
}, },
......
...@@ -6,7 +6,6 @@ var Utils = require('./utils') ...@@ -6,7 +6,6 @@ var Utils = require('./utils')
, Association = require('./associations/base') , Association = require('./associations/base')
, DataTypes = require('./data-types') , DataTypes = require('./data-types')
, Util = require('util') , Util = require('util')
, sql = require('sql')
, SqlString = require('./sql-string') , SqlString = require('./sql-string')
, Transaction = require('./transaction') , Transaction = require('./transaction')
, Promise = require('./promise') , Promise = require('./promise')
...@@ -125,40 +124,6 @@ module.exports = (function() { ...@@ -125,40 +124,6 @@ module.exports = (function() {
get: function() { return this.QueryInterface.QueryGenerator; } get: function() { return this.QueryInterface.QueryGenerator; }
}); });
// inject the node-sql methods to the dao factory in order to
// receive the syntax sugar ...
(function() {
var instance = sql.define({ name: 'dummy', columns: [] });
for (var methodName in instance) {
;(function(methodName) {
Model.prototype[methodName] = function() {
var dataset = this.dataset()
, result = dataset[methodName].apply(dataset, arguments)
, dialect = this.modelManager.sequelize.options.dialect
, self = this;
result.toSql = function() {
var query = result.toQuery();
return SqlString.format(query.text.replace(/(\$\d)/g, '?'), query.values, null, dialect) + ';';
};
result.exec = function(options) {
options = Utils._.extend({
transaction: null,
type: QueryTypes.SELECT
}, options || {});
return self.sequelize.query(result.toSql(), self, options);
};
return result;
};
})(methodName);
}
})();
Model.prototype.toString = function () { Model.prototype.toString = function () {
return '[object SequelizeModel]'; return '[object SequelizeModel]';
}; };
...@@ -1713,33 +1678,6 @@ module.exports = (function() { ...@@ -1713,33 +1678,6 @@ module.exports = (function() {
return this.QueryInterface.describeTable(this.tableName, schema || this.options.schema || undefined); return this.QueryInterface.describeTable(this.tableName, schema || this.options.schema || undefined);
}; };
/**
* A proxy to the node-sql query builder, which allows you to build your query through a chain of method calls.
* The returned instance already has all the fields property populated with the field of the model.
*
* @see https://github.com/brianc/node-sql
* @return {node-sql} A node-sql instance
*/
Model.prototype.dataset = function() {
if (!this.__sql) {
this.__setSqlDialect();
}
var instance = this.__sql.define({ name: this.tableName, columns: [] })
, attributes = this.attributes;
Object.keys(attributes).forEach(function(key) {
instance.addColumn(key, attributes[key]);
});
return instance;
};
Model.prototype.__setSqlDialect = function() {
var dialect = this.modelManager.sequelize.options.dialect;
this.__sql = sql.setDialect(dialect === 'mariadb' ? 'mysql' : dialect);
};
Model.prototype.__getTimestamp = function(attr) { Model.prototype.__getTimestamp = function(attr) {
if (!!this.rawAttributes[attr] && !!this.rawAttributes[attr].defaultValue) { if (!!this.rawAttributes[attr] && !!this.rawAttributes[attr].defaultValue) {
return this.rawAttributes[attr].defaultValue; return this.rawAttributes[attr].defaultValue;
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
"moment": "~2.8.0", "moment": "~2.8.0",
"node-uuid": "~1.4.1", "node-uuid": "~1.4.1",
"pg-hstore": "^2.2.0", "pg-hstore": "^2.2.0",
"sql": "~0.42.0",
"toposort-class": "~0.3.0", "toposort-class": "~0.3.0",
"validator": "~3.22.1" "validator": "~3.22.1"
}, },
......
...@@ -230,7 +230,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -230,7 +230,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
expect(user.updatedAt).not.to.exist expect(user.updatedAt).not.to.exist
return user.destroy().then(function(user) { return user.destroy().then(function(user) {
expect(user.deletedAtThisTime).to.exist expect(user.deletedAtThisTime).to.exist
}); });
}); });
}); });
...@@ -2148,141 +2148,6 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -2148,141 +2148,6 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
}) })
describe("syntax sugar", function() {
before(function(done) {
this.User = this.sequelize.define("user", {
username: Sequelize.STRING,
firstName: Sequelize.STRING,
lastName: Sequelize.STRING
})
this.User.sync({ force: true }).success(function() {
done()
})
})
describe("dataset", function() {
it("returns a node-sql instance with the correct dialect", function() {
var _dialect = dialect === 'mariadb' ? 'mysql' : dialect
expect(this.User.dataset().sql.dialectName).to.equal(_dialect)
})
it("allows me to generate sql queries", function() {
var query = this.User.dataset().select("username").toQuery()
expect(Object.keys(query)).to.eql(['text', 'values'])
})
})
describe("select", function() {
it("sets .select() as an alias to .dataset().select()", function() {
var query1 = this.User.select("username").toQuery()
, query2 = this.User.dataset().select("username").toQuery()
expect(query1.text).to.equal(query2.text)
})
})
describe("toSql", function() {
it("transforms the node-sql instance into a proper sql string", function() {
var sql = this.User.select("username").toSql()
var sqlMap = {
postgres: 'SELECT username FROM "' + this.User.tableName + '";',
mariadb: 'SELECT username FROM `' + this.User.tableName + '`;',
mysql: 'SELECT username FROM `' + this.User.tableName + '`;',
sqlite: 'SELECT username FROM "' + this.User.tableName + '";'
}
expect(sql).to.equal(sqlMap[dialect])
})
it("transforms node-sql instances with chaining into a proper sql string", function() {
var sql = this.User.select("username").select("firstName").group("username").toSql()
var sqlMap = {
postgres: 'SELECT username, firstName FROM "' + this.User.tableName + '" GROUP BY username;',
mariadb: 'SELECT username, firstName FROM `' + this.User.tableName + '` GROUP BY username;',
mysql: 'SELECT username, firstName FROM `' + this.User.tableName + '` GROUP BY username;',
sqlite: 'SELECT username, firstName FROM "' + this.User.tableName + '" GROUP BY username;'
}
expect(sql).to.equal(sqlMap[dialect])
})
})
describe("exec", function() {
beforeEach(function(done) {
var self = this
this
.User
.sync({ force: true })
.then(function() { return self.User.create({ username: "foo" }) })
.then(function() { return self.User.create({ username: "bar" }) })
.then(function() { return self.User.create({ username: "baz" }) })
.then(function() { done() })
})
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.where({ username: "foo" }).exec().success(function(users1) {
User.where({ username: "foo" }).exec({ transaction: t }).success(function(users2) {
expect(users1).to.have.length(0)
expect(users2).to.have.length(1)
t.rollback().success(function() { done() })
})
})
})
})
})
})
})
}
it("selects all users with name 'foo'", function(done) {
this
.User
.where({ username: "foo" })
.exec()
.success(function(users) {
expect(users).to.have.length(1)
expect(users[0].username).to.equal("foo")
done()
})
})
it("returns an instanceof DAO", function(done) {
var DAO = require(__dirname + "/../lib/instance")
this.User.where({ username: "foo" }).exec().success(function(users) {
expect(users[0]).to.be.instanceOf(DAO)
done()
})
})
it("returns all users in the db", function(done) {
this.User.select().exec().success(function(users) {
expect(users).to.have.length(3)
done()
})
})
it("can handle or queries", function(done) {
this
.User
.where(this.User.dataset().username.equals("bar").or(this.User.dataset().username.equals("baz")))
.exec()
.success(function(users) {
expect(users).to.have.length(2)
done()
})
})
})
})
describe("blob", function() { describe("blob", function() {
beforeEach(function(done) { beforeEach(function(done) {
this.BlobUser = this.sequelize.define("blobUser", { this.BlobUser = this.sequelize.define("blobUser", {
......
...@@ -4,9 +4,12 @@ var chai = require('chai') ...@@ -4,9 +4,12 @@ var chai = require('chai')
, Migrator = require("../lib/migrator") , Migrator = require("../lib/migrator")
, DataTypes = require("../lib/data-types") , DataTypes = require("../lib/data-types")
, dialect = Support.getTestDialect() , dialect = Support.getTestDialect()
, current = Support.sequelize;
chai.config.includeStack = true chai.config.includeStack = true
if (current.dialect.supports.migrations) {
describe(Support.getTestDialectTeaser("Migrator"), function() { describe(Support.getTestDialectTeaser("Migrator"), function() {
beforeEach(function() { beforeEach(function() {
this.init = function(options, callback) { this.init = function(options, callback) {
...@@ -590,3 +593,5 @@ describe(Support.getTestDialectTeaser("Migrator"), function() { ...@@ -590,3 +593,5 @@ describe(Support.getTestDialectTeaser("Migrator"), function() {
} // if dialect postgres } // if dialect postgres
}) })
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!