mirror of
https://github.com/knex/knex.git
synced 2025-10-01 19:16:41 +00:00
432 lines
12 KiB
JavaScript
432 lines
12 KiB
JavaScript
module.exports = function(client) {
|
|
|
|
var _ = require('lodash');
|
|
var inherits = require('inherits');
|
|
|
|
var Promise = require('../../promise');
|
|
|
|
var SchemaBuilder = require('../../schema/builder');
|
|
var SchemaCompiler = require('../../schema/compiler');
|
|
|
|
var TableBuilder = require('../../schema/tablebuilder');
|
|
var TableCompiler = require('../../schema/tablecompiler');
|
|
|
|
var ColumnBuilder = require('../../schema/columnbuilder');
|
|
var ColumnCompiler = require('../../schema/columncompiler');
|
|
|
|
function SchemaBuilder_MySQL() {
|
|
SchemaBuilder.apply(this, arguments);
|
|
}
|
|
inherits(SchemaBuilder_MySQL, SchemaBuilder);
|
|
|
|
SchemaBuilder_MySQL.prototype.toSql = function() {
|
|
var sql = [];
|
|
new SchemaCompiler_MySQL(this);
|
|
for (var i = 0, l = this._sequence.length; i < l; i++) {
|
|
|
|
}
|
|
_.map(this._sequence, function() {
|
|
|
|
});
|
|
};
|
|
|
|
// Set the "then" method to call `runThen` on the client, processing the query.
|
|
SchemaBuilder_MySQL.prototype.then = function(onFulfilled, onRejected) {
|
|
return client.runThen(this).then(onFulfilled, onRejected);
|
|
};
|
|
|
|
function SchemaCompiler_MySQL() {
|
|
this.Formatter = client.Formatter;
|
|
SchemaCompiler.apply(this, arguments);
|
|
}
|
|
inherits(SchemaCompiler_MySQL, SchemaCompiler);
|
|
|
|
// Rename a table on the schema.
|
|
SchemaCompiler_MySQL.prototype.renameTable = function(tableName, to) {
|
|
return {
|
|
sql: 'rename table ' + this.formatter.wrap(tableName) + ' to ' + this.formatter.wrap(to)
|
|
};
|
|
};
|
|
|
|
// Check whether a table exists on the query.
|
|
SchemaCompiler_MySQL.prototype.hasTable = function(tableName) {
|
|
return {
|
|
sql: 'select * from information_schema.tables where table_schema = ? and table_name = ?',
|
|
bindings: [client.database(), tableName],
|
|
output: function(resp) {
|
|
return resp.length > 0;
|
|
}
|
|
};
|
|
};
|
|
|
|
// Check whether a column exists on the
|
|
SchemaCompiler_MySQL.prototype.hasColumn = function(tableName, column) {
|
|
return {
|
|
sql: 'show columns from ' + this.formatter.wrap(tableName) + ' like ?',
|
|
output: function(resp) {
|
|
return resp.length > 0;
|
|
}
|
|
};
|
|
};
|
|
|
|
// Create a new table.
|
|
SchemaCompiler_MySQL.prototype.createTable = function() {
|
|
|
|
};
|
|
|
|
SchemaCompiler_MySQL.prototype.alterTable = function() {
|
|
|
|
};
|
|
|
|
function TableCompiler_MySQL() {
|
|
this.modifierTypes = ['unsigned', 'nullable', 'defaultTo', 'after', 'comment'];
|
|
TableCompiler.apply(this, arguments);
|
|
}
|
|
inherits(TableCompiler_MySQL, TableCompiler);
|
|
|
|
TableCompiler_MySQL.prototype.create = function() {
|
|
var conn = {};
|
|
var returnSql = TableCompiler_MySQL.super_.create();
|
|
var sql = returnSql[0].sql;
|
|
|
|
// Check if the connection settings are set.
|
|
if (client.connectionSettings) {
|
|
conn = client.connectionSettings;
|
|
}
|
|
var charset = this.flags.charset || conn.charset;
|
|
var collation = this.flags.collate || conn.collate;
|
|
var engine = this.flags.engine;
|
|
|
|
// var conn = builder.client.connectionSettings;
|
|
if (charset) sql += ' default character set ' + charset;
|
|
if (collation) sql += ' collate ' + collation;
|
|
if (engine) sql += ' engine = ' + engine;
|
|
|
|
// // TODO: Handle max comment length ?
|
|
var maxTableCommentLength = 60;
|
|
var hasComment = _.has(this.attributes, 'comment');
|
|
if (hasComment) sql += " comment = '" + (this.attributes.comment || '') + "'";
|
|
|
|
this.push(sql);
|
|
};
|
|
|
|
|
|
addColumnsPrefix: 'add ',
|
|
|
|
dropColumnPrefix: 'drop ',
|
|
|
|
// Compiles the comment on the table.
|
|
SchemaCompiler_MySQL.prototype.comment = function(comment) {
|
|
this.push('alter table ' + this.tableName() + " comment = '" + comment + "'");
|
|
},
|
|
|
|
changeType: function() {
|
|
alter table + table + ' modify ' + wrapped + '// type';
|
|
}
|
|
|
|
// Renames a column on the table.
|
|
renameColumn: function(from, to) {
|
|
var wrapped = this._wrap(from) + ' ' + this._wrap(to);
|
|
var table = this.tableName();
|
|
return {
|
|
sql: 'show fields from ' + table + ' where field = ' +
|
|
this.formatter.parameter(from),
|
|
output: function(resp) {
|
|
var column = resp[0];
|
|
return this.query({
|
|
sql: 'alter table ' + table + ' change ' + wrapped + ' ' + column.Type
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function TableBuilder_MySQL() {
|
|
|
|
}
|
|
|
|
// 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) {
|
|
warn('Knex only supports ' + method + ' statement with mysql.');
|
|
} if (this.__method === 'alter') {
|
|
warn('Knex does not support altering the ' + method + ' outside of the create table, please use knex.raw statement.');
|
|
} else {
|
|
this.__attributes[method] = value;
|
|
}
|
|
};
|
|
});
|
|
|
|
|
|
module.exports = function(client) {
|
|
|
|
var _ = require('lodash');
|
|
var SchemaTableCompiler = require('../../../schema/tablecompiler')(client);
|
|
|
|
return SchemaTableCompiler.extend({
|
|
|
|
// The possible column modifiers.
|
|
modifierTypes: ['unsigned', 'nullable', 'defaultTo', 'after', 'comment'],
|
|
|
|
// All types for sqlite3 builder. Feel free to fiddle with them on
|
|
// the client object if you wish, they're unique per-client.
|
|
types: require('./tablecompiler/types')(client),
|
|
|
|
// All modifiers for the sqlite3 builder.
|
|
modifiers: require('./tablecompiler/modifiers')(client),
|
|
|
|
// All key related statements for the sqlite3 builder.
|
|
keys: require('./tablecompiler/keys')(client),
|
|
|
|
// Create a new table
|
|
create: function() {
|
|
var conn = {};
|
|
var returnSql = SchemaTableCompiler.prototype.create.apply(this, arguments);
|
|
var sql = returnSql[0].sql;
|
|
|
|
// Check if the connection settings are set.
|
|
if (client.connectionSettings) {
|
|
conn = client.connectionSettings;
|
|
}
|
|
var charset = this.attributes.charset || conn.charset;
|
|
var collation = this.attributes.collate || conn.collate;
|
|
var engine = this.attributes.engine;
|
|
|
|
|
|
// var conn = builder.client.connectionSettings;
|
|
if (charset) sql += ' default character set ' + charset;
|
|
if (collation) sql += ' collate ' + collation;
|
|
if (engine) sql += ' engine = ' + engine;
|
|
|
|
// // TODO: Handle max comment length ?
|
|
var maxTableCommentLength = 60;
|
|
var hasComment = _.has(this.attributes, 'comment');
|
|
if (hasComment) sql += " comment = '" + (this.attributes.comment || '') + "'";
|
|
|
|
returnSql[0].sql = sql;
|
|
|
|
return returnSql;
|
|
},
|
|
|
|
addColumnsPrefix: 'add ',
|
|
|
|
dropColumnPrefix: 'drop ',
|
|
|
|
// Compiles the comment on the table.
|
|
comment: function(comment) {
|
|
return {
|
|
sql: 'alter table ' + this.tableName + " comment = '" + comment + "'"
|
|
};
|
|
},
|
|
|
|
// Renames a column on the table.
|
|
renameColumn: function(from, to) {
|
|
var wrapped = this._wrap(from) + ' ' + this._wrap(to);
|
|
var table = this.tableName;
|
|
return {
|
|
sql: 'show fields from ' + this.tableName + ' where field = ?',
|
|
bindings: [from],
|
|
output: function(resp) {
|
|
var column = resp[0];
|
|
return this.query({
|
|
sql: 'alter table ' + table + ' change ' + wrapped + ' ' + column.Type
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
// MySQL Schema Types
|
|
// -------
|
|
module.exports = function() {
|
|
|
|
var _ = require('lodash');
|
|
|
|
return _.extend({}, require('../../../../schema/tablecompiler/types'), {
|
|
increments: 'int unsigned not null auto_increment primary key',
|
|
bigincrements: 'bigint unsigned not null auto_increment primary key',
|
|
bigint: 'bigint',
|
|
double: function(precision, scale) {
|
|
if (!precision) return 'double';
|
|
return 'double(' + num(precision, 8) + ', ' + num(scale, 2) + ')';
|
|
},
|
|
integer: function(length) {
|
|
length = length ? '(' + num(length, 11) + ')' : '';
|
|
return 'int' + length;
|
|
},
|
|
mediumint: 'mediumint',
|
|
smallint: 'smallint',
|
|
tinyint: function(length) {
|
|
length = length ? '(' + num(length, 1) + ')' : '';
|
|
return 'tinyint' + length;
|
|
},
|
|
text: function(column) {
|
|
switch (column) {
|
|
case 'medium':
|
|
case 'mediumtext':
|
|
return 'mediumtext';
|
|
case 'long':
|
|
case 'longtext':
|
|
return 'longtext';
|
|
default:
|
|
return 'text';
|
|
}
|
|
},
|
|
mediumtext: function() {
|
|
return this.text('medium');
|
|
},
|
|
longtext: function() {
|
|
return this.text('long');
|
|
},
|
|
float: function(precision, scale) {
|
|
return 'float(' + precision + ',' + scale + ')';
|
|
},
|
|
typeDecimal: function(precision, scale) {
|
|
return 'decimal(' + precision + ', ' + scale + ')';
|
|
},
|
|
enu: function(allowed) {
|
|
return "enum('" + allowed.join("', '") + "')";
|
|
},
|
|
datetime: 'datetime',
|
|
timestamp: 'timestamp',
|
|
bit: function(length) {
|
|
return length ? 'bit(' + length + ')' : 'bit';
|
|
}
|
|
});
|
|
|
|
function num(val, fallback) {
|
|
if (val == null) return fallback;
|
|
var number = parseInt(val, 10);
|
|
return isNaN(number) ? fallback : number;
|
|
}
|
|
};
|
|
|
|
|
|
module.exports = function(client) {
|
|
var _ = require('lodash');
|
|
|
|
return {
|
|
|
|
index: function(columns, indexName) {
|
|
indexName = indexName || this._indexCommand('index', this.tableNameRaw, columns);
|
|
return {
|
|
sql: 'alter table ' + this.tableName + " add index " + indexName + "(" + this.formatter.columnize(columns) + ")"
|
|
};
|
|
},
|
|
|
|
primary: function(columns, indexName) {
|
|
indexName = indexName || this._indexCommand('primary', this.tableNameRaw, columns);
|
|
return {
|
|
sql: 'alter table ' + this.tableName + " add primary key " + indexName + "(" + this.formatter.columnize(columns) + ")"
|
|
};
|
|
},
|
|
|
|
unique: function(columns, indexName) {
|
|
indexName = indexName || this._indexCommand('unique', this.tableNameRaw, columns);
|
|
return {
|
|
sql: 'alter table ' + this.tableName + " add unique " + indexName + "(" + this.formatter.columnize(columns) + ")"
|
|
};
|
|
},
|
|
|
|
// Compile a drop index command.
|
|
dropIndex: function(key) {
|
|
return {
|
|
sql: 'alter table ' + this.tableName + ' drop index ' + key
|
|
};
|
|
},
|
|
|
|
// Compile a drop foreign key command.
|
|
dropForeign: function(key) {
|
|
return {
|
|
sql: 'alter table ' + this.tableName + ' drop foreign key ' + key
|
|
};
|
|
},
|
|
|
|
// Compile a drop primary key command.
|
|
dropPrimary: function() {
|
|
return {
|
|
sql: 'alter table ' + this.tableName + ' drop primary key'
|
|
};
|
|
},
|
|
|
|
// Compile a drop unique key command.
|
|
dropUnique: function(key) {
|
|
return {
|
|
sql: 'alter table ' + this.tableName + ' drop index ' + key
|
|
};
|
|
},
|
|
|
|
// Compile a foreign key command.
|
|
foreign: function(foreignData) {
|
|
var sql = '';
|
|
if (foreignData.inTable && foreignData.references) {
|
|
var keyName = this._indexCommand('foreign', this.tableNameRaw, foreignData.column);
|
|
var column = this.formatter.columnize(foreignData.column);
|
|
var references = this.formatter.columnize(foreignData.references);
|
|
var inTable = this.formatter.wrap(foreignData.inTable);
|
|
|
|
sql = 'alter table ' + this.tableName + ' add constraint ' + keyName + ' ';
|
|
sql += 'foreign key (' + column + ') references ' + inTable + ' (' + references + ')';
|
|
|
|
// Once we have the basic foreign key creation statement constructed we can
|
|
// build out the syntax for what should happen on an update or delete of
|
|
// the affected columns, which will get something like 'cascade', etc.
|
|
if (foreignData.onDelete) sql += ' on delete ' + foreignData.onDelete;
|
|
if (foreignData.onUpdate) sql += ' on update ' + foreignData.onUpdate;
|
|
}
|
|
return {
|
|
sql: sql
|
|
};
|
|
}
|
|
};
|
|
|
|
};
|
|
|
|
|
|
module.exports = function(client) {
|
|
var _ = require('lodash');
|
|
var BaseModifiers = require('../../../../schema/tablecompiler/modifiers');
|
|
|
|
return _.extend({}, BaseModifiers, {
|
|
|
|
// Get the SQL for a default column modifier.
|
|
defaultTo: function MySQLModifiers$defaultTo(value) {
|
|
var defaultVal = BaseModifiers.defaultTo.apply(this, arguments);
|
|
var column = this.currentColumn;
|
|
if (column.method != 'blob' && column.method.indexOf('text') === -1) {
|
|
return defaultVal;
|
|
}
|
|
return '';
|
|
},
|
|
|
|
// Get the SQL for an unsigned column modifier.
|
|
unsigned: function() {
|
|
return 'unsigned';
|
|
},
|
|
|
|
// Get the SQL for an "after" column modifier.
|
|
after: function(column) {
|
|
return 'after ' + this.formatter.wrap(column);
|
|
},
|
|
|
|
// Get the SQL for a comment column modifier.
|
|
comment: function(comment) {
|
|
var maxColumnCommentLength = 255;
|
|
if (comment) return "comment '" + comment + "'";
|
|
}
|
|
|
|
});
|
|
};
|