diff --git a/lib/migration.js b/lib/migration.js index c1dee3c3..ad03de44 100644 --- a/lib/migration.js +++ b/lib/migration.js @@ -11,136 +11,46 @@ var async = require('async'); module.exports = mixinMigration; function mixinMigration(PostgreSQL) { - /*! - * Discover the properties from a table - * @param {String} model The model name - * @param {Function} cb The callback function - */ - PostgreSQL.prototype.getTableStatus = function(model, cb) { - var fields; - var indexes; - - function done(err) { - if (fields && indexes) { - cb(err, fields, indexes); - } - } - - function decoratedTableDataCallback(err, data) { + PostgreSQL.prototype.showFields = function(model, cb) { + var sql = 'SELECT column_name AS "column", data_type AS "type", ' + + 'is_nullable AS "nullable", character_maximum_length as "length"' // , data_default AS "Default"' + + ' FROM "information_schema"."columns" WHERE table_name=\'' + + this.table(model) + '\''; + this.execute(sql, function(err, fields) { if (err) { - console.error(err); - } - if (!err) { - data.forEach(function(field) { + return cb(err); + } else { + fields.forEach(function(field) { field.type = mapPostgreSQLDatatypes(field.type, field.length); }); + cb(err, fields); } - fields = data; - done(err); - } - - function decoratedIndexDataCallback(err, data) { - var indexHash = {}; - - if (err) { - console.log(err); - } - - indexes = data; - done(err); - } - - this.execute('SELECT column_name AS "column", data_type AS "type", ' + - 'is_nullable AS "nullable", character_maximum_length as "length"' // , data_default AS "Default"' - + ' FROM "information_schema"."columns" WHERE table_name=\'' + - this.table(model) + '\'', decoratedTableDataCallback); - - this.execute( - 'SELECT t.relname AS "table", i.relname AS "name", ' + - 'am.amname AS "type", ix.indisprimary AS "primary", ' + - 'ix.indisunique AS "unique", ' + - 'ARRAY(SELECT pg_get_indexdef(ix.indexrelid, k + 1, true) ' + - ' FROM generate_subscripts(ix.indkey, 1) AS k ' + - ' ORDER BY k ) AS "keys", ' + - 'ARRAY(SELECT ' + - ' CASE ix.indoption[k] & 1 WHEN 1 THEN \'DESC\' ELSE \'ASC\' END ' + - ' FROM generate_subscripts(ix.indoption, 1) AS k ' + - ' ORDER BY k ' + - ') AS "order" ' + - 'FROM pg_class t, pg_class i, pg_index ix, pg_am am ' + - 'WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND ' + - 'i.relam = am.oid AND ' + - 't.relkind=\'r\' AND t.relname=\'' + - this.table(model) + '\'', decoratedIndexDataCallback); - }; - - /** - * Perform autoupdate for the given models - * @param {String[]} [models] A model name or an array of model names. If not present, apply to all models - * @callback {Function} [callback] The callback function - * @param {String|Error} err The error string or object - */ - PostgreSQL.prototype.autoupdate = function(models, cb) { - var self = this; - if ((!cb) && ('function' === typeof models)) { - cb = models; - models = undefined; - } - // First argument is a model name - if ('string' === typeof models) { - models = [models]; - } - - models = models || Object.keys(this._models); - - async.each(models, function(model, done) { - if (!(model in self._models)) { - return process.nextTick(function() { - done(new Error(g.f('Model not found: %s' + model))); - }); - } - self.getTableStatus(model, function(err, fields, indexes) { - if (!err && fields.length) { - self.alterTable(model, fields, indexes, done); - } else { - self.createTable(model, done); - } - }); - }, cb); + }); }; - /*! - * Check if the models exist - * @param {String[]} [models] A model name or an array of model names. If not present, apply to all models - * @param {Function} [cb] The callback function - */ - PostgreSQL.prototype.isActual = function(models, cb) { - var self = this; - - if ((!cb) && ('function' === typeof models)) { - cb = models; - models = undefined; - } - // First argument is a model name - if ('string' === typeof models) { - models = [models]; - } - - models = models || Object.keys(this._models); - - var changes = []; - async.each(models, function(model, done) { - self.getTableStatus(model, function(err, fields) { - changes = changes.concat(self.getAddModifyColumns(model, fields)); - changes = changes.concat(self.getDropColumns(model, fields)); - done(err); - }); - }, function done(err) { + PostgreSQL.prototype.showIndexes = function(model, cb) { + var sql = 'SELECT t.relname AS "table", i.relname AS "name", ' + + 'am.amname AS "type", ix.indisprimary AS "primary", ' + + 'ix.indisunique AS "unique", ' + + 'ARRAY(SELECT pg_get_indexdef(ix.indexrelid, k + 1, true) ' + + ' FROM generate_subscripts(ix.indkey, 1) AS k ' + + ' ORDER BY k ) AS "keys", ' + + 'ARRAY(SELECT ' + + ' CASE ix.indoption[k] & 1 WHEN 1 THEN \'DESC\' ELSE \'ASC\' END ' + + ' FROM generate_subscripts(ix.indoption, 1) AS k ' + + ' ORDER BY k ' + + ') AS "order" ' + + 'FROM pg_class t, pg_class i, pg_index ix, pg_am am ' + + 'WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND ' + + 'i.relam = am.oid AND ' + + 't.relkind=\'r\' AND t.relname=\'' + + this.table(model) + '\''; + this.execute(sql, function(err, indexes) { if (err) { - return cb && cb(err); + return cb(err); + } else { + cb(err, indexes); } - var actual = (changes.length === 0); - cb && cb(null, actual); }); }; @@ -205,13 +115,6 @@ function mixinMigration(PostgreSQL) { return sql; }; - PostgreSQL.prototype.getDropColumns = function(model, actualFields) { - var sql = []; - var self = this; - sql = sql.concat(self.getColumnsToDrop(model, actualFields)); - return sql; - }; - PostgreSQL.prototype.getColumnsToAdd = function(model, actualFields) { var self = this; var m = self._models[model]; @@ -231,28 +134,6 @@ function mixinMigration(PostgreSQL) { return sql; }; - PostgreSQL.prototype.addPropertyToActual = function(model, propName) { - var self = this; - var prop = this.getModelDefinition(model).properties[propName]; - var sqlCommand = self.columnEscaped(model, propName) - + ' ' + self.columnDataType(model, propName) + - (self.isNullable(prop) ? '' : ' NOT NULL') + - self.columnDbDefault(model, propName); - return sqlCommand; - }; - - PostgreSQL.prototype.searchForPropertyInActual = function(model, propName, actualFields) { - var self = this; - var found = false; - actualFields.forEach(function(f) { - if (f.column === self.column(model, propName)) { - found = f; - return; - } - }); - return found; - }; - PostgreSQL.prototype.getPropertiesToModify = function(model, actualFields) { var self = this; var sql = []; @@ -345,23 +226,6 @@ function mixinMigration(PostgreSQL) { } }; - PostgreSQL.prototype.applySqlChanges = function(model, pendingChanges, cb) { - var self = this; - if (pendingChanges.length) { - var thisQuery = 'ALTER TABLE ' + self.tableEscaped(model); - var ranOnce = false; - pendingChanges.forEach(function(change) { - if (ranOnce) { - thisQuery = thisQuery + ' '; - } - thisQuery = thisQuery + ' ' + change; - ranOnce = true; - }); - // thisQuery = thisQuery + ';'; - self.execute(thisQuery, cb); - } - }; - /*! * Build a list of columns for the given model * @param {String} model The model name @@ -517,29 +381,9 @@ function mixinMigration(PostgreSQL) { return colDefault ? (' DEFAULT ' + colDefault) : ''; }; - /*! - * Find the column type for a given model property - * - * @param {String} model The model name - * @param {String} property The property name - * @returns {String} The column type - */ - PostgreSQL.prototype.columnDataType = function(model, property) { - var columnMetadata = this.columnMetadata(model, property); - var colType = columnMetadata && columnMetadata.dataType; - if (colType) { - colType = colType.toUpperCase(); - } - var prop = this.getModelDefinition(model).properties[property]; - if (!prop) { - return null; - } - var colLength = columnMetadata && columnMetadata.dataLength || prop.length; - if (colType) { - return colType + (colLength ? '(' + colLength + ')' : ''); - } - - switch (prop.type.name) { + PostgreSQL.prototype.buildColumnType = function buildColumnType(propertyDefinition) { + var p = propertyDefinition; + switch (p.type.name) { default: case 'String': case 'JSON': @@ -641,10 +485,6 @@ function mixinMigration(PostgreSQL) { } } - PostgreSQL.prototype.propertyHasNotBeenDeleted = function(model, propName) { - return !!this.getModelDefinition(model).properties[propName]; - }; - PostgreSQL.prototype.addIndexes = function(model, actualIndexes, cb) { var self = this; var m = self._models[model];