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

Commit eb7d40c8 by Sascha Gehlich

Merge branch 'master' into feature/pass-instance-to-hooks

2 parents 71b4a3e4 3194400a
Notice: All 1.7.x changed are present in 2.0.x aswell
# v1.7.0-rc1
- instance.createAssociationInstance functionality added [#1213](https://github.com/sequelize/sequelize/pull/1213)
- fixes a few bugs with transactions in regards to associations
# v1.7.0-beta8
- max()/min() now supports dates [#1200](https://github.com/sequelize/sequelize/pull/1200)
- findAndCountAll now supports the include option
......
var Utils = require("./../utils")
, DataTypes = require('./../data-types')
, Helpers = require('./helpers')
, Transaction = require('../transaction')
module.exports = (function() {
var BelongsTo = function(source, target, options) {
......@@ -28,7 +29,8 @@ module.exports = (function() {
this.accessors = {
get: Utils._.camelize('get_' + this.as),
set: Utils._.camelize('set_' + this.as)
set: Utils._.camelize('set_' + this.as),
create: Utils._.camelize('create_' + this.as)
}
}
......@@ -98,5 +100,30 @@ module.exports = (function() {
return this
}
BelongsTo.prototype.injectCreator = function(obj) {
var self = this
obj[this.accessors.create] = function(values, fieldsOrOptions) {
var instance = this
, options = {}
if ((fieldsOrOptions || {}).transaction instanceof Transaction) {
options.transaction = fieldsOrOptions.transaction
}
return new Utils.CustomEventEmitter(function(emitter) {
self.target
.create(values, fieldsOrOptions)
.proxy(emitter, { events: ['error', 'sql'] })
.success(function(newAssociatedObject) {
instance[self.accessors.set](newAssociatedObject, options)
.proxy(emitter)
})
}).run()
}
return this
}
return BelongsTo
})()
......@@ -2,9 +2,10 @@ var Utils = require("./../utils")
, DataTypes = require('./../data-types')
, Helpers = require('./helpers')
, _ = require('lodash')
, Transaction = require('../transaction')
var HasManySingleLinked = require("./has-many-single-linked")
, HasManyMultiLinked = require("./has-many-double-linked")
, HasManyDoubleLinked = require("./has-many-double-linked")
module.exports = (function() {
var HasMany = function(source, target, options) {
......@@ -115,6 +116,7 @@ module.exports = (function() {
get: Utils._.camelize('get_' + as),
set: Utils._.camelize('set_' + as),
add: Utils._.camelize(Utils.singularize('add_' + as, this.target.options.language)),
create: Utils._.camelize(Utils.singularize('create_' + as, this.target.options.language)),
remove: Utils._.camelize(Utils.singularize('remove_' + as, this.target.options.language)),
hasSingle: Utils._.camelize(Utils.singularize('has_' + as, this.target.options.language)),
hasAll: Utils._.camelize('has_' + as)
......@@ -188,7 +190,7 @@ module.exports = (function() {
var self = this
obj[this.accessors.get] = function(options) {
var Class = Object(self.through) === self.through ? HasManyMultiLinked : HasManySingleLinked
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked
return new Class(self, this).injectGetter(options)
}
......@@ -246,7 +248,7 @@ module.exports = (function() {
return new Utils.CustomEventEmitter(function(emitter) {
instance[self.accessors.get]()
.success(function(oldAssociatedObjects) {
var Class = Object(self.through) === self.through ? HasManyMultiLinked : HasManySingleLinked
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked
new Class(self, instance).injectSetter(emitter, oldAssociatedObjects, newAssociatedObjects, defaultAttributes)
})
.proxy(emitter, {events: ['error', 'sql']})
......@@ -266,7 +268,7 @@ module.exports = (function() {
.proxy(emitter, {events: ['error', 'sql']})
.success(function(currentAssociatedObjects) {
if (currentAssociatedObjects.length === 0 || Object(self.through) === self.through) {
var Class = Object(self.through) === self.through ? HasManyMultiLinked : HasManySingleLinked
var Class = Object(self.through) === self.through ? HasManyDoubleLinked : HasManySingleLinked
new Class(self, instance).injectAdder(emitter, newAssociatedObject, additionalAttributes, !!currentAssociatedObjects.length)
} else {
emitter.emit('success', newAssociatedObject);
......@@ -323,6 +325,33 @@ module.exports = (function() {
return this
}
HasMany.prototype.injectCreator = function(obj) {
var self = this
obj[this.accessors.create] = function(values, fieldsOrOptions) {
var instance = this
, options = {}
if ((fieldsOrOptions || {}).transaction instanceof Transaction) {
options.transaction = fieldsOrOptions.transaction
delete fieldsOrOptions.transaction
}
return new Utils.CustomEventEmitter(function(emitter) {
// Create the related model instance
self.target
.create(values, fieldsOrOptions)
.proxy(emitter, { events: ['error', 'sql'] })
.success(function(newAssociatedObject) {
instance[self.accessors.add](newAssociatedObject, options)
.proxy(emitter)
})
}).run()
}
return this
};
/**
* The method checks if it is ok to delete the previously defined foreign key.
* This is done because we need to keep the foreign key if another association
......
var Utils = require("./../utils")
, DataTypes = require('./../data-types')
, Helpers = require("./helpers")
, Transaction = require("../transaction")
module.exports = (function() {
var HasOne = function(srcDAO, targetDAO, options) {
......@@ -27,7 +28,8 @@ module.exports = (function() {
this.accessors = {
get: Utils._.camelize('get_' + this.options.as),
set: Utils._.camelize('set_' + this.options.as)
set: Utils._.camelize('set_' + this.options.as),
create: Utils._.camelize('create_' + this.options.as)
}
}
......@@ -73,7 +75,12 @@ module.exports = (function() {
params.where = smart
}
return self.target.find(params)
var options = {}
if (params.transaction) {
options.transaction = params.transaction;
delete params.transaction;
}
return self.target.find(params, options)
}
return this
......@@ -128,5 +135,31 @@ module.exports = (function() {
return this
}
HasOne.prototype.injectCreator = function(obj) {
var self = this
obj[this.accessors.create] = function(values, fieldsOrOptions) {
var instance = this
, options = {}
if ((fieldsOrOptions || {}).transaction instanceof Transaction) {
options.transaction = fieldsOrOptions.transaction
}
return new Utils.CustomEventEmitter(function(emitter) {
self.target
.create(values, fieldsOrOptions)
.proxy(emitter, { events: ['error', 'sql'] })
.success(function(newAssociatedObject) {
console.log(self.accessors.set, !!newAssociatedObject, !!options.transaction);
instance[self.accessors.set](newAssociatedObject, options)
.proxy(emitter)
})
}).run()
}
return this
};
return HasOne
})()
......@@ -18,6 +18,7 @@ Mixin.hasOne = function(associatedDAOFactory, options) {
association.injectGetter(this.DAO.prototype);
association.injectSetter(this.DAO.prototype);
association.injectCreator(this.DAO.prototype);
return this
}
......@@ -34,6 +35,7 @@ Mixin.belongsTo = function(associatedDAOFactory, options) {
association.injectGetter(this.DAO.prototype)
association.injectSetter(this.DAO.prototype)
association.injectCreator(this.DAO.prototype)
return this
}
......@@ -50,6 +52,7 @@ Mixin.hasMany = function(associatedDAOFactory, options) {
association.injectGetter(this.DAO.prototype)
association.injectSetter(this.DAO.prototype)
association.injectCreator(this.DAO.prototype)
return this
}
......
......@@ -165,6 +165,55 @@ describe(Support.getTestDialectTeaser("BelongsTo"), function() {
})
})
describe('createAssociation', function() {
it('creates an associated model instance', function(done) {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING })
Task.belongsTo(User)
this.sequelize.sync({ force: true }).success(function() {
Task.create({ title: 'task' }).success(function(task) {
task.createUser({ username: 'bob' }).success(function() {
task.getUser().success(function(user) {
expect(user).not.to.be.null
expect(user.username).to.equal('bob')
done()
})
})
})
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING })
, Group = sequelize.define('Group', { name: Support.Sequelize.STRING })
Group.belongsTo(User)
sequelize.sync({ force: true }).success(function() {
Group.create({ name: 'bar' }).success(function(group) {
sequelize.transaction(function(t) {
group.createUser({ username: 'foo' }, { transaction: t }).success(function() {
group.getUser().success(function(user) {
expect(user).to.be.null
group.getUser({ transaction: t }).success(function(user) {
expect(user).not.to.be.null
t.rollback().success(function() { done() })
})
})
})
})
})
})
})
})
})
describe("Foreign key constraints", function() {
it("are not enabled by default", function(done) {
var Task = this.sequelize.define('Task', { title: DataTypes.STRING })
......
......@@ -329,6 +329,59 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
})
})
describe('createAssociations', function() {
it('creates a new associated object', function(done) {
var Article = this.sequelize.define('Article', { 'title': DataTypes.STRING })
, Label = this.sequelize.define('Label', { 'text': DataTypes.STRING })
Article.hasMany(Label)
Article.sync({ force: true }).success(function() {
Label.sync({ force: true }).success(function() {
Article.create({ title: 'foo' }).success(function(article) {
article.createLabel({ text: 'bar' }).success(function(label) {
Label
.findAll({ where: { ArticleId: article.id }})
.success(function(labels) {
expect(labels.length).to.equal(1)
done()
})
})
})
})
})
})
it('supports transactions', function(done) {
var self = this
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var Article = sequelize.define('Article', { 'title': DataTypes.STRING })
, Label = sequelize.define('Label', { 'text': DataTypes.STRING })
Article.hasMany(Label)
Article.sync({ force: true }).success(function() {
Label.sync({ force: true }).success(function() {
Article.create({ title: 'foo' }).success(function(article) {
sequelize.transaction(function (t) {
article.createLabel({ text: 'bar' }, { transaction: t }).success(function(label) {
Label.findAll({ where: { ArticleId: article.id }}).success(function(labels) {
expect(labels.length).to.equal(0)
Label.findAll({ where: { ArticleId: article.id }}, { transaction: t }).success(function(labels) {
expect(labels.length).to.equal(1)
t.rollback().success(function() { done() })
})
})
})
})
})
})
})
})
})
})
describe("getting assocations with options", function() {
beforeEach(function(done) {
var self = this
......@@ -654,6 +707,60 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
})
})
describe('createAssociations', function() {
it('creates a new associated object', function(done) {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING })
User.hasMany(Task)
Task.hasMany(User)
User.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
Task.create({ title: 'task' }).success(function(task) {
task.createUser({ username: 'foo' }).success(function() {
task.getUsers().success(function(_users) {
expect(_users).to.have.length(1)
done()
})
})
})
})
})
})
it('supports transactions', function(done) {
var self = this
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: DataTypes.STRING })
, Task = sequelize.define('Task', { title: DataTypes.STRING })
User.hasMany(Task)
Task.hasMany(User)
User.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
Task.create({ title: 'task' }).success(function(task) {
sequelize.transaction(function (t) {
task.createUser({ username: 'foo' }, { transaction: t }).success(function() {
task.getUsers().success(function(users) {
expect(users).to.have.length(0)
task.getUsers({ transaction: t }).success(function(users) {
expect(users).to.have.length(1)
t.rollback().success(function() { done() })
})
})
})
})
})
})
})
})
})
})
describe('addAssociations', function() {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
......
......@@ -160,6 +160,57 @@ describe(Support.getTestDialectTeaser("HasOne"), function() {
})
})
describe('createAssociation', function() {
it('creates an associated model instance', function(done) {
var User = this.sequelize.define('User', { username: Sequelize.STRING })
, Task = this.sequelize.define('Task', { title: Sequelize.STRING })
User.hasOne(Task)
this.sequelize.sync({ force: true }).success(function() {
User.create({ username: 'bob' }).success(function(user) {
user.createTask({ title: 'task' }).success(function() {
user.getTask().success(function(task) {
expect(task).not.to.be.null
expect(task.title).to.equal('task')
done()
})
})
})
})
})
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING })
, Group = sequelize.define('Group', { name: Sequelize.STRING })
User.hasOne(Group)
sequelize.sync({ force: true }).success(function() {
User.create({ username: 'bob' }).success(function(user) {
sequelize.transaction(function(t) {
user.createGroup({ name: 'testgroup' }, { transaction: t }).success(function(group) {
User.all().success(function (users) {
users[0].getGroup().success(function (group) {
expect(group).to.be.null;
User.all({ transaction: t }).success(function (users) {
users[0].getGroup({ transaction: t }).success(function (group) {
expect(group).to.be.not.null;
t.rollback().success(function() { done() })
})
})
})
})
})
})
})
})
})
})
})
describe("Foreign key constraints", function() {
it("are not enabled by default", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING })
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!