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

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) {
* @param {Object} [options]
* @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} [options.schema] Apply a schema on the related model
* @return {Promise<Array<Instance>>}
* @method getAssociations
*/
......@@ -466,6 +467,10 @@ BelongsToMany.prototype.injectGetter = function(obj) {
}
}
if (options.hasOwnProperty('schema')) {
model = model.schema(options.schema, options.schemaDelimiter);
}
return model.findAll(options);
};
......
......@@ -76,6 +76,7 @@ var BelongsTo = function(source, target, 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} [options.schema] Apply a schema on the related model
* @return {Promise<Instance>}
* @method getAssociation
*/
......@@ -159,6 +160,10 @@ BelongsTo.prototype.injectGetter = function(instancePrototype) {
}
}
if (options.hasOwnProperty('schema')) {
model = model.schema(options.schema, options.schemaDelimiter);
}
return model.find(options);
};
......
......@@ -97,6 +97,7 @@ var HasMany = function(source, target, options) {
* @param {Object} [options]
* @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} [options.schema] Apply a schema on the related model
* @return {Promise<Array<Instance>>}
* @method getAssociations
*/
......@@ -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) {
if (instance) return results;
......
......@@ -70,6 +70,7 @@ var HasOne = function(srcModel, targetModel, 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} [options.schema] Apply a schema on the related model
* @return {Promise<Instance>}
* @method getAssociation
*/
......@@ -153,6 +154,10 @@ HasOne.prototype.injectGetter = function(instancePrototype) {
}
}
if (options.hasOwnProperty('schema')) {
model = model.schema(options.schema, options.schemaDelimiter);
}
return model.find(options);
};
......
......@@ -24,14 +24,12 @@ function addForeignKeyConstraints (newAttribute, source, target, options, key) {
.map(function($key) { return source.rawAttributes[$key].field || $key; }).value();
if (primaryKeys.length === 1) {
if (!!source.options.schema) {
if (!!source.$schema) {
newAttribute.references = {
model: source.modelManager.sequelize.queryInterface.QueryGenerator.addSchema({
tableName: source.tableName,
options: {
schema: source.options.schema,
schemaDelimiter: source.options.schemaDelimiter
}
$schema: source.$schema,
$schemaDelimiter: source.$schemaDelimiter
})
};
} else {
......
......@@ -20,18 +20,16 @@ var QueryGenerator = {
options: {},
addSchema: function(param) {
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);
var self = this;
if (!schema) return param.tableName || param;
if (!param.$schema) return param.tableName || param;
return {
tableName: param.tableName || param,
table: param.tableName || param,
name: param.name || param,
schema: schema,
delimiter: schemaDelimiter || '.',
schema: param.$schema,
delimiter: param.$schemaDelimiter || '.',
toString: function() {
return self.quoteTable(this);
}
......@@ -69,10 +67,8 @@ var QueryGenerator = {
var table = this.quoteTable(
this.addSchema({
tableName: tableName,
options: {
schema: schema,
schemaDelimiter: schemaDelimiter
}
$schema: schema,
$schemaDelimiter: schemaDelimiter
})
);
......@@ -1588,7 +1584,7 @@ var QueryGenerator = {
left.rawAttributes[left.primaryKeyAttribute].field
/* Attributes for the right side */
, right = association.target
, right = include.model
, asRight = include.as
, tableRight = right.getTableName()
, fieldRight = association instanceof BelongsTo ?
......
......@@ -293,13 +293,13 @@ var QueryGenerator = {
},
describeTableQuery: function(tableName, schema, schemaDelimiter) {
var options = {};
options.schema = schema;
options.schemaDelimiter = schemaDelimiter;
options.quoted = false;
var table = {};
table.$schema = schema;
table.$schemaDelimiter = schemaDelimiter;
table.tableName = 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) {
......
......@@ -641,14 +641,14 @@ Instance.prototype.save = function(options) {
if (self.isNewRecord) {
query = 'insert';
args = [self, self.Model.getTableName(options), values, options];
args = [self, self.$Model.getTableName(options), values, options];
} else {
var where = this.where();
where = Utils.mapValueFieldNames(where, Object.keys(where), this.Model);
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)
......@@ -832,9 +832,9 @@ Instance.prototype.destroy = function(options) {
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 {
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() {
// Run after hook
......@@ -943,7 +943,7 @@ Instance.prototype.increment = function(fields, options) {
}
}, 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) {
this.tableName = this.options.tableName;
}
this.$schema = this.options.schema;
this.$schemaDelimiter = this.options.schemaDelimiter;
// error check options
Utils._.each(options.validate, function(validator, validatorType) {
if (Utils._.contains(Utils._.keys(attributes), validatorType)) {
......@@ -271,8 +274,6 @@ function conformInclude(include, self) {
include = { model: model, association: include, as: include.as };
} else if (include instanceof Model) {
model = include;
include = { model: include };
} else if (_.isPlainObject(include)) {
if (include.association) {
......@@ -1033,19 +1034,28 @@ Model.prototype.dropSchema = function(schema) {
* @return {this}
*/
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 (typeof options === 'string') {
this.options.schemaDelimiter = options;
clone.$schemaDelimiter = options;
} else {
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
return this.bulkBuild(values, options);
}
options = _.extend({
isNewRecord: true
isNewRecord: true,
$schema: this.$schema,
$schemaDelimiter: this.$schemaDelimiter
}, options || {});
if (options.attributes) {
......@@ -2557,7 +2569,7 @@ Model.prototype.update = function(values, options) {
* @return {Promise}
*/
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) {
......
......@@ -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: tableName,
schema: options.schema
$schema: (!!model && model.$schema) || options.schema
});
}
......@@ -173,10 +174,11 @@ QueryInterface.prototype.createTable = function(tableName, attributes, options,
});
});
} else {
if (!tableName.schema && options.schema) {
if (!tableName.schema &&
(options.schema || (!!model && model.$schema))) {
tableName = self.QueryGenerator.addSchema({
tableName: tableName,
schema: options.schema
$schema: (!!model && model.$schema) || options.schema
});
}
......@@ -693,7 +695,7 @@ QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelec
if (options.schema) {
tableName = this.QueryGenerator.addSchema({
tableName: tableName,
schema: options.schema
$schema: options.schema
});
}
......
......@@ -206,7 +206,12 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() {
return self.sequelize.dropAllSchemas().then(function() {
return self.sequelize.createSchema('acme');
}).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() {
return AcmeUser.create();
}).then(function(u) {
......
......@@ -110,7 +110,9 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() {
return self.sequelize.dropAllSchemas().then(function() {
return self.sequelize.createSchema('archive');
}).then(function() {
return self.sequelize.sync({force: true });
return User.sync({force: true });
}).then(function() {
return Task.sync({force: true });
}).then(function() {
return Promise.all([
User.create({ username: 'foo', gender: 'male' }),
......
'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() {
});
expectsql(sql.addIndexQuery(sql.quoteTable(sql.addSchema({
schema: 'schema',
$schema: 'schema',
tableName: '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!