2013-12-27 14:44:21 -05:00
|
|
|
// Table Compiler
|
|
|
|
// -------
|
|
|
|
module.exports = function(client) {
|
|
|
|
var _ = require('lodash');
|
|
|
|
|
|
|
|
var Raw = require('../raw');
|
|
|
|
var Helpers = require('../helpers');
|
|
|
|
var Formatters = require('../formatters');
|
|
|
|
var modifierFns = require('./tablecompiler/modifiers');
|
|
|
|
|
|
|
|
function SchemaTableCompiler(tableInterface) {
|
2014-02-21 18:11:39 -05:00
|
|
|
_.each(['method', 'tableName', 'columns', 'statements', 'attributes'], function(method) {
|
2013-12-27 14:44:21 -05:00
|
|
|
this[method] = tableInterface['__' + method];
|
|
|
|
}, this);
|
|
|
|
this.tableNameRaw = this.tableName;
|
|
|
|
this.tableName = this._wrap(this.tableName);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The "alter" and "create" methods are the two main methods called
|
|
|
|
_.extend(SchemaTableCompiler.prototype, Formatters, {
|
|
|
|
|
|
|
|
toSql: function TableCompiler$toSql() {
|
|
|
|
return this[this.method]();
|
|
|
|
},
|
|
|
|
|
|
|
|
create: function TableCompiler$create() {
|
|
|
|
var returnSql = this.returnSql = [];
|
|
|
|
returnSql.push({sql: ''});
|
|
|
|
returnSql[0].sql = 'create table ' + this.tableName + ' (' + this.getColumns().join(', ') + ')';
|
|
|
|
this.alterColumns();
|
|
|
|
this.addIndexes();
|
|
|
|
return returnSql;
|
|
|
|
},
|
|
|
|
|
|
|
|
alter: function() {
|
|
|
|
var returnSql = this.returnSql = [];
|
|
|
|
this.addColumns();
|
|
|
|
this.alterColumns();
|
|
|
|
this.addIndexes();
|
|
|
|
return returnSql;
|
|
|
|
},
|
|
|
|
|
|
|
|
addColumnsPrefix: 'add column ',
|
|
|
|
|
|
|
|
addColumns: function() {
|
|
|
|
var columns = this.getColumns();
|
|
|
|
if (columns.length > 0) {
|
|
|
|
this.returnSql.push({sql: '', bindings: []});
|
|
|
|
columns = _.map(columns, function(column) {
|
|
|
|
return this.addColumnsPrefix + column;
|
|
|
|
}, this);
|
|
|
|
this.returnSql[0].sql = 'alter table ' + this.tableName + ' ' + columns.join(', ');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
alterColumns: function() {
|
|
|
|
var alterColumns = _.where(this.statements, {type: 'alterColumns'});
|
|
|
|
for (var i = 0, l = alterColumns.length; i < l; i++) {
|
|
|
|
var statement = alterColumns[i];
|
|
|
|
this.returnSql.push(this[statement.method].apply(this, statement.args));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// Add indexes on the statements.
|
|
|
|
addIndexes: function TableCompiler$addIndexes() {
|
|
|
|
var indexStatements = _.where(this.statements, {type: 'indexes'});
|
|
|
|
for (var i = 0, l = indexStatements.length; i < l; i++) {
|
|
|
|
var statement = indexStatements[i];
|
|
|
|
var obj = this.keys[statement.method].apply(this, statement.args);
|
|
|
|
if (obj) this.returnSql.push(obj);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// ----------------------------------------
|
|
|
|
|
|
|
|
// Compile the columns as needed for the current create or alter table
|
|
|
|
getColumns: function TableCompiler$getColumns() {
|
|
|
|
var compiledColumns = [], columns = this.columns;
|
|
|
|
for (var i = 0, l = columns.length; i < l; i++) {
|
|
|
|
this.currentColumn = columns[i];
|
|
|
|
compiledColumns.push(this.compileColumn(columns[i]));
|
|
|
|
}
|
|
|
|
this.currentColumn = void 0;
|
|
|
|
return compiledColumns;
|
|
|
|
},
|
|
|
|
|
|
|
|
compileColumn: function TableCompiler$compileColumn(column) {
|
|
|
|
return this._wrap(this.getColumnName(column)) + ' ' + this.getColumnType(column) + this.getModifiers(column);
|
|
|
|
},
|
|
|
|
|
|
|
|
getColumnType: function TableCompiler$getColumnType(column) {
|
|
|
|
var type = this.types[column.method];
|
|
|
|
return _.isFunction(type) ? type.apply(this, _.rest(column.args)) : type;
|
|
|
|
},
|
|
|
|
|
|
|
|
getModifiers: function(column) {
|
|
|
|
var modifiers = [];
|
|
|
|
if (column.method !== 'timestamps' && column.method.indexOf('increments') === -1) {
|
|
|
|
var modifierTypes = this.modifierTypes;
|
|
|
|
var statements = column.chainable.__modifiers;
|
|
|
|
for (var i = 0, l = modifierTypes.length; i < l; i++) {
|
|
|
|
var modifier = modifierTypes[i];
|
|
|
|
var statement = statements[modifier];
|
|
|
|
if (statement) {
|
|
|
|
var val = this.modifiers[modifier].apply(this, statement);
|
|
|
|
if (val) modifiers.push(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return modifiers.length > 0 ? ' ' + modifiers.join(' ') : '';
|
|
|
|
},
|
|
|
|
|
|
|
|
// Assumes that the autoincrementing key is named `id` if not otherwise specified.
|
|
|
|
getColumnName: function(column) {
|
|
|
|
var value = _.first(column.args);
|
|
|
|
if (value) return value;
|
|
|
|
if (column.method === 'timestamps') return '';
|
|
|
|
if (column.method.indexOf('increments') !== -1) {
|
|
|
|
return 'id';
|
|
|
|
} else {
|
|
|
|
throw new Error('You did not specify a column name for the ' + column.originalMethod + 'column on ' + this.tableName);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
dropUnique: function(value) {
|
|
|
|
return {
|
|
|
|
sql: 'drop index ' + value
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
dropColumnPrefix: 'drop column ',
|
|
|
|
|
|
|
|
dropColumn: function() {
|
|
|
|
var columns = Helpers.normalizeArr.apply(null, arguments);
|
|
|
|
var drops = _.map(_.isArray(columns) ? columns : [columns], function(column) {
|
|
|
|
return this.dropColumnPrefix + this._wrap(column);
|
|
|
|
}, this);
|
|
|
|
return {
|
|
|
|
sql: 'alter table ' + this.tableName + ' ' + drops.join(', ')
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
// If no name was specified for this index, we will create one using a basic
|
|
|
|
// convention of the table name, followed by the columns, followed by an
|
|
|
|
// index type, such as primary or index, which makes the index unique.
|
|
|
|
_indexCommand: function(type, tableName, columns) {
|
|
|
|
if (!_.isArray(columns)) columns = columns ? [columns] : [];
|
|
|
|
var table = tableName.replace(/\.|-/g, '_');
|
|
|
|
return (table + '_' + columns.join('_') + '_' + type).toLowerCase();
|
|
|
|
},
|
|
|
|
|
2014-02-21 18:11:39 -05:00
|
|
|
// TODO: See if this is still needed
|
|
|
|
// _checkRaw: function(value, parameter) {
|
|
|
|
// if (value instanceof Raw) {
|
|
|
|
// if (value.bindings) this.binding.push(value.bindings);
|
|
|
|
// return value.sql;
|
|
|
|
// }
|
|
|
|
// // if (parameter) this.binding.push(value);
|
|
|
|
// },
|
2013-12-27 14:44:21 -05:00
|
|
|
|
|
|
|
_wrapValue: function tablecompiler$wrapValue() {
|
|
|
|
return client.wrapValue.apply(this, arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
SchemaTableCompiler.extend = require('simple-extend');
|
|
|
|
|
|
|
|
return SchemaTableCompiler;
|
|
|
|
|
|
|
|
};
|