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

Commit 2b4195cb by Matt Liszewski

make schema a property on the model independent of prototype

1 parent 46a3cd42
...@@ -202,6 +202,7 @@ var BelongsToMany = function(source, target, options) { ...@@ -202,6 +202,7 @@ var BelongsToMany = function(source, target, options) {
* @param {Object} [options] * @param {Object} [options]
* @param {Object} [options.where] An optional where clause to limit the associated models * @param {Object} [options.where] An optional where clause to limit the associated models
* @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false * @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false
* @param {String} [options.schema] Apply a schema on the related model
* @return {Promise<Array<Instance>>} * @return {Promise<Array<Instance>>}
* @method getAssociations * @method getAssociations
*/ */
...@@ -466,6 +467,10 @@ BelongsToMany.prototype.injectGetter = function(obj) { ...@@ -466,6 +467,10 @@ BelongsToMany.prototype.injectGetter = function(obj) {
} }
} }
if (options.hasOwnProperty('schema')) {
model = model.schema(options.schema, options.schemaDelimiter);
}
return model.findAll(options); return model.findAll(options);
}; };
......
...@@ -76,6 +76,7 @@ var BelongsTo = function(source, target, options) { ...@@ -76,6 +76,7 @@ var BelongsTo = function(source, target, options) {
* *
* @param {Object} [options] * @param {Object} [options]
* @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false. * @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false.
* @param {String} [options.schema] Apply a schema on the related model
* @return {Promise<Instance>} * @return {Promise<Instance>}
* @method getAssociation * @method getAssociation
*/ */
...@@ -159,6 +160,10 @@ BelongsTo.prototype.injectGetter = function(instancePrototype) { ...@@ -159,6 +160,10 @@ BelongsTo.prototype.injectGetter = function(instancePrototype) {
} }
} }
if (options.hasOwnProperty('schema')) {
model = model.schema(options.schema, options.schemaDelimiter);
}
return model.find(options); return model.find(options);
}; };
......
...@@ -97,6 +97,7 @@ var HasMany = function(source, target, options) { ...@@ -97,6 +97,7 @@ var HasMany = function(source, target, options) {
* @param {Object} [options] * @param {Object} [options]
* @param {Object} [options.where] An optional where clause to limit the associated models * @param {Object} [options.where] An optional where clause to limit the associated models
* @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false * @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false
* @param {String} [options.schema] Apply a schema on the related model
* @return {Promise<Array<Instance>>} * @return {Promise<Array<Instance>>}
* @method getAssociations * @method getAssociations
*/ */
...@@ -312,6 +313,11 @@ HasMany.prototype.get = function(instances, options) { ...@@ -312,6 +313,11 @@ HasMany.prototype.get = function(instances, options) {
} }
} }
if (options.hasOwnProperty('schema')) {
Model = Model.schema(options.schema, options.schemaDelimiter);
}
return Model.findAll(options).then(function (results) { return Model.findAll(options).then(function (results) {
if (instance) return results; if (instance) return results;
......
...@@ -70,6 +70,7 @@ var HasOne = function(srcModel, targetModel, options) { ...@@ -70,6 +70,7 @@ var HasOne = function(srcModel, targetModel, options) {
* *
* @param {Object} [options] * @param {Object} [options]
* @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false * @param {String|Boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false
* @param {String} [options.schema] Apply a schema on the related model
* @return {Promise<Instance>} * @return {Promise<Instance>}
* @method getAssociation * @method getAssociation
*/ */
...@@ -153,6 +154,10 @@ HasOne.prototype.injectGetter = function(instancePrototype) { ...@@ -153,6 +154,10 @@ HasOne.prototype.injectGetter = function(instancePrototype) {
} }
} }
if (options.hasOwnProperty('schema')) {
model = model.schema(options.schema, options.schemaDelimiter);
}
return model.find(options); return model.find(options);
}; };
......
...@@ -24,14 +24,12 @@ function addForeignKeyConstraints (newAttribute, source, target, options, key) { ...@@ -24,14 +24,12 @@ function addForeignKeyConstraints (newAttribute, source, target, options, key) {
.map(function($key) { return source.rawAttributes[$key].field || $key; }).value(); .map(function($key) { return source.rawAttributes[$key].field || $key; }).value();
if (primaryKeys.length === 1) { if (primaryKeys.length === 1) {
if (!!source.options.schema) { if (!!source.$schema) {
newAttribute.references = { newAttribute.references = {
model: source.modelManager.sequelize.queryInterface.QueryGenerator.addSchema({ model: source.modelManager.sequelize.queryInterface.QueryGenerator.addSchema({
tableName: source.tableName, tableName: source.tableName,
options: { $schema: source.$schema,
schema: source.options.schema, $schemaDelimiter: source.$schemaDelimiter
schemaDelimiter: source.options.schemaDelimiter
}
}) })
}; };
} else { } else {
......
...@@ -20,18 +20,16 @@ var QueryGenerator = { ...@@ -20,18 +20,16 @@ var QueryGenerator = {
options: {}, options: {},
addSchema: function(param) { addSchema: function(param) {
var self = this var self = this;
, schema = (!param.options && param.schema) || (param.options && param.options.schema ? param.options.schema : undefined)
, schemaDelimiter = (param.options && param.options.schemaDelimiter ? param.options.schemaDelimiter : undefined);
if (!schema) return param.tableName || param; if (!param.$schema) return param.tableName || param;
return { return {
tableName: param.tableName || param, tableName: param.tableName || param,
table: param.tableName || param, table: param.tableName || param,
name: param.name || param, name: param.name || param,
schema: schema, schema: param.$schema,
delimiter: schemaDelimiter || '.', delimiter: param.$schemaDelimiter || '.',
toString: function() { toString: function() {
return self.quoteTable(this); return self.quoteTable(this);
} }
...@@ -69,10 +67,8 @@ var QueryGenerator = { ...@@ -69,10 +67,8 @@ var QueryGenerator = {
var table = this.quoteTable( var table = this.quoteTable(
this.addSchema({ this.addSchema({
tableName: tableName, tableName: tableName,
options: { $schema: schema,
schema: schema, $schemaDelimiter: schemaDelimiter
schemaDelimiter: schemaDelimiter
}
}) })
); );
...@@ -1588,7 +1584,7 @@ var QueryGenerator = { ...@@ -1588,7 +1584,7 @@ var QueryGenerator = {
left.rawAttributes[left.primaryKeyAttribute].field left.rawAttributes[left.primaryKeyAttribute].field
/* Attributes for the right side */ /* Attributes for the right side */
, right = association.target , right = include.model
, asRight = include.as , asRight = include.as
, tableRight = right.getTableName() , tableRight = right.getTableName()
, fieldRight = association instanceof BelongsTo ? , fieldRight = association instanceof BelongsTo ?
......
...@@ -293,13 +293,13 @@ var QueryGenerator = { ...@@ -293,13 +293,13 @@ var QueryGenerator = {
}, },
describeTableQuery: function(tableName, schema, schemaDelimiter) { describeTableQuery: function(tableName, schema, schemaDelimiter) {
var options = {}; var table = {};
options.schema = schema; table.$schema = schema;
options.schemaDelimiter = schemaDelimiter; table.$schemaDelimiter = schemaDelimiter;
options.quoted = false; table.tableName = tableName;
var sql = 'PRAGMA TABLE_INFO(<%= tableName %>);'; var sql = 'PRAGMA TABLE_INFO(<%= tableName %>);';
return Utils._.template(sql)({ tableName: this.addSchema({tableName: this.quoteIdentifiers(tableName), options: options})}); return Utils._.template(sql)({tableName: this.quoteTable(this.addSchema(table))});
}, },
removeColumnQuery: function(tableName, attributes) { removeColumnQuery: function(tableName, attributes) {
......
...@@ -641,14 +641,14 @@ Instance.prototype.save = function(options) { ...@@ -641,14 +641,14 @@ Instance.prototype.save = function(options) {
if (self.isNewRecord) { if (self.isNewRecord) {
query = 'insert'; query = 'insert';
args = [self, self.Model.getTableName(options), values, options]; args = [self, self.$Model.getTableName(options), values, options];
} else { } else {
var where = this.where(); var where = this.where();
where = Utils.mapValueFieldNames(where, Object.keys(where), this.Model); where = Utils.mapValueFieldNames(where, Object.keys(where), this.Model);
query = 'update'; query = 'update';
args = [self, self.Model.getTableName(options), values, where, options]; args = [self, self.$Model.getTableName(options), values, where, options];
} }
return self.sequelize.getQueryInterface()[query].apply(self.sequelize.getQueryInterface(), args) return self.sequelize.getQueryInterface()[query].apply(self.sequelize.getQueryInterface(), args)
...@@ -832,9 +832,9 @@ Instance.prototype.destroy = function(options) { ...@@ -832,9 +832,9 @@ Instance.prototype.destroy = function(options) {
this.setDataValue(field, values[field]); this.setDataValue(field, values[field]);
return this.sequelize.getQueryInterface().update(this, this.Model.getTableName(options), values, where, _.defaults({ hooks: false }, options)); return this.sequelize.getQueryInterface().update(this, this.$Model.getTableName(options), values, where, _.defaults({ hooks: false }, options));
} else { } else {
return this.sequelize.getQueryInterface().delete(this, this.Model.getTableName(options), where, _.assign({ type: QueryTypes.DELETE, limit: null }, options)); return this.sequelize.getQueryInterface().delete(this, this.$Model.getTableName(options), where, _.assign({ type: QueryTypes.DELETE, limit: null }, options));
} }
}).tap(function() { }).tap(function() {
// Run after hook // Run after hook
...@@ -943,7 +943,7 @@ Instance.prototype.increment = function(fields, options) { ...@@ -943,7 +943,7 @@ Instance.prototype.increment = function(fields, options) {
} }
}, this); }, this);
return this.sequelize.getQueryInterface().increment(this, this.Model.getTableName(options), values, where, options).return(this); return this.sequelize.getQueryInterface().increment(this, this.$Model.getTableName(options), values, where, options).return(this);
}; };
/** /**
......
...@@ -60,6 +60,9 @@ var Model = function(name, attributes, options) { ...@@ -60,6 +60,9 @@ var Model = function(name, attributes, options) {
this.tableName = this.options.tableName; this.tableName = this.options.tableName;
} }
this.$schema = this.options.schema;
this.$schemaDelimiter = this.options.schemaDelimiter;
// error check options // error check options
Utils._.each(options.validate, function(validator, validatorType) { Utils._.each(options.validate, function(validator, validatorType) {
if (Utils._.contains(Utils._.keys(attributes), validatorType)) { if (Utils._.contains(Utils._.keys(attributes), validatorType)) {
...@@ -271,8 +274,6 @@ function conformInclude(include, self) { ...@@ -271,8 +274,6 @@ function conformInclude(include, self) {
include = { model: model, association: include, as: include.as }; include = { model: model, association: include, as: include.as };
} else if (include instanceof Model) { } else if (include instanceof Model) {
model = include;
include = { model: include }; include = { model: include };
} else if (_.isPlainObject(include)) { } else if (_.isPlainObject(include)) {
if (include.association) { if (include.association) {
...@@ -1033,19 +1034,28 @@ Model.prototype.dropSchema = function(schema) { ...@@ -1033,19 +1034,28 @@ Model.prototype.dropSchema = function(schema) {
* @return {this} * @return {this}
*/ */
Model.prototype.schema = function(schema, options) { // testhint options:none Model.prototype.schema = function(schema, options) { // testhint options:none
this.options.schema = schema; var self = this;
var clone = Object.create(self);
clone.$schema = schema;
if (!!options) { if (!!options) {
if (typeof options === 'string') { if (typeof options === 'string') {
this.options.schemaDelimiter = options; clone.$schemaDelimiter = options;
} else { } else {
if (!!options.schemaDelimiter) { if (!!options.schemaDelimiter) {
this.options.schemaDelimiter = options.schemaDelimiter; clone.$schemaDelimiter = options.schemaDelimiter;
} }
} }
} }
return this; clone.Instance = function() {
self.Instance.apply(this, arguments);
};
clone.Instance.prototype = Object.create(self.Instance.prototype);
clone.Instance.prototype.$Model = clone;
return clone;
}; };
/** /**
...@@ -1711,7 +1721,9 @@ Model.prototype.build = function(values, options) { // testhint options:none ...@@ -1711,7 +1721,9 @@ Model.prototype.build = function(values, options) { // testhint options:none
return this.bulkBuild(values, options); return this.bulkBuild(values, options);
} }
options = _.extend({ options = _.extend({
isNewRecord: true isNewRecord: true,
$schema: this.$schema,
$schemaDelimiter: this.$schemaDelimiter
}, options || {}); }, options || {});
if (options.attributes) { if (options.attributes) {
...@@ -2557,7 +2569,7 @@ Model.prototype.update = function(values, options) { ...@@ -2557,7 +2569,7 @@ Model.prototype.update = function(values, options) {
* @return {Promise} * @return {Promise}
*/ */
Model.prototype.describe = function(schema, options) { Model.prototype.describe = function(schema, options) {
return this.QueryInterface.describeTable(this.tableName, _.assign({schema: schema || this.options.schema || undefined}, options)); return this.QueryInterface.describeTable(this.tableName, _.assign({schema: schema || this.$schema || undefined}, options));
}; };
Model.prototype.$getDefaultTimestamp = function(attr) { Model.prototype.$getDefaultTimestamp = function(attr) {
......
...@@ -156,10 +156,11 @@ QueryInterface.prototype.createTable = function(tableName, attributes, options, ...@@ -156,10 +156,11 @@ QueryInterface.prototype.createTable = function(tableName, attributes, options,
} }
} }
if (!tableName.schema && options.schema) { if (!tableName.schema &&
(options.schema || (!!model && model.$schema))) {
tableName = self.QueryGenerator.addSchema({ tableName = self.QueryGenerator.addSchema({
tableName: tableName, tableName: tableName,
schema: options.schema $schema: (!!model && model.$schema) || options.schema
}); });
} }
...@@ -173,10 +174,11 @@ QueryInterface.prototype.createTable = function(tableName, attributes, options, ...@@ -173,10 +174,11 @@ QueryInterface.prototype.createTable = function(tableName, attributes, options,
}); });
}); });
} else { } else {
if (!tableName.schema && options.schema) { if (!tableName.schema &&
(options.schema || (!!model && model.$schema))) {
tableName = self.QueryGenerator.addSchema({ tableName = self.QueryGenerator.addSchema({
tableName: tableName, tableName: tableName,
schema: options.schema $schema: (!!model && model.$schema) || options.schema
}); });
} }
...@@ -693,7 +695,7 @@ QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelec ...@@ -693,7 +695,7 @@ QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelec
if (options.schema) { if (options.schema) {
tableName = this.QueryGenerator.addSchema({ tableName = this.QueryGenerator.addSchema({
tableName: tableName, tableName: tableName,
schema: options.schema $schema: options.schema
}); });
} }
......
...@@ -206,7 +206,12 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() { ...@@ -206,7 +206,12 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() {
return self.sequelize.dropAllSchemas().then(function() { return self.sequelize.dropAllSchemas().then(function() {
return self.sequelize.createSchema('acme'); return self.sequelize.createSchema('acme');
}).then(function() { }).then(function() {
return self.sequelize.sync({force: true}); return Promise.all([
AcmeUser.sync({force: true}),
AcmeProject.sync({force: true})
]);
}).then(function() {
return AcmeProjectUsers.sync({force: true});
}).bind({}).then(function() { }).bind({}).then(function() {
return AcmeUser.create(); return AcmeUser.create();
}).then(function(u) { }).then(function(u) {
......
...@@ -110,7 +110,9 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() { ...@@ -110,7 +110,9 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() {
return self.sequelize.dropAllSchemas().then(function() { return self.sequelize.dropAllSchemas().then(function() {
return self.sequelize.createSchema('archive'); return self.sequelize.createSchema('archive');
}).then(function() { }).then(function() {
return self.sequelize.sync({force: true }); return User.sync({force: true });
}).then(function() {
return Task.sync({force: true });
}).then(function() { }).then(function() {
return Promise.all([ return Promise.all([
User.create({ username: 'foo', gender: 'male' }), User.create({ username: 'foo', gender: 'male' }),
......
'use strict';
/* jshint -W030 */
/* jshint -W110 */
var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, DataTypes = require(__dirname + '/../../../lib/data-types')
, current = Support.sequelize
, Promise = current.Promise;
var SCHEMA_ONE = 'schema_one';
var SCHEMA_TWO = 'schema_two';
var locationId;
describe(Support.getTestDialectTeaser('Model'), function() {
if (current.dialect.supports.schemas) {
describe('schemas', function() {
before(function() {
this.Restaurant = current.define('restaurant', {
foo: DataTypes.STRING,
bar: DataTypes.STRING
},
{tableName: "restaurants"});
this.Location = current.define('location', {
name: DataTypes.STRING
},
{tableName: "locations"});
this.Employee = current.define('employee', {
first_name: DataTypes.STRING,
last_name: DataTypes.STRING
},
{tableName: "employees"});
this.EmployeeOne = this.Employee.schema(SCHEMA_ONE);
this.Restaurant.belongsTo(this.Location,
{
foreignKey: 'location_id',
constraints: false
});
this.Employee.belongsTo(this.Restaurant,
{
foreignKey: 'restaurant_id',
constraints: false
});
this.Restaurant.hasMany(this.Employee, {
foreignKey: 'restaurant_id',
constraints: false
});
this.RestaurantOne = this.Restaurant.schema(SCHEMA_ONE);
this.RestaurantTwo = this.Restaurant.schema(SCHEMA_TWO);
});
beforeEach('build restaurant tables', function() {
var self = this;
return Promise.all([
current.createSchema('schema_one'),
current.createSchema('schema_two')
]).then(function() {
return Promise.all([
self.RestaurantOne.sync({force: true}),
self.RestaurantTwo.sync({force: true})
]);
});
});
afterEach('drop schemas', function() {
return Promise.all([
current.dropSchema('schema_one'),
current.dropSchema('schema_two')
]);
});
describe('Add data via model.create, retrieve via model.findOne', function() {
it('should be able to insert data into the table in schema_one using create', function() {
var self = this;
var restaurantId;
return self.RestaurantOne.create({
foo: 'one',
location_id: locationId
}).then(function() {
return self.RestaurantOne.findOne({
where: {foo: 'one'}
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.foo).to.equal('one');
restaurantId = obj.id;
return self.RestaurantOne.findById(restaurantId);
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.foo).to.equal('one');
return self.RestaurantTwo.findOne({where: {foo: 'one'}}).then(function(RestaurantObj) {
expect(RestaurantObj).to.be.null;
});
});
});
it('should be able to insert data into the table in schema_two using create', function() {
var self = this;
var restaurantId;
return self.RestaurantTwo.create({
foo: 'two',
location_id: locationId
}).then(function() {
return self.RestaurantTwo.findOne({
where: {foo: 'two'}
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.foo).to.equal('two');
restaurantId = obj.id;
return self.RestaurantTwo.findById(restaurantId);
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.foo).to.equal('two');
return self.RestaurantOne.findOne({where: {foo: 'two'}}).then(function(RestaurantObj) {
expect(RestaurantObj).to.be.null;
});
});
});
});
describe('Persist and retrieve data', function() {
it('should be able to insert data into both schemas using instance.save and retrieve/count it', function() {
var self = this;
//building and saving in random order to make sure calling
// .schema doesn't impact model prototype
var restaurauntModel = self.RestaurantOne.build({bar: 'one.1'});
return restaurauntModel.save()
.then(function() {
restaurauntModel = self.RestaurantTwo.build({bar: 'two.1'});
return restaurauntModel.save();
}).then(function() {
restaurauntModel = self.RestaurantOne.build({bar: 'one.2'});
return restaurauntModel.save();
}).then(function() {
restaurauntModel = self.RestaurantTwo.build({bar: 'two.2'});
return restaurauntModel.save();
}).then(function() {
restaurauntModel = self.RestaurantTwo.build({bar: 'two.3'});
return restaurauntModel.save();
}).then(function() {
return self.RestaurantOne.findAll();
}).then(function(restaurantsOne) {
expect(restaurantsOne).to.not.be.null;
expect(restaurantsOne.length).to.equal(2);
restaurantsOne.forEach(function(restaurant) {
expect(restaurant.bar).to.contain('one');
});
return self.RestaurantOne.findAndCountAll();
}).then(function(restaurantsOne) {
expect(restaurantsOne).to.not.be.null;
expect(restaurantsOne.rows.length).to.equal(2);
expect(restaurantsOne.count).to.equal(2);
restaurantsOne.rows.forEach(function(restaurant) {
expect(restaurant.bar).to.contain('one');
});
return self.RestaurantOne.findAll({
where: {bar: {$like: '%.1'}}
});
}).then(function(restaurantsOne) {
expect(restaurantsOne).to.not.be.null;
expect(restaurantsOne.length).to.equal(1);
restaurantsOne.forEach(function(restaurant) {
expect(restaurant.bar).to.contain('one');
});
return self.RestaurantOne.count();
}).then(function(count) {
expect(count).to.not.be.null;
expect(count).to.equal(2);
return self.RestaurantTwo.findAll();
}).then(function(restaurantsTwo) {
expect(restaurantsTwo).to.not.be.null;
expect(restaurantsTwo.length).to.equal(3);
restaurantsTwo.forEach(function(restaurant) {
expect(restaurant.bar).to.contain('two');
});
return self.RestaurantTwo.findAndCountAll();
}).then(function(restaurantsTwo) {
expect(restaurantsTwo).to.not.be.null;
expect(restaurantsTwo.rows.length).to.equal(3);
expect(restaurantsTwo.count).to.equal(3);
restaurantsTwo.rows.forEach(function(restaurant) {
expect(restaurant.bar).to.contain('two');
});
return self.RestaurantTwo.findAll({
where: {bar: {$like: '%.3'}}
});
}).then(function(restaurantsTwo) {
expect(restaurantsTwo).to.not.be.null;
expect(restaurantsTwo.length).to.equal(1);
restaurantsTwo.forEach(function(restaurant) {
expect(restaurant.bar).to.contain('two');
});
return self.RestaurantTwo.count();
}).then(function(count) {
expect(count).to.not.be.null;
expect(count).to.equal(3);
});
});
});
describe('Get associated data in public schema via include', function() {
beforeEach(function() {
var Location = this.Location;
return Location.sync({force: true})
.then(function() {
return Location.create({name: 'HQ'}).then(function() {
return Location.findOne({where: {name: 'HQ'}}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.name).to.equal('HQ');
locationId = obj.id;
});
});
})
.catch(function(err) {
expect(err).to.be.null;
});
});
it('should be able to insert and retrieve associated data into the table in schema_one', function() {
var self = this;
return self.RestaurantOne.create({
foo: 'one',
location_id: locationId
}).then(function() {
return self.RestaurantOne.findOne({
where: {foo: 'one'}, include: [{
model: self.Location, as: 'location'
}]
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.foo).to.equal('one');
expect(obj.location).to.not.be.null;
expect(obj.location.name).to.equal('HQ');
});
});
});
describe('Get schema specific associated data via include', function() {
beforeEach(function() {
var Employee = this.Employee;
return Promise.all([
Employee.schema(SCHEMA_ONE).sync({force: true}),
Employee.schema(SCHEMA_TWO).sync({force: true})
]);
});
it('should be able to insert and retrieve associated data into the table in schema_one', function() {
var self = this;
var restaurantId;
return self.RestaurantOne.create({
foo: 'one'
}).then(function() {
return self.RestaurantOne.findOne({
where: {foo: 'one'}
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.foo).to.equal('one');
restaurantId = obj.id;
return self.EmployeeOne.create({
first_name: 'Restaurant',
last_name: 'one',
restaurant_id: restaurantId
});
}).then(function() {
return self.RestaurantOne.findOne({
where: {foo: 'one'}, include: [{
model: self.EmployeeOne, as: 'employees'
}]
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.employees).to.not.be.null;
expect(obj.employees.length).to.equal(1);
expect(obj.employees[0].last_name).to.equal('one');
return obj.getEmployees({schema:SCHEMA_ONE});
}).then(function(employees) {
expect(employees.length).to.equal(1);
expect(employees[0].last_name).to.equal('one');
return self.EmployeeOne.findOne({
where: {last_name: 'one'}, include: [{
model: self.RestaurantOne, as: 'restaurant'
}]
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.restaurant).to.not.be.null;
expect(obj.restaurant.foo).to.equal('one');
return obj.getRestaurant({schema:SCHEMA_ONE});
}).then(function(restaurant) {
expect(restaurant).to.not.be.null;
expect(restaurant.foo).to.equal('one');
});
});
it('should be able to insert and retrieve associated data into the table in schema_two', function() {
var self = this;
var restaurantId;
return self.RestaurantTwo.create({
foo: 'two'
}).then(function() {
return self.RestaurantTwo.findOne({
where: {foo: 'two'}
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.foo).to.equal('two');
restaurantId = obj.id;
return self.Employee.schema(SCHEMA_TWO).create({
first_name: 'Restaurant',
last_name: 'two',
restaurant_id: restaurantId
});
}).then(function() {
return self.RestaurantTwo.findOne({
where: {foo: 'two'}, include: [{
model: self.Employee.schema(SCHEMA_TWO), as: 'employees'
}]
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.employees).to.not.be.null;
expect(obj.employees.length).to.equal(1);
expect(obj.employees[0].last_name).to.equal('two');
return obj.getEmployees({schema:SCHEMA_TWO});
}).then(function(employees) {
expect(employees.length).to.equal(1);
expect(employees[0].last_name).to.equal('two');
return self.Employee.schema(SCHEMA_TWO).findOne({
where: {last_name: 'two'}, include: [{
model: self.RestaurantTwo, as: 'restaurant'
}]
});
}).then(function(obj) {
expect(obj).to.not.be.null;
expect(obj.restaurant).to.not.be.null;
expect(obj.restaurant.foo).to.equal('two');
return obj.getRestaurant({schema:SCHEMA_TWO});
}).then(function(restaurant) {
expect(restaurant).to.not.be.null;
expect(restaurant.foo).to.equal('two');
});
});
});
describe('concurency tests', function() {
it('should build and persist instances to 2 schemas concurrently in any order', function() {
var Restaurant = this.Restaurant;
var restaurauntModelSchema1 = Restaurant.schema(SCHEMA_ONE).build({bar: 'one.1'});
var restaurauntModelSchema2 = Restaurant.schema(SCHEMA_TWO).build({bar: 'two.1'});
return restaurauntModelSchema1.save()
.then(function() {
restaurauntModelSchema1 = Restaurant.schema(SCHEMA_ONE).build({bar: 'one.2'});
return restaurauntModelSchema2.save();
}).then(function() {
return restaurauntModelSchema1.save();
}).then(function() {
return Restaurant.schema(SCHEMA_ONE).findAll();
}).then(function(restaurantsOne) {
expect(restaurantsOne).to.not.be.null;
expect(restaurantsOne.length).to.equal(2);
restaurantsOne.forEach(function(restaurant) {
expect(restaurant.bar).to.contain('one');
});
return Restaurant.schema(SCHEMA_TWO).findAll();
}).then(function(restaurantsTwo) {
expect(restaurantsTwo).to.not.be.null;
expect(restaurantsTwo.length).to.equal(1);
restaurantsTwo.forEach(function(restaurant) {
expect(restaurant.bar).to.contain('two');
});
});
});
});
});
}
});
'use strict';
/* jshint -W030 */
var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, current = Support.sequelize;
describe(Support.getTestDialectTeaser('Model') + 'Schemas', function() {
if (current.dialect.supports.schemas) {
var Project = current.define('project'),
Company = current.define('company', {}, {
schema: 'default',
schemaDelimiter: '&'
});
describe('schema', function() {
it('should work with no default schema', function() {
expect(Project.$schema).to.be.null;
});
it('should apply default schema from define', function() {
expect(Company.$schema).to.equal('default');
});
it('should be able to override the default schema', function() {
expect(Company.schema('newSchema').$schema).to.equal('newSchema');
});
it('should be able nullify schema', function() {
expect(Company.schema(null).$schema).to.be.null;
});
it('should support multiple, coexistent schema models', function() {
var schema1 = Company.schema('schema1')
, schema2 = Company.schema('schema1');
expect(schema1.$schema).to.equal('schema1');
expect(schema2.$schema).to.equal('schema1');
});
});
describe('schema delimiter', function() {
it('should work with no default schema delimiter', function() {
expect(Project.$schemaDelimiter).to.equal('');
});
it('should apply default schema delimiter from define', function() {
expect(Company.$schemaDelimiter).to.equal('&');
});
it('should be able to override the default schema delimiter', function() {
expect(Company.schema(Company.$schema,'^').$schemaDelimiter).to.equal('^');
});
it('should support multiple, coexistent schema delimiter models', function() {
var schema1 = Company.schema(Company.$schema,'$')
, schema2 = Company.schema(Company.$schema,'#');
expect(schema1.$schemaDelimiter).to.equal('$');
expect(schema2.$schemaDelimiter).to.equal('#');
});
});
}
});
...@@ -29,7 +29,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -29,7 +29,7 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
}); });
expectsql(sql.addIndexQuery(sql.quoteTable(sql.addSchema({ expectsql(sql.addIndexQuery(sql.quoteTable(sql.addSchema({
schema: 'schema', $schema: 'schema',
tableName: 'table' tableName: 'table'
})), ['column1', 'column2'], {}), { })), ['column1', 'column2'], {}), {
default: 'CREATE INDEX [schema_table_column1_column2] ON [schema].[table] ([column1], [column2])' default: 'CREATE INDEX [schema_table_column1_column2] ON [schema].[table] ([column1], [column2])'
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!