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

Commit d983e96b by Daniel Durante

Merge pull request #805 from sequelize/features/first_steps_for_syntax_sugar

First iteration of syntax sugar for DAOs
2 parents 44ac75c4 deb909d5
...@@ -2,6 +2,8 @@ var Utils = require("./utils") ...@@ -2,6 +2,8 @@ var Utils = require("./utils")
, DAO = require("./dao") , DAO = require("./dao")
, DataTypes = require("./data-types") , DataTypes = require("./data-types")
, Util = require('util') , Util = require('util')
, sql = require('sql')
, SqlString = require('./sql-string')
module.exports = (function() { module.exports = (function() {
var DAOFactory = function(name, attributes, options) { var DAOFactory = function(name, attributes, options) {
...@@ -60,6 +62,32 @@ module.exports = (function() { ...@@ -60,6 +62,32 @@ module.exports = (function() {
get: function() { return this.QueryInterface.QueryGenerator } get: function() { return this.QueryInterface.QueryGenerator }
}) })
;(function() {
var instance = sql.define({ name: "dummy", columns: [] })
for (var methodName in instance) {
;(function(methodName) {
DAOFactory.prototype[methodName] = function() {
var dataset = this.dataset()
, result = dataset[methodName].apply(dataset, arguments)
, dialect = this.daoFactoryManager.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() {
return self.QueryInterface.queryAndEmit([result.toSql(), self, { type: 'SELECT' }], 'snafu')
}
return result
}
})(methodName)
}
})()
DAOFactory.prototype.init = function(daoFactoryManager) { DAOFactory.prototype.init = function(daoFactoryManager) {
var self = this; var self = this;
...@@ -543,24 +571,22 @@ module.exports = (function() { ...@@ -543,24 +571,22 @@ module.exports = (function() {
return this.QueryInterface.describeTable(this.tableName) return this.QueryInterface.describeTable(this.tableName)
} }
// private DAOFactory.prototype.dataset = function() {
if (!this.__sql) {
this.__sql = sql.setDialect(this.daoFactoryManager.sequelize.options.dialect)
}
var query = function() { var instance = this.__sql.define({ name: this.tableName, columns: [] })
var args = Utils._.map(arguments, function(arg, _) { return arg }) , attributes = this.attributes
, sequelize = this.daoFactoryManager.sequelize
// add this as the second argument Object.keys(attributes).forEach(function(key) {
if (arguments.length === 1) { instance.addColumn(key, attributes[key])
args.push(this) })
}
// add {} as options return instance
if (args.length === 2) {
args.push({})
} }
return sequelize.query.apply(sequelize, args) // private
}
var addOptionalClassMethods = function() { var addOptionalClassMethods = function() {
var self = this var self = this
......
...@@ -45,7 +45,8 @@ ...@@ -45,7 +45,8 @@
"dottie": "0.0.8-0", "dottie": "0.0.8-0",
"toposort-class": "~0.2.0", "toposort-class": "~0.2.0",
"generic-pool": "2.0.4", "generic-pool": "2.0.4",
"promise": "~3.2.0" "promise": "~3.2.0",
"sql": "~0.26.0"
}, },
"devDependencies": { "devDependencies": {
"sqlite3": "~2.1.12", "sqlite3": "~2.1.12",
......
...@@ -2544,15 +2544,15 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -2544,15 +2544,15 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
describe('references', function() { describe('references', function() {
this.timeout(3000) this.timeout(3000)
beforeEach(function(done) { beforeEach(function(done) {
var self = this this.Author = this.sequelize.define('author', { firstName: Sequelize.STRING })
self.Author = self.sequelize.define('author', { firstName: Sequelize.STRING }) this.Author.sync({ force: true }).success(function() {
self.Author.sync({ force: true }).success(function() {
done() done()
}) })
}) })
afterEach(function(done) { afterEach(function(done) {
var self = this var self = this
self.sequelize.getQueryInterface().dropTable('posts', { force: true }).success(function() { self.sequelize.getQueryInterface().dropTable('posts', { force: true }).success(function() {
self.sequelize.getQueryInterface().dropTable('authors', { force: true }).success(function() { self.sequelize.getQueryInterface().dropTable('authors', { force: true }).success(function() {
done() done()
...@@ -2664,4 +2664,116 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -2664,4 +2664,116 @@ 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() {
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 + '";',
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;',
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
.create({ username: "foo" })
.then(function() {
return self.User.create({ username: "bar" })
})
.then(function() {
return self.User.create({ username: "baz" })
})
.then(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/dao")
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()
})
})
})
})
}) })
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!