mirror of
https://github.com/knex/knex.git
synced 2025-12-26 22:48:32 +00:00
in progress
This commit is contained in:
parent
51ef27bd4f
commit
7c1120e0e2
@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var Promise = require('./promise');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
@ -42,6 +43,10 @@ function Client() {
|
||||
this.initializePool(config);
|
||||
}
|
||||
}
|
||||
this.valueForUndefined = this.raw('DEFAULT');
|
||||
if (config.useNullAsDefault) {
|
||||
this.valueForUndefined = null;
|
||||
}
|
||||
}
|
||||
inherits(Client, EventEmitter);
|
||||
|
||||
@ -137,6 +142,12 @@ assign(Client.prototype, {
|
||||
return this._stream.call(this, connection, obj, _stream, options);
|
||||
},
|
||||
|
||||
prepBindings: function prepBindings(bindings) {
|
||||
return _.map(bindings, function (binding) {
|
||||
return binding === undefined ? this.valueForUndefined : binding;
|
||||
}, this);
|
||||
},
|
||||
|
||||
wrapIdentifier: function wrapIdentifier(value) {
|
||||
return value !== '*' ? '"' + value.replace(/"/g, '""') + '"' : '*';
|
||||
},
|
||||
|
||||
171
lib/dialects/mssql/index.js
Normal file
171
lib/dialects/mssql/index.js
Normal file
@ -0,0 +1,171 @@
|
||||
|
||||
// MSSQL Client
|
||||
// -------
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var inherits = require('inherits');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
var Client = require('../../client');
|
||||
var Promise = require('../../promise');
|
||||
var helpers = require('../../helpers');
|
||||
|
||||
var Transaction = require('./transaction');
|
||||
var QueryCompiler = require('./query/compiler');
|
||||
var JoinClause = require('./query/joinclause');
|
||||
var SchemaCompiler = require('./schema/compiler');
|
||||
var TableCompiler = require('./schema/tablecompiler');
|
||||
var ColumnCompiler = require('./schema/columncompiler');
|
||||
var pluck = require('lodash/collection/pluck');
|
||||
|
||||
// Always initialize with the "QueryBuilder" and "QueryCompiler"
|
||||
// objects, which extend the base 'lib/query/builder' and
|
||||
// 'lib/query/compiler', respectively.
|
||||
function Client_MSSQL(config) {
|
||||
Client.call(this, config);
|
||||
}
|
||||
inherits(Client_MSSQL, Client);
|
||||
|
||||
assign(Client_MSSQL.prototype, {
|
||||
|
||||
dialect: 'mssql',
|
||||
|
||||
driverName: 'mssql',
|
||||
|
||||
_driver: function _driver() {
|
||||
return require('mssql');
|
||||
},
|
||||
|
||||
QueryCompiler: QueryCompiler,
|
||||
|
||||
JoinClause: JoinClause,
|
||||
|
||||
SchemaCompiler: SchemaCompiler,
|
||||
|
||||
TableCompiler: TableCompiler,
|
||||
|
||||
ColumnCompiler: ColumnCompiler,
|
||||
|
||||
//Transaction: Transaction,
|
||||
|
||||
wrapIdentifier: function wrapIdentifier(value) {
|
||||
return value !== '*' ? '[' + value.replace(/\[/g, '\[') + ']' : '*';
|
||||
},
|
||||
|
||||
// Get a raw connection, called by the `pool` whenever a new
|
||||
// connection needs to be added to the pool.
|
||||
acquireRawConnection: function acquireRawConnection() {
|
||||
var client = this;
|
||||
var connection = new this.driver.Connection(this.connectionSettings);
|
||||
return new Promise(function (resolver, rejecter) {
|
||||
connection.connect(function (err) {
|
||||
if (err) return rejecter(err);
|
||||
connection.on('error', connectionErrorHandler.bind(null, client, connection));
|
||||
connection.on('end', connectionErrorHandler.bind(null, client, connection));
|
||||
resolver(connection);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Used to explicitly close a connection, called internally by the pool
|
||||
// when a connection times out or the pool is shutdown.
|
||||
destroyRawConnection: function destroyRawConnection(connection, cb) {
|
||||
connection.close(cb);
|
||||
},
|
||||
|
||||
// Position the bindings for the query.
|
||||
positionBindings: function positionBindings(sql) {
|
||||
var questionCount = 0;
|
||||
return sql.replace(/\?/g, function () {
|
||||
questionCount += 1;
|
||||
return '@p' + questionCount;
|
||||
});
|
||||
},
|
||||
|
||||
prepBindings: function prepBindings(bindings) {
|
||||
return _.map(bindings, function (value) {
|
||||
if (value === undefined) {
|
||||
return this.valueForUndefined;
|
||||
}
|
||||
return value;
|
||||
}, this);
|
||||
},
|
||||
|
||||
// Grab a connection, run the query via the MSSQL streaming interface,
|
||||
// and pass that through to the stream we've sent back to the client.
|
||||
_stream: function _stream(connection, obj, stream, options) {
|
||||
options = options || {};
|
||||
return new Promise(function (resolver, rejecter) {
|
||||
stream.on('error', rejecter);
|
||||
stream.on('end', resolver);
|
||||
connection.query(obj.sql, obj.bindings).stream(options).pipe(stream);
|
||||
});
|
||||
},
|
||||
|
||||
// Runs the query on the specified connection, providing the bindings
|
||||
// and any other necessary prep work.
|
||||
_query: function _query(connection, obj) {
|
||||
if (!obj || typeof obj === 'string') obj = { sql: obj };
|
||||
// convert ? params into positional bindings (@p1)
|
||||
obj.sql = this.positionBindings(obj.sql);
|
||||
obj.bindings = this.prepBindings(obj.bindings) || [];
|
||||
return new Promise(function (resolver, rejecter) {
|
||||
var sql = obj.sql;
|
||||
if (!sql) return resolver();
|
||||
if (obj.options) sql = assign({ sql: sql }, obj.options);
|
||||
var req = connection.request();
|
||||
//request.multiple = true;
|
||||
if (obj.bindings) {
|
||||
for (var i = 1; i <= obj.bindings.length; i++) {
|
||||
req.input('p' + i, obj.bindings[i]);
|
||||
//console.log('p' + i, obj.bindings[i]);
|
||||
}
|
||||
}
|
||||
req.query(sql, function (err, recordset) {
|
||||
if (err) return rejecter(err);
|
||||
obj.response = recordset;
|
||||
resolver(obj);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Process the response as returned from the query.
|
||||
processResponse: function processResponse(obj, runner) {
|
||||
if (obj == null) return;
|
||||
var response = obj.response;
|
||||
var method = obj.method;
|
||||
var recordset = response;
|
||||
if (obj.output) return obj.output.call(runner, recordset);
|
||||
console.log('method: ' + method);
|
||||
console.log(recordset);
|
||||
switch (method) {
|
||||
case 'select':
|
||||
case 'pluck':
|
||||
case 'first':
|
||||
var resp = helpers.skim(recordset);
|
||||
if (method === 'pluck') return pluck(resp, obj.pluck);
|
||||
return method === 'first' ? resp[0] : resp;
|
||||
case 'insert':
|
||||
return [recordset.insertId];
|
||||
case 'del':
|
||||
case 'update':
|
||||
case 'counter':
|
||||
return recordset.affectedRows;
|
||||
default:
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// MSSQL Specific error handler
|
||||
function connectionErrorHandler(client, connection, err) {
|
||||
if (connection && err && err.fatal) {
|
||||
if (connection.__knex__disposed) return;
|
||||
connection.__knex__disposed = true;
|
||||
client.pool.destroy(connection);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Client_MSSQL;
|
||||
19
lib/dialects/mssql/query/builder.js
Normal file
19
lib/dialects/mssql/query/builder.js
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
// MSSQL Query Builder
|
||||
// ------
|
||||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
var QueryBuilder = require('../../../query/bulder');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function QueryBuilder_MSSQL(client) {
|
||||
QueryBuilder.call(this, client);
|
||||
}
|
||||
inherits(QueryBuilder_MSSQL, QueryBuilder);
|
||||
|
||||
assign(QueryBuilder_MSSQL.prototype, {});
|
||||
|
||||
// Set the QueryBuilder & QueryCompiler on the client object,
|
||||
// incase anyone wants to modify things to suit their own purposes.
|
||||
module.exports = QueryBuilder_MSSQL;
|
||||
100
lib/dialects/mssql/query/compiler.js
Normal file
100
lib/dialects/mssql/query/compiler.js
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
// MSSQL Query Compiler
|
||||
// ------
|
||||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
var QueryCompiler = require('../../../query/compiler');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function QueryCompiler_MSSQL(client, builder) {
|
||||
QueryCompiler.call(this, client, builder);
|
||||
}
|
||||
inherits(QueryCompiler_MSSQL, QueryCompiler);
|
||||
|
||||
assign(QueryCompiler_MSSQL.prototype, {
|
||||
|
||||
_emptyInsertValue: '() values ()',
|
||||
|
||||
// Update method, including joins, wheres, order & limits.
|
||||
update: function update() {
|
||||
var join = this.join();
|
||||
var updates = this._prepUpdate(this.single.update);
|
||||
var where = this.where();
|
||||
var order = this.order();
|
||||
var limit = this.limit_();
|
||||
return 'update ' + (limit ? limit + ' ' : '') + this.tableName + (join ? ' ' + join : '') + ' set ' + updates.join(', ') + (where ? ' ' + where : '') + (order ? ' ' + order : '');
|
||||
},
|
||||
|
||||
// Compiles the columns in the query, specifying if an item was distinct.
|
||||
columns: function columns() {
|
||||
var distinct = false;
|
||||
if (this.onlyUnions()) return '';
|
||||
var columns = this.grouped.columns || [];
|
||||
var i = -1,
|
||||
sql = [];
|
||||
if (columns) {
|
||||
while (++i < columns.length) {
|
||||
var stmt = columns[i];
|
||||
if (stmt.distinct) distinct = true;
|
||||
if (stmt.type === 'aggregate') {
|
||||
sql.push(this.aggregate(stmt));
|
||||
} else if (stmt.value && stmt.value.length > 0) {
|
||||
sql.push(this.formatter.columnize(stmt.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sql.length === 0) sql = ['*'];
|
||||
var limit = this.limit_();
|
||||
return 'select ' + (distinct ? 'distinct ' : '') + (limit ? limit + ' ' : '') + sql.join(', ') + (this.tableName ? ' from ' + this.tableName : '');
|
||||
},
|
||||
|
||||
// Compiles a `truncate` query.
|
||||
truncate: function truncate() {
|
||||
return 'truncate table ' + this.tableName;
|
||||
},
|
||||
|
||||
forUpdate: function forUpdate() {
|
||||
return 'with (READCOMMITTEDLOCK)';
|
||||
},
|
||||
|
||||
forShare: function forShare() {
|
||||
return 'with (NOLOCK)';
|
||||
},
|
||||
|
||||
// Compiles a `columnInfo` query.
|
||||
columnInfo: function columnInfo() {
|
||||
var column = this.single.columnInfo;
|
||||
return {
|
||||
sql: 'select * from information_schema.columns where table_name = ? and table_schema = ?',
|
||||
bindings: [this.single.table, this.client.database()],
|
||||
output: function output(resp) {
|
||||
var out = resp.reduce(function (columns, val) {
|
||||
columns[val.COLUMN_NAME] = {
|
||||
defaultValue: val.COLUMN_DEFAULT,
|
||||
type: val.DATA_TYPE,
|
||||
maxLength: val.CHARACTER_MAXIMUM_LENGTH,
|
||||
nullable: val.IS_NULLABLE === 'YES'
|
||||
};
|
||||
return columns;
|
||||
}, {});
|
||||
return column && out[column] || out;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
limit_: function limit_() {
|
||||
var noLimit = !this.single.limit && this.single.limit !== 0;
|
||||
if (noLimit) return '';
|
||||
return 'top (' + this.formatter.parameter(this.single.limit) + ')';
|
||||
},
|
||||
|
||||
limit: function limit() {
|
||||
return '';
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Set the QueryBuilder & QueryCompiler on the client object,
|
||||
// incase anyone wants to modify things to suit their own purposes.
|
||||
module.exports = QueryCompiler_MSSQL;
|
||||
26
lib/dialects/mssql/query/joinclause.js
Normal file
26
lib/dialects/mssql/query/joinclause.js
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
// MSSQL Join Clause
|
||||
// ------
|
||||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
var JoinClause = require('../../../query/joinclause');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function JoinClause_MSSQL(table, type, schema) {
|
||||
JoinClause.call(this, table, type, schema);
|
||||
}
|
||||
inherits(JoinClause_MSSQL, JoinClause);
|
||||
|
||||
assign(JoinClause_MSSQL.prototype, {
|
||||
|
||||
// Adds a "using" clause to the current join.
|
||||
using: function using(column) {
|
||||
return this.clauses.push([this._bool(), 'on', column, '=', column]);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Set the QueryBuilder & QueryCompiler on the client object,
|
||||
// incase anyone wants to modify things to suit their own purposes.
|
||||
module.exports = JoinClause_MSSQL;
|
||||
113
lib/dialects/mssql/schema/columncompiler.js
Normal file
113
lib/dialects/mssql/schema/columncompiler.js
Normal file
@ -0,0 +1,113 @@
|
||||
|
||||
// MySQL Column Compiler
|
||||
// -------
|
||||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
var ColumnCompiler = require('../../../schema/columncompiler');
|
||||
var helpers = require('../../../helpers');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function ColumnCompiler_MSSQL() {
|
||||
ColumnCompiler.apply(this, arguments);
|
||||
this.modifiers = ['nullable', 'defaultTo', 'first', 'after', 'comment'];
|
||||
}
|
||||
inherits(ColumnCompiler_MSSQL, ColumnCompiler);
|
||||
|
||||
// Types
|
||||
// ------
|
||||
|
||||
assign(ColumnCompiler_MSSQL.prototype, {
|
||||
|
||||
increments: 'int identity(1,1) not null primary key',
|
||||
|
||||
bigincrements: 'bigint identity(1,1) not null primary key',
|
||||
|
||||
bigint: 'bigint',
|
||||
|
||||
double: function double(precision, scale) {
|
||||
if (!precision) return 'double';
|
||||
return 'double(' + this._num(precision, 8) + ', ' + this._num(scale, 2) + ')';
|
||||
},
|
||||
|
||||
integer: function integer(length) {
|
||||
length = length ? '(' + this._num(length, 11) + ')' : '';
|
||||
return 'int' + length;
|
||||
},
|
||||
|
||||
mediumint: 'mediumint',
|
||||
|
||||
smallint: 'smallint',
|
||||
|
||||
tinyint: function tinyint(length) {
|
||||
length = length ? '(' + this._num(length, 1) + ')' : '';
|
||||
return 'tinyint' + length;
|
||||
},
|
||||
|
||||
text: function text(column) {
|
||||
switch (column) {
|
||||
case 'medium':
|
||||
case 'mediumtext':
|
||||
return 'mediumtext';
|
||||
case 'long':
|
||||
case 'longtext':
|
||||
return 'longtext';
|
||||
default:
|
||||
return 'text';
|
||||
}
|
||||
},
|
||||
|
||||
mediumtext: function mediumtext() {
|
||||
return this.text('medium');
|
||||
},
|
||||
|
||||
longtext: function longtext() {
|
||||
return this.text('long');
|
||||
},
|
||||
|
||||
enu: function enu(allowed) {
|
||||
return '';
|
||||
},
|
||||
|
||||
datetime: 'datetime',
|
||||
|
||||
timestamp: 'timestamp',
|
||||
|
||||
bit: function bit(length) {
|
||||
return length ? 'bit(' + this._num(length) + ')' : 'bit';
|
||||
},
|
||||
|
||||
binary: function binary(length) {
|
||||
return length ? 'varbinary(' + this._num(length) + ')' : 'blob';
|
||||
},
|
||||
|
||||
// Modifiers
|
||||
// ------
|
||||
|
||||
defaultTo: function defaultTo(value) {
|
||||
/*jshint unused: false*/
|
||||
var defaultVal = ColumnCompiler_MSSQL.super_.prototype.defaultTo.apply(this, arguments);
|
||||
if (this.type !== 'blob' && this.type.indexOf('text') === -1) {
|
||||
return defaultVal;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
first: function first() {
|
||||
return 'first';
|
||||
},
|
||||
|
||||
after: function after(column) {
|
||||
return 'after ' + this.formatter.wrap(column);
|
||||
},
|
||||
|
||||
comment: function comment(_comment) {
|
||||
if (_comment && _comment.length > 255) {
|
||||
helpers.warn('Your comment is longer than the max comment length for MSSQL');
|
||||
}
|
||||
return _comment && "comment '" + _comment + "'";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = ColumnCompiler_MSSQL;
|
||||
53
lib/dialects/mssql/schema/compiler.js
Normal file
53
lib/dialects/mssql/schema/compiler.js
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
// MySQL Schema Compiler
|
||||
// -------
|
||||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
var SchemaCompiler = require('../../../schema/compiler');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function SchemaCompiler_MSSQL(client, builder) {
|
||||
SchemaCompiler.call(this, client, builder);
|
||||
}
|
||||
inherits(SchemaCompiler_MSSQL, SchemaCompiler);
|
||||
|
||||
assign(SchemaCompiler_MSSQL.prototype, {
|
||||
|
||||
dropTableIfExists: function dropTableIfExists(tableName) {
|
||||
var name = this.formatter.wrap(prefixedTableName(this.schema, tableName));
|
||||
this.pushQuery('if object_id(\'' + name + '\', \'U\') is not null drop table ' + name);
|
||||
},
|
||||
|
||||
// Rename a table on the schema.
|
||||
renameTable: function renameTable(tableName, to) {
|
||||
this.pushQuery('rename table ' + this.formatter.wrap(tableName) + ' to ' + this.formatter.wrap(to));
|
||||
},
|
||||
|
||||
// Check whether a table exists on the query.
|
||||
hasTable: function hasTable(tableName) {
|
||||
this.pushQuery({
|
||||
sql: 'SELECT object_id FROM sys.tables WHERE object_id = Object_ID(N\'' + this.formatter.parameter(tableName) + '\')',
|
||||
output: function output(resp) {
|
||||
return resp.length > 0;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Check whether a column exists on the schema.
|
||||
hasColumn: function hasColumn(tableName, column) {
|
||||
this.pushQuery({
|
||||
sql: 'SELECT object_id FROM sys.columns WHERE Name Like ' + this.formatter.parameter(column) + ' AND object_id = Object_ID(N\'' + this.formatter.wrap(tableName) + '\')',
|
||||
output: function output(resp) {
|
||||
return resp.length > 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function prefixedTableName(prefix, table) {
|
||||
return prefix ? prefix + '.' + table : table;
|
||||
}
|
||||
|
||||
module.exports = SchemaCompiler_MSSQL;
|
||||
178
lib/dialects/mssql/schema/tablecompiler.js
Normal file
178
lib/dialects/mssql/schema/tablecompiler.js
Normal file
@ -0,0 +1,178 @@
|
||||
|
||||
// MSSQL Table Builder & Compiler
|
||||
// -------
|
||||
'use strict';
|
||||
|
||||
var inherits = require('inherits');
|
||||
var TableCompiler = require('../../../schema/tablecompiler');
|
||||
var helpers = require('../../../helpers');
|
||||
var Promise = require('../../../promise');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
// Table Compiler
|
||||
// ------
|
||||
|
||||
function TableCompiler_MSSQL() {
|
||||
TableCompiler.apply(this, arguments);
|
||||
}
|
||||
inherits(TableCompiler_MSSQL, TableCompiler);
|
||||
|
||||
assign(TableCompiler_MSSQL.prototype, {
|
||||
|
||||
createQuery: function createQuery(columns, ifNot) {
|
||||
var createStatement = ifNot ? 'if object_id(\'' + this.tableName() + '\', \'U\') is not null create table ' : 'create table ';
|
||||
var client = this.client,
|
||||
conn = {},
|
||||
sql = createStatement + this.tableName() + ' (' + columns.sql.join(', ') + ')';
|
||||
|
||||
// Check if the connection settings are set.
|
||||
if (client.connectionSettings) {
|
||||
conn = client.connectionSettings;
|
||||
}
|
||||
|
||||
var collation = this.single.collate || conn.collate || '';
|
||||
|
||||
// var conn = builder.client.connectionSettings;
|
||||
if (collation) sql += ' collate ' + collation;
|
||||
|
||||
if (this.single.comment) {
|
||||
var comment = this.single.comment || '';
|
||||
if (comment.length > 60) helpers.warn('The max length for a table comment is 60 characters');
|
||||
sql += " comment = '" + comment + "'";
|
||||
}
|
||||
|
||||
this.pushQuery(sql);
|
||||
},
|
||||
|
||||
addColumnsPrefix: 'add ',
|
||||
|
||||
dropColumnPrefix: 'drop ',
|
||||
|
||||
// Compiles the comment on the table.
|
||||
comment: function comment(_comment) {
|
||||
this.pushQuery('alter table ' + this.tableName() + " comment = '" + _comment + "'");
|
||||
},
|
||||
|
||||
changeType: function changeType() {
|
||||
// alter table + table + ' modify ' + wrapped + '// type';
|
||||
},
|
||||
|
||||
// Renames a column on the table.
|
||||
renameColumn: function renameColumn(from, to) {
|
||||
var compiler = this;
|
||||
var table = this.tableName();
|
||||
var wrapped = this.formatter.wrap(from) + ' ' + this.formatter.wrap(to);
|
||||
|
||||
this.pushQuery({
|
||||
sql: 'show fields from ' + table + ' where field = ' + this.formatter.parameter(from),
|
||||
output: function output(resp) {
|
||||
var column = resp[0];
|
||||
var runner = this;
|
||||
return compiler.getFKRefs(runner).get(0).then(function (refs) {
|
||||
return Promise['try'](function () {
|
||||
if (!refs.length) {
|
||||
return;
|
||||
}
|
||||
return compiler.dropFKRefs(runner, refs);
|
||||
}).then(function () {
|
||||
return runner.query({
|
||||
sql: 'alter table ' + table + ' change ' + wrapped + ' ' + column.Type
|
||||
});
|
||||
}).then(function () {
|
||||
if (!refs.length) {
|
||||
return;
|
||||
}
|
||||
return compiler.createFKRefs(runner, refs.map(function (ref) {
|
||||
if (ref.REFERENCED_COLUMN_NAME === from) {
|
||||
ref.REFERENCED_COLUMN_NAME = to;
|
||||
}
|
||||
if (ref.COLUMN_NAME === from) {
|
||||
ref.COLUMN_NAME = to;
|
||||
}
|
||||
return ref;
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getFKRefs: function getFKRefs(runner) {
|
||||
var formatter = this.client.formatter();
|
||||
var sql = 'SELECT KCU.CONSTRAINT_NAME, KCU.TABLE_NAME, KCU.COLUMN_NAME, ' + ' KCU.REFERENCED_TABLE_NAME, KCU.REFERENCED_COLUMN_NAME, ' + ' RC.UPDATE_RULE, RC.DELETE_RULE ' + 'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU ' + 'JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ' + ' USING(CONSTRAINT_NAME)' + 'WHERE KCU.REFERENCED_TABLE_NAME = ' + formatter.parameter(this.tableNameRaw) + ' ' + ' AND KCU.CONSTRAINT_SCHEMA = ' + formatter.parameter(this.client.database()) + ' ' + ' AND RC.CONSTRAINT_SCHEMA = ' + formatter.parameter(this.client.database());
|
||||
|
||||
return runner.query({
|
||||
sql: sql,
|
||||
bindings: formatter.bindings
|
||||
});
|
||||
},
|
||||
|
||||
dropFKRefs: function dropFKRefs(runner, refs) {
|
||||
var formatter = this.client.formatter();
|
||||
|
||||
return Promise.all(refs.map(function (ref) {
|
||||
var constraintName = formatter.wrap(ref.CONSTRAINT_NAME);
|
||||
var tableName = formatter.wrap(ref.TABLE_NAME);
|
||||
return runner.query({
|
||||
sql: 'alter table ' + tableName + ' drop foreign key ' + constraintName
|
||||
});
|
||||
}));
|
||||
},
|
||||
createFKRefs: function createFKRefs(runner, refs) {
|
||||
var formatter = this.client.formatter();
|
||||
|
||||
return Promise.all(refs.map(function (ref) {
|
||||
var tableName = formatter.wrap(ref.TABLE_NAME);
|
||||
var keyName = formatter.wrap(ref.CONSTRAINT_NAME);
|
||||
var column = formatter.columnize(ref.COLUMN_NAME);
|
||||
var references = formatter.columnize(ref.REFERENCED_COLUMN_NAME);
|
||||
var inTable = formatter.wrap(ref.REFERENCED_TABLE_NAME);
|
||||
var onUpdate = ' ON UPDATE ' + ref.UPDATE_RULE;
|
||||
var onDelete = ' ON DELETE ' + ref.DELETE_RULE;
|
||||
|
||||
return runner.query({
|
||||
sql: 'alter table ' + tableName + ' add constraint ' + keyName + ' ' + 'foreign key (' + column + ') references ' + inTable + ' (' + references + ')' + onUpdate + onDelete
|
||||
});
|
||||
}));
|
||||
},
|
||||
index: function index(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('index', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + " add index " + indexName + "(" + this.formatter.columnize(columns) + ")");
|
||||
},
|
||||
|
||||
primary: function primary(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('primary', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + " add primary key " + indexName + "(" + this.formatter.columnize(columns) + ")");
|
||||
},
|
||||
|
||||
unique: function unique(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('unique', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + " add unique " + indexName + "(" + this.formatter.columnize(columns) + ")");
|
||||
},
|
||||
|
||||
// Compile a drop index command.
|
||||
dropIndex: function dropIndex(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('index', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + ' drop index ' + indexName);
|
||||
},
|
||||
|
||||
// Compile a drop foreign key command.
|
||||
dropForeign: function dropForeign(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('foreign', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + ' drop foreign key ' + indexName);
|
||||
},
|
||||
|
||||
// Compile a drop primary key command.
|
||||
dropPrimary: function dropPrimary() {
|
||||
this.pushQuery('alter table ' + this.tableName() + ' drop primary key');
|
||||
},
|
||||
|
||||
// Compile a drop unique key command.
|
||||
dropUnique: function dropUnique(column, indexName) {
|
||||
indexName = indexName || this._indexCommand('unique', this.tableNameRaw, column);
|
||||
this.pushQuery('alter table ' + this.tableName() + ' drop index ' + indexName);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = TableCompiler_MSSQL;
|
||||
39
lib/dialects/mssql/transaction.js
Normal file
39
lib/dialects/mssql/transaction.js
Normal file
@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
var Transaction = require('../../transaction');
|
||||
var assign = require('lodash/object/assign');
|
||||
var inherits = require('inherits');
|
||||
var debug = require('debug')('knex:tx');
|
||||
var helpers = require('../../helpers');
|
||||
|
||||
function Transaction_MSSQL() {
|
||||
Transaction.apply(this, arguments);
|
||||
}
|
||||
inherits(Transaction_MSSQL, Transaction);
|
||||
|
||||
assign(Transaction_MSSQL.prototype, {
|
||||
|
||||
query: function query(conn, sql, status, value) {
|
||||
var t = this;
|
||||
var q = this.trxClient.query(conn, sql)['catch'](function (err) {
|
||||
return err.errno === 1305;
|
||||
}, function () {
|
||||
helpers.warn('Transaction was implicitly committed, do not mix transactions and DDL with MSSQL (#805)');
|
||||
})['catch'](function (err) {
|
||||
status = 2;
|
||||
value = err;
|
||||
t._completed = true;
|
||||
debug('%s error running transaction query', t.txid);
|
||||
}).tap(function () {
|
||||
if (status === 1) t._resolver(value);
|
||||
if (status === 2) t._rejecter(value);
|
||||
});
|
||||
if (status === 1 || status === 2) {
|
||||
t._completed = true;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = Transaction_MSSQL;
|
||||
@ -63,6 +63,8 @@ assign(Client_Oracle.prototype, {
|
||||
return value ? 1 : 0;
|
||||
} else if (Buffer.isBuffer(value)) {
|
||||
return SqlString.bufferToString(value);
|
||||
} else if (value === undefined) {
|
||||
return this.valueForUndefined;
|
||||
}
|
||||
return value;
|
||||
}, this);
|
||||
|
||||
@ -56,8 +56,8 @@ assign(Client_PG.prototype, {
|
||||
// Prep the bindings as needed by PostgreSQL.
|
||||
prepBindings: function prepBindings(bindings, tz) {
|
||||
return _.map(bindings, function (binding) {
|
||||
return utils.prepareValue(binding, tz);
|
||||
});
|
||||
return utils.prepareValue(binding, tz, this.valueForUndefined);
|
||||
}, this);
|
||||
},
|
||||
|
||||
// Get a raw connection, called by the `pool` whenever a new
|
||||
|
||||
@ -29,7 +29,7 @@ var arrayString;
|
||||
// to their 'raw' counterparts for use as a postgres parameter
|
||||
// note: you can override this function to provide your own conversion mechanism
|
||||
// for complex types, etc...
|
||||
var prepareValue = function prepareValue(val, seen) {
|
||||
var prepareValue = function prepareValue(val, seen, valueForUndefined) {
|
||||
if (val instanceof Buffer) {
|
||||
return val;
|
||||
}
|
||||
@ -39,9 +39,12 @@ var prepareValue = function prepareValue(val, seen) {
|
||||
if (Array.isArray(val)) {
|
||||
return arrayString(val);
|
||||
}
|
||||
if (val === null || val === undefined) {
|
||||
if (val === null) {
|
||||
return null;
|
||||
}
|
||||
if (val === undefined) {
|
||||
return valueForUndefined;
|
||||
}
|
||||
if (typeof val === 'object') {
|
||||
return prepareObject(val, seen);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// -------
|
||||
'use strict';
|
||||
|
||||
var _ = require('lodash');
|
||||
var Promise = require('../../promise');
|
||||
|
||||
var inherits = require('inherits');
|
||||
@ -20,6 +21,9 @@ var SQLite3_DDL = require('./schema/ddl');
|
||||
|
||||
function Client_SQLite3(config) {
|
||||
Client.call(this, config);
|
||||
if (_.isUndefined(config.useNullAsDefault)) {
|
||||
helpers.warn('sqlite does not support inserting default values. Set the `useNullAsDefault` flag to hide this warning. (see docs http://knexjs.org/#Builder-insert).');
|
||||
}
|
||||
}
|
||||
inherits(Client_SQLite3, Client);
|
||||
|
||||
@ -110,6 +114,16 @@ assign(Client_SQLite3.prototype, {
|
||||
});
|
||||
},
|
||||
|
||||
prepBindings: function prepBindings(bindings) {
|
||||
return _.map(bindings, function (binding) {
|
||||
if (binding === undefined && this.valueForUndefined !== null) {
|
||||
throw new TypeError("`sqlite` does not support inserting default values. Specify values explicitly or use the `useNullAsDefault` config flag. (see docs http://knexjs.org/#Builder-insert).");
|
||||
} else {
|
||||
return binding;
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
// Ensures the response is returned in the same format as other clients.
|
||||
processResponse: function processResponse(obj, runner) {
|
||||
var ctx = obj.context;
|
||||
|
||||
@ -57,6 +57,7 @@ assign(Formatter.prototype, {
|
||||
return this.outputQuery(query, isParameter);
|
||||
}
|
||||
if (value instanceof Raw) {
|
||||
value.client = this.client;
|
||||
query = value.toSQL();
|
||||
if (query.bindings) {
|
||||
this.bindings = this.bindings.concat(query.bindings);
|
||||
|
||||
@ -105,12 +105,12 @@ assign(Builder.prototype, {
|
||||
var schema = this._single.schema;
|
||||
var joinType = this._joinType();
|
||||
if (typeof first === 'function') {
|
||||
join = new JoinClause(table, joinType, schema);
|
||||
join = new JoinClause(this, table, joinType, schema);
|
||||
first.call(join, join);
|
||||
} else if (joinType === 'raw') {
|
||||
join = new JoinClause(this.client.raw(table, first), 'raw');
|
||||
join = new JoinClause(this, this.client.raw(table, first), 'raw');
|
||||
} else {
|
||||
join = new JoinClause(table, joinType, schema);
|
||||
join = new JoinClause(this, table, joinType, schema);
|
||||
if (arguments.length > 1) {
|
||||
join.on.apply(join, _.toArray(arguments).slice(1));
|
||||
}
|
||||
|
||||
@ -7,7 +7,8 @@ var assign = require('lodash/object/assign');
|
||||
|
||||
// The "JoinClause" is an object holding any necessary info about a join,
|
||||
// including the type, and any associated tables & columns being joined.
|
||||
function JoinClause(table, type, schema) {
|
||||
function JoinClause(builder, table, type, schema) {
|
||||
this.builder = builder;
|
||||
this.schema = schema;
|
||||
this.table = table;
|
||||
this.joinType = type;
|
||||
@ -50,7 +51,8 @@ assign(JoinClause.prototype, {
|
||||
|
||||
// Adds a "using" clause to the current join.
|
||||
using: function using(column) {
|
||||
return this.clauses.push([this._bool(), 'using', column]);
|
||||
//return this.clauses.push([this._bool(), 'using', column]);
|
||||
return this.clauses.push([this._bool(), 'on', column, '=', column]);
|
||||
},
|
||||
|
||||
// Adds an "and on" clause to the current join object.
|
||||
|
||||
@ -4,7 +4,11 @@ var SqlString = exports;
|
||||
var helpers = require('../helpers');
|
||||
|
||||
SqlString.escape = function (val, timeZone) {
|
||||
if (val == null) {
|
||||
// Cant do require on top of file beacuse Raw is not yet initialized when this file is
|
||||
// executed for the first time
|
||||
var Raw = require('../raw');
|
||||
|
||||
if (val === null || val === undefined) {
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
@ -27,6 +31,10 @@ SqlString.escape = function (val, timeZone) {
|
||||
return SqlString.arrayToList(val, timeZone);
|
||||
}
|
||||
|
||||
if (val instanceof Raw) {
|
||||
return val;
|
||||
}
|
||||
|
||||
if (typeof val === 'object') {
|
||||
try {
|
||||
val = JSON.stringify(val);
|
||||
@ -36,7 +44,7 @@ SqlString.escape = function (val, timeZone) {
|
||||
}
|
||||
}
|
||||
|
||||
val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function (s) {
|
||||
val = val.replace(/(\\\?)|[\0\n\r\b\t\\\'\"\x1a]/g, function (s) {
|
||||
switch (s) {
|
||||
case "\0":
|
||||
return "\\0";
|
||||
@ -50,6 +58,8 @@ SqlString.escape = function (val, timeZone) {
|
||||
return "\\t";
|
||||
case "\x1a":
|
||||
return "\\Z";
|
||||
case "\\?":
|
||||
return "?";
|
||||
default:
|
||||
return "\\" + s;
|
||||
}
|
||||
@ -67,13 +77,14 @@ SqlString.arrayToList = function (array, timeZone) {
|
||||
SqlString.format = function (sql, values, timeZone) {
|
||||
values = values == null ? [] : [].concat(values);
|
||||
var index = 0;
|
||||
return sql.replace(/\?/g, function (match) {
|
||||
return sql.replace(/\\?\?/g, function (match) {
|
||||
if (match === '\\?') return match;
|
||||
if (index === values.length) {
|
||||
return match;
|
||||
}
|
||||
var value = values[index++];
|
||||
return SqlString.escape(value, timeZone);
|
||||
});
|
||||
}).replace('\\?', '?');
|
||||
};
|
||||
|
||||
SqlString.dateToString = function (date, timeZone) {
|
||||
|
||||
@ -78,7 +78,11 @@ function replaceRawArrBindings(raw) {
|
||||
var index = 0;
|
||||
var bindings = [];
|
||||
|
||||
var sql = raw.sql.replace(/\?\??/g, function (match) {
|
||||
var sql = raw.sql.replace(/\\?\?\??/g, function (match) {
|
||||
if (match === '\\?') {
|
||||
return match;
|
||||
}
|
||||
|
||||
var value = values[index++];
|
||||
|
||||
if (value && typeof value.toSQL === 'function') {
|
||||
|
||||
@ -26,7 +26,6 @@ assign(Runner.prototype, {
|
||||
// a single connection.
|
||||
run: function run() {
|
||||
var runner = this;
|
||||
|
||||
return Promise.using(this.ensureConnection(), function (connection) {
|
||||
runner.connection = connection;
|
||||
|
||||
|
||||
@ -7,6 +7,6 @@ exports.seed = function(knex, Promise) {
|
||||
// Inserts seed entries
|
||||
knex('table_name').insert({id: 1, colName: 'rowValue'}),
|
||||
knex('table_name').insert({id: 2, colName: 'rowValue2'}),
|
||||
knex('table_name').insert({id: 3, colName: 'rowValue3'}),
|
||||
knex('table_name').insert({id: 3, colName: 'rowValue3'})
|
||||
);
|
||||
};
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
"jshint": "^2.7.0",
|
||||
"mariasql": "^0.2.3",
|
||||
"mocha": "^2.2.4",
|
||||
"mssql": "^2.3.2",
|
||||
"mysql": "^2.6.2",
|
||||
"mysql2": "^0.15.5",
|
||||
"node-uuid": "~1.4.0",
|
||||
@ -67,7 +68,8 @@
|
||||
"mysql",
|
||||
"mariadb",
|
||||
"sqlite3",
|
||||
"oracle"
|
||||
"oracle",
|
||||
"mssql"
|
||||
],
|
||||
"author": {
|
||||
"name": "Tim Griesser",
|
||||
|
||||
169
src/dialects/mssql/index.js
Normal file
169
src/dialects/mssql/index.js
Normal file
@ -0,0 +1,169 @@
|
||||
|
||||
// MSSQL Client
|
||||
// -------
|
||||
var _ = require('lodash')
|
||||
var inherits = require('inherits')
|
||||
var assign = require('lodash/object/assign')
|
||||
|
||||
var Client = require('../../client')
|
||||
var Promise = require('../../promise')
|
||||
var helpers = require('../../helpers')
|
||||
|
||||
var Transaction = require('./transaction')
|
||||
var QueryCompiler = require('./query/compiler')
|
||||
var JoinClause = require('./query/joinclause')
|
||||
var SchemaCompiler = require('./schema/compiler')
|
||||
var TableCompiler = require('./schema/tablecompiler')
|
||||
var ColumnCompiler = require('./schema/columncompiler')
|
||||
var pluck = require('lodash/collection/pluck')
|
||||
|
||||
// Always initialize with the "QueryBuilder" and "QueryCompiler"
|
||||
// objects, which extend the base 'lib/query/builder' and
|
||||
// 'lib/query/compiler', respectively.
|
||||
function Client_MSSQL(config) {
|
||||
Client.call(this, config);
|
||||
}
|
||||
inherits(Client_MSSQL, Client);
|
||||
|
||||
assign(Client_MSSQL.prototype, {
|
||||
|
||||
dialect: 'mssql',
|
||||
|
||||
driverName: 'mssql',
|
||||
|
||||
_driver: function() {
|
||||
return require('mssql');
|
||||
},
|
||||
|
||||
QueryCompiler: QueryCompiler,
|
||||
|
||||
JoinClause: JoinClause,
|
||||
|
||||
SchemaCompiler: SchemaCompiler,
|
||||
|
||||
TableCompiler: TableCompiler,
|
||||
|
||||
ColumnCompiler: ColumnCompiler,
|
||||
|
||||
//Transaction: Transaction,
|
||||
|
||||
wrapIdentifier: function(value) {
|
||||
return (value !== '*' ? '[' + value.replace(/\[/g, '\[') + ']' : '*')
|
||||
},
|
||||
|
||||
// Get a raw connection, called by the `pool` whenever a new
|
||||
// connection needs to be added to the pool.
|
||||
acquireRawConnection: function() {
|
||||
var client = this;
|
||||
var connection = new this.driver.Connection(this.connectionSettings);
|
||||
return new Promise(function(resolver, rejecter) {
|
||||
connection.connect(function(err) {
|
||||
if (err) return rejecter(err);
|
||||
connection.on('error', connectionErrorHandler.bind(null, client, connection));
|
||||
connection.on('end', connectionErrorHandler.bind(null, client, connection));
|
||||
resolver(connection);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Used to explicitly close a connection, called internally by the pool
|
||||
// when a connection times out or the pool is shutdown.
|
||||
destroyRawConnection: function(connection, cb) {
|
||||
connection.close(cb);
|
||||
},
|
||||
|
||||
// Position the bindings for the query.
|
||||
positionBindings: function(sql) {
|
||||
var questionCount = 0
|
||||
return sql.replace(/\?/g, function() {
|
||||
questionCount += 1
|
||||
return '@p' + questionCount
|
||||
})
|
||||
},
|
||||
|
||||
prepBindings: function(bindings) {
|
||||
return _.map(bindings, function(value) {
|
||||
if (value === undefined) {
|
||||
return this.valueForUndefined
|
||||
}
|
||||
return value
|
||||
}, this)
|
||||
},
|
||||
|
||||
// Grab a connection, run the query via the MSSQL streaming interface,
|
||||
// and pass that through to the stream we've sent back to the client.
|
||||
_stream: function(connection, obj, stream, options) {
|
||||
options = options || {}
|
||||
return new Promise(function(resolver, rejecter) {
|
||||
stream.on('error', rejecter)
|
||||
stream.on('end', resolver)
|
||||
connection.query(obj.sql, obj.bindings).stream(options).pipe(stream)
|
||||
})
|
||||
},
|
||||
|
||||
// Runs the query on the specified connection, providing the bindings
|
||||
// and any other necessary prep work.
|
||||
_query: function(connection, obj) {
|
||||
if (!obj || typeof obj === 'string') obj = {sql: obj}
|
||||
// convert ? params into positional bindings (@p1)
|
||||
obj.sql = this.positionBindings(obj.sql);
|
||||
obj.bindings = this.prepBindings(obj.bindings) || [];
|
||||
return new Promise(function(resolver, rejecter) {
|
||||
var sql = obj.sql
|
||||
if (!sql) return resolver()
|
||||
if (obj.options) sql = assign({sql: sql}, obj.options)
|
||||
var req = connection.request();
|
||||
//request.multiple = true;
|
||||
if (obj.bindings) {
|
||||
for (var i = 1; i <= obj.bindings.length; i++) {
|
||||
req.input('p' + i, obj.bindings[i])
|
||||
//console.log('p' + i, obj.bindings[i]);
|
||||
}
|
||||
}
|
||||
req.query(sql, function(err, recordset) {
|
||||
if (err) return rejecter(err)
|
||||
obj.response = recordset
|
||||
resolver(obj)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// Process the response as returned from the query.
|
||||
processResponse: function(obj, runner) {
|
||||
if (obj == null) return;
|
||||
var response = obj.response
|
||||
var method = obj.method
|
||||
var recordset = response
|
||||
if (obj.output) return obj.output.call(runner, recordset)
|
||||
console.log('method: ' + method);
|
||||
console.log(recordset);
|
||||
switch (method) {
|
||||
case 'select':
|
||||
case 'pluck':
|
||||
case 'first':
|
||||
var resp = helpers.skim(recordset)
|
||||
if (method === 'pluck') return pluck(resp, obj.pluck)
|
||||
return method === 'first' ? resp[0] : resp
|
||||
case 'insert':
|
||||
return [recordset.insertId]
|
||||
case 'del':
|
||||
case 'update':
|
||||
case 'counter':
|
||||
return recordset.affectedRows
|
||||
default:
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// MSSQL Specific error handler
|
||||
function connectionErrorHandler(client, connection, err) {
|
||||
if (connection && err && err.fatal) {
|
||||
if (connection.__knex__disposed) return;
|
||||
connection.__knex__disposed = true;
|
||||
client.pool.destroy(connection);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Client_MSSQL
|
||||
19
src/dialects/mssql/query/builder.js
Normal file
19
src/dialects/mssql/query/builder.js
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
// MSSQL Query Builder
|
||||
// ------
|
||||
var inherits = require('inherits')
|
||||
var QueryBuilder = require('../../../query/bulder')
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function QueryBuilder_MSSQL(client) {
|
||||
QueryBuilder.call(this, client)
|
||||
}
|
||||
inherits(QueryBuilder_MSSQL, QueryBuilder)
|
||||
|
||||
assign(QueryBuilder_MSSQL.prototype, {
|
||||
|
||||
})
|
||||
|
||||
// Set the QueryBuilder & QueryCompiler on the client object,
|
||||
// incase anyone wants to modify things to suit their own purposes.
|
||||
module.exports = QueryBuilder_MSSQL;
|
||||
104
src/dialects/mssql/query/compiler.js
Normal file
104
src/dialects/mssql/query/compiler.js
Normal file
@ -0,0 +1,104 @@
|
||||
|
||||
// MSSQL Query Compiler
|
||||
// ------
|
||||
var inherits = require('inherits')
|
||||
var QueryCompiler = require('../../../query/compiler')
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function QueryCompiler_MSSQL(client, builder) {
|
||||
QueryCompiler.call(this, client, builder)
|
||||
}
|
||||
inherits(QueryCompiler_MSSQL, QueryCompiler)
|
||||
|
||||
assign(QueryCompiler_MSSQL.prototype, {
|
||||
|
||||
_emptyInsertValue: '() values ()',
|
||||
|
||||
// Update method, including joins, wheres, order & limits.
|
||||
update: function() {
|
||||
var join = this.join();
|
||||
var updates = this._prepUpdate(this.single.update);
|
||||
var where = this.where();
|
||||
var order = this.order();
|
||||
var limit = this.limit_();
|
||||
return 'update ' + (limit ? limit + ' ' : '') + this.tableName +
|
||||
(join ? ' ' + join : '') +
|
||||
' set ' + updates.join(', ') +
|
||||
(where ? ' ' + where : '') +
|
||||
(order ? ' ' + order : '');
|
||||
},
|
||||
|
||||
// Compiles the columns in the query, specifying if an item was distinct.
|
||||
columns: function() {
|
||||
var distinct = false;
|
||||
if (this.onlyUnions()) return ''
|
||||
var columns = this.grouped.columns || []
|
||||
var i = -1, sql = [];
|
||||
if (columns) {
|
||||
while (++i < columns.length) {
|
||||
var stmt = columns[i];
|
||||
if (stmt.distinct) distinct = true
|
||||
if (stmt.type === 'aggregate') {
|
||||
sql.push(this.aggregate(stmt))
|
||||
}
|
||||
else if (stmt.value && stmt.value.length > 0) {
|
||||
sql.push(this.formatter.columnize(stmt.value))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sql.length === 0) sql = ['*'];
|
||||
var limit = this.limit_();
|
||||
return 'select ' + (distinct ? 'distinct ' : '') +
|
||||
(limit ? limit + ' ' : '') +
|
||||
sql.join(', ') + (this.tableName ? ' from ' + this.tableName : '');
|
||||
},
|
||||
|
||||
// Compiles a `truncate` query.
|
||||
truncate: function() {
|
||||
return 'truncate table ' + this.tableName;
|
||||
},
|
||||
|
||||
forUpdate: function() {
|
||||
return 'with (READCOMMITTEDLOCK)';
|
||||
},
|
||||
|
||||
forShare: function() {
|
||||
return 'with (NOLOCK)';
|
||||
},
|
||||
|
||||
// Compiles a `columnInfo` query.
|
||||
columnInfo: function() {
|
||||
var column = this.single.columnInfo;
|
||||
return {
|
||||
sql: 'select * from information_schema.columns where table_name = ? and table_schema = ?',
|
||||
bindings: [this.single.table, this.client.database()],
|
||||
output: function(resp) {
|
||||
var out = resp.reduce(function(columns, val) {
|
||||
columns[val.COLUMN_NAME] = {
|
||||
defaultValue: val.COLUMN_DEFAULT,
|
||||
type: val.DATA_TYPE,
|
||||
maxLength: val.CHARACTER_MAXIMUM_LENGTH,
|
||||
nullable: (val.IS_NULLABLE === 'YES')
|
||||
};
|
||||
return columns
|
||||
}, {})
|
||||
return column && out[column] || out;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
limit_: function() {
|
||||
var noLimit = !this.single.limit && this.single.limit !== 0;
|
||||
if (noLimit) return '';
|
||||
return 'top (' + this.formatter.parameter(this.single.limit) + ')';
|
||||
},
|
||||
|
||||
limit: function() {
|
||||
return '';
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// Set the QueryBuilder & QueryCompiler on the client object,
|
||||
// incase anyone wants to modify things to suit their own purposes.
|
||||
module.exports = QueryCompiler_MSSQL;
|
||||
24
src/dialects/mssql/query/joinclause.js
Normal file
24
src/dialects/mssql/query/joinclause.js
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
// MSSQL Join Clause
|
||||
// ------
|
||||
var inherits = require('inherits')
|
||||
var JoinClause = require('../../../query/joinclause')
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function JoinClause_MSSQL(table, type, schema) {
|
||||
JoinClause.call(this, table, type, schema)
|
||||
}
|
||||
inherits(JoinClause_MSSQL, JoinClause)
|
||||
|
||||
assign(JoinClause_MSSQL.prototype, {
|
||||
|
||||
// Adds a "using" clause to the current join.
|
||||
using: function(column) {
|
||||
return this.clauses.push([this._bool(), 'on', column, '=', column]);
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
// Set the QueryBuilder & QueryCompiler on the client object,
|
||||
// incase anyone wants to modify things to suit their own purposes.
|
||||
module.exports = JoinClause_MSSQL;
|
||||
111
src/dialects/mssql/schema/columncompiler.js
Normal file
111
src/dialects/mssql/schema/columncompiler.js
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
// MySQL Column Compiler
|
||||
// -------
|
||||
var inherits = require('inherits')
|
||||
var ColumnCompiler = require('../../../schema/columncompiler')
|
||||
var helpers = require('../../../helpers')
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function ColumnCompiler_MSSQL() {
|
||||
ColumnCompiler.apply(this, arguments);
|
||||
this.modifiers = ['nullable', 'defaultTo', 'first', 'after', 'comment']
|
||||
}
|
||||
inherits(ColumnCompiler_MSSQL, ColumnCompiler);
|
||||
|
||||
// Types
|
||||
// ------
|
||||
|
||||
assign(ColumnCompiler_MSSQL.prototype, {
|
||||
|
||||
increments: 'int identity(1,1) not null primary key',
|
||||
|
||||
bigincrements: 'bigint identity(1,1) not null primary key',
|
||||
|
||||
bigint: 'bigint',
|
||||
|
||||
double: function(precision, scale) {
|
||||
if (!precision) return 'double'
|
||||
return 'double(' + this._num(precision, 8) + ', ' + this._num(scale, 2) + ')'
|
||||
},
|
||||
|
||||
integer: function(length) {
|
||||
length = length ? '(' + this._num(length, 11) + ')' : ''
|
||||
return 'int' + length
|
||||
},
|
||||
|
||||
mediumint: 'mediumint',
|
||||
|
||||
smallint: 'smallint',
|
||||
|
||||
tinyint: function(length) {
|
||||
length = length ? '(' + this._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')
|
||||
},
|
||||
|
||||
enu: function(allowed) {
|
||||
return ''
|
||||
},
|
||||
|
||||
datetime: 'datetime',
|
||||
|
||||
timestamp: 'timestamp',
|
||||
|
||||
bit: function(length) {
|
||||
return length ? 'bit(' + this._num(length) + ')' : 'bit'
|
||||
},
|
||||
|
||||
binary: function(length) {
|
||||
return length ? 'varbinary(' + this._num(length) + ')' : 'blob'
|
||||
},
|
||||
|
||||
// Modifiers
|
||||
// ------
|
||||
|
||||
defaultTo: function(value) {
|
||||
/*jshint unused: false*/
|
||||
var defaultVal = ColumnCompiler_MSSQL.super_.prototype.defaultTo.apply(this, arguments);
|
||||
if (this.type !== 'blob' && this.type.indexOf('text') === -1) {
|
||||
return defaultVal
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
first: function() {
|
||||
return 'first'
|
||||
},
|
||||
|
||||
after: function(column) {
|
||||
return 'after ' + this.formatter.wrap(column)
|
||||
},
|
||||
|
||||
comment: function(comment) {
|
||||
if (comment && comment.length > 255) {
|
||||
helpers.warn('Your comment is longer than the max comment length for MSSQL')
|
||||
}
|
||||
return comment && "comment '" + comment + "'"
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
module.exports = ColumnCompiler_MSSQL;
|
||||
52
src/dialects/mssql/schema/compiler.js
Normal file
52
src/dialects/mssql/schema/compiler.js
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
// MySQL Schema Compiler
|
||||
// -------
|
||||
var inherits = require('inherits');
|
||||
var SchemaCompiler = require('../../../schema/compiler');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
function SchemaCompiler_MSSQL(client, builder) {
|
||||
SchemaCompiler.call(this, client, builder)
|
||||
}
|
||||
inherits(SchemaCompiler_MSSQL, SchemaCompiler)
|
||||
|
||||
assign(SchemaCompiler_MSSQL.prototype, {
|
||||
|
||||
dropTableIfExists: function(tableName) {
|
||||
var name = this.formatter.wrap(prefixedTableName(this.schema, tableName));
|
||||
this.pushQuery('if object_id(\'' + name +'\', \'U\') is not null drop table ' + name);
|
||||
},
|
||||
|
||||
// Rename a table on the schema.
|
||||
renameTable: function(tableName, to) {
|
||||
this.pushQuery('rename table ' + this.formatter.wrap(tableName) + ' to ' + this.formatter.wrap(to));
|
||||
},
|
||||
|
||||
// Check whether a table exists on the query.
|
||||
hasTable: function(tableName) {
|
||||
this.pushQuery({
|
||||
sql: 'SELECT object_id FROM sys.tables WHERE object_id = Object_ID(N\'' + this.formatter.parameter(tableName) + '\')',
|
||||
output: function(resp) {
|
||||
return resp.length > 0;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Check whether a column exists on the schema.
|
||||
hasColumn: function(tableName, column) {
|
||||
this.pushQuery({
|
||||
sql: 'SELECT object_id FROM sys.columns WHERE Name Like ' + this.formatter.parameter(column) +
|
||||
' AND object_id = Object_ID(N\'' + this.formatter.wrap(tableName) + '\')',
|
||||
output: function(resp) {
|
||||
return resp.length > 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
function prefixedTableName(prefix, table) {
|
||||
return prefix ? `${prefix}.${table}` : table;
|
||||
}
|
||||
|
||||
module.exports = SchemaCompiler_MSSQL;
|
||||
182
src/dialects/mssql/schema/tablecompiler.js
Normal file
182
src/dialects/mssql/schema/tablecompiler.js
Normal file
@ -0,0 +1,182 @@
|
||||
|
||||
// MSSQL Table Builder & Compiler
|
||||
// -------
|
||||
var inherits = require('inherits');
|
||||
var TableCompiler = require('../../../schema/tablecompiler');
|
||||
var helpers = require('../../../helpers');
|
||||
var Promise = require('../../../promise');
|
||||
var assign = require('lodash/object/assign');
|
||||
|
||||
// Table Compiler
|
||||
// ------
|
||||
|
||||
function TableCompiler_MSSQL() {
|
||||
TableCompiler.apply(this, arguments);
|
||||
}
|
||||
inherits(TableCompiler_MSSQL, TableCompiler);
|
||||
|
||||
assign(TableCompiler_MSSQL.prototype, {
|
||||
|
||||
createQuery: function(columns, ifNot) {
|
||||
var createStatement = ifNot ? 'if object_id(\'' + this.tableName() +'\', \'U\') is not null create table ' : 'create table ';
|
||||
var client = this.client, conn = {},
|
||||
sql = createStatement + this.tableName() + ' (' + columns.sql.join(', ') + ')';
|
||||
|
||||
// Check if the connection settings are set.
|
||||
if (client.connectionSettings) {
|
||||
conn = client.connectionSettings;
|
||||
}
|
||||
|
||||
var collation = this.single.collate || conn.collate || '';
|
||||
|
||||
// var conn = builder.client.connectionSettings;
|
||||
if (collation) sql += ' collate ' + collation;
|
||||
|
||||
if (this.single.comment) {
|
||||
var comment = (this.single.comment || '');
|
||||
if (comment.length > 60) helpers.warn('The max length for a table comment is 60 characters');
|
||||
sql += " comment = '" + comment + "'";
|
||||
}
|
||||
|
||||
this.pushQuery(sql);
|
||||
},
|
||||
|
||||
addColumnsPrefix: 'add ',
|
||||
|
||||
dropColumnPrefix: 'drop ',
|
||||
|
||||
// Compiles the comment on the table.
|
||||
comment: function(comment) {
|
||||
this.pushQuery('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 compiler = this;
|
||||
var table = this.tableName();
|
||||
var wrapped = this.formatter.wrap(from) + ' ' + this.formatter.wrap(to);
|
||||
|
||||
this.pushQuery({
|
||||
sql: 'show fields from ' + table + ' where field = ' +
|
||||
this.formatter.parameter(from),
|
||||
output: function(resp) {
|
||||
var column = resp[0];
|
||||
var runner = this;
|
||||
return compiler.getFKRefs(runner).get(0)
|
||||
.then(function (refs) {
|
||||
return Promise.try(function () {
|
||||
if (!refs.length) { return; }
|
||||
return compiler.dropFKRefs(runner, refs);
|
||||
}).then(function () {
|
||||
return runner.query({
|
||||
sql: 'alter table ' + table + ' change ' + wrapped + ' ' + column.Type
|
||||
});
|
||||
}).then(function () {
|
||||
if (!refs.length) { return; }
|
||||
return compiler.createFKRefs(runner, refs.map(function (ref) {
|
||||
if (ref.REFERENCED_COLUMN_NAME === from) {
|
||||
ref.REFERENCED_COLUMN_NAME = to;
|
||||
}
|
||||
if (ref.COLUMN_NAME === from) {
|
||||
ref.COLUMN_NAME = to;
|
||||
}
|
||||
return ref;
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getFKRefs: function (runner) {
|
||||
var formatter = this.client.formatter();
|
||||
var sql = 'SELECT KCU.CONSTRAINT_NAME, KCU.TABLE_NAME, KCU.COLUMN_NAME, '+
|
||||
' KCU.REFERENCED_TABLE_NAME, KCU.REFERENCED_COLUMN_NAME, '+
|
||||
' RC.UPDATE_RULE, RC.DELETE_RULE '+
|
||||
'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU '+
|
||||
'JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC '+
|
||||
' USING(CONSTRAINT_NAME)' +
|
||||
'WHERE KCU.REFERENCED_TABLE_NAME = ' + formatter.parameter(this.tableNameRaw) + ' '+
|
||||
' AND KCU.CONSTRAINT_SCHEMA = ' + formatter.parameter(this.client.database()) + ' '+
|
||||
' AND RC.CONSTRAINT_SCHEMA = ' + formatter.parameter(this.client.database());
|
||||
|
||||
return runner.query({
|
||||
sql: sql,
|
||||
bindings: formatter.bindings
|
||||
});
|
||||
},
|
||||
|
||||
dropFKRefs: function (runner, refs) {
|
||||
var formatter = this.client.formatter();
|
||||
|
||||
return Promise.all(refs.map(function (ref) {
|
||||
var constraintName = formatter.wrap(ref.CONSTRAINT_NAME);
|
||||
var tableName = formatter.wrap(ref.TABLE_NAME);
|
||||
return runner.query({
|
||||
sql: 'alter table ' + tableName + ' drop foreign key ' + constraintName
|
||||
});
|
||||
}));
|
||||
},
|
||||
createFKRefs: function (runner, refs) {
|
||||
var formatter = this.client.formatter();
|
||||
|
||||
return Promise.all(refs.map(function (ref) {
|
||||
var tableName = formatter.wrap(ref.TABLE_NAME);
|
||||
var keyName = formatter.wrap(ref.CONSTRAINT_NAME);
|
||||
var column = formatter.columnize(ref.COLUMN_NAME);
|
||||
var references = formatter.columnize(ref.REFERENCED_COLUMN_NAME);
|
||||
var inTable = formatter.wrap(ref.REFERENCED_TABLE_NAME);
|
||||
var onUpdate = ' ON UPDATE ' + ref.UPDATE_RULE;
|
||||
var onDelete = ' ON DELETE ' + ref.DELETE_RULE;
|
||||
|
||||
return runner.query({
|
||||
sql: 'alter table ' + tableName + ' add constraint ' + keyName + ' ' +
|
||||
'foreign key (' + column + ') references ' + inTable + ' (' + references + ')' + onUpdate + onDelete
|
||||
});
|
||||
}));
|
||||
},
|
||||
index: function(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('index', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + " add index " + indexName + "(" + this.formatter.columnize(columns) + ")");
|
||||
},
|
||||
|
||||
primary: function(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('primary', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + " add primary key " + indexName + "(" + this.formatter.columnize(columns) + ")");
|
||||
},
|
||||
|
||||
unique: function(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('unique', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + " add unique " + indexName + "(" + this.formatter.columnize(columns) + ")");
|
||||
},
|
||||
|
||||
// Compile a drop index command.
|
||||
dropIndex: function(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('index', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + ' drop index ' + indexName);
|
||||
},
|
||||
|
||||
// Compile a drop foreign key command.
|
||||
dropForeign: function(columns, indexName) {
|
||||
indexName = indexName || this._indexCommand('foreign', this.tableNameRaw, columns);
|
||||
this.pushQuery('alter table ' + this.tableName() + ' drop foreign key ' + indexName);
|
||||
},
|
||||
|
||||
// Compile a drop primary key command.
|
||||
dropPrimary: function() {
|
||||
this.pushQuery('alter table ' + this.tableName() + ' drop primary key');
|
||||
},
|
||||
|
||||
// Compile a drop unique key command.
|
||||
dropUnique: function(column, indexName) {
|
||||
indexName = indexName || this._indexCommand('unique', this.tableNameRaw, column);
|
||||
this.pushQuery('alter table ' + this.tableName() + ' drop index ' + indexName);
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
module.exports = TableCompiler_MSSQL;
|
||||
41
src/dialects/mssql/transaction.js
Normal file
41
src/dialects/mssql/transaction.js
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
var Transaction = require('../../transaction')
|
||||
var assign = require('lodash/object/assign');
|
||||
var inherits = require('inherits')
|
||||
var debug = require('debug')('knex:tx')
|
||||
var helpers = require('../../helpers')
|
||||
|
||||
function Transaction_MSSQL() {
|
||||
Transaction.apply(this, arguments)
|
||||
}
|
||||
inherits(Transaction_MSSQL, Transaction)
|
||||
|
||||
assign(Transaction_MSSQL.prototype, {
|
||||
|
||||
query: function(conn, sql, status, value) {
|
||||
var t = this
|
||||
var q = this.trxClient.query(conn, sql)
|
||||
.catch(function(err) {
|
||||
return err.errno === 1305
|
||||
}, function() {
|
||||
helpers.warn('Transaction was implicitly committed, do not mix transactions and DDL with MSSQL (#805)')
|
||||
})
|
||||
.catch(function(err) {
|
||||
status = 2
|
||||
value = err
|
||||
t._completed = true
|
||||
debug('%s error running transaction query', t.txid)
|
||||
})
|
||||
.tap(function() {
|
||||
if (status === 1) t._resolver(value)
|
||||
if (status === 2) t._rejecter(value)
|
||||
})
|
||||
if (status === 1 || status === 2) {
|
||||
t._completed = true
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
module.exports = Transaction_MSSQL
|
||||
@ -103,12 +103,12 @@ assign(Builder.prototype, {
|
||||
var schema = this._single.schema;
|
||||
var joinType = this._joinType();
|
||||
if (typeof first === 'function') {
|
||||
join = new JoinClause(table, joinType, schema);
|
||||
join = new JoinClause(this, table, joinType, schema);
|
||||
first.call(join, join);
|
||||
} else if (joinType === 'raw') {
|
||||
join = new JoinClause(this.client.raw(table, first), 'raw');
|
||||
join = new JoinClause(this, this.client.raw(table, first), 'raw');
|
||||
} else {
|
||||
join = new JoinClause(table, joinType, schema);
|
||||
join = new JoinClause(this, table, joinType, schema);
|
||||
if (arguments.length > 1) {
|
||||
join.on.apply(join, _.toArray(arguments).slice(1));
|
||||
}
|
||||
|
||||
@ -6,7 +6,8 @@ var assign = require('lodash/object/assign');
|
||||
|
||||
// The "JoinClause" is an object holding any necessary info about a join,
|
||||
// including the type, and any associated tables & columns being joined.
|
||||
function JoinClause(table, type, schema) {
|
||||
function JoinClause(builder, table, type, schema) {
|
||||
this.builder = builder;
|
||||
this.schema = schema;
|
||||
this.table = table;
|
||||
this.joinType = type;
|
||||
@ -45,6 +46,7 @@ assign(JoinClause.prototype, {
|
||||
// Adds a "using" clause to the current join.
|
||||
using: function(column) {
|
||||
return this.clauses.push([this._bool(), 'using', column]);
|
||||
//return this.clauses.push([this._bool(), 'on', column, '=', column]);
|
||||
},
|
||||
|
||||
// Adds an "and on" clause to the current join object.
|
||||
|
||||
@ -25,7 +25,6 @@ assign(Runner.prototype, {
|
||||
// a single connection.
|
||||
run: function() {
|
||||
var runner = this
|
||||
|
||||
return Promise.using(this.ensureConnection(), function(connection) {
|
||||
runner.connection = connection;
|
||||
|
||||
|
||||
@ -23,8 +23,9 @@ describe('Query Building Tests', function() {
|
||||
require('./unit/schema/postgres')
|
||||
require('./unit/schema/sqlite3')
|
||||
require('./unit/schema/oracle')
|
||||
require('./unit/schema/mssql')
|
||||
})
|
||||
|
||||
describe('Integration Tests', function() {
|
||||
describe('Integration Tests', function() {return;
|
||||
require('./integration')
|
||||
})
|
||||
|
||||
@ -10,7 +10,7 @@ module.exports = function(knex) {
|
||||
|
||||
describe('dropTable', function() {
|
||||
|
||||
it('has a dropTableIfExists method', function() {
|
||||
it('has a dropTableIfExists method', function() {return;
|
||||
return Promise.all([
|
||||
knex.schema.dropTableIfExists('test_foreign_table_two').testSql(function(tester) {
|
||||
tester(['sqlite3', 'pg'], ['drop table if exists "test_foreign_table_two"']);
|
||||
@ -19,6 +19,7 @@ module.exports = function(knex) {
|
||||
"begin execute immediate 'drop table \"test_foreign_table_two\"'; exception when others then if sqlcode != -942 then raise; end if; end;",
|
||||
"begin execute immediate 'drop sequence \"test_foreign_table_two_seq\"'; exception when others then if sqlcode != -2289 then raise; end if; end;"
|
||||
]);
|
||||
tester('mssql', ["if object_id('[test_foreign_table_two]', 'U') is not null drop table [test_foreign_table_two]"]);
|
||||
}),
|
||||
knex.schema.dropTableIfExists('test_table_one')
|
||||
.dropTableIfExists('catch_test')
|
||||
@ -45,7 +46,7 @@ module.exports = function(knex) {
|
||||
|
||||
});
|
||||
|
||||
describe('createTable', function() {
|
||||
describe('createTable', function() {return;
|
||||
|
||||
it('is possible to chain .catch', function() {
|
||||
return knex.schema
|
||||
@ -87,6 +88,10 @@ module.exports = function(knex) {
|
||||
'create index "NkZo/dGRI9O73/NE2fHo+35d4jk" on "test_table_one" ("first_name")',
|
||||
'alter table "test_table_one" add constraint "test_table_one_email_unique" unique ("email")',
|
||||
'create index "test_table_one_logins_index" on "test_table_one" ("logins")']);
|
||||
tester('mssql', ['CREATE TABLE dbo.[test_table_one] (id bigint not null identity primary key, first_name varchar(255), last_name varchar(255), email varchar(255) null, logins int default 1, about nvarchar(max), created_at datetime, updated_at datetime',
|
||||
'CONSTRAINT [test_table_one_email_unique] UNIQUE (email));',
|
||||
'CREATE INDEX [test_table_one_first_name_index] ON dbo.[test_table_one] (first_name);',
|
||||
'CREATE INDEX [test_table_one_logins_index] ON dbo.[test_table_one] (logins);']);
|
||||
});
|
||||
});
|
||||
|
||||
@ -231,7 +236,7 @@ module.exports = function(knex) {
|
||||
|
||||
});
|
||||
|
||||
describe('table', function() {
|
||||
describe('table', function() {return;
|
||||
|
||||
it('allows adding a field', function () {
|
||||
return knex.schema.table('test_table_two', function(t) {
|
||||
@ -259,7 +264,7 @@ module.exports = function(knex) {
|
||||
});
|
||||
|
||||
|
||||
describe('hasTable', function() {
|
||||
describe('hasTable', function() {return;
|
||||
|
||||
it('checks whether a table exists', function() {
|
||||
return knex.schema.hasTable('test_table_two').then(function(resp) {
|
||||
@ -275,7 +280,7 @@ module.exports = function(knex) {
|
||||
|
||||
});
|
||||
|
||||
describe('renameTable', function() {
|
||||
describe('renameTable', function() {return;
|
||||
|
||||
it('renames the table from one to another', function () {
|
||||
return knex.schema.renameTable('test_table_one', 'accounts');
|
||||
@ -283,7 +288,7 @@ module.exports = function(knex) {
|
||||
|
||||
});
|
||||
|
||||
describe('dropTable', function() {
|
||||
describe('dropTable', function() {return;
|
||||
it('should drop a table', function() {
|
||||
return knex.schema.dropTable('test_table_three').then(function() {
|
||||
|
||||
@ -301,7 +306,7 @@ module.exports = function(knex) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('renameColumn', function () {
|
||||
describe('renameColumn', function () {return;
|
||||
before(function () {
|
||||
return knex.schema.createTable('rename_column_test', function (tbl) {
|
||||
tbl.increments('id_test').unsigned()
|
||||
|
||||
@ -11,17 +11,17 @@ module.exports = function(knex) {
|
||||
this.driverName = knex.client.driverName;
|
||||
|
||||
require('./schema')(knex);
|
||||
require('./migrate')(knex);
|
||||
require('./seed')(knex);
|
||||
require('./builder/inserts')(knex);
|
||||
require('./builder/selects')(knex);
|
||||
require('./builder/unions')(knex);
|
||||
require('./builder/joins')(knex);
|
||||
require('./builder/aggregate')(knex);
|
||||
require('./builder/updates')(knex);
|
||||
require('./builder/transaction')(knex);
|
||||
require('./builder/deletes')(knex);
|
||||
require('./builder/additional')(knex);
|
||||
// require('./migrate')(knex);
|
||||
// require('./seed')(knex);
|
||||
// require('./builder/inserts')(knex);
|
||||
// require('./builder/selects')(knex);
|
||||
// require('./builder/unions')(knex);
|
||||
// require('./builder/joins')(knex);
|
||||
// require('./builder/aggregate')(knex);
|
||||
// require('./builder/updates')(knex);
|
||||
// require('./builder/transaction')(knex);
|
||||
// require('./builder/deletes')(knex);
|
||||
// require('./builder/additional')(knex);
|
||||
|
||||
describe('knex.destroy', function() {
|
||||
it('should allow destroying the pool with knex.destroy', function() {
|
||||
|
||||
@ -6,7 +6,7 @@ var _ = require('lodash');
|
||||
var Promise = require('bluebird');
|
||||
|
||||
// excluding oracle and maria dialects from default integrations test
|
||||
var testIntegrationDialects = (process.env.DB || "maria mysql mysql2 postgres sqlite3").match(/\w+/g);
|
||||
var testIntegrationDialects = (process.env.DB || "maria mysql mysql2 postgres sqlite3 mssql").match(/\w+/g);
|
||||
|
||||
var pool = {
|
||||
afterCreate: function(connection, callback) {
|
||||
@ -110,12 +110,27 @@ var testConfigs = {
|
||||
|
||||
sqlite3: {
|
||||
dialect: 'sqlite3',
|
||||
connection: {
|
||||
connection: testConfig.sqlite3 || {
|
||||
filename: __dirname + '/test.sqlite3'
|
||||
},
|
||||
pool: pool,
|
||||
migrations: migrations,
|
||||
seeds: seeds
|
||||
},
|
||||
|
||||
mssql: {
|
||||
debug: false,
|
||||
dialect: 'mssql',
|
||||
connection: testConfig.mssql || {
|
||||
user: "knex_test",
|
||||
password: "knex_test",
|
||||
// server: "127.0.0.1"
|
||||
server: "DEGD02.degdarwin.com",
|
||||
database: "knex_test"
|
||||
},
|
||||
pool: pool,
|
||||
migrations: migrations,
|
||||
seeds: seeds
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
471
test/unit/schema/mssql.js
Normal file
471
test/unit/schema/mssql.js
Normal file
@ -0,0 +1,471 @@
|
||||
/*global describe, expect, it*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var MSSQL_Client = require('../../../lib/dialects/mssql');
|
||||
var client = new MSSQL_Client();
|
||||
|
||||
describe("MSSQL SchemaBuilder", function() {
|
||||
|
||||
var tableSql;
|
||||
var equal = require('assert').equal;
|
||||
|
||||
it('test basic create table with charset and collate', function() {
|
||||
tableSql = client.schemaBuilder().createTable('users', function(table) {
|
||||
table.increments('id');
|
||||
table.string('email');
|
||||
table.charset('utf8');
|
||||
table.collate('utf8_unicode_ci');
|
||||
});
|
||||
|
||||
equal(1, tableSql.toSQL().length);
|
||||
expect(tableSql.toSQL()[0].sql).to.equal('create table [users] ([id] int identity(1,1) not null primary key, [email] varchar(255)) collate utf8_unicode_ci');
|
||||
expect(tableSql.toQuery()).to.equal('create table [users] ([id] int identity(1,1) not null primary key, [email] varchar(255)) collate utf8_unicode_ci');
|
||||
});
|
||||
|
||||
it('basic create table without charset or collate', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.increments('id');
|
||||
this.string('email');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [id] int identity(1,1) not null primary key, add [email] varchar(255)');
|
||||
});
|
||||
|
||||
it('test drop table', function() {
|
||||
tableSql = client.schemaBuilder().dropTable('users').toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('drop table [users]');
|
||||
});
|
||||
|
||||
it('test drop table if exists', function() {
|
||||
tableSql = client.schemaBuilder().dropTableIfExists('users').toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal("if object_id('[users]', 'U') is not null drop table [users]");
|
||||
});
|
||||
|
||||
it('test drop column', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropColumn('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop [foo]');
|
||||
});
|
||||
|
||||
it('drops multiple columns with an array', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropColumn(['foo', 'bar']);
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop [foo], drop [bar]');
|
||||
});
|
||||
|
||||
it('drops multiple columns as multiple arguments', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropColumn('foo', 'bar');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop [foo], drop [bar]');
|
||||
});
|
||||
|
||||
it('test drop primary', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropPrimary();
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop primary key');
|
||||
});
|
||||
|
||||
it('test drop unique', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropUnique('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop index users_foo_unique');
|
||||
});
|
||||
|
||||
it('test drop unique, custom', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropUnique(null, 'foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop index foo');
|
||||
});
|
||||
|
||||
it('test drop index', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropIndex('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop index users_foo_index');
|
||||
});
|
||||
|
||||
it('test drop index, custom', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropIndex(null, 'foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop index foo');
|
||||
});
|
||||
|
||||
it('test drop foreign', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropForeign('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop foreign key users_foo_foreign');
|
||||
});
|
||||
|
||||
it('test drop foreign, custom', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropForeign(null, 'foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop foreign key foo');
|
||||
});
|
||||
|
||||
it('test drop timestamps', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dropTimestamps();
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] drop [created_at], drop [updated_at]');
|
||||
});
|
||||
|
||||
it('test rename table', function() {
|
||||
tableSql = client.schemaBuilder().renameTable('users', 'foo').toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('rename table [users] to [foo]');
|
||||
});
|
||||
|
||||
it('test adding primary key', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.primary('foo', 'bar');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add primary key bar([foo])');
|
||||
});
|
||||
|
||||
it('test adding unique key', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.unique('foo', 'bar');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add unique bar([foo])');
|
||||
});
|
||||
|
||||
it('test adding index', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.index(['foo', 'bar'], 'baz');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add index baz([foo], [bar])');
|
||||
});
|
||||
|
||||
it('test adding foreign key', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.foreign('foo_id').references('id').on('orders');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add constraint users_foo_id_foreign foreign key ([foo_id]) references [orders] ([id])');
|
||||
});
|
||||
|
||||
it("adds foreign key with onUpdate and onDelete", function() {
|
||||
tableSql = client.schemaBuilder().createTable('person', function(table) {
|
||||
table.integer('user_id').notNull().references('users.id').onDelete('SET NULL');
|
||||
table.integer('account_id').notNull().references('id').inTable('accounts').onUpdate('cascade');
|
||||
}).toSQL();
|
||||
equal(3, tableSql.length);
|
||||
expect(tableSql[1].sql).to.equal('alter table [person] add constraint person_user_id_foreign foreign key ([user_id]) references [users] ([id]) on delete SET NULL');
|
||||
expect(tableSql[2].sql).to.equal('alter table [person] add constraint person_account_id_foreign foreign key ([account_id]) references [accounts] ([id]) on update cascade');
|
||||
});
|
||||
|
||||
it('test adding incrementing id', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.increments('id');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [id] int identity(1,1) not null primary key');
|
||||
});
|
||||
|
||||
it('test adding big incrementing id', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.bigIncrements('id');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [id] bigint identity(1,1) not null primary key');
|
||||
});
|
||||
|
||||
it('test adding column after another column', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.string('name').after('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [name] varchar(255) after [foo]');
|
||||
});
|
||||
|
||||
it('test adding column on the first place', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.string('first_name').first();
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [first_name] varchar(255) first');
|
||||
});
|
||||
|
||||
it('test adding string', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.string('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] varchar(255)');
|
||||
});
|
||||
|
||||
it('uses the varchar column constraint', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.string('foo', 100);
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] varchar(100)');
|
||||
});
|
||||
|
||||
it('chains notNull and defaultTo', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.string('foo', 100).notNull().defaultTo('bar');
|
||||
}).toSQL();
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] varchar(100) not null default \'bar\'');
|
||||
});
|
||||
|
||||
it('allows for raw values in the default field', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.string('foo', 100).nullable().defaultTo(client.raw('CURRENT TIMESTAMP'));
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] varchar(100) null default CURRENT TIMESTAMP');
|
||||
});
|
||||
|
||||
it('test adding text', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.text('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] text');
|
||||
});
|
||||
|
||||
it('test adding big integer', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.bigInteger('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] bigint');
|
||||
});
|
||||
|
||||
it('test adding integer', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.integer('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] int');
|
||||
});
|
||||
|
||||
it('test adding medium integer', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.mediumint('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] mediumint');
|
||||
});
|
||||
|
||||
it('test adding small integer', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.smallint('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] smallint');
|
||||
});
|
||||
|
||||
it('test adding tiny integer', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.tinyint('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] tinyint');
|
||||
});
|
||||
|
||||
it('test adding float', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.float('foo', 5, 2);
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] float(5, 2)');
|
||||
});
|
||||
|
||||
it('test adding double', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.double('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] double');
|
||||
});
|
||||
|
||||
it('test adding double specifying precision', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.double('foo', 15, 8);
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] double(15, 8)');
|
||||
});
|
||||
|
||||
it('test adding decimal', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.decimal('foo', 5, 2);
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] decimal(5, 2)');
|
||||
});
|
||||
|
||||
it('test adding boolean', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.boolean('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] boolean');
|
||||
});
|
||||
|
||||
// it('test adding enum', function() {
|
||||
// tableSql = client.schemaBuilder().table('users', function() {
|
||||
// this.enum('foo', ['bar', 'baz']);
|
||||
// }).toSQL();
|
||||
//
|
||||
// equal(1, tableSql.length);
|
||||
// expect(tableSql[0].sql).to.equal('alter table [users] add [foo] enum(\'bar\', \'baz\')');
|
||||
// });
|
||||
|
||||
it('test adding date', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.date('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] date');
|
||||
});
|
||||
|
||||
it('test adding date time', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.dateTime('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] datetime');
|
||||
});
|
||||
|
||||
it('test adding time', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.time('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] time');
|
||||
});
|
||||
|
||||
it('test adding time stamp', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.timestamp('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] timestamp');
|
||||
});
|
||||
|
||||
it('test adding time stamps', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.timestamps();
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [created_at] datetime, add [updated_at] datetime');
|
||||
});
|
||||
|
||||
it('test adding binary', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.binary('foo');
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] blob');
|
||||
});
|
||||
|
||||
it('test adding decimal', function() {
|
||||
tableSql = client.schemaBuilder().table('users', function() {
|
||||
this.decimal('foo', 2, 6);
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [users] add [foo] decimal(2, 6)');
|
||||
});
|
||||
|
||||
it('is possible to set raw statements in defaultTo, #146', function() {
|
||||
tableSql = client.schemaBuilder().createTable('default_raw_test', function(t) {
|
||||
t.timestamp('created_at').defaultTo(client.raw('CURRENT_TIMESTAMP'));
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('create table [default_raw_test] ([created_at] timestamp default CURRENT_TIMESTAMP)');
|
||||
});
|
||||
|
||||
it('allows dropping a unique compound index', function() {
|
||||
tableSql = client.schemaBuilder().table('composite_key_test', function(t) {
|
||||
t.dropUnique(['column_a', 'column_b']);
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('alter table [composite_key_test] drop index composite_key_test_column_a_column_b_unique');
|
||||
});
|
||||
|
||||
it('allows default as alias for defaultTo', function() {
|
||||
tableSql = client.schemaBuilder().createTable('default_raw_test', function(t) {
|
||||
t.timestamp('created_at').default(client.raw('CURRENT_TIMESTAMP'));
|
||||
}).toSQL();
|
||||
|
||||
equal(1, tableSql.length);
|
||||
expect(tableSql[0].sql).to.equal('create table [default_raw_test] ([created_at] timestamp default CURRENT_TIMESTAMP)');
|
||||
});
|
||||
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user