Add initial version of dijkstra backend cloudron image

This commit is contained in:
2020-10-12 11:27:15 +02:00
commit 4f5db9ab26
4209 changed files with 448228 additions and 0 deletions

85
node_modules/knex/lib/schema/builder.js generated vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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;