Add initial version of dijkstra backend cloudron image
This commit is contained in:
85
node_modules/knex/lib/schema/builder.js
generated
vendored
Normal file
85
node_modules/knex/lib/schema/builder.js
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
const inherits = require('inherits');
|
||||
const { EventEmitter } = require('events');
|
||||
const { each, toArray } = require('lodash');
|
||||
const { addQueryContext } = require('../helpers');
|
||||
const saveAsyncStack = require('../util/save-async-stack');
|
||||
|
||||
// Constructor for the builder instance, typically called from
|
||||
// `knex.builder`, accepting the current `knex` instance,
|
||||
// and pulling out the `client` and `grammar` from the current
|
||||
// knex instance.
|
||||
function SchemaBuilder(client) {
|
||||
this.client = client;
|
||||
this._sequence = [];
|
||||
|
||||
if (client.config) {
|
||||
this._debug = client.config.debug;
|
||||
saveAsyncStack(this, 4);
|
||||
}
|
||||
}
|
||||
|
||||
inherits(SchemaBuilder, EventEmitter);
|
||||
|
||||
// Each of the schema builder methods just add to the
|
||||
// "_sequence" array for consistency.
|
||||
each(
|
||||
[
|
||||
'createTable',
|
||||
'createTableIfNotExists',
|
||||
'createSchema',
|
||||
'createSchemaIfNotExists',
|
||||
'dropSchema',
|
||||
'dropSchemaIfExists',
|
||||
'createExtension',
|
||||
'createExtensionIfNotExists',
|
||||
'dropExtension',
|
||||
'dropExtensionIfExists',
|
||||
'table',
|
||||
'alterTable',
|
||||
'hasTable',
|
||||
'hasColumn',
|
||||
'dropTable',
|
||||
'renameTable',
|
||||
'dropTableIfExists',
|
||||
'raw',
|
||||
],
|
||||
function(method) {
|
||||
SchemaBuilder.prototype[method] = function() {
|
||||
if (method === 'createTableIfNotExists') {
|
||||
this.client.logger.warn(
|
||||
[
|
||||
'Use async .hasTable to check if table exists and then use plain .createTable. Since ',
|
||||
'.createTableIfNotExists actually just generates plain "CREATE TABLE IF NOT EXIST..." ',
|
||||
'query it will not work correctly if there are any alter table queries generated for ',
|
||||
'columns afterwards. To not break old migrations this function is left untouched for now',
|
||||
', but it should not be used when writing new code and it is removed from documentation.',
|
||||
].join('')
|
||||
);
|
||||
}
|
||||
if (method === 'table') method = 'alterTable';
|
||||
this._sequence.push({
|
||||
method,
|
||||
args: toArray(arguments),
|
||||
});
|
||||
return this;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
require('../interface')(SchemaBuilder);
|
||||
addQueryContext(SchemaBuilder);
|
||||
|
||||
SchemaBuilder.prototype.withSchema = function(schemaName) {
|
||||
this._schema = schemaName;
|
||||
return this;
|
||||
};
|
||||
|
||||
SchemaBuilder.prototype.toString = function() {
|
||||
return this.toQuery();
|
||||
};
|
||||
|
||||
SchemaBuilder.prototype.toSQL = function() {
|
||||
return this.client.schemaCompiler(this).toSQL();
|
||||
};
|
||||
|
||||
module.exports = SchemaBuilder;
|
||||
116
node_modules/knex/lib/schema/columnbuilder.js
generated
vendored
Normal file
116
node_modules/knex/lib/schema/columnbuilder.js
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
const { extend, each, toArray } = require('lodash');
|
||||
const { addQueryContext } = require('../helpers');
|
||||
|
||||
// The chainable interface off the original "column" method.
|
||||
function ColumnBuilder(client, tableBuilder, type, args) {
|
||||
this.client = client;
|
||||
this._method = 'add';
|
||||
this._single = {};
|
||||
this._modifiers = {};
|
||||
this._statements = [];
|
||||
this._type = columnAlias[type] || type;
|
||||
this._args = args;
|
||||
this._tableBuilder = tableBuilder;
|
||||
|
||||
// If we're altering the table, extend the object
|
||||
// with the available "alter" methods.
|
||||
if (tableBuilder._method === 'alter') {
|
||||
extend(this, AlterMethods);
|
||||
}
|
||||
}
|
||||
|
||||
// All of the modifier methods that can be used to modify the current query.
|
||||
const modifiers = [
|
||||
'default',
|
||||
'defaultsTo',
|
||||
'defaultTo',
|
||||
'unsigned',
|
||||
'nullable',
|
||||
'first',
|
||||
'after',
|
||||
'comment',
|
||||
'collate',
|
||||
];
|
||||
|
||||
// Aliases for convenience.
|
||||
const aliasMethod = {
|
||||
default: 'defaultTo',
|
||||
defaultsTo: 'defaultTo',
|
||||
};
|
||||
|
||||
// If we call any of the modifiers (index or otherwise) on the chainable, we pretend
|
||||
// as though we're calling `table.method(column)` directly.
|
||||
each(modifiers, function(method) {
|
||||
const key = aliasMethod[method] || method;
|
||||
ColumnBuilder.prototype[method] = function() {
|
||||
this._modifiers[key] = toArray(arguments);
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
addQueryContext(ColumnBuilder);
|
||||
|
||||
ColumnBuilder.prototype.notNull = ColumnBuilder.prototype.notNullable = function notNullable() {
|
||||
return this.nullable(false);
|
||||
};
|
||||
|
||||
each(['index', 'primary', 'unique'], function(method) {
|
||||
ColumnBuilder.prototype[method] = function() {
|
||||
if (this._type.toLowerCase().indexOf('increments') === -1) {
|
||||
this._tableBuilder[method].apply(
|
||||
this._tableBuilder,
|
||||
[this._args[0]].concat(toArray(arguments))
|
||||
);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
// Specify that the current column "references" a column,
|
||||
// which may be tableName.column or just "column"
|
||||
ColumnBuilder.prototype.references = function(value) {
|
||||
return this._tableBuilder.foreign
|
||||
.call(this._tableBuilder, this._args[0], undefined, this)
|
||||
._columnBuilder(this)
|
||||
.references(value);
|
||||
};
|
||||
|
||||
const AlterMethods = {};
|
||||
|
||||
// Specify that the column is to be dropped. This takes precedence
|
||||
// over all other rules for the column.
|
||||
AlterMethods.drop = function() {
|
||||
this._single.drop = true;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Specify the "type" that we're looking to set the
|
||||
// Knex takes no responsibility for any data-loss that may
|
||||
// occur when changing data types.
|
||||
AlterMethods.alterType = function(type) {
|
||||
this._statements.push({
|
||||
grouping: 'alterType',
|
||||
value: type,
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Set column method to alter (default is add).
|
||||
AlterMethods.alter = function() {
|
||||
this._method = 'alter';
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Alias a few methods for clarity when processing.
|
||||
const columnAlias = {
|
||||
float: 'floating',
|
||||
enum: 'enu',
|
||||
boolean: 'bool',
|
||||
string: 'varchar',
|
||||
bigint: 'bigInteger',
|
||||
};
|
||||
|
||||
module.exports = ColumnBuilder;
|
||||
173
node_modules/knex/lib/schema/columncompiler.js
generated
vendored
Normal file
173
node_modules/knex/lib/schema/columncompiler.js
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
// Column Compiler
|
||||
// Used for designating column definitions
|
||||
// during the table "create" / "alter" statements.
|
||||
// -------
|
||||
const Raw = require('../raw');
|
||||
const helpers = require('./helpers');
|
||||
const { groupBy, first, tail, has, isObject } = require('lodash');
|
||||
|
||||
function ColumnCompiler(client, tableCompiler, columnBuilder) {
|
||||
this.client = client;
|
||||
this.tableCompiler = tableCompiler;
|
||||
this.columnBuilder = columnBuilder;
|
||||
this._commonBuilder = this.columnBuilder;
|
||||
this.args = columnBuilder._args;
|
||||
this.type = columnBuilder._type.toLowerCase();
|
||||
this.grouped = groupBy(columnBuilder._statements, 'grouping');
|
||||
this.modified = columnBuilder._modifiers;
|
||||
this.isIncrements = this.type.indexOf('increments') !== -1;
|
||||
this.formatter = client.formatter(columnBuilder);
|
||||
this.sequence = [];
|
||||
this.modifiers = [];
|
||||
}
|
||||
|
||||
ColumnCompiler.prototype.pushQuery = helpers.pushQuery;
|
||||
|
||||
ColumnCompiler.prototype.pushAdditional = helpers.pushAdditional;
|
||||
|
||||
ColumnCompiler.prototype.unshiftQuery = helpers.unshiftQuery;
|
||||
|
||||
ColumnCompiler.prototype._defaultMap = {
|
||||
columnName: function() {
|
||||
if (!this.isIncrements) {
|
||||
throw new Error(
|
||||
`You did not specify a column name for the ${this.type} column.`
|
||||
);
|
||||
}
|
||||
return 'id';
|
||||
},
|
||||
};
|
||||
|
||||
ColumnCompiler.prototype.defaults = function(label) {
|
||||
if (Object.prototype.hasOwnProperty.call(this._defaultMap, label)) {
|
||||
return this._defaultMap[label].bind(this)();
|
||||
} else {
|
||||
throw new Error(
|
||||
`There is no default for the specified identifier ${label}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// To convert to sql, we first go through and build the
|
||||
// column as it would be in the insert statement
|
||||
ColumnCompiler.prototype.toSQL = function() {
|
||||
this.pushQuery(this.compileColumn());
|
||||
if (this.sequence.additional) {
|
||||
this.sequence = this.sequence.concat(this.sequence.additional);
|
||||
}
|
||||
return this.sequence;
|
||||
};
|
||||
|
||||
// Compiles a column.
|
||||
ColumnCompiler.prototype.compileColumn = function() {
|
||||
return (
|
||||
this.formatter.wrap(this.getColumnName()) +
|
||||
' ' +
|
||||
this.getColumnType() +
|
||||
this.getModifiers()
|
||||
);
|
||||
};
|
||||
|
||||
// Assumes the autoincrementing key is named `id` if not otherwise specified.
|
||||
ColumnCompiler.prototype.getColumnName = function() {
|
||||
const value = first(this.args);
|
||||
return value || this.defaults('columnName');
|
||||
};
|
||||
|
||||
ColumnCompiler.prototype.getColumnType = function() {
|
||||
const type = this[this.type];
|
||||
return typeof type === 'function' ? type.apply(this, tail(this.args)) : type;
|
||||
};
|
||||
|
||||
ColumnCompiler.prototype.getModifiers = function() {
|
||||
const modifiers = [];
|
||||
|
||||
for (let i = 0, l = this.modifiers.length; i < l; i++) {
|
||||
const modifier = this.modifiers[i];
|
||||
|
||||
//Cannot allow 'nullable' modifiers on increments types
|
||||
if (!this.isIncrements || (this.isIncrements && modifier === 'comment')) {
|
||||
if (has(this.modified, modifier)) {
|
||||
const val = this[modifier].apply(this, this.modified[modifier]);
|
||||
if (val) modifiers.push(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modifiers.length > 0 ? ` ${modifiers.join(' ')}` : '';
|
||||
};
|
||||
|
||||
// Types
|
||||
// ------
|
||||
|
||||
ColumnCompiler.prototype.increments =
|
||||
'integer not null primary key autoincrement';
|
||||
ColumnCompiler.prototype.bigincrements =
|
||||
'integer not null primary key autoincrement';
|
||||
ColumnCompiler.prototype.integer = ColumnCompiler.prototype.smallint = ColumnCompiler.prototype.mediumint =
|
||||
'integer';
|
||||
ColumnCompiler.prototype.biginteger = 'bigint';
|
||||
ColumnCompiler.prototype.varchar = function(length) {
|
||||
return `varchar(${this._num(length, 255)})`;
|
||||
};
|
||||
ColumnCompiler.prototype.text = 'text';
|
||||
ColumnCompiler.prototype.tinyint = 'tinyint';
|
||||
ColumnCompiler.prototype.floating = function(precision, scale) {
|
||||
return `float(${this._num(precision, 8)}, ${this._num(scale, 2)})`;
|
||||
};
|
||||
ColumnCompiler.prototype.decimal = function(precision, scale) {
|
||||
if (precision === null) {
|
||||
throw new Error(
|
||||
'Specifying no precision on decimal columns is not supported for that SQL dialect.'
|
||||
);
|
||||
}
|
||||
return `decimal(${this._num(precision, 8)}, ${this._num(scale, 2)})`;
|
||||
};
|
||||
ColumnCompiler.prototype.binary = 'blob';
|
||||
ColumnCompiler.prototype.bool = 'boolean';
|
||||
ColumnCompiler.prototype.date = 'date';
|
||||
ColumnCompiler.prototype.datetime = 'datetime';
|
||||
ColumnCompiler.prototype.time = 'time';
|
||||
ColumnCompiler.prototype.timestamp = 'timestamp';
|
||||
ColumnCompiler.prototype.enu = 'varchar';
|
||||
|
||||
ColumnCompiler.prototype.bit = ColumnCompiler.prototype.json = 'text';
|
||||
|
||||
ColumnCompiler.prototype.uuid = 'char(36)';
|
||||
ColumnCompiler.prototype.specifictype = (type) => type;
|
||||
|
||||
// Modifiers
|
||||
// -------
|
||||
|
||||
ColumnCompiler.prototype.nullable = (nullable) =>
|
||||
nullable === false ? 'not null' : 'null';
|
||||
ColumnCompiler.prototype.notNullable = function() {
|
||||
return this.nullable(false);
|
||||
};
|
||||
ColumnCompiler.prototype.defaultTo = function(value) {
|
||||
if (value === void 0) {
|
||||
return '';
|
||||
} else if (value === null) {
|
||||
value = 'null';
|
||||
} else if (value instanceof Raw) {
|
||||
value = value.toQuery();
|
||||
} else if (this.type === 'bool') {
|
||||
if (value === 'false') value = 0;
|
||||
value = `'${value ? 1 : 0}'`;
|
||||
} else if (
|
||||
(this.type === 'json' || this.type === 'jsonb') &&
|
||||
isObject(value)
|
||||
) {
|
||||
value = `'${JSON.stringify(value)}'`;
|
||||
} else {
|
||||
value = `'${value}'`;
|
||||
}
|
||||
return `default ${value}`;
|
||||
};
|
||||
ColumnCompiler.prototype._num = function(val, fallback) {
|
||||
if (val === undefined || val === null) return fallback;
|
||||
const number = parseInt(val, 10);
|
||||
return isNaN(number) ? fallback : number;
|
||||
};
|
||||
|
||||
module.exports = ColumnCompiler;
|
||||
103
node_modules/knex/lib/schema/compiler.js
generated
vendored
Normal file
103
node_modules/knex/lib/schema/compiler.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
const { pushQuery, pushAdditional, unshiftQuery } = require('./helpers');
|
||||
|
||||
const { isUndefined } = require('lodash');
|
||||
|
||||
// The "SchemaCompiler" takes all of the query statements which have been
|
||||
// gathered in the "SchemaBuilder" and turns them into an array of
|
||||
// properly formatted / bound query strings.
|
||||
function SchemaCompiler(client, builder) {
|
||||
this.builder = builder;
|
||||
this._commonBuilder = this.builder;
|
||||
this.client = client;
|
||||
this.schema = builder._schema;
|
||||
this.formatter = client.formatter(builder);
|
||||
this.sequence = [];
|
||||
}
|
||||
|
||||
function throwOnlyPGError(operationName) {
|
||||
throw new Error(
|
||||
`${operationName} is not supported for this dialect (only PostgreSQL supports it currently).`
|
||||
);
|
||||
}
|
||||
|
||||
Object.assign(SchemaCompiler.prototype, {
|
||||
pushQuery: pushQuery,
|
||||
|
||||
pushAdditional: pushAdditional,
|
||||
|
||||
unshiftQuery: unshiftQuery,
|
||||
|
||||
createTable: buildTable('create'),
|
||||
|
||||
createTableIfNotExists: buildTable('createIfNot'),
|
||||
|
||||
createSchema: () => {
|
||||
throwOnlyPGError('createSchema');
|
||||
},
|
||||
createSchemaIfNotExists: () => {
|
||||
throwOnlyPGError('createSchemaIfNotExists');
|
||||
},
|
||||
dropSchema: () => {
|
||||
throwOnlyPGError('dropSchema');
|
||||
},
|
||||
dropSchemaIfExists: () => {
|
||||
throwOnlyPGError('dropSchemaIfExists');
|
||||
},
|
||||
|
||||
alterTable: buildTable('alter'),
|
||||
|
||||
dropTablePrefix: 'drop table ',
|
||||
|
||||
dropTable(tableName) {
|
||||
this.pushQuery(
|
||||
this.dropTablePrefix +
|
||||
this.formatter.wrap(prefixedTableName(this.schema, tableName))
|
||||
);
|
||||
},
|
||||
|
||||
dropTableIfExists(tableName) {
|
||||
this.pushQuery(
|
||||
this.dropTablePrefix +
|
||||
'if exists ' +
|
||||
this.formatter.wrap(prefixedTableName(this.schema, tableName))
|
||||
);
|
||||
},
|
||||
|
||||
raw(sql, bindings) {
|
||||
this.sequence.push(this.client.raw(sql, bindings).toSQL());
|
||||
},
|
||||
|
||||
toSQL() {
|
||||
const sequence = this.builder._sequence;
|
||||
for (let i = 0, l = sequence.length; i < l; i++) {
|
||||
const query = sequence[i];
|
||||
this[query.method].apply(this, query.args);
|
||||
}
|
||||
return this.sequence;
|
||||
},
|
||||
});
|
||||
|
||||
function buildTable(type) {
|
||||
return function(tableName, fn) {
|
||||
const builder = this.client.tableBuilder(type, tableName, fn);
|
||||
|
||||
// pass queryContext down to tableBuilder but do not overwrite it if already set
|
||||
const queryContext = this.builder.queryContext();
|
||||
if (!isUndefined(queryContext) && isUndefined(builder.queryContext())) {
|
||||
builder.queryContext(queryContext);
|
||||
}
|
||||
|
||||
builder.setSchema(this.schema);
|
||||
const sql = builder.toSQL();
|
||||
|
||||
for (let i = 0, l = sql.length; i < l; i++) {
|
||||
this.sequence.push(sql[i]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function prefixedTableName(prefix, table) {
|
||||
return prefix ? `${prefix}.${table}` : table;
|
||||
}
|
||||
|
||||
module.exports = SchemaCompiler;
|
||||
50
node_modules/knex/lib/schema/helpers.js
generated
vendored
Normal file
50
node_modules/knex/lib/schema/helpers.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
const { isString, tail } = require('lodash');
|
||||
|
||||
// Push a new query onto the compiled "sequence" stack,
|
||||
// creating a new formatter, returning the compiler.
|
||||
function pushQuery(query) {
|
||||
if (!query) return;
|
||||
if (isString(query)) {
|
||||
query = { sql: query };
|
||||
}
|
||||
if (!query.bindings) {
|
||||
query.bindings = this.formatter.bindings;
|
||||
}
|
||||
this.sequence.push(query);
|
||||
|
||||
this.formatter = this.client.formatter(this._commonBuilder);
|
||||
}
|
||||
|
||||
// Used in cases where we need to push some additional column specific statements.
|
||||
function pushAdditional(fn) {
|
||||
const child = new this.constructor(
|
||||
this.client,
|
||||
this.tableCompiler,
|
||||
this.columnBuilder
|
||||
);
|
||||
fn.call(child, tail(arguments));
|
||||
this.sequence.additional = (this.sequence.additional || []).concat(
|
||||
child.sequence
|
||||
);
|
||||
}
|
||||
|
||||
// Unshift a new query onto the compiled "sequence" stack,
|
||||
// creating a new formatter, returning the compiler.
|
||||
function unshiftQuery(query) {
|
||||
if (!query) return;
|
||||
if (isString(query)) {
|
||||
query = { sql: query };
|
||||
}
|
||||
if (!query.bindings) {
|
||||
query.bindings = this.formatter.bindings;
|
||||
}
|
||||
this.sequence.unshift(query);
|
||||
|
||||
this.formatter = this.client.formatter(this._commonBuilder);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
pushAdditional,
|
||||
pushQuery,
|
||||
unshiftQuery,
|
||||
};
|
||||
285
node_modules/knex/lib/schema/tablebuilder.js
generated
vendored
Normal file
285
node_modules/knex/lib/schema/tablebuilder.js
generated
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
// TableBuilder
|
||||
|
||||
// Takes the function passed to the "createTable" or "table/editTable"
|
||||
// functions and calls it with the "TableBuilder" as both the context and
|
||||
// the first argument. Inside this function we can specify what happens to the
|
||||
// method, pushing everything we want to do onto the "allStatements" array,
|
||||
// which is then compiled into sql.
|
||||
// ------
|
||||
const { extend, each, toArray, isString, isFunction } = require('lodash');
|
||||
const helpers = require('../helpers');
|
||||
|
||||
function TableBuilder(client, method, tableName, fn) {
|
||||
this.client = client;
|
||||
this._fn = fn;
|
||||
this._method = method;
|
||||
this._schemaName = undefined;
|
||||
this._tableName = tableName;
|
||||
this._statements = [];
|
||||
this._single = {};
|
||||
|
||||
if (!isFunction(this._fn)) {
|
||||
throw new TypeError(
|
||||
'A callback function must be supplied to calls against `.createTable` ' +
|
||||
'and `.table`'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TableBuilder.prototype.setSchema = function(schemaName) {
|
||||
this._schemaName = schemaName;
|
||||
};
|
||||
|
||||
// Convert the current tableBuilder object "toSQL"
|
||||
// giving us additional methods if we're altering
|
||||
// rather than creating the table.
|
||||
TableBuilder.prototype.toSQL = function() {
|
||||
if (this._method === 'alter') {
|
||||
extend(this, AlterMethods);
|
||||
}
|
||||
this._fn.call(this, this);
|
||||
return this.client.tableCompiler(this).toSQL();
|
||||
};
|
||||
|
||||
each(
|
||||
[
|
||||
// Each of the index methods can be called individually, with the
|
||||
// column name to be used, e.g. table.unique('column').
|
||||
'index',
|
||||
'primary',
|
||||
'unique',
|
||||
|
||||
// Key specific
|
||||
'dropPrimary',
|
||||
'dropUnique',
|
||||
'dropIndex',
|
||||
'dropForeign',
|
||||
],
|
||||
function(method) {
|
||||
TableBuilder.prototype[method] = function() {
|
||||
this._statements.push({
|
||||
grouping: 'alterTable',
|
||||
method,
|
||||
args: toArray(arguments),
|
||||
});
|
||||
return this;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// Warn for dialect-specific table methods, since that's the
|
||||
// only time these are supported.
|
||||
const specialMethods = {
|
||||
mysql: ['engine', 'charset', 'collate'],
|
||||
postgresql: ['inherits'],
|
||||
};
|
||||
each(specialMethods, function(methods, dialect) {
|
||||
each(methods, function(method) {
|
||||
TableBuilder.prototype[method] = function(value) {
|
||||
if (this.client.dialect !== dialect) {
|
||||
throw new Error(
|
||||
`Knex only supports ${method} statement with ${dialect}.`
|
||||
);
|
||||
}
|
||||
if (this._method === 'alter') {
|
||||
throw new Error(
|
||||
`Knex does not support altering the ${method} outside of create ` +
|
||||
`table, please use knex.raw statement.`
|
||||
);
|
||||
}
|
||||
this._single[method] = value;
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
helpers.addQueryContext(TableBuilder);
|
||||
|
||||
// Each of the column types that we can add, we create a new ColumnBuilder
|
||||
// instance and push it onto the statements array.
|
||||
const columnTypes = [
|
||||
// Numeric
|
||||
'tinyint',
|
||||
'smallint',
|
||||
'mediumint',
|
||||
'int',
|
||||
'bigint',
|
||||
'decimal',
|
||||
'float',
|
||||
'double',
|
||||
'real',
|
||||
'bit',
|
||||
'boolean',
|
||||
'serial',
|
||||
|
||||
// Date / Time
|
||||
'date',
|
||||
'datetime',
|
||||
'timestamp',
|
||||
'time',
|
||||
'year',
|
||||
|
||||
// String
|
||||
'char',
|
||||
'varchar',
|
||||
'tinytext',
|
||||
'tinyText',
|
||||
'text',
|
||||
'mediumtext',
|
||||
'mediumText',
|
||||
'longtext',
|
||||
'longText',
|
||||
'binary',
|
||||
'varbinary',
|
||||
'tinyblob',
|
||||
'tinyBlob',
|
||||
'mediumblob',
|
||||
'mediumBlob',
|
||||
'blob',
|
||||
'longblob',
|
||||
'longBlob',
|
||||
'enum',
|
||||
'set',
|
||||
|
||||
// Increments, Aliases, and Additional
|
||||
'bool',
|
||||
'dateTime',
|
||||
'increments',
|
||||
'bigincrements',
|
||||
'bigIncrements',
|
||||
'integer',
|
||||
'biginteger',
|
||||
'bigInteger',
|
||||
'string',
|
||||
'json',
|
||||
'jsonb',
|
||||
'uuid',
|
||||
'enu',
|
||||
'specificType',
|
||||
];
|
||||
|
||||
// For each of the column methods, create a new "ColumnBuilder" interface,
|
||||
// push it onto the "allStatements" stack, and then return the interface,
|
||||
// with which we can add indexes, etc.
|
||||
each(columnTypes, function(type) {
|
||||
TableBuilder.prototype[type] = function() {
|
||||
const args = toArray(arguments);
|
||||
const builder = this.client.columnBuilder(this, type, args);
|
||||
this._statements.push({
|
||||
grouping: 'columns',
|
||||
builder,
|
||||
});
|
||||
return builder;
|
||||
};
|
||||
});
|
||||
|
||||
// The "timestamps" call is really just sets the `created_at` and `updated_at` columns.
|
||||
TableBuilder.prototype.timestamps = function timestamps() {
|
||||
const method = arguments[0] === true ? 'timestamp' : 'datetime';
|
||||
const createdAt = this[method]('created_at');
|
||||
const updatedAt = this[method]('updated_at');
|
||||
if (arguments[1] === true) {
|
||||
const now = this.client.raw('CURRENT_TIMESTAMP');
|
||||
createdAt.notNullable().defaultTo(now);
|
||||
updatedAt.notNullable().defaultTo(now);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
// Set the comment value for a table, they're only allowed to be called
|
||||
// once per table.
|
||||
TableBuilder.prototype.comment = function(value) {
|
||||
if (typeof value !== 'string') {
|
||||
throw new TypeError('Table comment must be string');
|
||||
}
|
||||
this._single.comment = value;
|
||||
};
|
||||
|
||||
// Set a foreign key on the table, calling
|
||||
// `table.foreign('column_name').references('column').on('table').onDelete()...
|
||||
// Also called from the ColumnBuilder context when chaining.
|
||||
TableBuilder.prototype.foreign = function(column, keyName) {
|
||||
const foreignData = { column: column, keyName: keyName };
|
||||
this._statements.push({
|
||||
grouping: 'alterTable',
|
||||
method: 'foreign',
|
||||
args: [foreignData],
|
||||
});
|
||||
let returnObj = {
|
||||
references(tableColumn) {
|
||||
let pieces;
|
||||
if (isString(tableColumn)) {
|
||||
pieces = tableColumn.split('.');
|
||||
}
|
||||
if (!pieces || pieces.length === 1) {
|
||||
foreignData.references = pieces ? pieces[0] : tableColumn;
|
||||
return {
|
||||
on(tableName) {
|
||||
if (typeof tableName !== 'string') {
|
||||
throw new TypeError(
|
||||
`Expected tableName to be a string, got: ${typeof tableName}`
|
||||
);
|
||||
}
|
||||
foreignData.inTable = tableName;
|
||||
return returnObj;
|
||||
},
|
||||
inTable() {
|
||||
return this.on.apply(this, arguments);
|
||||
},
|
||||
};
|
||||
}
|
||||
foreignData.inTable = pieces[0];
|
||||
foreignData.references = pieces[1];
|
||||
return returnObj;
|
||||
},
|
||||
withKeyName(keyName) {
|
||||
foreignData.keyName = keyName;
|
||||
return returnObj;
|
||||
},
|
||||
onUpdate(statement) {
|
||||
foreignData.onUpdate = statement;
|
||||
return returnObj;
|
||||
},
|
||||
onDelete(statement) {
|
||||
foreignData.onDelete = statement;
|
||||
return returnObj;
|
||||
},
|
||||
_columnBuilder(builder) {
|
||||
extend(builder, returnObj);
|
||||
returnObj = builder;
|
||||
return builder;
|
||||
},
|
||||
};
|
||||
return returnObj;
|
||||
};
|
||||
|
||||
const AlterMethods = {
|
||||
// Renames the current column `from` the current
|
||||
// TODO: this.column(from).rename(to)
|
||||
renameColumn(from, to) {
|
||||
this._statements.push({
|
||||
grouping: 'alterTable',
|
||||
method: 'renameColumn',
|
||||
args: [from, to],
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
dropTimestamps() {
|
||||
return this.dropColumns(['created_at', 'updated_at']);
|
||||
},
|
||||
|
||||
// TODO: changeType
|
||||
};
|
||||
|
||||
// Drop a column from the current table.
|
||||
// TODO: Enable this.column(columnName).drop();
|
||||
AlterMethods.dropColumn = AlterMethods.dropColumns = function() {
|
||||
this._statements.push({
|
||||
grouping: 'alterTable',
|
||||
method: 'dropColumn',
|
||||
args: toArray(arguments),
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
module.exports = TableBuilder;
|
||||
306
node_modules/knex/lib/schema/tablecompiler.js
generated
vendored
Normal file
306
node_modules/knex/lib/schema/tablecompiler.js
generated
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
/* eslint max-len:0 */
|
||||
|
||||
// Table Compiler
|
||||
// -------
|
||||
const { pushAdditional, pushQuery, unshiftQuery } = require('./helpers');
|
||||
const helpers = require('../helpers');
|
||||
const {
|
||||
groupBy,
|
||||
reduce,
|
||||
map,
|
||||
first,
|
||||
tail,
|
||||
isEmpty,
|
||||
indexOf,
|
||||
isArray,
|
||||
isUndefined,
|
||||
} = require('lodash');
|
||||
|
||||
function TableCompiler(client, tableBuilder) {
|
||||
this.client = client;
|
||||
this.tableBuilder = tableBuilder;
|
||||
this._commonBuilder = this.tableBuilder;
|
||||
this.method = tableBuilder._method;
|
||||
this.schemaNameRaw = tableBuilder._schemaName;
|
||||
this.tableNameRaw = tableBuilder._tableName;
|
||||
this.single = tableBuilder._single;
|
||||
this.grouped = groupBy(tableBuilder._statements, 'grouping');
|
||||
this.formatter = client.formatter(tableBuilder);
|
||||
this.sequence = [];
|
||||
this._formatting = client.config && client.config.formatting;
|
||||
}
|
||||
|
||||
TableCompiler.prototype.pushQuery = pushQuery;
|
||||
|
||||
TableCompiler.prototype.pushAdditional = pushAdditional;
|
||||
|
||||
TableCompiler.prototype.unshiftQuery = unshiftQuery;
|
||||
|
||||
// Convert the tableCompiler toSQL
|
||||
TableCompiler.prototype.toSQL = function() {
|
||||
this[this.method]();
|
||||
return this.sequence;
|
||||
};
|
||||
|
||||
TableCompiler.prototype.lowerCase = true;
|
||||
|
||||
// Column Compilation
|
||||
// -------
|
||||
|
||||
// If this is a table "creation", we need to first run through all
|
||||
// of the columns to build them into a single string,
|
||||
// and then run through anything else and push it to the query sequence.
|
||||
TableCompiler.prototype.createAlterTableMethods = null;
|
||||
TableCompiler.prototype.create = function(ifNot) {
|
||||
const columnBuilders = this.getColumns();
|
||||
const columns = columnBuilders.map((col) => col.toSQL());
|
||||
const columnTypes = this.getColumnTypes(columns);
|
||||
if (this.createAlterTableMethods) {
|
||||
this.alterTableForCreate(columnTypes);
|
||||
}
|
||||
this.createQuery(columnTypes, ifNot);
|
||||
this.columnQueries(columns);
|
||||
delete this.single.comment;
|
||||
this.alterTable();
|
||||
};
|
||||
|
||||
// Only create the table if it doesn't exist.
|
||||
TableCompiler.prototype.createIfNot = function() {
|
||||
this.create(true);
|
||||
};
|
||||
|
||||
// If we're altering the table, we need to one-by-one
|
||||
// go through and handle each of the queries associated
|
||||
// with altering the table's schema.
|
||||
TableCompiler.prototype.alter = function() {
|
||||
const addColBuilders = this.getColumns();
|
||||
const addColumns = addColBuilders.map((col) => col.toSQL());
|
||||
const alterColBuilders = this.getColumns('alter');
|
||||
const alterColumns = alterColBuilders.map((col) => col.toSQL());
|
||||
const addColumnTypes = this.getColumnTypes(addColumns);
|
||||
const alterColumnTypes = this.getColumnTypes(alterColumns);
|
||||
|
||||
this.addColumns(addColumnTypes);
|
||||
this.alterColumns(alterColumnTypes, alterColBuilders);
|
||||
this.columnQueries(addColumns);
|
||||
this.columnQueries(alterColumns);
|
||||
this.alterTable();
|
||||
};
|
||||
|
||||
TableCompiler.prototype.foreign = function(foreignData) {
|
||||
if (foreignData.inTable && foreignData.references) {
|
||||
const keyName = foreignData.keyName
|
||||
? this.formatter.wrap(foreignData.keyName)
|
||||
: this._indexCommand('foreign', this.tableNameRaw, foreignData.column);
|
||||
const column = this.formatter.columnize(foreignData.column);
|
||||
const references = this.formatter.columnize(foreignData.references);
|
||||
const inTable = this.formatter.wrap(foreignData.inTable);
|
||||
const onUpdate = foreignData.onUpdate
|
||||
? (this.lowerCase ? ' on update ' : ' ON UPDATE ') + foreignData.onUpdate
|
||||
: '';
|
||||
const onDelete = foreignData.onDelete
|
||||
? (this.lowerCase ? ' on delete ' : ' ON DELETE ') + foreignData.onDelete
|
||||
: '';
|
||||
if (this.lowerCase) {
|
||||
this.pushQuery(
|
||||
(!this.forCreate ? `alter table ${this.tableName()} add ` : '') +
|
||||
'constraint ' +
|
||||
keyName +
|
||||
' ' +
|
||||
'foreign key (' +
|
||||
column +
|
||||
') references ' +
|
||||
inTable +
|
||||
' (' +
|
||||
references +
|
||||
')' +
|
||||
onUpdate +
|
||||
onDelete
|
||||
);
|
||||
} else {
|
||||
this.pushQuery(
|
||||
(!this.forCreate ? `ALTER TABLE ${this.tableName()} ADD ` : '') +
|
||||
'CONSTRAINT ' +
|
||||
keyName +
|
||||
' ' +
|
||||
'FOREIGN KEY (' +
|
||||
column +
|
||||
') REFERENCES ' +
|
||||
inTable +
|
||||
' (' +
|
||||
references +
|
||||
')' +
|
||||
onUpdate +
|
||||
onDelete
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Get all of the column sql & bindings individually for building the table queries.
|
||||
TableCompiler.prototype.getColumnTypes = (columns) =>
|
||||
reduce(
|
||||
map(columns, first),
|
||||
function(memo, column) {
|
||||
memo.sql.push(column.sql);
|
||||
memo.bindings.concat(column.bindings);
|
||||
return memo;
|
||||
},
|
||||
{ sql: [], bindings: [] }
|
||||
);
|
||||
|
||||
// Adds all of the additional queries from the "column"
|
||||
TableCompiler.prototype.columnQueries = function(columns) {
|
||||
const queries = reduce(
|
||||
map(columns, tail),
|
||||
function(memo, column) {
|
||||
if (!isEmpty(column)) return memo.concat(column);
|
||||
return memo;
|
||||
},
|
||||
[]
|
||||
);
|
||||
for (const q of queries) {
|
||||
this.pushQuery(q);
|
||||
}
|
||||
};
|
||||
|
||||
// Add a new column.
|
||||
TableCompiler.prototype.addColumnsPrefix = 'add column ';
|
||||
|
||||
// All of the columns to "add" for the query
|
||||
TableCompiler.prototype.addColumns = function(columns, prefix) {
|
||||
prefix = prefix || this.addColumnsPrefix;
|
||||
|
||||
if (columns.sql.length > 0) {
|
||||
const columnSql = map(columns.sql, (column) => {
|
||||
return prefix + column;
|
||||
});
|
||||
this.pushQuery({
|
||||
sql:
|
||||
(this.lowerCase ? 'alter table ' : 'ALTER TABLE ') +
|
||||
this.tableName() +
|
||||
' ' +
|
||||
columnSql.join(', '),
|
||||
bindings: columns.bindings,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Alter column
|
||||
TableCompiler.prototype.alterColumnsPrefix = 'alter column ';
|
||||
|
||||
TableCompiler.prototype.alterColumns = function(columns, colBuilders) {
|
||||
if (columns.sql.length > 0) {
|
||||
this.addColumns(columns, this.alterColumnsPrefix, colBuilders);
|
||||
}
|
||||
};
|
||||
|
||||
// Compile the columns as needed for the current create or alter table
|
||||
TableCompiler.prototype.getColumns = function(method) {
|
||||
const columns = this.grouped.columns || [];
|
||||
method = method || 'add';
|
||||
|
||||
const queryContext = this.tableBuilder.queryContext();
|
||||
|
||||
return columns
|
||||
.filter((column) => column.builder._method === method)
|
||||
.map((column) => {
|
||||
// pass queryContext down to columnBuilder but do not overwrite it if already set
|
||||
if (
|
||||
!isUndefined(queryContext) &&
|
||||
isUndefined(column.builder.queryContext())
|
||||
) {
|
||||
column.builder.queryContext(queryContext);
|
||||
}
|
||||
return this.client.columnCompiler(this, column.builder);
|
||||
});
|
||||
};
|
||||
|
||||
TableCompiler.prototype.tableName = function() {
|
||||
const name = this.schemaNameRaw
|
||||
? `${this.schemaNameRaw}.${this.tableNameRaw}`
|
||||
: this.tableNameRaw;
|
||||
|
||||
return this.formatter.wrap(name);
|
||||
};
|
||||
|
||||
// Generate all of the alter column statements necessary for the query.
|
||||
TableCompiler.prototype.alterTable = function() {
|
||||
const alterTable = this.grouped.alterTable || [];
|
||||
for (let i = 0, l = alterTable.length; i < l; i++) {
|
||||
const statement = alterTable[i];
|
||||
if (this[statement.method]) {
|
||||
this[statement.method].apply(this, statement.args);
|
||||
} else {
|
||||
this.client.logger.error(`Debug: ${statement.method} does not exist`);
|
||||
}
|
||||
}
|
||||
for (const item in this.single) {
|
||||
if (typeof this[item] === 'function') this[item](this.single[item]);
|
||||
}
|
||||
};
|
||||
|
||||
TableCompiler.prototype.alterTableForCreate = function(columnTypes) {
|
||||
this.forCreate = true;
|
||||
const savedSequence = this.sequence;
|
||||
const alterTable = this.grouped.alterTable || [];
|
||||
this.grouped.alterTable = [];
|
||||
for (let i = 0, l = alterTable.length; i < l; i++) {
|
||||
const statement = alterTable[i];
|
||||
if (indexOf(this.createAlterTableMethods, statement.method) < 0) {
|
||||
this.grouped.alterTable.push(statement);
|
||||
continue;
|
||||
}
|
||||
if (this[statement.method]) {
|
||||
this.sequence = [];
|
||||
this[statement.method].apply(this, statement.args);
|
||||
columnTypes.sql.push(this.sequence[0].sql);
|
||||
} else {
|
||||
this.client.logger.error(`Debug: ${statement.method} does not exist`);
|
||||
}
|
||||
}
|
||||
this.sequence = savedSequence;
|
||||
this.forCreate = false;
|
||||
};
|
||||
|
||||
// Drop the index on the current table.
|
||||
TableCompiler.prototype.dropIndex = function(value) {
|
||||
this.pushQuery(`drop index${value}`);
|
||||
};
|
||||
|
||||
// Drop the unique
|
||||
TableCompiler.prototype.dropUnique = TableCompiler.prototype.dropForeign = function() {
|
||||
throw new Error('Method implemented in the dialect driver');
|
||||
};
|
||||
|
||||
TableCompiler.prototype.dropColumnPrefix = 'drop column ';
|
||||
TableCompiler.prototype.dropColumn = function() {
|
||||
const columns = helpers.normalizeArr.apply(null, arguments);
|
||||
const drops = map(isArray(columns) ? columns : [columns], (column) => {
|
||||
return this.dropColumnPrefix + this.formatter.wrap(column);
|
||||
});
|
||||
this.pushQuery(
|
||||
(this.lowerCase ? 'alter table ' : 'ALTER TABLE ') +
|
||||
this.tableName() +
|
||||
' ' +
|
||||
drops.join(', ')
|
||||
);
|
||||
};
|
||||
|
||||
// If no name was specified for this index, we will create one using a basic
|
||||
// convention of the table name, followed by the columns, followed by an
|
||||
// index type, such as primary or index, which makes the index unique.
|
||||
TableCompiler.prototype._indexCommand = function(type, tableName, columns) {
|
||||
if (!isArray(columns)) columns = columns ? [columns] : [];
|
||||
const table = tableName.replace(/\.|-/g, '_');
|
||||
const indexName = (
|
||||
table +
|
||||
'_' +
|
||||
columns.join('_') +
|
||||
'_' +
|
||||
type
|
||||
).toLowerCase();
|
||||
return this.formatter.wrap(indexName);
|
||||
};
|
||||
|
||||
module.exports = TableCompiler;
|
||||
Reference in New Issue
Block a user