knex 0.95.14 → 1.0.2

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 (78) hide show
  1. package/CHANGELOG.md +90 -1
  2. package/README.md +1 -1
  3. package/UPGRADING.md +7 -0
  4. package/lib/client.js +14 -1
  5. package/lib/constants.js +2 -0
  6. package/lib/dialects/better-sqlite3/index.js +72 -0
  7. package/lib/dialects/cockroachdb/crdb-querycompiler.js +92 -33
  8. package/lib/dialects/cockroachdb/crdb-tablecompiler.js +19 -0
  9. package/lib/dialects/cockroachdb/index.js +13 -0
  10. package/lib/dialects/mssql/index.js +0 -11
  11. package/lib/dialects/mssql/query/mssql-querycompiler.js +122 -64
  12. package/lib/dialects/mssql/schema/mssql-columncompiler.js +41 -6
  13. package/lib/dialects/mssql/schema/mssql-compiler.js +3 -4
  14. package/lib/dialects/mssql/schema/mssql-tablecompiler.js +24 -9
  15. package/lib/dialects/mssql/schema/mssql-viewcompiler.js +15 -1
  16. package/lib/dialects/mysql/query/mysql-querycompiler.js +93 -5
  17. package/lib/dialects/mysql/schema/mysql-columncompiler.js +32 -5
  18. package/lib/dialects/mysql/schema/mysql-tablecompiler.js +33 -6
  19. package/lib/dialects/oracle/query/oracle-querycompiler.js +7 -6
  20. package/lib/dialects/oracle/schema/internal/trigger.js +1 -1
  21. package/lib/dialects/oracle/schema/oracle-columncompiler.js +10 -4
  22. package/lib/dialects/oracle/schema/oracle-tablecompiler.js +17 -6
  23. package/lib/dialects/oracledb/index.js +0 -4
  24. package/lib/dialects/oracledb/query/oracledb-querycompiler.js +89 -0
  25. package/lib/dialects/oracledb/schema/oracledb-columncompiler.js +23 -0
  26. package/lib/dialects/postgres/index.js +21 -6
  27. package/lib/dialects/postgres/query/pg-querybuilder.js +38 -0
  28. package/lib/dialects/postgres/query/pg-querycompiler.js +172 -9
  29. package/lib/dialects/postgres/schema/pg-columncompiler.js +24 -4
  30. package/lib/dialects/postgres/schema/pg-tablecompiler.js +63 -46
  31. package/lib/dialects/redshift/index.js +12 -0
  32. package/lib/dialects/redshift/query/redshift-querycompiler.js +62 -26
  33. package/lib/dialects/redshift/schema/redshift-columncompiler.js +2 -1
  34. package/lib/dialects/redshift/schema/redshift-tablecompiler.js +4 -1
  35. package/lib/dialects/sqlite3/index.js +23 -4
  36. package/lib/dialects/sqlite3/query/sqlite-querybuilder.js +33 -0
  37. package/lib/dialects/sqlite3/query/sqlite-querycompiler.js +87 -22
  38. package/lib/dialects/sqlite3/schema/ddl.js +274 -282
  39. package/lib/dialects/sqlite3/schema/internal/sqlite-ddl-operations.js +18 -8
  40. package/lib/dialects/sqlite3/schema/sqlite-columncompiler.js +20 -0
  41. package/lib/dialects/sqlite3/schema/sqlite-compiler.js +16 -12
  42. package/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js +15 -5
  43. package/lib/dialects/sqlite3/schema/sqlite-viewcompiler.js +31 -2
  44. package/lib/execution/runner.js +37 -2
  45. package/lib/knex-builder/FunctionHelper.js +36 -0
  46. package/lib/migrations/common/MigrationsLoader.js +36 -0
  47. package/lib/migrations/migrate/MigrationGenerator.js +1 -1
  48. package/lib/migrations/migrate/Migrator.js +22 -24
  49. package/lib/migrations/migrate/migration-list-resolver.js +2 -5
  50. package/lib/migrations/migrate/{configuration-merger.js → migrator-configuration-merger.js} +2 -4
  51. package/lib/migrations/migrate/sources/fs-migrations.js +4 -29
  52. package/lib/migrations/migrate/stub/js.stub +8 -1
  53. package/lib/migrations/migrate/stub/knexfile-js.stub +3 -0
  54. package/lib/migrations/migrate/stub/knexfile-ts.stub +5 -2
  55. package/lib/migrations/migrate/table-creator.js +6 -5
  56. package/lib/migrations/seed/Seeder.js +25 -92
  57. package/lib/migrations/seed/seeder-configuration-merger.js +60 -0
  58. package/lib/migrations/seed/sources/fs-seeds.js +65 -0
  59. package/lib/migrations/seed/stub/js.stub +4 -1
  60. package/lib/migrations/util/import-file.js +0 -1
  61. package/lib/query/joinclause.js +24 -5
  62. package/lib/query/method-constants.js +37 -0
  63. package/lib/query/querybuilder.js +292 -53
  64. package/lib/query/querycompiler.js +309 -85
  65. package/lib/schema/columnbuilder.js +14 -1
  66. package/lib/schema/columncompiler.js +132 -5
  67. package/lib/schema/compiler.js +1 -0
  68. package/lib/schema/tablebuilder.js +41 -8
  69. package/lib/schema/tablecompiler.js +61 -4
  70. package/lib/schema/viewcompiler.js +13 -10
  71. package/package.json +37 -27
  72. package/scripts/docker-compose.yml +7 -7
  73. package/scripts/oracledb-install-driver-libs.sh +82 -0
  74. package/scripts/runkit-example.js +1 -1
  75. package/scripts/stress-test/docker-compose.yml +3 -3
  76. package/scripts/stress-test/knex-stress-test.js +1 -1
  77. package/scripts/stress-test/reconnect-test-mysql-based-drivers.js +1 -1
  78. package/types/index.d.ts +133 -21
@@ -6,6 +6,9 @@ const compact = require('lodash/compact');
6
6
  const identity = require('lodash/identity');
7
7
  const isEmpty = require('lodash/isEmpty');
8
8
  const Raw = require('../../../raw.js');
9
+ const {
10
+ columnize: columnize_,
11
+ } = require('../../../formatter/wrappingFormatter');
9
12
 
10
13
  const components = [
11
14
  'columns',
@@ -100,40 +103,37 @@ class QueryCompiler_MSSQL extends QueryCompiler {
100
103
  returning,
101
104
  };
102
105
  }
106
+ sql += this._buildInsertData(insertValues, returningSql);
103
107
 
108
+ if (returning) {
109
+ sql += this._buildReturningSelect(returning);
110
+ }
111
+
112
+ return {
113
+ sql,
114
+ returning,
115
+ };
116
+ }
117
+
118
+ _buildInsertData(insertValues, returningSql) {
119
+ let sql = '';
104
120
  const insertData = this._prepInsert(insertValues);
105
121
  if (typeof insertData === 'string') {
106
122
  sql += insertData;
107
123
  } else {
108
124
  if (insertData.columns.length) {
109
125
  sql += `(${this.formatter.columnize(insertData.columns)}`;
110
- sql += `) ${returningSql}values (`;
111
- let i = -1;
112
- while (++i < insertData.values.length) {
113
- if (i !== 0) sql += '), (';
114
- sql += this.client.parameterize(
115
- insertData.values[i],
116
- this.client.valueForUndefined,
117
- this.builder,
118
- this.bindingsHolder
119
- );
120
- }
121
- sql += ')';
126
+ sql +=
127
+ `) ${returningSql}values (` +
128
+ this._buildInsertValues(insertData) +
129
+ ')';
122
130
  } else if (insertValues.length === 1 && insertValues[0]) {
123
131
  sql += returningSql + this._emptyInsertValue;
124
132
  } else {
125
- sql = '';
133
+ return '';
126
134
  }
127
135
  }
128
-
129
- if (returning) {
130
- sql += this._buildReturningSelect(returning);
131
- }
132
-
133
- return {
134
- sql,
135
- returning,
136
- };
136
+ return sql;
137
137
  }
138
138
 
139
139
  standardInsert() {
@@ -155,30 +155,7 @@ class QueryCompiler_MSSQL extends QueryCompiler {
155
155
  };
156
156
  }
157
157
 
158
- const insertData = this._prepInsert(insertValues);
159
- if (typeof insertData === 'string') {
160
- sql += insertData;
161
- } else {
162
- if (insertData.columns.length) {
163
- sql += `(${this.formatter.columnize(insertData.columns)}`;
164
- sql += `) ${returningSql}values (`;
165
- let i = -1;
166
- while (++i < insertData.values.length) {
167
- if (i !== 0) sql += '), (';
168
- sql += this.client.parameterize(
169
- insertData.values[i],
170
- this.client.valueForUndefined,
171
- this.builder,
172
- this.bindingsHolder
173
- );
174
- }
175
- sql += ')';
176
- } else if (insertValues.length === 1 && insertValues[0]) {
177
- sql += returningSql + this._emptyInsertValue;
178
- } else {
179
- sql = '';
180
- }
181
- }
158
+ sql += this._buildInsertData(insertValues, returningSql);
182
159
 
183
160
  return {
184
161
  sql,
@@ -354,15 +331,17 @@ class QueryCompiler_MSSQL extends QueryCompiler {
354
331
  sql.push(this.aggregateRaw(stmt));
355
332
  } else if (stmt.type === 'analytic') {
356
333
  sql.push(this.analytic(stmt));
334
+ } else if (stmt.type === 'json') {
335
+ sql.push(this.json(stmt));
357
336
  } else if (stmt.value && stmt.value.length > 0) {
358
337
  sql.push(this.formatter.columnize(stmt.value));
359
338
  }
360
339
  }
361
340
  }
362
341
  if (sql.length === 0) sql = ['*'];
363
-
342
+ const select = this.onlyJson() ? '' : 'select ';
364
343
  return (
365
- `select ${hints}${distinctClause}` +
344
+ `${select}${hints}${distinctClause}` +
366
345
  (top ? top + ' ' : '') +
367
346
  sql.join(', ') +
368
347
  (this.tableName ? ` from ${this.tableName}` : '')
@@ -502,11 +481,7 @@ class QueryCompiler_MSSQL extends QueryCompiler {
502
481
  const noLimit = !this.single.limit && this.single.limit !== 0;
503
482
  const noOffset = !this.single.offset;
504
483
  if (noLimit || !noOffset) return '';
505
- return `top (${this.client.parameter(
506
- this.single.limit,
507
- this.builder,
508
- this.bindingsHolder
509
- )})`;
484
+ return `top (${this._getValueOrParameterFromAttribute('limit')})`;
510
485
  }
511
486
 
512
487
  limit() {
@@ -518,23 +493,106 @@ class QueryCompiler_MSSQL extends QueryCompiler {
518
493
  const noOffset = !this.single.offset;
519
494
  if (noOffset) return '';
520
495
  let offset = `offset ${
521
- noOffset
522
- ? '0'
523
- : this.client.parameter(
524
- this.single.offset,
525
- this.builder,
526
- this.bindingsHolder
527
- )
496
+ noOffset ? '0' : this._getValueOrParameterFromAttribute('offset')
528
497
  } rows`;
529
498
  if (!noLimit) {
530
- offset += ` fetch next ${this.client.parameter(
531
- this.single.limit,
532
- this.builder,
533
- this.bindingsHolder
499
+ offset += ` fetch next ${this._getValueOrParameterFromAttribute(
500
+ 'limit'
534
501
  )} rows only`;
535
502
  }
536
503
  return offset;
537
504
  }
505
+
506
+ whereLike(statement) {
507
+ return `${this._columnClause(
508
+ statement
509
+ )} collate SQL_Latin1_General_CP1_CS_AS ${this._not(
510
+ statement,
511
+ 'like '
512
+ )}${this._valueClause(statement)}`;
513
+ }
514
+
515
+ whereILike(statement) {
516
+ return `${this._columnClause(
517
+ statement
518
+ )} collate SQL_Latin1_General_CP1_CI_AS ${this._not(
519
+ statement,
520
+ 'like '
521
+ )}${this._valueClause(statement)}`;
522
+ }
523
+
524
+ jsonExtract(params) {
525
+ // JSON_VALUE return NULL if we query object or array
526
+ // JSON_QUERY return NULL if we query literal/single value
527
+ return this._jsonExtract(
528
+ params.singleValue ? 'JSON_VALUE' : 'JSON_QUERY',
529
+ params
530
+ );
531
+ }
532
+
533
+ jsonSet(params) {
534
+ return this._jsonSet('JSON_MODIFY', params);
535
+ }
536
+
537
+ jsonInsert(params) {
538
+ return this._jsonSet('JSON_MODIFY', params);
539
+ }
540
+
541
+ jsonRemove(params) {
542
+ const jsonCol = `JSON_MODIFY(${columnize_(
543
+ params.column,
544
+ this.builder,
545
+ this.client,
546
+ this.bindingsHolder
547
+ )},${this.client.parameter(
548
+ params.path,
549
+ this.builder,
550
+ this.bindingsHolder
551
+ )}, NULL)`;
552
+ return params.alias
553
+ ? this.client.alias(jsonCol, this.formatter.wrap(params.alias))
554
+ : jsonCol;
555
+ }
556
+
557
+ whereJsonPath(statement) {
558
+ return this._whereJsonPath('JSON_VALUE', statement);
559
+ }
560
+
561
+ whereJsonSupersetOf(statement) {
562
+ throw new Error(
563
+ 'Json superset where clause not actually supported by MSSQL'
564
+ );
565
+ }
566
+
567
+ whereJsonSubsetOf(statement) {
568
+ throw new Error('Json subset where clause not actually supported by MSSQL');
569
+ }
570
+
571
+ _getExtracts(statement, operator) {
572
+ const column = columnize_(
573
+ statement.column,
574
+ this.builder,
575
+ this.client,
576
+ this.bindingsHolder
577
+ );
578
+ return (
579
+ Array.isArray(statement.values) ? statement.values : [statement.values]
580
+ )
581
+ .map(function (value) {
582
+ return (
583
+ 'JSON_VALUE(' +
584
+ column +
585
+ ',' +
586
+ this.client.parameter(value, this.builder, this.bindingsHolder) +
587
+ ')'
588
+ );
589
+ }, this)
590
+ .join(operator);
591
+ }
592
+
593
+ onJsonPathEquals(clause) {
594
+ return this._onJsonPathEquals('JSON_VALUE', clause);
595
+ }
538
596
  }
539
597
 
540
598
  // Set the QueryBuilder & QueryCompiler on the client object,
@@ -3,11 +3,13 @@
3
3
  const ColumnCompiler = require('../../../schema/columncompiler');
4
4
  const { toNumber } = require('../../../util/helpers');
5
5
  const { formatDefault } = require('../../../formatter/formatterUtils');
6
+ const { operator: operator_ } = require('../../../formatter/wrappingFormatter');
6
7
 
7
8
  class ColumnCompiler_MSSQL extends ColumnCompiler {
8
9
  constructor(client, tableCompiler, columnBuilder) {
9
10
  super(client, tableCompiler, columnBuilder);
10
11
  this.modifiers = ['nullable', 'defaultTo', 'first', 'after', 'comment'];
12
+ this._addCheckModifiers();
11
13
  }
12
14
 
13
15
  // Types
@@ -126,24 +128,57 @@ class ColumnCompiler_MSSQL extends ColumnCompiler {
126
128
  });
127
129
  return '';
128
130
  }
131
+
132
+ checkLength(operator, length, constraintName) {
133
+ return this._check(
134
+ `LEN(${this.formatter.wrap(this.getColumnName())}) ${operator_(
135
+ operator,
136
+ this.columnBuilder,
137
+ this.bindingsHolder
138
+ )} ${toNumber(length)}`,
139
+ constraintName
140
+ );
141
+ }
142
+
143
+ checkRegex(regex, constraintName) {
144
+ return this._check(
145
+ `${this.formatter.wrap(
146
+ this.getColumnName()
147
+ )} LIKE ${this.client._escapeBinding('%' + regex + '%')}`,
148
+ constraintName
149
+ );
150
+ }
151
+
152
+ increments(options = { primaryKey: true }) {
153
+ return (
154
+ 'int identity(1,1) not null' +
155
+ (this.tableCompiler._canBeAddPrimaryKey(options) ? ' primary key' : '')
156
+ );
157
+ }
158
+
159
+ bigincrements(options = { primaryKey: true }) {
160
+ return (
161
+ 'bigint identity(1,1) not null' +
162
+ (this.tableCompiler._canBeAddPrimaryKey(options) ? ' primary key' : '')
163
+ );
164
+ }
129
165
  }
130
166
 
131
- ColumnCompiler_MSSQL.prototype.increments = ({ primaryKey = true } = {}) =>
132
- 'int identity(1,1) not null' + (primaryKey ? ' primary key' : '');
133
- ColumnCompiler_MSSQL.prototype.bigincrements = ({ primaryKey = true } = {}) =>
134
- 'bigint identity(1,1) not null' + (primaryKey ? ' primary key' : '');
135
167
  ColumnCompiler_MSSQL.prototype.bigint = 'bigint';
136
168
  ColumnCompiler_MSSQL.prototype.mediumint = 'int';
137
169
  ColumnCompiler_MSSQL.prototype.smallint = 'smallint';
138
170
  ColumnCompiler_MSSQL.prototype.text = 'nvarchar(max)';
139
171
  ColumnCompiler_MSSQL.prototype.mediumtext = 'nvarchar(max)';
140
172
  ColumnCompiler_MSSQL.prototype.longtext = 'nvarchar(max)';
141
- ColumnCompiler_MSSQL.prototype.json = 'nvarchar(max)';
173
+ ColumnCompiler_MSSQL.prototype.json = ColumnCompiler_MSSQL.prototype.jsonb =
174
+ 'nvarchar(max)';
142
175
 
143
176
  // TODO: mssql supports check constraints as of SQL Server 2008
144
177
  // so make enu here more like postgres
145
178
  ColumnCompiler_MSSQL.prototype.enu = 'nvarchar(100)';
146
- ColumnCompiler_MSSQL.prototype.uuid = 'uniqueidentifier';
179
+ ColumnCompiler_MSSQL.prototype.uuid = ({ useBinaryUuid = false } = {}) =>
180
+ useBinaryUuid ? 'binary(16)' : 'uniqueidentifier';
181
+
147
182
  ColumnCompiler_MSSQL.prototype.datetime = 'datetime2';
148
183
  ColumnCompiler_MSSQL.prototype.bool = 'bit';
149
184
 
@@ -45,14 +45,13 @@ class SchemaCompiler_MSSQL extends SchemaCompiler {
45
45
  // Check whether a table exists on the query.
46
46
  hasTable(tableName) {
47
47
  const formattedTable = this.client.parameter(
48
- this.formatter.wrap(prefixedTableName(this.schema, tableName)),
48
+ prefixedTableName(this.schema, tableName),
49
49
  this.builder,
50
50
  this.bindingsHolder
51
51
  );
52
-
53
52
  const sql =
54
- `select object_id from sys.tables ` +
55
- `where object_id = object_id(${formattedTable})`;
53
+ `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES ` +
54
+ `WHERE TABLE_NAME = ${formattedTable}`;
56
55
  this.pushQuery({ sql, output: (resp) => resp.length > 0 });
57
56
  }
58
57
 
@@ -28,6 +28,7 @@ class TableCompiler_MSSQL extends TableCompiler {
28
28
  this.tableName() +
29
29
  (this._formatting ? ' (\n ' : ' (') +
30
30
  columns.sql.join(this._formatting ? ',\n ' : ', ') +
31
+ this._addChecks() +
31
32
  ')';
32
33
  }
33
34
 
@@ -36,6 +37,9 @@ class TableCompiler_MSSQL extends TableCompiler {
36
37
  if (this.single.comment) {
37
38
  this.comment(this.single.comment);
38
39
  }
40
+ if (like) {
41
+ this.addColumns(columns, this.addColumnsPrefix);
42
+ }
39
43
  }
40
44
 
41
45
  comment(/** @type {string} */ comment) {
@@ -276,13 +280,14 @@ class TableCompiler_MSSQL extends TableCompiler {
276
280
  * Create a unique index.
277
281
  *
278
282
  * @param {string | string[]} columns
279
- * @param {string | {indexName: undefined | string, deferrable?: 'not deferrable'|'deferred'|'immediate' }} indexName
283
+ * @param {string | {indexName: undefined | string, deferrable?: 'not deferrable'|'deferred'|'immediate', useConstraint?: true|false }} indexName
280
284
  */
281
285
  unique(columns, indexName) {
282
286
  /** @type {string | undefined} */
283
287
  let deferrable;
288
+ let useConstraint = false;
284
289
  if (isObject(indexName)) {
285
- ({ indexName, deferrable } = indexName);
290
+ ({ indexName, deferrable, useConstraint } = indexName);
286
291
  }
287
292
  if (deferrable && deferrable !== 'not deferrable') {
288
293
  this.client.logger.warn(
@@ -301,13 +306,23 @@ class TableCompiler_MSSQL extends TableCompiler {
301
306
  .map((column) => this.formatter.columnize(column) + ' IS NOT NULL')
302
307
  .join(' AND ');
303
308
 
304
- // make unique constraint that allows null https://stackoverflow.com/a/767702/360060
305
- // to be more or less compatible with other DBs (if any of the columns is NULL then "duplicates" are allowed)
306
- this.pushQuery(
307
- `CREATE UNIQUE INDEX ${indexName} ON ${this.tableName()} (${this.formatter.columnize(
308
- columns
309
- )}) WHERE ${whereAllTheColumnsAreNotNull}`
310
- );
309
+ if (useConstraint) {
310
+ // mssql supports unique indexes and unique constraints.
311
+ // unique indexes cannot be used with foreign key relationships hence unique constraints are used instead.
312
+ this.pushQuery(
313
+ `ALTER TABLE ${this.tableName()} ADD CONSTRAINT ${indexName} UNIQUE (${this.formatter.columnize(
314
+ columns
315
+ )})`
316
+ );
317
+ } else {
318
+ // make unique constraint that allows null https://stackoverflow.com/a/767702/360060
319
+ // to be more or less compatible with other DBs (if any of the columns is NULL then "duplicates" are allowed)
320
+ this.pushQuery(
321
+ `CREATE UNIQUE INDEX ${indexName} ON ${this.tableName()} (${this.formatter.columnize(
322
+ columns
323
+ )}) WHERE ${whereAllTheColumnsAreNotNull}`
324
+ );
325
+ }
311
326
  }
312
327
 
313
328
  // Compile a drop index command.
@@ -1,6 +1,9 @@
1
1
  /* eslint max-len: 0 */
2
2
 
3
3
  const ViewCompiler = require('../../../schema/viewcompiler.js');
4
+ const {
5
+ columnize: columnize_,
6
+ } = require('../../../formatter/wrappingFormatter');
4
7
 
5
8
  class ViewCompiler_MSSQL extends ViewCompiler {
6
9
  constructor(client, viewCompiler) {
@@ -11,7 +14,18 @@ class ViewCompiler_MSSQL extends ViewCompiler {
11
14
  const createStatement = 'CREATE ' + (replace ? 'OR ALTER ' : '') + 'VIEW ';
12
15
  let sql = createStatement + this.viewName();
13
16
 
14
- sql += ' (' + columns.join(', ') + ')';
17
+ const columnList = columns
18
+ ? ' (' +
19
+ columnize_(
20
+ columns,
21
+ this.viewBuilder,
22
+ this.client,
23
+ this.bindingsHolder
24
+ ) +
25
+ ')'
26
+ : '';
27
+
28
+ sql += columnList;
15
29
  sql += ' AS ';
16
30
  sql += selectQuery.toString();
17
31
  this.pushQuery({
@@ -3,6 +3,10 @@
3
3
  const identity = require('lodash/identity');
4
4
  const QueryCompiler = require('../../../query/querycompiler');
5
5
  const { wrapAsIdentifier } = require('../../../formatter/formatterUtils');
6
+ const {
7
+ columnize: columnize_,
8
+ wrap: wrap_,
9
+ } = require('../../../formatter/wrappingFormatter');
6
10
 
7
11
  class QueryCompiler_MySQL extends QueryCompiler {
8
12
  constructor(client, builder, formatter) {
@@ -76,12 +80,14 @@ class QueryCompiler_MySQL extends QueryCompiler {
76
80
 
77
81
  // Update method, including joins, wheres, order & limits.
78
82
  update() {
83
+ const withSQL = this.with();
79
84
  const join = this.join();
80
85
  const updates = this._prepUpdate(this.single.update);
81
86
  const where = this.where();
82
87
  const order = this.order();
83
88
  const limit = this.limit();
84
89
  return (
90
+ withSQL +
85
91
  `update ${this.tableName}` +
86
92
  (join ? ` ${join}` : '') +
87
93
  ' set ' +
@@ -146,13 +152,95 @@ class QueryCompiler_MySQL extends QueryCompiler {
146
152
  const limit =
147
153
  this.single.offset && noLimit
148
154
  ? '18446744073709551615'
149
- : this.client.parameter(
150
- this.single.limit,
151
- this.builder,
152
- this.bindingsHolder
153
- );
155
+ : this._getValueOrParameterFromAttribute('limit');
154
156
  return `limit ${limit}`;
155
157
  }
158
+
159
+ whereLike(statement) {
160
+ return `${this._columnClause(statement)} ${this._not(
161
+ statement,
162
+ 'like '
163
+ )}${this._valueClause(statement)} COLLATE utf8_bin`;
164
+ }
165
+
166
+ whereILike(statement) {
167
+ return `${this._columnClause(statement)} ${this._not(
168
+ statement,
169
+ 'like '
170
+ )}${this._valueClause(statement)}`;
171
+ }
172
+
173
+ // Json functions
174
+ jsonExtract(params) {
175
+ return this._jsonExtract(['json_extract', 'json_unquote'], params);
176
+ }
177
+
178
+ jsonSet(params) {
179
+ return this._jsonSet('json_set', params);
180
+ }
181
+
182
+ jsonInsert(params) {
183
+ return this._jsonSet('json_insert', params);
184
+ }
185
+
186
+ jsonRemove(params) {
187
+ const jsonCol = `json_remove(${columnize_(
188
+ params.column,
189
+ this.builder,
190
+ this.client,
191
+ this.bindingsHolder
192
+ )},${this.client.parameter(
193
+ params.path,
194
+ this.builder,
195
+ this.bindingsHolder
196
+ )})`;
197
+ return params.alias
198
+ ? this.client.alias(jsonCol, this.formatter.wrap(params.alias))
199
+ : jsonCol;
200
+ }
201
+
202
+ whereJsonObject(statement) {
203
+ return this._not(
204
+ statement,
205
+ `json_contains(${this._columnClause(statement)}, ${this._jsonValueClause(
206
+ statement
207
+ )})`
208
+ );
209
+ }
210
+
211
+ whereJsonPath(statement) {
212
+ return this._whereJsonPath('json_extract', statement);
213
+ }
214
+
215
+ whereJsonSupersetOf(statement) {
216
+ return this._not(
217
+ statement,
218
+ `json_contains(${wrap_(
219
+ statement.column,
220
+ undefined,
221
+ this.builder,
222
+ this.client,
223
+ this.bindingsHolder
224
+ )},${this._jsonValueClause(statement)})`
225
+ );
226
+ }
227
+
228
+ whereJsonSubsetOf(statement) {
229
+ return this._not(
230
+ statement,
231
+ `json_contains(${this._jsonValueClause(statement)},${wrap_(
232
+ statement.column,
233
+ undefined,
234
+ this.builder,
235
+ this.client,
236
+ this.bindingsHolder
237
+ )})`
238
+ );
239
+ }
240
+
241
+ onJsonPathEquals(clause) {
242
+ return this._onJsonPathEquals('json_extract', clause);
243
+ }
156
244
  }
157
245
 
158
246
  // Set the QueryBuilder & QueryCompiler on the client object,
@@ -18,6 +18,7 @@ class ColumnCompiler_MySQL extends ColumnCompiler {
18
18
  'first',
19
19
  'after',
20
20
  ];
21
+ this._addCheckModifiers();
21
22
  }
22
23
 
23
24
  // Types
@@ -152,13 +153,39 @@ class ColumnCompiler_MySQL extends ColumnCompiler {
152
153
  collate(collation) {
153
154
  return collation && `collate '${collation}'`;
154
155
  }
156
+
157
+ checkRegex(regex, constraintName) {
158
+ return this._check(
159
+ `${this.formatter.wrap(
160
+ this.getColumnName()
161
+ )} REGEXP ${this.client._escapeBinding(regex)}`,
162
+ constraintName
163
+ );
164
+ }
165
+
166
+ increments(options = { primaryKey: true }) {
167
+ return (
168
+ 'int unsigned not null' +
169
+ // In MySQL autoincrement are always a primary key. If you already have a primary key, we
170
+ // initialize this column as classic int column then modify it later in table compiler
171
+ (this.tableCompiler._canBeAddPrimaryKey(options)
172
+ ? ' auto_increment primary key'
173
+ : '')
174
+ );
175
+ }
176
+
177
+ bigincrements(options = { primaryKey: true }) {
178
+ return (
179
+ 'bigint unsigned not null' +
180
+ // In MySQL autoincrement are always a primary key. If you already have a primary key, we
181
+ // initialize this column as classic int column then modify it later in table compiler
182
+ (this.tableCompiler._canBeAddPrimaryKey(options)
183
+ ? ' auto_increment primary key'
184
+ : '')
185
+ );
186
+ }
155
187
  }
156
188
 
157
- ColumnCompiler_MySQL.prototype.increments = ({ primaryKey = true } = {}) =>
158
- 'int unsigned not null auto_increment' + (primaryKey ? ' primary key' : '');
159
- ColumnCompiler_MySQL.prototype.bigincrements = ({ primaryKey = true } = {}) =>
160
- 'bigint unsigned not null auto_increment' +
161
- (primaryKey ? ' primary key' : '');
162
189
  ColumnCompiler_MySQL.prototype.bigint = 'bigint';
163
190
  ColumnCompiler_MySQL.prototype.mediumint = 'mediumint';
164
191
  ColumnCompiler_MySQL.prototype.smallint = 'smallint';