knex 3.2.3 → 3.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2447 -2441
- package/CONTRIBUTING.md +190 -190
- package/LICENSE +22 -22
- package/README.md +156 -156
- package/UPGRADING.md +245 -245
- package/bin/cli.js +516 -516
- package/bin/knexfile-runtime-error.js +27 -27
- package/bin/utils/cli-config-utils.js +217 -217
- package/bin/utils/constants.js +7 -7
- package/bin/utils/migrationsLister.js +37 -37
- package/knex.js +23 -23
- package/knex.mjs +11 -11
- package/lib/builder-interface-augmenter.js +120 -120
- package/lib/client.js +585 -585
- package/lib/constants.js +61 -61
- package/lib/dialects/better-sqlite3/index.js +101 -101
- package/lib/dialects/cockroachdb/crdb-columncompiler.js +14 -14
- package/lib/dialects/cockroachdb/crdb-querybuilder.js +11 -11
- package/lib/dialects/cockroachdb/crdb-querycompiler.js +122 -122
- package/lib/dialects/cockroachdb/crdb-tablecompiler.js +46 -46
- package/lib/dialects/cockroachdb/crdb-viewcompiler.js +15 -15
- package/lib/dialects/cockroachdb/index.js +86 -86
- package/lib/dialects/index.js +34 -34
- package/lib/dialects/mssql/index.js +498 -498
- package/lib/dialects/mssql/mssql-formatter.js +34 -34
- package/lib/dialects/mssql/query/mssql-querycompiler.js +601 -601
- package/lib/dialects/mssql/schema/mssql-columncompiler.js +185 -185
- package/lib/dialects/mssql/schema/mssql-compiler.js +91 -91
- package/lib/dialects/mssql/schema/mssql-tablecompiler.js +393 -393
- package/lib/dialects/mssql/schema/mssql-viewcompiler.js +55 -55
- package/lib/dialects/mssql/transaction.js +176 -176
- package/lib/dialects/mysql/index.js +317 -317
- package/lib/dialects/mysql/query/mysql-querybuilder.js +14 -14
- package/lib/dialects/mysql/query/mysql-querycompiler.js +292 -292
- package/lib/dialects/mysql/schema/mysql-columncompiler.js +193 -193
- package/lib/dialects/mysql/schema/mysql-compiler.js +60 -60
- package/lib/dialects/mysql/schema/mysql-tablecompiler.js +426 -426
- package/lib/dialects/mysql/schema/mysql-viewbuilder.js +21 -21
- package/lib/dialects/mysql/schema/mysql-viewcompiler.js +15 -15
- package/lib/dialects/mysql/transaction.js +46 -46
- package/lib/dialects/mysql2/index.js +53 -53
- package/lib/dialects/mysql2/transaction.js +44 -44
- package/lib/dialects/oracle/DEAD_CODE.md +5 -5
- package/lib/dialects/oracle/index.js +92 -92
- package/lib/dialects/oracle/query/oracle-querycompiler.js +343 -343
- package/lib/dialects/oracle/schema/internal/incrementUtils.js +22 -22
- package/lib/dialects/oracle/schema/internal/trigger.js +155 -155
- package/lib/dialects/oracle/schema/oracle-columnbuilder.js +17 -17
- package/lib/dialects/oracle/schema/oracle-columncompiler.js +126 -126
- package/lib/dialects/oracle/schema/oracle-compiler.js +124 -124
- package/lib/dialects/oracle/schema/oracle-tablecompiler.js +210 -210
- package/lib/dialects/oracle/utils.js +107 -107
- package/lib/dialects/oracledb/index.js +381 -381
- package/lib/dialects/oracledb/query/oracledb-querycompiler.js +481 -481
- package/lib/dialects/oracledb/schema/oracledb-columncompiler.js +61 -61
- package/lib/dialects/oracledb/schema/oracledb-tablecompiler.js +19 -19
- package/lib/dialects/oracledb/schema/oracledb-viewbuilder.js +13 -13
- package/lib/dialects/oracledb/schema/oracledb-viewcompiler.js +19 -19
- package/lib/dialects/oracledb/transaction.js +98 -98
- package/lib/dialects/oracledb/utils.js +208 -208
- package/lib/dialects/pgnative/index.js +60 -60
- package/lib/dialects/postgres/execution/pg-transaction.js +19 -19
- package/lib/dialects/postgres/index.js +373 -373
- package/lib/dialects/postgres/query/pg-querybuilder.js +43 -43
- package/lib/dialects/postgres/query/pg-querycompiler.js +400 -400
- package/lib/dialects/postgres/schema/pg-columncompiler.js +162 -162
- package/lib/dialects/postgres/schema/pg-compiler.js +138 -138
- package/lib/dialects/postgres/schema/pg-tablecompiler.js +331 -331
- package/lib/dialects/postgres/schema/pg-viewbuilder.js +21 -21
- package/lib/dialects/postgres/schema/pg-viewcompiler.js +35 -35
- package/lib/dialects/redshift/index.js +86 -86
- package/lib/dialects/redshift/query/redshift-querycompiler.js +163 -163
- package/lib/dialects/redshift/schema/redshift-columnbuilder.js +22 -22
- package/lib/dialects/redshift/schema/redshift-columncompiler.js +67 -67
- package/lib/dialects/redshift/schema/redshift-compiler.js +14 -14
- package/lib/dialects/redshift/schema/redshift-tablecompiler.js +134 -134
- package/lib/dialects/redshift/schema/redshift-viewcompiler.js +11 -11
- package/lib/dialects/redshift/transaction.js +32 -32
- package/lib/dialects/sqlite3/execution/sqlite-transaction.js +172 -172
- package/lib/dialects/sqlite3/index.js +263 -263
- package/lib/dialects/sqlite3/query/sqlite-querybuilder.js +33 -33
- package/lib/dialects/sqlite3/query/sqlite-querycompiler.js +341 -341
- package/lib/dialects/sqlite3/schema/ddl.js +380 -380
- package/lib/dialects/sqlite3/schema/internal/compiler.js +327 -327
- package/lib/dialects/sqlite3/schema/internal/parser-combinator.js +161 -161
- package/lib/dialects/sqlite3/schema/internal/parser.js +638 -638
- package/lib/dialects/sqlite3/schema/internal/sqlite-ddl-operations.js +41 -41
- package/lib/dialects/sqlite3/schema/internal/tokenizer.js +38 -38
- package/lib/dialects/sqlite3/schema/internal/utils.js +12 -12
- package/lib/dialects/sqlite3/schema/sqlite-columncompiler.js +50 -50
- package/lib/dialects/sqlite3/schema/sqlite-compiler.js +80 -80
- package/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js +364 -364
- package/lib/dialects/sqlite3/schema/sqlite-viewcompiler.js +40 -40
- package/lib/execution/batch-insert.js +51 -51
- package/lib/execution/internal/delay.js +6 -6
- package/lib/execution/internal/ensure-connection-callback.js +41 -41
- package/lib/execution/internal/query-executioner.js +62 -62
- package/lib/execution/runner.js +325 -325
- package/lib/execution/transaction.js +417 -417
- package/lib/formatter/formatterUtils.js +42 -42
- package/lib/formatter/rawFormatter.js +84 -84
- package/lib/formatter/wrappingFormatter.js +253 -253
- package/lib/formatter.js +25 -25
- package/lib/index.js +3 -3
- package/lib/knex-builder/FunctionHelper.js +80 -80
- package/lib/knex-builder/Knex.js +59 -59
- package/lib/knex-builder/internal/config-resolver.js +57 -57
- package/lib/knex-builder/internal/parse-connection.js +87 -87
- package/lib/knex-builder/make-knex.js +345 -345
- package/lib/logger.js +76 -76
- package/lib/migrations/common/MigrationsLoader.js +36 -36
- package/lib/migrations/migrate/MigrationGenerator.js +84 -84
- package/lib/migrations/migrate/Migrator.js +632 -632
- package/lib/migrations/migrate/migrate-stub.js +17 -17
- package/lib/migrations/migrate/migration-list-resolver.js +33 -33
- package/lib/migrations/migrate/migrator-configuration-merger.js +58 -58
- package/lib/migrations/migrate/sources/fs-migrations.js +74 -74
- package/lib/migrations/migrate/stub/cjs.stub +15 -15
- package/lib/migrations/migrate/stub/coffee.stub +13 -13
- package/lib/migrations/migrate/stub/eg.stub +14 -14
- package/lib/migrations/migrate/stub/js-schema.stub +22 -22
- package/lib/migrations/migrate/stub/js.stub +22 -22
- package/lib/migrations/migrate/stub/knexfile-coffee.stub +34 -34
- package/lib/migrations/migrate/stub/knexfile-eg.stub +43 -43
- package/lib/migrations/migrate/stub/knexfile-js.stub +47 -47
- package/lib/migrations/migrate/stub/knexfile-ls.stub +35 -35
- package/lib/migrations/migrate/stub/knexfile-ts.stub +47 -47
- package/lib/migrations/migrate/stub/ls.stub +14 -14
- package/lib/migrations/migrate/stub/mjs.stub +23 -23
- package/lib/migrations/migrate/stub/ts-schema.stub +21 -21
- package/lib/migrations/migrate/stub/ts.stub +21 -21
- package/lib/migrations/migrate/table-creator.js +77 -77
- package/lib/migrations/migrate/table-resolver.js +27 -27
- package/lib/migrations/seed/Seeder.js +137 -137
- package/lib/migrations/seed/seed-stub.js +13 -13
- package/lib/migrations/seed/seeder-configuration-merger.js +60 -60
- package/lib/migrations/seed/sources/fs-seeds.js +65 -65
- package/lib/migrations/seed/stub/coffee.stub +9 -9
- package/lib/migrations/seed/stub/eg.stub +11 -11
- package/lib/migrations/seed/stub/js.stub +13 -13
- package/lib/migrations/seed/stub/ls.stub +11 -11
- package/lib/migrations/seed/stub/mjs.stub +12 -12
- package/lib/migrations/seed/stub/ts.stub +13 -13
- package/lib/migrations/util/fs.js +86 -86
- package/lib/migrations/util/import-file.js +12 -12
- package/lib/migrations/util/is-module-type.js +9 -9
- package/lib/migrations/util/template.js +52 -52
- package/lib/migrations/util/timestamp.js +14 -14
- package/lib/query/analytic.js +52 -52
- package/lib/query/constants.js +15 -15
- package/lib/query/joinclause.js +270 -270
- package/lib/query/method-constants.js +136 -136
- package/lib/query/querybuilder.js +1793 -1793
- package/lib/query/querycompiler.js +1634 -1634
- package/lib/raw.js +139 -139
- package/lib/ref.js +39 -39
- package/lib/schema/builder.js +115 -115
- package/lib/schema/columnbuilder.js +146 -146
- package/lib/schema/columncompiler.js +307 -307
- package/lib/schema/compiler.js +187 -187
- package/lib/schema/internal/helpers.js +55 -55
- package/lib/schema/tablebuilder.js +379 -379
- package/lib/schema/tablecompiler.js +450 -450
- package/lib/schema/viewbuilder.js +92 -92
- package/lib/schema/viewcompiler.js +138 -138
- package/lib/util/finally-mixin.js +13 -13
- package/lib/util/helpers.js +95 -95
- package/lib/util/is.js +32 -32
- package/lib/util/nanoid.js +40 -40
- package/lib/util/noop.js +1 -1
- package/lib/util/save-async-stack.js +14 -14
- package/lib/util/security.js +32 -32
- package/lib/util/string.js +190 -190
- package/lib/util/timeout.js +29 -29
- package/package.json +294 -293
- package/scripts/act-testing/act.sh +19 -19
- package/scripts/act-testing/merged-no-label.json +11 -11
- package/scripts/act-testing/merged-patch-labeled.json +12 -12
- package/scripts/act-testing/merged-skip-labeled.json +12 -12
- package/scripts/act-testing/not-merged-patch-labeled.json +12 -12
- package/scripts/build-for-release.sh +121 -121
- package/scripts/build.js +125 -125
- package/scripts/clean.js +31 -31
- package/scripts/docker-compose.yml +150 -150
- package/scripts/format-changelog.js +55 -55
- package/scripts/next-release-howto.md +24 -24
- package/scripts/oracledb-install-driver-libs.sh +82 -82
- package/scripts/release.sh +36 -36
- package/scripts/runkit-example.js +35 -35
- package/scripts/stress-test/README.txt +18 -18
- package/scripts/stress-test/docker-compose.yml +55 -55
- package/scripts/stress-test/knex-stress-test.js +212 -212
- package/scripts/stress-test/mysql2-random-hanging-every-now-and-then.js +149 -149
- package/scripts/stress-test/mysql2-sudden-exit-without-error.js +101 -101
- package/scripts/stress-test/reconnect-test-mysql-based-drivers.js +188 -188
- package/types/index.d.mts +11 -0
- package/types/index.d.ts +3321 -3321
- package/types/result.d.ts +27 -27
- package/types/tables.d.ts +4 -4
|
@@ -1,379 +1,379 @@
|
|
|
1
|
-
// TableBuilder
|
|
2
|
-
|
|
3
|
-
// Takes the function passed to the "createTable" or "table/editTable"
|
|
4
|
-
// functions and calls it with the "TableBuilder" as both the context and
|
|
5
|
-
// the first argument. Inside this function we can specify what happens to the
|
|
6
|
-
// method, pushing everything we want to do onto the "allStatements" array,
|
|
7
|
-
// which is then compiled into sql.
|
|
8
|
-
// ------
|
|
9
|
-
const each = require('lodash/each');
|
|
10
|
-
const extend = require('lodash/extend');
|
|
11
|
-
const assign = require('lodash/assign');
|
|
12
|
-
const toArray = require('lodash/toArray');
|
|
13
|
-
const helpers = require('../util/helpers');
|
|
14
|
-
const { isString, isFunction, isObject } = require('../util/is');
|
|
15
|
-
|
|
16
|
-
class TableBuilder {
|
|
17
|
-
constructor(client, method, tableName, tableNameLike, fn) {
|
|
18
|
-
this.client = client;
|
|
19
|
-
this._fn = fn;
|
|
20
|
-
this._method = method;
|
|
21
|
-
this._schemaName = undefined;
|
|
22
|
-
this._tableName = tableName;
|
|
23
|
-
this._tableNameLike = tableNameLike;
|
|
24
|
-
this._statements = [];
|
|
25
|
-
this._single = {};
|
|
26
|
-
|
|
27
|
-
if (!tableNameLike && !isFunction(this._fn)) {
|
|
28
|
-
throw new TypeError(
|
|
29
|
-
'A callback function must be supplied to calls against `.createTable` ' +
|
|
30
|
-
'and `.table`'
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
setSchema(schemaName) {
|
|
36
|
-
this._schemaName = schemaName;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Convert the current tableBuilder object "toSQL"
|
|
40
|
-
// giving us additional methods if we're altering
|
|
41
|
-
// rather than creating the table.
|
|
42
|
-
toSQL() {
|
|
43
|
-
if (this._method === 'alter') {
|
|
44
|
-
extend(this, AlterMethods);
|
|
45
|
-
}
|
|
46
|
-
// With 'create table ... like' callback function is useless.
|
|
47
|
-
if (this._fn) {
|
|
48
|
-
this._fn.call(this, this);
|
|
49
|
-
}
|
|
50
|
-
return this.client.tableCompiler(this).toSQL();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// The "timestamps" call is really just sets the `created_at` and `updated_at` columns.
|
|
54
|
-
|
|
55
|
-
timestamps(useTimestamps, defaultToNow, useCamelCase) {
|
|
56
|
-
if (isObject(useTimestamps)) {
|
|
57
|
-
({ useTimestamps, defaultToNow, useCamelCase } = useTimestamps);
|
|
58
|
-
}
|
|
59
|
-
const method = useTimestamps === true ? 'timestamp' : 'datetime';
|
|
60
|
-
const createdAt = this[method](useCamelCase ? 'createdAt' : 'created_at');
|
|
61
|
-
const updatedAt = this[method](useCamelCase ? 'updatedAt' : 'updated_at');
|
|
62
|
-
|
|
63
|
-
if (defaultToNow === true) {
|
|
64
|
-
const now = this.client.raw('CURRENT_TIMESTAMP');
|
|
65
|
-
createdAt.notNullable().defaultTo(now);
|
|
66
|
-
updatedAt.notNullable().defaultTo(now);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Set the comment value for a table, they're only allowed to be called
|
|
71
|
-
// once per table.
|
|
72
|
-
comment(value) {
|
|
73
|
-
if (typeof value !== 'string') {
|
|
74
|
-
throw new TypeError('Table comment must be string');
|
|
75
|
-
}
|
|
76
|
-
this._single.comment = value;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Set a foreign key on the table, calling
|
|
80
|
-
// `table.foreign('column_name').references('column').on('table').onDelete()...
|
|
81
|
-
// Also called from the ColumnBuilder context when chaining.
|
|
82
|
-
foreign(column, keyName) {
|
|
83
|
-
const foreignData = { column: column, keyName: keyName };
|
|
84
|
-
this._statements.push({
|
|
85
|
-
grouping: 'alterTable',
|
|
86
|
-
method: 'foreign',
|
|
87
|
-
args: [foreignData],
|
|
88
|
-
});
|
|
89
|
-
let returnObj = {
|
|
90
|
-
references(tableColumn) {
|
|
91
|
-
let pieces;
|
|
92
|
-
if (isString(tableColumn)) {
|
|
93
|
-
pieces = tableColumn.split('.');
|
|
94
|
-
}
|
|
95
|
-
if (!pieces || pieces.length === 1) {
|
|
96
|
-
foreignData.references = pieces ? pieces[0] : tableColumn;
|
|
97
|
-
return {
|
|
98
|
-
on(tableName) {
|
|
99
|
-
if (typeof tableName !== 'string') {
|
|
100
|
-
throw new TypeError(
|
|
101
|
-
`Expected tableName to be a string, got: ${typeof tableName}`
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
foreignData.inTable = tableName;
|
|
105
|
-
return returnObj;
|
|
106
|
-
},
|
|
107
|
-
inTable() {
|
|
108
|
-
return this.on.apply(this, arguments);
|
|
109
|
-
},
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
foreignData.inTable = pieces[0];
|
|
113
|
-
foreignData.references = pieces[1];
|
|
114
|
-
return returnObj;
|
|
115
|
-
},
|
|
116
|
-
withKeyName(keyName) {
|
|
117
|
-
foreignData.keyName = keyName;
|
|
118
|
-
return returnObj;
|
|
119
|
-
},
|
|
120
|
-
onUpdate(statement) {
|
|
121
|
-
foreignData.onUpdate = statement;
|
|
122
|
-
return returnObj;
|
|
123
|
-
},
|
|
124
|
-
onDelete(statement) {
|
|
125
|
-
foreignData.onDelete = statement;
|
|
126
|
-
return returnObj;
|
|
127
|
-
},
|
|
128
|
-
deferrable: (type) => {
|
|
129
|
-
const unSupported = [
|
|
130
|
-
'mysql',
|
|
131
|
-
'mssql',
|
|
132
|
-
'redshift',
|
|
133
|
-
'mysql2',
|
|
134
|
-
'oracledb',
|
|
135
|
-
];
|
|
136
|
-
if (unSupported.indexOf(this.client.dialect) !== -1) {
|
|
137
|
-
throw new Error(`${this.client.dialect} does not support deferrable`);
|
|
138
|
-
}
|
|
139
|
-
foreignData.deferrable = type;
|
|
140
|
-
return returnObj;
|
|
141
|
-
},
|
|
142
|
-
_columnBuilder(builder) {
|
|
143
|
-
extend(builder, returnObj);
|
|
144
|
-
returnObj = builder;
|
|
145
|
-
return builder;
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
return returnObj;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
check(checkPredicate, bindings, constraintName) {
|
|
152
|
-
this._statements.push({
|
|
153
|
-
grouping: 'checks',
|
|
154
|
-
args: [checkPredicate, bindings, constraintName],
|
|
155
|
-
});
|
|
156
|
-
return this;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
[
|
|
161
|
-
// Each of the index methods can be called individually, with the
|
|
162
|
-
// column name to be used, e.g. table.unique('column').
|
|
163
|
-
'index',
|
|
164
|
-
'primary',
|
|
165
|
-
'unique',
|
|
166
|
-
|
|
167
|
-
// Key specific
|
|
168
|
-
'dropPrimary',
|
|
169
|
-
'dropPrimaryIfExists',
|
|
170
|
-
'dropUnique',
|
|
171
|
-
'dropUniqueIfExists',
|
|
172
|
-
'dropIndex',
|
|
173
|
-
'dropForeign',
|
|
174
|
-
'dropForeignIfExists',
|
|
175
|
-
].forEach((method) => {
|
|
176
|
-
TableBuilder.prototype[method] = function () {
|
|
177
|
-
this._statements.push({
|
|
178
|
-
grouping: 'alterTable',
|
|
179
|
-
method,
|
|
180
|
-
args: toArray(arguments),
|
|
181
|
-
});
|
|
182
|
-
return this;
|
|
183
|
-
};
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// Warn for dialect-specific table methods, since that's the
|
|
187
|
-
// only time these are supported.
|
|
188
|
-
const specialMethods = {
|
|
189
|
-
mysql: ['engine', 'charset', 'collate'],
|
|
190
|
-
postgresql: ['inherits'],
|
|
191
|
-
};
|
|
192
|
-
each(specialMethods, function (methods, dialect) {
|
|
193
|
-
methods.forEach(function (method) {
|
|
194
|
-
TableBuilder.prototype[method] = function (value) {
|
|
195
|
-
if (this.client.dialect !== dialect) {
|
|
196
|
-
throw new Error(
|
|
197
|
-
`Knex only supports ${method} statement with ${dialect}.`
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
if (this._method === 'alter') {
|
|
201
|
-
throw new Error(
|
|
202
|
-
`Knex does not support altering the ${method} outside of create ` +
|
|
203
|
-
`table, please use knex.raw statement.`
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
this._single[method] = value;
|
|
207
|
-
};
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
helpers.addQueryContext(TableBuilder);
|
|
212
|
-
|
|
213
|
-
// Each of the column types that we can add, we create a new ColumnBuilder
|
|
214
|
-
// instance and push it onto the statements array.
|
|
215
|
-
const columnTypes = [
|
|
216
|
-
// Numeric
|
|
217
|
-
'tinyint',
|
|
218
|
-
'smallint',
|
|
219
|
-
'mediumint',
|
|
220
|
-
'int',
|
|
221
|
-
'bigint',
|
|
222
|
-
'decimal',
|
|
223
|
-
'float',
|
|
224
|
-
'double',
|
|
225
|
-
'real',
|
|
226
|
-
'bit',
|
|
227
|
-
'boolean',
|
|
228
|
-
'serial',
|
|
229
|
-
|
|
230
|
-
// Date / Time
|
|
231
|
-
'date',
|
|
232
|
-
'datetime',
|
|
233
|
-
'timestamp',
|
|
234
|
-
'time',
|
|
235
|
-
'year',
|
|
236
|
-
|
|
237
|
-
// Geometry
|
|
238
|
-
'geometry',
|
|
239
|
-
'geography',
|
|
240
|
-
'point',
|
|
241
|
-
|
|
242
|
-
// String
|
|
243
|
-
'char',
|
|
244
|
-
'varchar',
|
|
245
|
-
'tinytext',
|
|
246
|
-
'tinyText',
|
|
247
|
-
'text',
|
|
248
|
-
'mediumtext',
|
|
249
|
-
'mediumText',
|
|
250
|
-
'longtext',
|
|
251
|
-
'longText',
|
|
252
|
-
'binary',
|
|
253
|
-
'varbinary',
|
|
254
|
-
'tinyblob',
|
|
255
|
-
'tinyBlob',
|
|
256
|
-
'mediumblob',
|
|
257
|
-
'mediumBlob',
|
|
258
|
-
'blob',
|
|
259
|
-
'longblob',
|
|
260
|
-
'longBlob',
|
|
261
|
-
'enum',
|
|
262
|
-
'set',
|
|
263
|
-
|
|
264
|
-
// Increments, Aliases, and Additional
|
|
265
|
-
'bool',
|
|
266
|
-
'dateTime',
|
|
267
|
-
'increments',
|
|
268
|
-
'bigincrements',
|
|
269
|
-
'bigIncrements',
|
|
270
|
-
'integer',
|
|
271
|
-
'biginteger',
|
|
272
|
-
'bigInteger',
|
|
273
|
-
'string',
|
|
274
|
-
'json',
|
|
275
|
-
'jsonb',
|
|
276
|
-
'uuid',
|
|
277
|
-
'enu',
|
|
278
|
-
'specificType',
|
|
279
|
-
];
|
|
280
|
-
|
|
281
|
-
// For each of the column methods, create a new "ColumnBuilder" interface,
|
|
282
|
-
// push it onto the "allStatements" stack, and then return the interface,
|
|
283
|
-
// with which we can add indexes, etc.
|
|
284
|
-
columnTypes.forEach((type) => {
|
|
285
|
-
TableBuilder.prototype[type] = function () {
|
|
286
|
-
const args = toArray(arguments);
|
|
287
|
-
const builder = this.client.columnBuilder(this, type, args);
|
|
288
|
-
this._statements.push({
|
|
289
|
-
grouping: 'columns',
|
|
290
|
-
builder,
|
|
291
|
-
});
|
|
292
|
-
return builder;
|
|
293
|
-
};
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
const AlterMethods = {
|
|
297
|
-
// Renames the current column `from` the current
|
|
298
|
-
// TODO: this.column(from).rename(to)
|
|
299
|
-
renameColumn(from, to) {
|
|
300
|
-
this._statements.push({
|
|
301
|
-
grouping: 'alterTable',
|
|
302
|
-
method: 'renameColumn',
|
|
303
|
-
args: [from, to],
|
|
304
|
-
});
|
|
305
|
-
return this;
|
|
306
|
-
},
|
|
307
|
-
|
|
308
|
-
dropTimestamps() {
|
|
309
|
-
// arguments[0] = useCamelCase
|
|
310
|
-
return this.dropColumns(
|
|
311
|
-
arguments[0] === true
|
|
312
|
-
? ['createdAt', 'updatedAt']
|
|
313
|
-
: ['created_at', 'updated_at']
|
|
314
|
-
);
|
|
315
|
-
},
|
|
316
|
-
|
|
317
|
-
setNullable(column) {
|
|
318
|
-
this._statements.push({
|
|
319
|
-
grouping: 'alterTable',
|
|
320
|
-
method: 'setNullable',
|
|
321
|
-
args: [column],
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
return this;
|
|
325
|
-
},
|
|
326
|
-
|
|
327
|
-
check(checkPredicate, bindings, constraintName) {
|
|
328
|
-
this._statements.push({
|
|
329
|
-
grouping: 'alterTable',
|
|
330
|
-
method: 'check',
|
|
331
|
-
args: [checkPredicate, bindings, constraintName],
|
|
332
|
-
});
|
|
333
|
-
},
|
|
334
|
-
|
|
335
|
-
dropChecks() {
|
|
336
|
-
this._statements.push({
|
|
337
|
-
grouping: 'alterTable',
|
|
338
|
-
method: 'dropChecks',
|
|
339
|
-
args: toArray(arguments),
|
|
340
|
-
});
|
|
341
|
-
},
|
|
342
|
-
|
|
343
|
-
dropNullable(column) {
|
|
344
|
-
this._statements.push({
|
|
345
|
-
grouping: 'alterTable',
|
|
346
|
-
method: 'dropNullable',
|
|
347
|
-
args: [column],
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
return this;
|
|
351
|
-
},
|
|
352
|
-
|
|
353
|
-
// TODO: changeType
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
// Drop a column from the current table.
|
|
357
|
-
// TODO: Enable this.column(columnName).drop();
|
|
358
|
-
AlterMethods.dropColumn = AlterMethods.dropColumns = function () {
|
|
359
|
-
this._statements.push({
|
|
360
|
-
grouping: 'alterTable',
|
|
361
|
-
method: 'dropColumn',
|
|
362
|
-
args: toArray(arguments),
|
|
363
|
-
});
|
|
364
|
-
return this;
|
|
365
|
-
};
|
|
366
|
-
|
|
367
|
-
TableBuilder.extend = (methodName, fn) => {
|
|
368
|
-
if (
|
|
369
|
-
Object.prototype.hasOwnProperty.call(TableBuilder.prototype, methodName)
|
|
370
|
-
) {
|
|
371
|
-
throw new Error(
|
|
372
|
-
`Can't extend TableBuilder with existing method ('${methodName}').`
|
|
373
|
-
);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
assign(TableBuilder.prototype, { [methodName]: fn });
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
module.exports = TableBuilder;
|
|
1
|
+
// TableBuilder
|
|
2
|
+
|
|
3
|
+
// Takes the function passed to the "createTable" or "table/editTable"
|
|
4
|
+
// functions and calls it with the "TableBuilder" as both the context and
|
|
5
|
+
// the first argument. Inside this function we can specify what happens to the
|
|
6
|
+
// method, pushing everything we want to do onto the "allStatements" array,
|
|
7
|
+
// which is then compiled into sql.
|
|
8
|
+
// ------
|
|
9
|
+
const each = require('lodash/each');
|
|
10
|
+
const extend = require('lodash/extend');
|
|
11
|
+
const assign = require('lodash/assign');
|
|
12
|
+
const toArray = require('lodash/toArray');
|
|
13
|
+
const helpers = require('../util/helpers');
|
|
14
|
+
const { isString, isFunction, isObject } = require('../util/is');
|
|
15
|
+
|
|
16
|
+
class TableBuilder {
|
|
17
|
+
constructor(client, method, tableName, tableNameLike, fn) {
|
|
18
|
+
this.client = client;
|
|
19
|
+
this._fn = fn;
|
|
20
|
+
this._method = method;
|
|
21
|
+
this._schemaName = undefined;
|
|
22
|
+
this._tableName = tableName;
|
|
23
|
+
this._tableNameLike = tableNameLike;
|
|
24
|
+
this._statements = [];
|
|
25
|
+
this._single = {};
|
|
26
|
+
|
|
27
|
+
if (!tableNameLike && !isFunction(this._fn)) {
|
|
28
|
+
throw new TypeError(
|
|
29
|
+
'A callback function must be supplied to calls against `.createTable` ' +
|
|
30
|
+
'and `.table`'
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
setSchema(schemaName) {
|
|
36
|
+
this._schemaName = schemaName;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Convert the current tableBuilder object "toSQL"
|
|
40
|
+
// giving us additional methods if we're altering
|
|
41
|
+
// rather than creating the table.
|
|
42
|
+
toSQL() {
|
|
43
|
+
if (this._method === 'alter') {
|
|
44
|
+
extend(this, AlterMethods);
|
|
45
|
+
}
|
|
46
|
+
// With 'create table ... like' callback function is useless.
|
|
47
|
+
if (this._fn) {
|
|
48
|
+
this._fn.call(this, this);
|
|
49
|
+
}
|
|
50
|
+
return this.client.tableCompiler(this).toSQL();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// The "timestamps" call is really just sets the `created_at` and `updated_at` columns.
|
|
54
|
+
|
|
55
|
+
timestamps(useTimestamps, defaultToNow, useCamelCase) {
|
|
56
|
+
if (isObject(useTimestamps)) {
|
|
57
|
+
({ useTimestamps, defaultToNow, useCamelCase } = useTimestamps);
|
|
58
|
+
}
|
|
59
|
+
const method = useTimestamps === true ? 'timestamp' : 'datetime';
|
|
60
|
+
const createdAt = this[method](useCamelCase ? 'createdAt' : 'created_at');
|
|
61
|
+
const updatedAt = this[method](useCamelCase ? 'updatedAt' : 'updated_at');
|
|
62
|
+
|
|
63
|
+
if (defaultToNow === true) {
|
|
64
|
+
const now = this.client.raw('CURRENT_TIMESTAMP');
|
|
65
|
+
createdAt.notNullable().defaultTo(now);
|
|
66
|
+
updatedAt.notNullable().defaultTo(now);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Set the comment value for a table, they're only allowed to be called
|
|
71
|
+
// once per table.
|
|
72
|
+
comment(value) {
|
|
73
|
+
if (typeof value !== 'string') {
|
|
74
|
+
throw new TypeError('Table comment must be string');
|
|
75
|
+
}
|
|
76
|
+
this._single.comment = value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Set a foreign key on the table, calling
|
|
80
|
+
// `table.foreign('column_name').references('column').on('table').onDelete()...
|
|
81
|
+
// Also called from the ColumnBuilder context when chaining.
|
|
82
|
+
foreign(column, keyName) {
|
|
83
|
+
const foreignData = { column: column, keyName: keyName };
|
|
84
|
+
this._statements.push({
|
|
85
|
+
grouping: 'alterTable',
|
|
86
|
+
method: 'foreign',
|
|
87
|
+
args: [foreignData],
|
|
88
|
+
});
|
|
89
|
+
let returnObj = {
|
|
90
|
+
references(tableColumn) {
|
|
91
|
+
let pieces;
|
|
92
|
+
if (isString(tableColumn)) {
|
|
93
|
+
pieces = tableColumn.split('.');
|
|
94
|
+
}
|
|
95
|
+
if (!pieces || pieces.length === 1) {
|
|
96
|
+
foreignData.references = pieces ? pieces[0] : tableColumn;
|
|
97
|
+
return {
|
|
98
|
+
on(tableName) {
|
|
99
|
+
if (typeof tableName !== 'string') {
|
|
100
|
+
throw new TypeError(
|
|
101
|
+
`Expected tableName to be a string, got: ${typeof tableName}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
foreignData.inTable = tableName;
|
|
105
|
+
return returnObj;
|
|
106
|
+
},
|
|
107
|
+
inTable() {
|
|
108
|
+
return this.on.apply(this, arguments);
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
foreignData.inTable = pieces[0];
|
|
113
|
+
foreignData.references = pieces[1];
|
|
114
|
+
return returnObj;
|
|
115
|
+
},
|
|
116
|
+
withKeyName(keyName) {
|
|
117
|
+
foreignData.keyName = keyName;
|
|
118
|
+
return returnObj;
|
|
119
|
+
},
|
|
120
|
+
onUpdate(statement) {
|
|
121
|
+
foreignData.onUpdate = statement;
|
|
122
|
+
return returnObj;
|
|
123
|
+
},
|
|
124
|
+
onDelete(statement) {
|
|
125
|
+
foreignData.onDelete = statement;
|
|
126
|
+
return returnObj;
|
|
127
|
+
},
|
|
128
|
+
deferrable: (type) => {
|
|
129
|
+
const unSupported = [
|
|
130
|
+
'mysql',
|
|
131
|
+
'mssql',
|
|
132
|
+
'redshift',
|
|
133
|
+
'mysql2',
|
|
134
|
+
'oracledb',
|
|
135
|
+
];
|
|
136
|
+
if (unSupported.indexOf(this.client.dialect) !== -1) {
|
|
137
|
+
throw new Error(`${this.client.dialect} does not support deferrable`);
|
|
138
|
+
}
|
|
139
|
+
foreignData.deferrable = type;
|
|
140
|
+
return returnObj;
|
|
141
|
+
},
|
|
142
|
+
_columnBuilder(builder) {
|
|
143
|
+
extend(builder, returnObj);
|
|
144
|
+
returnObj = builder;
|
|
145
|
+
return builder;
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
return returnObj;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
check(checkPredicate, bindings, constraintName) {
|
|
152
|
+
this._statements.push({
|
|
153
|
+
grouping: 'checks',
|
|
154
|
+
args: [checkPredicate, bindings, constraintName],
|
|
155
|
+
});
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
[
|
|
161
|
+
// Each of the index methods can be called individually, with the
|
|
162
|
+
// column name to be used, e.g. table.unique('column').
|
|
163
|
+
'index',
|
|
164
|
+
'primary',
|
|
165
|
+
'unique',
|
|
166
|
+
|
|
167
|
+
// Key specific
|
|
168
|
+
'dropPrimary',
|
|
169
|
+
'dropPrimaryIfExists',
|
|
170
|
+
'dropUnique',
|
|
171
|
+
'dropUniqueIfExists',
|
|
172
|
+
'dropIndex',
|
|
173
|
+
'dropForeign',
|
|
174
|
+
'dropForeignIfExists',
|
|
175
|
+
].forEach((method) => {
|
|
176
|
+
TableBuilder.prototype[method] = function () {
|
|
177
|
+
this._statements.push({
|
|
178
|
+
grouping: 'alterTable',
|
|
179
|
+
method,
|
|
180
|
+
args: toArray(arguments),
|
|
181
|
+
});
|
|
182
|
+
return this;
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Warn for dialect-specific table methods, since that's the
|
|
187
|
+
// only time these are supported.
|
|
188
|
+
const specialMethods = {
|
|
189
|
+
mysql: ['engine', 'charset', 'collate'],
|
|
190
|
+
postgresql: ['inherits'],
|
|
191
|
+
};
|
|
192
|
+
each(specialMethods, function (methods, dialect) {
|
|
193
|
+
methods.forEach(function (method) {
|
|
194
|
+
TableBuilder.prototype[method] = function (value) {
|
|
195
|
+
if (this.client.dialect !== dialect) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
`Knex only supports ${method} statement with ${dialect}.`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
if (this._method === 'alter') {
|
|
201
|
+
throw new Error(
|
|
202
|
+
`Knex does not support altering the ${method} outside of create ` +
|
|
203
|
+
`table, please use knex.raw statement.`
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
this._single[method] = value;
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
helpers.addQueryContext(TableBuilder);
|
|
212
|
+
|
|
213
|
+
// Each of the column types that we can add, we create a new ColumnBuilder
|
|
214
|
+
// instance and push it onto the statements array.
|
|
215
|
+
const columnTypes = [
|
|
216
|
+
// Numeric
|
|
217
|
+
'tinyint',
|
|
218
|
+
'smallint',
|
|
219
|
+
'mediumint',
|
|
220
|
+
'int',
|
|
221
|
+
'bigint',
|
|
222
|
+
'decimal',
|
|
223
|
+
'float',
|
|
224
|
+
'double',
|
|
225
|
+
'real',
|
|
226
|
+
'bit',
|
|
227
|
+
'boolean',
|
|
228
|
+
'serial',
|
|
229
|
+
|
|
230
|
+
// Date / Time
|
|
231
|
+
'date',
|
|
232
|
+
'datetime',
|
|
233
|
+
'timestamp',
|
|
234
|
+
'time',
|
|
235
|
+
'year',
|
|
236
|
+
|
|
237
|
+
// Geometry
|
|
238
|
+
'geometry',
|
|
239
|
+
'geography',
|
|
240
|
+
'point',
|
|
241
|
+
|
|
242
|
+
// String
|
|
243
|
+
'char',
|
|
244
|
+
'varchar',
|
|
245
|
+
'tinytext',
|
|
246
|
+
'tinyText',
|
|
247
|
+
'text',
|
|
248
|
+
'mediumtext',
|
|
249
|
+
'mediumText',
|
|
250
|
+
'longtext',
|
|
251
|
+
'longText',
|
|
252
|
+
'binary',
|
|
253
|
+
'varbinary',
|
|
254
|
+
'tinyblob',
|
|
255
|
+
'tinyBlob',
|
|
256
|
+
'mediumblob',
|
|
257
|
+
'mediumBlob',
|
|
258
|
+
'blob',
|
|
259
|
+
'longblob',
|
|
260
|
+
'longBlob',
|
|
261
|
+
'enum',
|
|
262
|
+
'set',
|
|
263
|
+
|
|
264
|
+
// Increments, Aliases, and Additional
|
|
265
|
+
'bool',
|
|
266
|
+
'dateTime',
|
|
267
|
+
'increments',
|
|
268
|
+
'bigincrements',
|
|
269
|
+
'bigIncrements',
|
|
270
|
+
'integer',
|
|
271
|
+
'biginteger',
|
|
272
|
+
'bigInteger',
|
|
273
|
+
'string',
|
|
274
|
+
'json',
|
|
275
|
+
'jsonb',
|
|
276
|
+
'uuid',
|
|
277
|
+
'enu',
|
|
278
|
+
'specificType',
|
|
279
|
+
];
|
|
280
|
+
|
|
281
|
+
// For each of the column methods, create a new "ColumnBuilder" interface,
|
|
282
|
+
// push it onto the "allStatements" stack, and then return the interface,
|
|
283
|
+
// with which we can add indexes, etc.
|
|
284
|
+
columnTypes.forEach((type) => {
|
|
285
|
+
TableBuilder.prototype[type] = function () {
|
|
286
|
+
const args = toArray(arguments);
|
|
287
|
+
const builder = this.client.columnBuilder(this, type, args);
|
|
288
|
+
this._statements.push({
|
|
289
|
+
grouping: 'columns',
|
|
290
|
+
builder,
|
|
291
|
+
});
|
|
292
|
+
return builder;
|
|
293
|
+
};
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
const AlterMethods = {
|
|
297
|
+
// Renames the current column `from` the current
|
|
298
|
+
// TODO: this.column(from).rename(to)
|
|
299
|
+
renameColumn(from, to) {
|
|
300
|
+
this._statements.push({
|
|
301
|
+
grouping: 'alterTable',
|
|
302
|
+
method: 'renameColumn',
|
|
303
|
+
args: [from, to],
|
|
304
|
+
});
|
|
305
|
+
return this;
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
dropTimestamps() {
|
|
309
|
+
// arguments[0] = useCamelCase
|
|
310
|
+
return this.dropColumns(
|
|
311
|
+
arguments[0] === true
|
|
312
|
+
? ['createdAt', 'updatedAt']
|
|
313
|
+
: ['created_at', 'updated_at']
|
|
314
|
+
);
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
setNullable(column) {
|
|
318
|
+
this._statements.push({
|
|
319
|
+
grouping: 'alterTable',
|
|
320
|
+
method: 'setNullable',
|
|
321
|
+
args: [column],
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
return this;
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
check(checkPredicate, bindings, constraintName) {
|
|
328
|
+
this._statements.push({
|
|
329
|
+
grouping: 'alterTable',
|
|
330
|
+
method: 'check',
|
|
331
|
+
args: [checkPredicate, bindings, constraintName],
|
|
332
|
+
});
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
dropChecks() {
|
|
336
|
+
this._statements.push({
|
|
337
|
+
grouping: 'alterTable',
|
|
338
|
+
method: 'dropChecks',
|
|
339
|
+
args: toArray(arguments),
|
|
340
|
+
});
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
dropNullable(column) {
|
|
344
|
+
this._statements.push({
|
|
345
|
+
grouping: 'alterTable',
|
|
346
|
+
method: 'dropNullable',
|
|
347
|
+
args: [column],
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
return this;
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
// TODO: changeType
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
// Drop a column from the current table.
|
|
357
|
+
// TODO: Enable this.column(columnName).drop();
|
|
358
|
+
AlterMethods.dropColumn = AlterMethods.dropColumns = function () {
|
|
359
|
+
this._statements.push({
|
|
360
|
+
grouping: 'alterTable',
|
|
361
|
+
method: 'dropColumn',
|
|
362
|
+
args: toArray(arguments),
|
|
363
|
+
});
|
|
364
|
+
return this;
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
TableBuilder.extend = (methodName, fn) => {
|
|
368
|
+
if (
|
|
369
|
+
Object.prototype.hasOwnProperty.call(TableBuilder.prototype, methodName)
|
|
370
|
+
) {
|
|
371
|
+
throw new Error(
|
|
372
|
+
`Can't extend TableBuilder with existing method ('${methodName}').`
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
assign(TableBuilder.prototype, { [methodName]: fn });
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
module.exports = TableBuilder;
|