diff --git a/README.md b/README.md index 1da4c3da..e42ea191 100644 --- a/README.md +++ b/README.md @@ -765,6 +765,19 @@ if (!someTeam.players) { } ``` +### Database names and schemas (SQL adapters only) + +To determine to which database and/or schema a model is referring, the model +can define `database` (MySQL, Postgres) and `schema` (Postgres) properties: + +```javascript +var User = function () { + this.db = 'mydatabase'; + this.schema = 'myschema'; + +... +``` + - - - Model JavaScript ORM copyright 2112 mde@fleegix.org. diff --git a/lib/adapters/sql/base.js b/lib/adapters/sql/base.js index 242e6389..ace9dbc6 100644 --- a/lib/adapters/sql/base.js +++ b/lib/adapters/sql/base.js @@ -23,10 +23,18 @@ utils.mixin(Adapter.prototype, new (function () { // Package up the SQL-specific query data used in generating the // statements and processing the results this._getSqlMetadata = function (query) { - var tableName = this._tableizeModelName(query.model.modelName) + var tableName = this._tableizeModelNameFull(query.model.modelName) , includes = this._getIncludes(query) , selects = this._getSelectCols(query, tableName, includes) , meta; + + /*if(query.model.hasOwnProperty('schema')) { + tableName = query.model.schema+'.'+tableName; + } + if(query.model.hasOwnProperty('db')) { + tableName = query.model.db+'.'+tableName; + }*/ + meta = { mainTableName: tableName , selects: selects @@ -35,6 +43,20 @@ utils.mixin(Adapter.prototype, new (function () { return meta; }; + this._tableizeModelNameFull = function (modelName) { + var tableName = this._tableizeModelName(modelName); + + if (model.hasOwnProperty(modelName)) { + if(model[modelName].hasOwnProperty('schema')) { + tableName = model[modelName].schema+'.'+tableName; + } + if(model[modelName].hasOwnProperty('db')) { + tableName = model[modelName].db+'.'+tableName; + } + } + return tableName; + }; + this._getIncludes = function (query) { var self = this , includes = query.opts.includes; @@ -134,7 +156,7 @@ utils.mixin(Adapter.prototype, new (function () { updates.push(update); } } - sql += 'UPDATE ' + this._tableizeModelName(modelName) + ' SET '; + sql += 'UPDATE ' + this._tableizeModelNameFull(modelName) + ' SET '; sql += updates.join(', ') + ' '; sql += 'WHERE ' + this.transformConditions(query.conditions); sql += ';' @@ -144,15 +166,24 @@ utils.mixin(Adapter.prototype, new (function () { this._createDeleteStatementWithConditions = function (query) { var sql = ''; - sql += 'DELETE FROM ' + this._tableizeModelName(query.model.modelName) + ' '; + sql += 'DELETE FROM ' + this._tableizeModelNameFull(query.model.modelName) + ' '; sql += 'WHERE ' + this.transformConditions(query.conditions); sql += ';' return sql; }; + /** + * Removes db and schema from table name, eg. mydatabse.myschema.tablename => tablename + **/ + this.clearSchema = function (fullModelName) + { + var parts = fullModelName.split('.'); + return parts[parts.length - 1]; + }; + this._createSelectStatement = function (modelName, ownerModelName) { var name - , assumedName = utils.string.getInflection(modelName, 'constructor', 'singular') + , assumedName = utils.string.getInflection(this.clearSchema(modelName), 'constructor', 'singular') , ownerName , tableName , assumedTableName @@ -167,7 +198,7 @@ utils.mixin(Adapter.prototype, new (function () { // Otherwise it's a named association, need to look up the // actual model via it's owner's associations list else { - ownerName = utils.string.getInflection(ownerModelName, 'constructor', 'singular'); + ownerName = utils.string.getInflection(this.clearSchema(ownerModelName), 'constructor', 'singular'); name = model.getAssociation(ownerName, assumedName).model; } @@ -338,7 +369,7 @@ utils.mixin(Adapter.prototype, new (function () { vals.push(prop); } } - sql += 'INSERT INTO ' + this._tableizeModelName(modelName) + ' '; + sql += 'INSERT INTO ' + this._tableizeModelNameFull(modelName) + ' '; sql += '(' + cols.join(', ') + ')'; sql += ' VALUES '; sql += '(' + vals.join(', ') + ')'; @@ -403,9 +434,9 @@ utils.mixin(EventedQueryProcessor.prototype, new (function () { // First item in this list should be the owner table for // any subsequent associations, e.g., ['users', 'profiles'] tables.forEach(function (t) { - self.models[t] = { - ctor: converter._modelizeTableName(t, mainTable) - , assnType: t == mainTable ? null : model.getAssociation(mainTable, t).type + self.models[Adapter.prototype.clearSchema(t)] = { + ctor: converter._modelizeTableName(Adapter.prototype.clearSchema(t), Adapter.prototype.clearSchema(mainTable)) + , assnType: Adapter.prototype.clearSchema(t) == Adapter.prototype.clearSchema(mainTable) ? null : model.getAssociation(Adapter.prototype.clearSchema(mainTable), Adapter.prototype.clearSchema(t)).type } }); @@ -417,7 +448,7 @@ utils.mixin(EventedQueryProcessor.prototype, new (function () { , colArr , query = this.query , meta = query._sqlMetadata - , mainTable = meta.mainTableName + , mainTable = Adapter.prototype.clearSchema(meta.mainTableName) , tables = meta.selects , table , key @@ -445,8 +476,9 @@ utils.mixin(EventedQueryProcessor.prototype, new (function () { // when a new id shows up. (Owner object record is repeated for multiple // associations.) For each subsquent record, instantiate the association // and append it to an array in the named property for that association - tables.forEach(function (p) { - var params = obj[p] + tables.forEach(function (fullTableName) { + var p = Adapter.prototype.clearSchema(fullTableName) + , params = obj[p] , modelItem = self.models[p] , keyName; diff --git a/lib/adapters/sql/postgres.js b/lib/adapters/sql/postgres.js index 598bfdca..0969e678 100644 --- a/lib/adapters/sql/postgres.js +++ b/lib/adapters/sql/postgres.js @@ -121,7 +121,7 @@ utils.mixin(Adapter.prototype, new (function () { }; this.bySQL = function (query, model, callback) { - var name = this._tableizeModelName(model.modelName) + var name = this._tableizeModelNameFull(model.modelName) , sql = 'SELECT ' + name + '.* FROM ' + name; sql += ' ' + query; this._itemsWithSQL.apply(sql, [name], name, query, callback);