knex 2.5.0 → 2.5.1

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.
Files changed (167) hide show
  1. package/CHANGELOG.md +64 -58
  2. package/CONTRIBUTING.md +194 -194
  3. package/README.md +149 -147
  4. package/UPGRADING.md +245 -233
  5. package/bin/cli.js +475 -473
  6. package/bin/utils/cli-config-utils.js +212 -210
  7. package/bin/utils/constants.js +7 -7
  8. package/bin/utils/migrationsLister.js +37 -37
  9. package/knex.js +23 -23
  10. package/knex.mjs +11 -11
  11. package/lib/builder-interface-augmenter.js +120 -120
  12. package/lib/client.js +495 -495
  13. package/lib/constants.js +61 -61
  14. package/lib/dialects/better-sqlite3/index.js +77 -77
  15. package/lib/dialects/cockroachdb/crdb-columncompiler.js +14 -14
  16. package/lib/dialects/cockroachdb/crdb-querybuilder.js +11 -11
  17. package/lib/dialects/cockroachdb/crdb-querycompiler.js +122 -122
  18. package/lib/dialects/cockroachdb/crdb-tablecompiler.js +37 -37
  19. package/lib/dialects/cockroachdb/crdb-viewcompiler.js +15 -15
  20. package/lib/dialects/cockroachdb/index.js +86 -86
  21. package/lib/dialects/index.js +20 -20
  22. package/lib/dialects/mssql/index.js +500 -500
  23. package/lib/dialects/mssql/mssql-formatter.js +34 -34
  24. package/lib/dialects/mssql/query/mssql-querycompiler.js +601 -601
  25. package/lib/dialects/mssql/schema/mssql-columncompiler.js +185 -185
  26. package/lib/dialects/mssql/schema/mssql-compiler.js +91 -91
  27. package/lib/dialects/mssql/schema/mssql-tablecompiler.js +378 -378
  28. package/lib/dialects/mssql/schema/mssql-viewcompiler.js +55 -55
  29. package/lib/dialects/mssql/transaction.js +176 -176
  30. package/lib/dialects/mysql/index.js +201 -201
  31. package/lib/dialects/mysql/query/mysql-querycompiler.js +274 -274
  32. package/lib/dialects/mysql/schema/mysql-columncompiler.js +193 -193
  33. package/lib/dialects/mysql/schema/mysql-compiler.js +60 -60
  34. package/lib/dialects/mysql/schema/mysql-tablecompiler.js +381 -381
  35. package/lib/dialects/mysql/schema/mysql-viewbuilder.js +21 -21
  36. package/lib/dialects/mysql/schema/mysql-viewcompiler.js +15 -15
  37. package/lib/dialects/mysql/transaction.js +46 -46
  38. package/lib/dialects/mysql2/index.js +53 -53
  39. package/lib/dialects/mysql2/transaction.js +44 -44
  40. package/lib/dialects/oracle/DEAD_CODE.md +5 -5
  41. package/lib/dialects/oracle/index.js +92 -92
  42. package/lib/dialects/oracle/query/oracle-querycompiler.js +343 -343
  43. package/lib/dialects/oracle/schema/internal/incrementUtils.js +20 -20
  44. package/lib/dialects/oracle/schema/internal/trigger.js +135 -135
  45. package/lib/dialects/oracle/schema/oracle-columnbuilder.js +17 -17
  46. package/lib/dialects/oracle/schema/oracle-columncompiler.js +126 -126
  47. package/lib/dialects/oracle/schema/oracle-compiler.js +122 -122
  48. package/lib/dialects/oracle/schema/oracle-tablecompiler.js +190 -190
  49. package/lib/dialects/oracle/utils.js +87 -87
  50. package/lib/dialects/oracledb/index.js +327 -327
  51. package/lib/dialects/oracledb/query/oracledb-querycompiler.js +481 -481
  52. package/lib/dialects/oracledb/schema/oracledb-columncompiler.js +61 -61
  53. package/lib/dialects/oracledb/schema/oracledb-tablecompiler.js +19 -19
  54. package/lib/dialects/oracledb/schema/oracledb-viewbuilder.js +13 -13
  55. package/lib/dialects/oracledb/schema/oracledb-viewcompiler.js +19 -19
  56. package/lib/dialects/oracledb/transaction.js +98 -98
  57. package/lib/dialects/oracledb/utils.js +208 -208
  58. package/lib/dialects/pgnative/index.js +60 -60
  59. package/lib/dialects/postgres/execution/pg-transaction.js +19 -19
  60. package/lib/dialects/postgres/index.js +358 -358
  61. package/lib/dialects/postgres/query/pg-querybuilder.js +43 -43
  62. package/lib/dialects/postgres/query/pg-querycompiler.js +400 -400
  63. package/lib/dialects/postgres/schema/pg-columncompiler.js +156 -156
  64. package/lib/dialects/postgres/schema/pg-compiler.js +138 -138
  65. package/lib/dialects/postgres/schema/pg-tablecompiler.js +304 -304
  66. package/lib/dialects/postgres/schema/pg-viewbuilder.js +21 -21
  67. package/lib/dialects/postgres/schema/pg-viewcompiler.js +35 -35
  68. package/lib/dialects/redshift/index.js +86 -86
  69. package/lib/dialects/redshift/query/redshift-querycompiler.js +163 -163
  70. package/lib/dialects/redshift/schema/redshift-columnbuilder.js +22 -22
  71. package/lib/dialects/redshift/schema/redshift-columncompiler.js +67 -67
  72. package/lib/dialects/redshift/schema/redshift-compiler.js +14 -14
  73. package/lib/dialects/redshift/schema/redshift-tablecompiler.js +122 -122
  74. package/lib/dialects/redshift/schema/redshift-viewcompiler.js +11 -11
  75. package/lib/dialects/redshift/transaction.js +32 -32
  76. package/lib/dialects/sqlite3/execution/sqlite-transaction.js +25 -25
  77. package/lib/dialects/sqlite3/index.js +250 -250
  78. package/lib/dialects/sqlite3/query/sqlite-querybuilder.js +33 -33
  79. package/lib/dialects/sqlite3/query/sqlite-querycompiler.js +334 -334
  80. package/lib/dialects/sqlite3/schema/ddl.js +400 -400
  81. package/lib/dialects/sqlite3/schema/internal/compiler.js +327 -327
  82. package/lib/dialects/sqlite3/schema/internal/parser-combinator.js +161 -161
  83. package/lib/dialects/sqlite3/schema/internal/parser.js +638 -638
  84. package/lib/dialects/sqlite3/schema/internal/sqlite-ddl-operations.js +41 -41
  85. package/lib/dialects/sqlite3/schema/internal/tokenizer.js +38 -38
  86. package/lib/dialects/sqlite3/schema/internal/utils.js +12 -12
  87. package/lib/dialects/sqlite3/schema/sqlite-columncompiler.js +50 -50
  88. package/lib/dialects/sqlite3/schema/sqlite-compiler.js +80 -80
  89. package/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js +347 -347
  90. package/lib/dialects/sqlite3/schema/sqlite-viewcompiler.js +40 -40
  91. package/lib/execution/batch-insert.js +51 -51
  92. package/lib/execution/internal/delay.js +6 -6
  93. package/lib/execution/internal/ensure-connection-callback.js +41 -41
  94. package/lib/execution/internal/query-executioner.js +62 -62
  95. package/lib/execution/runner.js +325 -325
  96. package/lib/execution/transaction.js +409 -409
  97. package/lib/formatter/formatterUtils.js +42 -42
  98. package/lib/formatter/rawFormatter.js +84 -84
  99. package/lib/formatter/wrappingFormatter.js +250 -250
  100. package/lib/formatter.js +25 -25
  101. package/lib/index.js +3 -3
  102. package/lib/knex-builder/FunctionHelper.js +80 -80
  103. package/lib/knex-builder/Knex.js +59 -59
  104. package/lib/knex-builder/internal/config-resolver.js +57 -57
  105. package/lib/knex-builder/internal/parse-connection.js +87 -87
  106. package/lib/knex-builder/make-knex.js +345 -345
  107. package/lib/logger.js +76 -76
  108. package/lib/migrations/common/MigrationsLoader.js +36 -36
  109. package/lib/migrations/migrate/MigrationGenerator.js +84 -84
  110. package/lib/migrations/migrate/Migrator.js +598 -598
  111. package/lib/migrations/migrate/migrate-stub.js +17 -17
  112. package/lib/migrations/migrate/migration-list-resolver.js +33 -33
  113. package/lib/migrations/migrate/migrator-configuration-merger.js +58 -58
  114. package/lib/migrations/migrate/sources/fs-migrations.js +74 -74
  115. package/lib/migrations/migrate/table-creator.js +77 -77
  116. package/lib/migrations/migrate/table-resolver.js +27 -27
  117. package/lib/migrations/seed/Seeder.js +137 -137
  118. package/lib/migrations/seed/seed-stub.js +13 -13
  119. package/lib/migrations/seed/seeder-configuration-merger.js +60 -60
  120. package/lib/migrations/seed/sources/fs-seeds.js +65 -65
  121. package/lib/migrations/util/fs.js +86 -86
  122. package/lib/migrations/util/import-file.js +12 -12
  123. package/lib/migrations/util/is-module-type.js +9 -9
  124. package/lib/migrations/util/template.js +52 -52
  125. package/lib/migrations/util/timestamp.js +14 -14
  126. package/lib/query/analytic.js +52 -52
  127. package/lib/query/constants.js +15 -15
  128. package/lib/query/joinclause.js +270 -270
  129. package/lib/query/method-constants.js +136 -136
  130. package/lib/query/querybuilder.js +1793 -1793
  131. package/lib/query/querycompiler.js +1591 -1591
  132. package/lib/raw.js +139 -139
  133. package/lib/ref.js +39 -39
  134. package/lib/schema/builder.js +115 -115
  135. package/lib/schema/columnbuilder.js +146 -146
  136. package/lib/schema/columncompiler.js +307 -307
  137. package/lib/schema/compiler.js +187 -187
  138. package/lib/schema/internal/helpers.js +55 -55
  139. package/lib/schema/tablebuilder.js +376 -376
  140. package/lib/schema/tablecompiler.js +433 -433
  141. package/lib/schema/viewbuilder.js +92 -92
  142. package/lib/schema/viewcompiler.js +138 -138
  143. package/lib/util/finally-mixin.js +13 -13
  144. package/lib/util/helpers.js +95 -95
  145. package/lib/util/is.js +32 -32
  146. package/lib/util/nanoid.js +40 -40
  147. package/lib/util/noop.js +1 -1
  148. package/lib/util/save-async-stack.js +14 -14
  149. package/lib/util/security.js +26 -26
  150. package/lib/util/string.js +190 -190
  151. package/lib/util/timeout.js +29 -29
  152. package/package.json +11 -10
  153. package/scripts/build.js +125 -125
  154. package/scripts/clean.js +31 -31
  155. package/scripts/docker-compose.yml +152 -152
  156. package/scripts/next-release-howto.md +24 -24
  157. package/scripts/release.sh +2 -0
  158. package/scripts/runkit-example.js +35 -34
  159. package/scripts/stress-test/docker-compose.yml +57 -57
  160. package/scripts/stress-test/knex-stress-test.js +212 -208
  161. package/scripts/stress-test/mysql2-random-hanging-every-now-and-then.js +149 -145
  162. package/scripts/stress-test/mysql2-sudden-exit-without-error.js +101 -100
  163. package/scripts/stress-test/reconnect-test-mysql-based-drivers.js +188 -184
  164. package/scripts/update_gitignore_for_tsc_output.js +90 -90
  165. package/types/index.d.ts +3274 -3273
  166. package/types/result.d.ts +27 -27
  167. package/types/tables.d.ts +4 -4
@@ -1,347 +1,347 @@
1
- const filter = require('lodash/filter');
2
- const values = require('lodash/values');
3
- const identity = require('lodash/identity');
4
- const { isObject } = require('../../../util/is');
5
-
6
- const TableCompiler = require('../../../schema/tablecompiler');
7
- const { formatDefault } = require('../../../formatter/formatterUtils');
8
-
9
- class TableCompiler_SQLite3 extends TableCompiler {
10
- constructor() {
11
- super(...arguments);
12
- }
13
-
14
- // Create a new table.
15
- createQuery(columns, ifNot, like) {
16
- const createStatement = ifNot
17
- ? 'create table if not exists '
18
- : 'create table ';
19
-
20
- let sql = createStatement + this.tableName();
21
-
22
- if (like && this.tableNameLike()) {
23
- sql += ' as select * from ' + this.tableNameLike() + ' where 0=1';
24
- } else {
25
- // so we will need to check for a primary key commands and add the columns
26
- // to the table's declaration here so they can be created on the tables.
27
- sql += ' (' + columns.sql.join(', ');
28
- sql += this.foreignKeys() || '';
29
- sql += this.primaryKeys() || '';
30
- sql += this._addChecks();
31
- sql += ')';
32
- }
33
- this.pushQuery(sql);
34
-
35
- if (like) {
36
- this.addColumns(columns, this.addColumnsPrefix);
37
- }
38
- }
39
-
40
- addColumns(columns, prefix, colCompilers) {
41
- if (prefix === this.alterColumnsPrefix) {
42
- const compiler = this;
43
-
44
- const columnsInfo = colCompilers.map((col) => {
45
- const name = this.client.customWrapIdentifier(
46
- col.getColumnName(),
47
- identity,
48
- col.columnBuilder.queryContext()
49
- );
50
-
51
- const type = col.getColumnType();
52
-
53
- const defaultTo = col.modified['defaultTo']
54
- ? formatDefault(col.modified['defaultTo'][0], col.type, this.client)
55
- : null;
56
-
57
- const notNull =
58
- col.modified['nullable'] && col.modified['nullable'][0] === false;
59
-
60
- return { name, type, defaultTo, notNull };
61
- });
62
-
63
- this.pushQuery({
64
- sql: `PRAGMA table_info(${this.tableName()})`,
65
- statementsProducer(pragma, connection) {
66
- return compiler.client
67
- .ddl(compiler, pragma, connection)
68
- .alterColumn(columnsInfo);
69
- },
70
- });
71
- } else {
72
- for (let i = 0, l = columns.sql.length; i < l; i++) {
73
- this.pushQuery({
74
- sql: `alter table ${this.tableName()} add column ${columns.sql[i]}`,
75
- bindings: columns.bindings[i],
76
- });
77
- }
78
- }
79
- }
80
-
81
- // Compile a drop unique key command.
82
- dropUnique(columns, indexName) {
83
- indexName = indexName
84
- ? this.formatter.wrap(indexName)
85
- : this._indexCommand('unique', this.tableNameRaw, columns);
86
- this.pushQuery(`drop index ${indexName}`);
87
- }
88
-
89
- // Compile a drop foreign key command.
90
- dropForeign(columns, indexName) {
91
- const compiler = this;
92
-
93
- columns = Array.isArray(columns) ? columns : [columns];
94
- columns = columns.map((column) =>
95
- this.client.customWrapIdentifier(column, identity)
96
- );
97
- indexName = this.client.customWrapIdentifier(indexName, identity);
98
-
99
- this.pushQuery({
100
- sql: `PRAGMA table_info(${this.tableName()})`,
101
- output(pragma) {
102
- return compiler.client
103
- .ddl(compiler, pragma, this.connection)
104
- .dropForeign(columns, indexName);
105
- },
106
- });
107
- }
108
-
109
- // Compile a drop primary key command.
110
- dropPrimary(constraintName) {
111
- const compiler = this;
112
-
113
- constraintName = this.client.customWrapIdentifier(constraintName, identity);
114
-
115
- this.pushQuery({
116
- sql: `PRAGMA table_info(${this.tableName()})`,
117
- output(pragma) {
118
- return compiler.client
119
- .ddl(compiler, pragma, this.connection)
120
- .dropPrimary(constraintName);
121
- },
122
- });
123
- }
124
-
125
- dropIndex(columns, indexName) {
126
- indexName = indexName
127
- ? this.formatter.wrap(indexName)
128
- : this._indexCommand('index', this.tableNameRaw, columns);
129
- this.pushQuery(`drop index ${indexName}`);
130
- }
131
-
132
- // Compile a unique key command.
133
- unique(columns, indexName) {
134
- let deferrable;
135
- let predicate;
136
- if (isObject(indexName)) {
137
- ({ indexName, deferrable, predicate } = indexName);
138
- }
139
- if (deferrable && deferrable !== 'not deferrable') {
140
- this.client.logger.warn(
141
- `sqlite3: unique index \`${indexName}\` will not be deferrable ${deferrable} because sqlite3 does not support deferred constraints.`
142
- );
143
- }
144
- indexName = indexName
145
- ? this.formatter.wrap(indexName)
146
- : this._indexCommand('unique', this.tableNameRaw, columns);
147
- columns = this.formatter.columnize(columns);
148
-
149
- const predicateQuery = predicate
150
- ? ' ' + this.client.queryCompiler(predicate).where()
151
- : '';
152
-
153
- this.pushQuery(
154
- `create unique index ${indexName} on ${this.tableName()} (${columns})${predicateQuery}`
155
- );
156
- }
157
-
158
- // Compile a plain index key command.
159
- index(columns, indexName, options) {
160
- indexName = indexName
161
- ? this.formatter.wrap(indexName)
162
- : this._indexCommand('index', this.tableNameRaw, columns);
163
- columns = this.formatter.columnize(columns);
164
-
165
- let predicate;
166
- if (isObject(options)) {
167
- ({ predicate } = options);
168
- }
169
- const predicateQuery = predicate
170
- ? ' ' + this.client.queryCompiler(predicate).where()
171
- : '';
172
- this.pushQuery(
173
- `create index ${indexName} on ${this.tableName()} (${columns})${predicateQuery}`
174
- );
175
- }
176
-
177
- /**
178
- * Add a primary key to an existing table.
179
- *
180
- * @NOTE The `createQuery` method above handles table creation. Don't do anything regarding table
181
- * creation in this method
182
- *
183
- * @param {string | string[]} columns - Column name(s) to assign as primary keys
184
- * @param {string} [constraintName] - Custom name for the PK constraint
185
- */
186
- primary(columns, constraintName) {
187
- const compiler = this;
188
-
189
- columns = Array.isArray(columns) ? columns : [columns];
190
- columns = columns.map((column) =>
191
- this.client.customWrapIdentifier(column, identity)
192
- );
193
-
194
- let deferrable;
195
- if (isObject(constraintName)) {
196
- ({ constraintName, deferrable } = constraintName);
197
- }
198
- if (deferrable && deferrable !== 'not deferrable') {
199
- this.client.logger.warn(
200
- `sqlite3: primary key constraint \`${constraintName}\` will not be deferrable ${deferrable} because sqlite3 does not support deferred constraints.`
201
- );
202
- }
203
- constraintName = this.client.customWrapIdentifier(constraintName, identity);
204
-
205
- if (this.method !== 'create' && this.method !== 'createIfNot') {
206
- this.pushQuery({
207
- sql: `PRAGMA table_info(${this.tableName()})`,
208
- output(pragma) {
209
- return compiler.client
210
- .ddl(compiler, pragma, this.connection)
211
- .primary(columns, constraintName);
212
- },
213
- });
214
- }
215
- }
216
-
217
- /**
218
- * Add a foreign key constraint to an existing table
219
- *
220
- * @NOTE The `createQuery` method above handles foreign key constraints on table creation. Don't do
221
- * anything regarding table creation in this method
222
- *
223
- * @param {object} foreignInfo - Information about the current column foreign setup
224
- * @param {string | string[]} [foreignInfo.column] - Column in the current constraint
225
- * @param {string | undefined} foreignInfo.keyName - Name of the foreign key constraint
226
- * @param {string | string[]} foreignInfo.references - What column it references in the other table
227
- * @param {string} foreignInfo.inTable - What table is referenced in this constraint
228
- * @param {string} [foreignInfo.onUpdate] - What to do on updates
229
- * @param {string} [foreignInfo.onDelete] - What to do on deletions
230
- */
231
- foreign(foreignInfo) {
232
- const compiler = this;
233
-
234
- if (this.method !== 'create' && this.method !== 'createIfNot') {
235
- foreignInfo.column = Array.isArray(foreignInfo.column)
236
- ? foreignInfo.column
237
- : [foreignInfo.column];
238
- foreignInfo.column = foreignInfo.column.map((column) =>
239
- this.client.customWrapIdentifier(column, identity)
240
- );
241
- foreignInfo.inTable = this.client.customWrapIdentifier(
242
- foreignInfo.inTable,
243
- identity
244
- );
245
- foreignInfo.references = Array.isArray(foreignInfo.references)
246
- ? foreignInfo.references
247
- : [foreignInfo.references];
248
- foreignInfo.references = foreignInfo.references.map((column) =>
249
- this.client.customWrapIdentifier(column, identity)
250
- );
251
-
252
- this.pushQuery({
253
- sql: `PRAGMA table_info(${this.tableName()})`,
254
- statementsProducer(pragma, connection) {
255
- return compiler.client
256
- .ddl(compiler, pragma, connection)
257
- .foreign(foreignInfo);
258
- },
259
- });
260
- }
261
- }
262
-
263
- primaryKeys() {
264
- const pks = filter(this.grouped.alterTable || [], { method: 'primary' });
265
- if (pks.length > 0 && pks[0].args.length > 0) {
266
- const columns = pks[0].args[0];
267
- let constraintName = pks[0].args[1] || '';
268
- if (constraintName) {
269
- constraintName = ' constraint ' + this.formatter.wrap(constraintName);
270
- }
271
- const needUniqueCols =
272
- this.grouped.columns.filter((t) => t.builder._type === 'increments')
273
- .length > 0;
274
- // SQLite dont support autoincrement columns and composite primary keys (autoincrement is always primary key).
275
- // You need to add unique index instead when you have autoincrement columns (https://stackoverflow.com/a/6154876/1535159)
276
- return `,${constraintName} ${
277
- needUniqueCols ? 'unique' : 'primary key'
278
- } (${this.formatter.columnize(columns)})`;
279
- }
280
- }
281
-
282
- foreignKeys() {
283
- let sql = '';
284
- const foreignKeys = filter(this.grouped.alterTable || [], {
285
- method: 'foreign',
286
- });
287
- for (let i = 0, l = foreignKeys.length; i < l; i++) {
288
- const foreign = foreignKeys[i].args[0];
289
- const column = this.formatter.columnize(foreign.column);
290
- const references = this.formatter.columnize(foreign.references);
291
- const foreignTable = this.formatter.wrap(foreign.inTable);
292
- let constraintName = foreign.keyName || '';
293
- if (constraintName) {
294
- constraintName = ' constraint ' + this.formatter.wrap(constraintName);
295
- }
296
- sql += `,${constraintName} foreign key(${column}) references ${foreignTable}(${references})`;
297
- if (foreign.onDelete) sql += ` on delete ${foreign.onDelete}`;
298
- if (foreign.onUpdate) sql += ` on update ${foreign.onUpdate}`;
299
- }
300
- return sql;
301
- }
302
-
303
- createTableBlock() {
304
- return this.getColumns().concat().join(',');
305
- }
306
-
307
- renameColumn(from, to) {
308
- this.pushQuery({
309
- sql: `alter table ${this.tableName()} rename ${this.formatter.wrap(
310
- from
311
- )} to ${this.formatter.wrap(to)}`,
312
- });
313
- }
314
-
315
- _setNullableState(column, isNullable) {
316
- const compiler = this;
317
-
318
- this.pushQuery({
319
- sql: `PRAGMA table_info(${this.tableName()})`,
320
- statementsProducer(pragma, connection) {
321
- return compiler.client
322
- .ddl(compiler, pragma, connection)
323
- .setNullable(column, isNullable);
324
- },
325
- });
326
- }
327
-
328
- dropColumn() {
329
- const compiler = this;
330
- const columns = values(arguments);
331
-
332
- const columnsWrapped = columns.map((column) =>
333
- this.client.customWrapIdentifier(column, identity)
334
- );
335
-
336
- this.pushQuery({
337
- sql: `PRAGMA table_info(${this.tableName()})`,
338
- output(pragma) {
339
- return compiler.client
340
- .ddl(compiler, pragma, this.connection)
341
- .dropColumn(columnsWrapped);
342
- },
343
- });
344
- }
345
- }
346
-
347
- module.exports = TableCompiler_SQLite3;
1
+ const filter = require('lodash/filter');
2
+ const values = require('lodash/values');
3
+ const identity = require('lodash/identity');
4
+ const { isObject } = require('../../../util/is');
5
+
6
+ const TableCompiler = require('../../../schema/tablecompiler');
7
+ const { formatDefault } = require('../../../formatter/formatterUtils');
8
+
9
+ class TableCompiler_SQLite3 extends TableCompiler {
10
+ constructor() {
11
+ super(...arguments);
12
+ }
13
+
14
+ // Create a new table.
15
+ createQuery(columns, ifNot, like) {
16
+ const createStatement = ifNot
17
+ ? 'create table if not exists '
18
+ : 'create table ';
19
+
20
+ let sql = createStatement + this.tableName();
21
+
22
+ if (like && this.tableNameLike()) {
23
+ sql += ' as select * from ' + this.tableNameLike() + ' where 0=1';
24
+ } else {
25
+ // so we will need to check for a primary key commands and add the columns
26
+ // to the table's declaration here so they can be created on the tables.
27
+ sql += ' (' + columns.sql.join(', ');
28
+ sql += this.foreignKeys() || '';
29
+ sql += this.primaryKeys() || '';
30
+ sql += this._addChecks();
31
+ sql += ')';
32
+ }
33
+ this.pushQuery(sql);
34
+
35
+ if (like) {
36
+ this.addColumns(columns, this.addColumnsPrefix);
37
+ }
38
+ }
39
+
40
+ addColumns(columns, prefix, colCompilers) {
41
+ if (prefix === this.alterColumnsPrefix) {
42
+ const compiler = this;
43
+
44
+ const columnsInfo = colCompilers.map((col) => {
45
+ const name = this.client.customWrapIdentifier(
46
+ col.getColumnName(),
47
+ identity,
48
+ col.columnBuilder.queryContext()
49
+ );
50
+
51
+ const type = col.getColumnType();
52
+
53
+ const defaultTo = col.modified['defaultTo']
54
+ ? formatDefault(col.modified['defaultTo'][0], col.type, this.client)
55
+ : null;
56
+
57
+ const notNull =
58
+ col.modified['nullable'] && col.modified['nullable'][0] === false;
59
+
60
+ return { name, type, defaultTo, notNull };
61
+ });
62
+
63
+ this.pushQuery({
64
+ sql: `PRAGMA table_info(${this.tableName()})`,
65
+ statementsProducer(pragma, connection) {
66
+ return compiler.client
67
+ .ddl(compiler, pragma, connection)
68
+ .alterColumn(columnsInfo);
69
+ },
70
+ });
71
+ } else {
72
+ for (let i = 0, l = columns.sql.length; i < l; i++) {
73
+ this.pushQuery({
74
+ sql: `alter table ${this.tableName()} add column ${columns.sql[i]}`,
75
+ bindings: columns.bindings[i],
76
+ });
77
+ }
78
+ }
79
+ }
80
+
81
+ // Compile a drop unique key command.
82
+ dropUnique(columns, indexName) {
83
+ indexName = indexName
84
+ ? this.formatter.wrap(indexName)
85
+ : this._indexCommand('unique', this.tableNameRaw, columns);
86
+ this.pushQuery(`drop index ${indexName}`);
87
+ }
88
+
89
+ // Compile a drop foreign key command.
90
+ dropForeign(columns, indexName) {
91
+ const compiler = this;
92
+
93
+ columns = Array.isArray(columns) ? columns : [columns];
94
+ columns = columns.map((column) =>
95
+ this.client.customWrapIdentifier(column, identity)
96
+ );
97
+ indexName = this.client.customWrapIdentifier(indexName, identity);
98
+
99
+ this.pushQuery({
100
+ sql: `PRAGMA table_info(${this.tableName()})`,
101
+ output(pragma) {
102
+ return compiler.client
103
+ .ddl(compiler, pragma, this.connection)
104
+ .dropForeign(columns, indexName);
105
+ },
106
+ });
107
+ }
108
+
109
+ // Compile a drop primary key command.
110
+ dropPrimary(constraintName) {
111
+ const compiler = this;
112
+
113
+ constraintName = this.client.customWrapIdentifier(constraintName, identity);
114
+
115
+ this.pushQuery({
116
+ sql: `PRAGMA table_info(${this.tableName()})`,
117
+ output(pragma) {
118
+ return compiler.client
119
+ .ddl(compiler, pragma, this.connection)
120
+ .dropPrimary(constraintName);
121
+ },
122
+ });
123
+ }
124
+
125
+ dropIndex(columns, indexName) {
126
+ indexName = indexName
127
+ ? this.formatter.wrap(indexName)
128
+ : this._indexCommand('index', this.tableNameRaw, columns);
129
+ this.pushQuery(`drop index ${indexName}`);
130
+ }
131
+
132
+ // Compile a unique key command.
133
+ unique(columns, indexName) {
134
+ let deferrable;
135
+ let predicate;
136
+ if (isObject(indexName)) {
137
+ ({ indexName, deferrable, predicate } = indexName);
138
+ }
139
+ if (deferrable && deferrable !== 'not deferrable') {
140
+ this.client.logger.warn(
141
+ `sqlite3: unique index \`${indexName}\` will not be deferrable ${deferrable} because sqlite3 does not support deferred constraints.`
142
+ );
143
+ }
144
+ indexName = indexName
145
+ ? this.formatter.wrap(indexName)
146
+ : this._indexCommand('unique', this.tableNameRaw, columns);
147
+ columns = this.formatter.columnize(columns);
148
+
149
+ const predicateQuery = predicate
150
+ ? ' ' + this.client.queryCompiler(predicate).where()
151
+ : '';
152
+
153
+ this.pushQuery(
154
+ `create unique index ${indexName} on ${this.tableName()} (${columns})${predicateQuery}`
155
+ );
156
+ }
157
+
158
+ // Compile a plain index key command.
159
+ index(columns, indexName, options) {
160
+ indexName = indexName
161
+ ? this.formatter.wrap(indexName)
162
+ : this._indexCommand('index', this.tableNameRaw, columns);
163
+ columns = this.formatter.columnize(columns);
164
+
165
+ let predicate;
166
+ if (isObject(options)) {
167
+ ({ predicate } = options);
168
+ }
169
+ const predicateQuery = predicate
170
+ ? ' ' + this.client.queryCompiler(predicate).where()
171
+ : '';
172
+ this.pushQuery(
173
+ `create index ${indexName} on ${this.tableName()} (${columns})${predicateQuery}`
174
+ );
175
+ }
176
+
177
+ /**
178
+ * Add a primary key to an existing table.
179
+ *
180
+ * @NOTE The `createQuery` method above handles table creation. Don't do anything regarding table
181
+ * creation in this method
182
+ *
183
+ * @param {string | string[]} columns - Column name(s) to assign as primary keys
184
+ * @param {string} [constraintName] - Custom name for the PK constraint
185
+ */
186
+ primary(columns, constraintName) {
187
+ const compiler = this;
188
+
189
+ columns = Array.isArray(columns) ? columns : [columns];
190
+ columns = columns.map((column) =>
191
+ this.client.customWrapIdentifier(column, identity)
192
+ );
193
+
194
+ let deferrable;
195
+ if (isObject(constraintName)) {
196
+ ({ constraintName, deferrable } = constraintName);
197
+ }
198
+ if (deferrable && deferrable !== 'not deferrable') {
199
+ this.client.logger.warn(
200
+ `sqlite3: primary key constraint \`${constraintName}\` will not be deferrable ${deferrable} because sqlite3 does not support deferred constraints.`
201
+ );
202
+ }
203
+ constraintName = this.client.customWrapIdentifier(constraintName, identity);
204
+
205
+ if (this.method !== 'create' && this.method !== 'createIfNot') {
206
+ this.pushQuery({
207
+ sql: `PRAGMA table_info(${this.tableName()})`,
208
+ output(pragma) {
209
+ return compiler.client
210
+ .ddl(compiler, pragma, this.connection)
211
+ .primary(columns, constraintName);
212
+ },
213
+ });
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Add a foreign key constraint to an existing table
219
+ *
220
+ * @NOTE The `createQuery` method above handles foreign key constraints on table creation. Don't do
221
+ * anything regarding table creation in this method
222
+ *
223
+ * @param {object} foreignInfo - Information about the current column foreign setup
224
+ * @param {string | string[]} [foreignInfo.column] - Column in the current constraint
225
+ * @param {string | undefined} foreignInfo.keyName - Name of the foreign key constraint
226
+ * @param {string | string[]} foreignInfo.references - What column it references in the other table
227
+ * @param {string} foreignInfo.inTable - What table is referenced in this constraint
228
+ * @param {string} [foreignInfo.onUpdate] - What to do on updates
229
+ * @param {string} [foreignInfo.onDelete] - What to do on deletions
230
+ */
231
+ foreign(foreignInfo) {
232
+ const compiler = this;
233
+
234
+ if (this.method !== 'create' && this.method !== 'createIfNot') {
235
+ foreignInfo.column = Array.isArray(foreignInfo.column)
236
+ ? foreignInfo.column
237
+ : [foreignInfo.column];
238
+ foreignInfo.column = foreignInfo.column.map((column) =>
239
+ this.client.customWrapIdentifier(column, identity)
240
+ );
241
+ foreignInfo.inTable = this.client.customWrapIdentifier(
242
+ foreignInfo.inTable,
243
+ identity
244
+ );
245
+ foreignInfo.references = Array.isArray(foreignInfo.references)
246
+ ? foreignInfo.references
247
+ : [foreignInfo.references];
248
+ foreignInfo.references = foreignInfo.references.map((column) =>
249
+ this.client.customWrapIdentifier(column, identity)
250
+ );
251
+
252
+ this.pushQuery({
253
+ sql: `PRAGMA table_info(${this.tableName()})`,
254
+ statementsProducer(pragma, connection) {
255
+ return compiler.client
256
+ .ddl(compiler, pragma, connection)
257
+ .foreign(foreignInfo);
258
+ },
259
+ });
260
+ }
261
+ }
262
+
263
+ primaryKeys() {
264
+ const pks = filter(this.grouped.alterTable || [], { method: 'primary' });
265
+ if (pks.length > 0 && pks[0].args.length > 0) {
266
+ const columns = pks[0].args[0];
267
+ let constraintName = pks[0].args[1] || '';
268
+ if (constraintName) {
269
+ constraintName = ' constraint ' + this.formatter.wrap(constraintName);
270
+ }
271
+ const needUniqueCols =
272
+ this.grouped.columns.filter((t) => t.builder._type === 'increments')
273
+ .length > 0;
274
+ // SQLite dont support autoincrement columns and composite primary keys (autoincrement is always primary key).
275
+ // You need to add unique index instead when you have autoincrement columns (https://stackoverflow.com/a/6154876/1535159)
276
+ return `,${constraintName} ${
277
+ needUniqueCols ? 'unique' : 'primary key'
278
+ } (${this.formatter.columnize(columns)})`;
279
+ }
280
+ }
281
+
282
+ foreignKeys() {
283
+ let sql = '';
284
+ const foreignKeys = filter(this.grouped.alterTable || [], {
285
+ method: 'foreign',
286
+ });
287
+ for (let i = 0, l = foreignKeys.length; i < l; i++) {
288
+ const foreign = foreignKeys[i].args[0];
289
+ const column = this.formatter.columnize(foreign.column);
290
+ const references = this.formatter.columnize(foreign.references);
291
+ const foreignTable = this.formatter.wrap(foreign.inTable);
292
+ let constraintName = foreign.keyName || '';
293
+ if (constraintName) {
294
+ constraintName = ' constraint ' + this.formatter.wrap(constraintName);
295
+ }
296
+ sql += `,${constraintName} foreign key(${column}) references ${foreignTable}(${references})`;
297
+ if (foreign.onDelete) sql += ` on delete ${foreign.onDelete}`;
298
+ if (foreign.onUpdate) sql += ` on update ${foreign.onUpdate}`;
299
+ }
300
+ return sql;
301
+ }
302
+
303
+ createTableBlock() {
304
+ return this.getColumns().concat().join(',');
305
+ }
306
+
307
+ renameColumn(from, to) {
308
+ this.pushQuery({
309
+ sql: `alter table ${this.tableName()} rename ${this.formatter.wrap(
310
+ from
311
+ )} to ${this.formatter.wrap(to)}`,
312
+ });
313
+ }
314
+
315
+ _setNullableState(column, isNullable) {
316
+ const compiler = this;
317
+
318
+ this.pushQuery({
319
+ sql: `PRAGMA table_info(${this.tableName()})`,
320
+ statementsProducer(pragma, connection) {
321
+ return compiler.client
322
+ .ddl(compiler, pragma, connection)
323
+ .setNullable(column, isNullable);
324
+ },
325
+ });
326
+ }
327
+
328
+ dropColumn() {
329
+ const compiler = this;
330
+ const columns = values(arguments);
331
+
332
+ const columnsWrapped = columns.map((column) =>
333
+ this.client.customWrapIdentifier(column, identity)
334
+ );
335
+
336
+ this.pushQuery({
337
+ sql: `PRAGMA table_info(${this.tableName()})`,
338
+ output(pragma) {
339
+ return compiler.client
340
+ .ddl(compiler, pragma, this.connection)
341
+ .dropColumn(columnsWrapped);
342
+ },
343
+ });
344
+ }
345
+ }
346
+
347
+ module.exports = TableCompiler_SQLite3;