mirror of
https://github.com/knex/knex.git
synced 2025-07-03 23:19:26 +00:00

Returns 0 if all migrations are run and DB is up to date. Return negative number if DB is missing migrations. Return positive number if DB is ahead (rare case, e.g. if migrations were run then code is reverted)
203 lines
6.0 KiB
JavaScript
203 lines
6.0 KiB
JavaScript
|
|
// TableBuilder
|
|
|
|
// Takes the function passed to the "createTable" or "table/editTable"
|
|
// functions and calls it with the "TableBuilder" as both the context and
|
|
// the first argument. Inside this function we can specify what happens to the
|
|
// method, pushing everything we want to do onto the "allStatements" array,
|
|
// which is then compiled into sql.
|
|
// ------
|
|
'use strict';
|
|
|
|
var _ = require('lodash');
|
|
var helpers = require('../helpers');
|
|
|
|
function TableBuilder(client, method, tableName, fn) {
|
|
this.client = client;
|
|
this._fn = fn;
|
|
this._method = method;
|
|
this._schemaName = undefined;
|
|
this._tableName = tableName;
|
|
this._statements = [];
|
|
this._single = {};
|
|
}
|
|
|
|
TableBuilder.prototype.setSchema = function (schemaName) {
|
|
this._schemaName = schemaName;
|
|
};
|
|
|
|
// Convert the current tableBuilder object "toSQL"
|
|
// giving us additional methods if we're altering
|
|
// rather than creating the table.
|
|
TableBuilder.prototype.toSQL = function () {
|
|
if (this._method === 'alter') {
|
|
_.extend(this, AlterMethods);
|
|
}
|
|
this._fn.call(this, this);
|
|
return this.client.tableCompiler(this).toSQL();
|
|
};
|
|
|
|
_.each([
|
|
|
|
// Each of the index methods can be called individually, with the
|
|
// column name to be used, e.g. table.unique('column').
|
|
'index', 'primary', 'unique',
|
|
|
|
// Key specific
|
|
'dropPrimary', 'dropUnique', 'dropIndex', 'dropForeign'], function (method) {
|
|
TableBuilder.prototype[method] = function () {
|
|
this._statements.push({
|
|
grouping: 'alterTable',
|
|
method: method,
|
|
args: _.toArray(arguments)
|
|
});
|
|
return this;
|
|
};
|
|
});
|
|
|
|
// Warn if we're not in MySQL, since that's the only time these
|
|
// three are supported.
|
|
var specialMethods = ['engine', 'charset', 'collate'];
|
|
_.each(specialMethods, function (method) {
|
|
TableBuilder.prototype[method] = function (value) {
|
|
if (false) {
|
|
helpers.warn('Knex only supports ' + method + ' statement with mysql.');
|
|
}if (this._method === 'alter') {
|
|
helpers.warn('Knex does not support altering the ' + method + ' outside of the create table, please use knex.raw statement.');
|
|
}
|
|
this._single[method] = value;
|
|
};
|
|
});
|
|
|
|
// Each of the column types that we can add, we create a new ColumnBuilder
|
|
// instance and push it onto the statements array.
|
|
var columnTypes = [
|
|
|
|
// Numeric
|
|
'tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'decimal', 'float', 'double', 'real', 'bit', 'boolean', 'serial',
|
|
|
|
// Date / Time
|
|
'date', 'datetime', 'timestamp', 'time', 'year',
|
|
|
|
// String
|
|
'char', 'varchar', 'tinytext', 'tinyText', 'text', 'mediumtext', 'mediumText', 'longtext', 'longText', 'binary', 'varbinary', 'tinyblob', 'tinyBlob', 'mediumblob', 'mediumBlob', 'blob', 'longblob', 'longBlob', 'enum', 'set',
|
|
|
|
// Increments, Aliases, and Additional
|
|
'bool', 'dateTime', 'increments', 'bigincrements', 'bigIncrements', 'integer', 'biginteger', 'bigInteger', 'string', 'timestamps', 'json', 'jsonb', 'uuid', 'enu', 'specificType'];
|
|
|
|
// For each of the column methods, create a new "ColumnBuilder" interface,
|
|
// push it onto the "allStatements" stack, and then return the interface,
|
|
// with which we can add indexes, etc.
|
|
_.each(columnTypes, function (type) {
|
|
TableBuilder.prototype[type] = function () {
|
|
var args = _.toArray(arguments);
|
|
|
|
// The "timestamps" call is really a compound call to set the
|
|
// `created_at` and `updated_at` columns.
|
|
if (type === 'timestamps') {
|
|
if (args[0] === true) {
|
|
this.timestamp('created_at');
|
|
this.timestamp('updated_at');
|
|
} else {
|
|
this.datetime('created_at');
|
|
this.datetime('updated_at');
|
|
}
|
|
return;
|
|
}
|
|
var builder = this.client.columnBuilder(this, type, args);
|
|
|
|
this._statements.push({
|
|
grouping: 'columns',
|
|
builder: builder
|
|
});
|
|
return builder;
|
|
};
|
|
});
|
|
|
|
// Set the comment value for a table, they're only allowed to be called
|
|
// once per table.
|
|
TableBuilder.prototype.comment = function (value) {
|
|
this._single.comment = value;
|
|
};
|
|
|
|
// Set a foreign key on the table, calling
|
|
// `table.foreign('column_name').references('column').on('table').onDelete()...
|
|
// Also called from the ColumnBuilder context when chaining.
|
|
TableBuilder.prototype.foreign = function (column) {
|
|
var foreignData = { column: column };
|
|
this._statements.push({
|
|
grouping: 'alterTable',
|
|
method: 'foreign',
|
|
args: [foreignData]
|
|
});
|
|
var returnObj = {
|
|
references: function references(tableColumn) {
|
|
var pieces;
|
|
if (_.isString(tableColumn)) {
|
|
pieces = tableColumn.split('.');
|
|
}
|
|
if (!pieces || pieces.length === 1) {
|
|
foreignData.references = pieces ? pieces[0] : tableColumn;
|
|
return {
|
|
on: function on(tableName) {
|
|
foreignData.inTable = tableName;
|
|
return returnObj;
|
|
},
|
|
inTable: function inTable() {
|
|
return this.on.apply(this, arguments);
|
|
}
|
|
};
|
|
}
|
|
foreignData.inTable = pieces[0];
|
|
foreignData.references = pieces[1];
|
|
return returnObj;
|
|
},
|
|
onUpdate: function onUpdate(statement) {
|
|
foreignData.onUpdate = statement;
|
|
return returnObj;
|
|
},
|
|
onDelete: function onDelete(statement) {
|
|
foreignData.onDelete = statement;
|
|
return returnObj;
|
|
},
|
|
_columnBuilder: function _columnBuilder(builder) {
|
|
_.extend(builder, returnObj);
|
|
returnObj = builder;
|
|
return builder;
|
|
}
|
|
};
|
|
return returnObj;
|
|
};
|
|
|
|
var AlterMethods = {
|
|
|
|
// Renames the current column `from` the current
|
|
// TODO: this.column(from).rename(to)
|
|
renameColumn: function renameColumn(from, to) {
|
|
this._statements.push({
|
|
grouping: 'alterTable',
|
|
method: 'renameColumn',
|
|
args: [from, to]
|
|
});
|
|
return this;
|
|
},
|
|
|
|
dropTimestamps: function dropTimestamps() {
|
|
return this.dropColumns(['created_at', 'updated_at']);
|
|
}
|
|
|
|
// TODO: changeType
|
|
};
|
|
|
|
// Drop a column from the current table.
|
|
// TODO: Enable this.column(columnName).drop();
|
|
AlterMethods.dropColumn = AlterMethods.dropColumns = function () {
|
|
this._statements.push({
|
|
grouping: 'alterTable',
|
|
method: 'dropColumn',
|
|
args: _.toArray(arguments)
|
|
});
|
|
return this;
|
|
};
|
|
|
|
module.exports = TableBuilder; |