mirror of
https://github.com/knex/knex.git
synced 2025-07-03 07:04:07 +00:00
148 lines
5.0 KiB
JavaScript
148 lines
5.0 KiB
JavaScript
// Table Compiler
|
|
// -------
|
|
var _ = require('lodash');
|
|
|
|
var Raw = require('../raw');
|
|
var util = require('../util');
|
|
|
|
function TableCompiler(schemaCompiler, tableBuilder) {
|
|
this.schemaCompiler = schemaCompiler;
|
|
this.formatter = schemaCompiler.formatter;
|
|
|
|
this.tableBuilder = tableBuilder;
|
|
this.tableNameRaw = tableBuilder.tableName;
|
|
|
|
this.grouped = _.groupBy(schemaCompiler._statements, 'grouping');
|
|
this.single = schemaCompiler._single;
|
|
}
|
|
|
|
// Push onto the schemaCompiler's stack of queries
|
|
TableCompiler.prototype.pushQuery = function(obj) {
|
|
this.schemaCompiler.pushQuery(obj);
|
|
this.formatter = this.schemaCompiler.formatter;
|
|
return this;
|
|
};
|
|
|
|
TableCompiler.prototype.toSQL = function() {
|
|
|
|
};
|
|
|
|
TableCompiler.prototype.create = function() {
|
|
this.pushQuery('create table ' + this.tableName() + ' (' + this.getColumns().join(', ') + ')');
|
|
this.alterColumns();
|
|
this.addIndexes();
|
|
};
|
|
|
|
TableCompiler.prototype.alter = function() {
|
|
this.addColumns();
|
|
this.alterColumns();
|
|
this.addIndexes();
|
|
};
|
|
|
|
TableCompiler.prototype.tableName = function() {
|
|
return this.formatter.wrap(this.tableNameRaw);
|
|
};
|
|
|
|
TableCompiler.prototype.addColumnsPrefix = 'add column ';
|
|
|
|
// All of the columns to "add" for the query
|
|
TableCompiler.prototype.addColumns = function() {
|
|
var columns = this.getColumns();
|
|
if (columns.length > 0) {
|
|
columns = _.map(columns, function(column) {
|
|
return this.addColumnsPrefix + column;
|
|
}, this);
|
|
this.pushQuery('alter table ' + this.tableName() + ' ' + columns.join(', '));
|
|
}
|
|
};
|
|
|
|
// Generate all of the alter column statements necessary for the query.
|
|
TableCompiler.prototype.alterColumns = function() {
|
|
var alterColumns = _.where(this.statements, {type: 'alterColumns'});
|
|
for (var i = 0, l = alterColumns.length; i < l; i++) {
|
|
var statement = alterColumns[i];
|
|
this.pushQuery(this[statement.method].apply(this, statement.args));
|
|
}
|
|
};
|
|
|
|
// Add indexes on the statements.
|
|
TableCompiler.prototype.addIndexes = function() {
|
|
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.pushQuery(obj);
|
|
}
|
|
};
|
|
|
|
// Compile the columns as needed for the current create or alter table
|
|
TableCompiler.prototype.getColumns = function() {
|
|
var compiledColumns = [], columns = this.columns;
|
|
for (var i = 0, l = columns.length; i < l; i++) {
|
|
compiledColumns.push(this.compileColumn(columns[i]));
|
|
}
|
|
return compiledColumns;
|
|
};
|
|
|
|
TableCompiler.prototype.compileColumn = function(column) {
|
|
return this.formatter.wrap(this.getColumnName(column)) + ' ' + this.getColumnType(column) + this.getModifiers(column);
|
|
};
|
|
|
|
TableCompiler.prototype.getColumnType = function(column) {
|
|
var type = this.types[column.method];
|
|
return _.isFunction(type) ? type.apply(this, _.rest(column.args)) : type;
|
|
};
|
|
|
|
TableCompiler.prototype.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.
|
|
TableCompiler.prototype.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());
|
|
}
|
|
};
|
|
|
|
TableCompiler.prototype.dropUnique = function(value) {
|
|
this.pushQuery('drop index ' + value);
|
|
};
|
|
|
|
// dropColumnPrefix: 'drop column ',
|
|
|
|
TableCompiler.prototype.dropColumn = function() {
|
|
var columns = util.normalizeArr.apply(null, arguments);
|
|
var drops = _.map(_.isArray(columns) ? columns : [columns], function(column) {
|
|
return this.dropColumnPrefix + this.formatter.wrap(column);
|
|
}, this);
|
|
this.pushQuery('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.
|
|
TableCompiler.prototype._indexCommand = function(type, tableName, columns) {
|
|
if (!_.isArray(columns)) columns = columns ? [columns] : [];
|
|
var table = tableName.replace(/\.|-/g, '_');
|
|
return (table + '_' + columns.join('_') + '_' + type).toLowerCase();
|
|
};
|
|
|
|
module.exports = TableCompiler; |