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

Commit 62ee8a64 by Matt Broadstone

remove node-sql and query generation syntactic sugar

This is an incomplete feature that seems to be unused by the user
base. Furthermore, it does not support incoming dialects (notably
MSSQL), and thus has been slated for removal for the 2.0 release
1 parent 9ab475de
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
- [BUG] Made the default for array search in postgres exact comparison instead of overlap - [BUG] Made the default for array search in postgres exact comparison instead of overlap
- [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)
- [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.
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,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
......
...@@ -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')
...@@ -124,40 +123,6 @@ module.exports = (function() { ...@@ -124,40 +123,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]';
}; };
...@@ -1687,33 +1652,6 @@ module.exports = (function() { ...@@ -1687,33 +1652,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", {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!