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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,94 @@
1
1
  # Master (Unreleased)
2
2
 
3
+ # 1.0.2 - 02 February, 2022
4
+
5
+ ### New features:
6
+
7
+ - Support of MATERIALIZED and NOT MATERIALIZED with WITH/CTE #4940
8
+ - Add raw support in onConflict clause #4960
9
+ - Alter nullable constraint when alterNullable is set to true #4730
10
+ - Add alterType parameter for alter function #4967
11
+ - Support string json in json values #4988
12
+ - MySQL: add with clause #4508
13
+
14
+ ### Bug fixes:
15
+
16
+ - Fix error message for missing migration files #4937
17
+ - Move deferrable to after on update/on delete #4976
18
+ - Do not use sys.tables to find if a table exists #2328
19
+ - PostgreSQL: Fix Order nulls #4989
20
+ - MySQL: Fix collation when renaming column #2666
21
+ - SQLite: Same boolean handling in better-sqlite3 as in sqlite3 #4982
22
+
23
+ ### Typings:
24
+
25
+ - WhereILike - fix typo #4941
26
+
27
+ # 1.0.1 - 16 January, 2022
28
+
29
+ ### Bug fixes:
30
+
31
+ - Fix package.json metadata
32
+
33
+ # 1.0.0 - 16 January, 2022
34
+
35
+ ### Breaking changes
36
+
37
+ - Dropped support for Node 10;
38
+ - Replaced unsupported `sqlite3` driver with `@vscode/sqlite3`;
39
+ - Changed data structure from `RETURNING` operation to be consistent with `SELECT`;
40
+ - Changed Migrator to return list of migrations as objects consistently.
41
+
42
+ ### New features:
43
+
44
+ - Support fromRaw #4781
45
+ - Support zero precision in timestamp/datetime #4784
46
+ - Support whereLike and whereILike #4779
47
+ - Add JSDoc (TS flavor) to stub files #4809
48
+ - Allow skip binding in limit and offset #4811
49
+ - Support creating a new table in the database based on another table #4821
50
+ - Accept Raw on onIn joins #4830
51
+ - Implement support for custom seed sources #4842
52
+ - Add binary uuid option #4836
53
+ - ForUpdate array parameter #4882
54
+ - Add camel case to timestamps method #4803
55
+ - Advanced JSON support #4859
56
+ - Add type to TypeScript knexfile #4909
57
+ - Checks Constraints Support #4874
58
+ - Support creating multiple PKs with increments #4903
59
+ - Enable wrapIdentifier for SQLite .hasTable #4915
60
+ - MSSQL: Add support for unique constraint #4887
61
+ - SQLite: New dialect, using better-sqlite3 driver #4871
62
+ - SQLite: Switch to @vscode/sqlite3 #4866
63
+ - SQLite: Support createViewOrReplace #4856
64
+ - SQLite: Support RETURNING statements for better-sqlite3 driver #4934
65
+ - PostgreSQL: Support JOIN and USING syntax for Delete Statement #4800
66
+
67
+ ### Bug fixes:
68
+
69
+ - Fix overzealous warning on use of whereNot with "in" or "between" #4780
70
+ - Fix Union all + first syntax error #4799
71
+ - Make view columns optional in create view like #4829
72
+ - Insert lock row fix during migration #4865
73
+ - Fix for createViewOrReplace #4856
74
+ - SQLite: Fix foreign key constraints when altering a table #4189
75
+ - MySQL: Validate connection fix #4794
76
+ - MySQL: Set comment size warning limit to 1024 #4867
77
+
78
+ ### Typings:
79
+
80
+ - Allow string indexType in index creation #4791
81
+ - Add missing ints typings #4832
82
+ - Returning method types #4881
83
+ - Improve columnInfo type #4868
84
+
85
+ # 0.95.15 - 22 December, 2021
86
+
87
+ ### Bug fixes:
88
+
89
+ - Oracle:
90
+ - MariaDB: lock row fix during migration in MariaDB and Oracle #4865
91
+
3
92
  # 0.95.14 - 09 November, 2021
4
93
 
5
94
  ### Bug fixes:
@@ -11,7 +100,7 @@
11
100
  ### Bug fixes:
12
101
 
13
102
  - PostgreSQL: Support zero precision in timestamp/datetime #4784
14
-
103
+
15
104
  ### Typings:
16
105
 
17
106
  - Allow string indexType in index creation #4791
package/README.md CHANGED
@@ -19,7 +19,7 @@ Node.js, featuring:
19
19
  - both a [promise](https://knexjs.org/#Interfaces-Promises) and [callback](https://knexjs.org/#Interfaces-Callbacks) API
20
20
  - a [thorough test suite](https://github.com/knex/knex/actions)
21
21
 
22
- Node.js versions 10+ are supported.
22
+ Node.js versions 12+ are supported.
23
23
 
24
24
  * Take a look at the [full documentation](https://knexjs.org) to get started!
25
25
  * Browse the [list of plugins and tools](https://github.com/knex/knex/blob/master/ECOSYSTEM.md) built for knex
package/UPGRADING.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## Upgrading to new knex.js versions
2
2
 
3
+ ### Upgrading to version 1.0.0+
4
+
5
+ * Node.js older than 12 is no longer supported, make sure to update your environment;
6
+ * If you are using `sqlite3` driver dependency, please replace it with `@vscode/sqlite3` in your `package.json`;
7
+ * `RETURNING` operations now always return an object with column names;
8
+ * Migrator now returns list of migrations as objects.
9
+
3
10
  ### Upgrading to version 0.95.0+
4
11
 
5
12
  * TypeScript type exports changed significantly. While `import Knex from 'knex';` used to import the knex instantiation function, the namespace and the interface for the knex instantiation function/object, there is now a clear distinction between them:
package/lib/client.js CHANGED
@@ -30,6 +30,7 @@ const Logger = require('./logger');
30
30
  const { POOL_CONFIG_OPTIONS } = require('./constants');
31
31
  const ViewBuilder = require('./schema/viewbuilder.js');
32
32
  const ViewCompiler = require('./schema/viewcompiler.js');
33
+ const isPlainObject = require('lodash/isPlainObject');
33
34
 
34
35
  const debug = require('debug')('knex:client');
35
36
 
@@ -51,6 +52,7 @@ class Client extends EventEmitter {
51
52
  `Using 'this.dialect' to identify the client is deprecated and support for it will be removed in the future. Please use configuration option 'client' instead.`
52
53
  );
53
54
  }
55
+
54
56
  const dbClient = this.config.client || this.dialect;
55
57
  if (!dbClient) {
56
58
  throw new Error(
@@ -392,8 +394,13 @@ class Client extends EventEmitter {
392
394
  i = -1;
393
395
  while (++i < values.length) {
394
396
  if (i > 0) str += ', ';
397
+ let value = values[i];
398
+ // json columns can have object in values.
399
+ if (isPlainObject(value)) {
400
+ value = JSON.stringify(value);
401
+ }
395
402
  str += this.parameter(
396
- values[i] === undefined ? notSetValue : values[i],
403
+ value === undefined ? notSetValue : value,
397
404
  builder,
398
405
  bindingsHolder
399
406
  );
@@ -442,6 +449,12 @@ class Client extends EventEmitter {
442
449
  processPassedConnection(connection) {
443
450
  // Default implementation is noop
444
451
  }
452
+
453
+ toPathForJson(jsonPath) {
454
+ // By default, we want a json path, so if this function is not overriden,
455
+ // we return the path.
456
+ return jsonPath;
457
+ }
445
458
  }
446
459
 
447
460
  Object.assign(Client.prototype, {
package/lib/constants.js CHANGED
@@ -16,6 +16,7 @@ const SUPPORTED_CLIENTS = Object.freeze(
16
16
  'redshift',
17
17
  'sqlite3',
18
18
  'cockroachdb',
19
+ 'better-sqlite3',
19
20
  ].concat(Object.keys(CLIENT_ALIASES))
20
21
  );
21
22
 
@@ -29,6 +30,7 @@ const DRIVER_NAMES = Object.freeze({
29
30
  Redshift: 'pg-redshift',
30
31
  SQLite: 'sqlite3',
31
32
  CockroachDB: 'cockroachdb',
33
+ BetterSQLite3: 'better-sqlite3',
32
34
  });
33
35
 
34
36
  const POOL_CONFIG_OPTIONS = Object.freeze([
@@ -0,0 +1,72 @@
1
+ // better-sqlite3 Client
2
+ // -------
3
+ const Client_SQLite3 = require('../sqlite3');
4
+
5
+ class Client_BetterSQLite3 extends Client_SQLite3 {
6
+ _driver() {
7
+ return require('better-sqlite3');
8
+ }
9
+
10
+ // Get a raw connection from the database, returning a promise with the connection object.
11
+ async acquireRawConnection() {
12
+ return new this.driver(this.connectionSettings.filename);
13
+ }
14
+
15
+ // Used to explicitly close a connection, called internally by the pool when
16
+ // a connection times out or the pool is shutdown.
17
+ async destroyRawConnection(connection) {
18
+ return connection.close();
19
+ }
20
+
21
+ // Runs the query on the specified connection, providing the bindings and any
22
+ // other necessary prep work.
23
+ async _query(connection, obj) {
24
+ if (!obj.sql) throw new Error('The query is empty');
25
+
26
+ if (!connection) {
27
+ throw new Error('No connection provided');
28
+ }
29
+
30
+ const statement = connection.prepare(obj.sql);
31
+ const bindings = this._formatBindings(obj.bindings);
32
+
33
+ if (statement.reader) {
34
+ const response = await statement.all(bindings);
35
+ obj.response = response;
36
+ return obj;
37
+ }
38
+
39
+ const response = await statement.run(bindings);
40
+ obj.response = response;
41
+ obj.context = {
42
+ lastID: response.lastInsertRowid,
43
+ changes: response.changes,
44
+ };
45
+
46
+ return obj;
47
+ }
48
+
49
+ _formatBindings(bindings) {
50
+ if (!bindings) {
51
+ return [];
52
+ }
53
+ return bindings.map((binding) => {
54
+ if (binding instanceof Date) {
55
+ return binding.valueOf();
56
+ }
57
+
58
+ if (typeof binding === 'boolean') {
59
+ return Number(binding);
60
+ }
61
+
62
+ return binding;
63
+ });
64
+ }
65
+ }
66
+
67
+ Object.assign(Client_BetterSQLite3.prototype, {
68
+ // The "dialect", for reference .
69
+ driverName: 'better-sqlite3',
70
+ });
71
+
72
+ module.exports = Client_BetterSQLite3;
@@ -1,6 +1,9 @@
1
1
  const QueryCompiler_PG = require('../postgres/query/pg-querycompiler');
2
- const isEmpty = require('lodash/isEmpty');
3
- const { columnize: columnize_ } = require('../../formatter/wrappingFormatter');
2
+ const {
3
+ columnize: columnize_,
4
+ wrap: wrap_,
5
+ operator: operator_,
6
+ } = require('../../formatter/wrappingFormatter');
4
7
 
5
8
  class QueryCompiler_CRDB extends QueryCompiler_PG {
6
9
  truncate() {
@@ -20,43 +23,99 @@ class QueryCompiler_CRDB extends QueryCompiler_PG {
20
23
 
21
24
  _upsert() {
22
25
  const upsertValues = this.single.upsert || [];
23
- let sql = this.with() + `upsert into ${this.tableName} `;
24
- if (Array.isArray(upsertValues)) {
25
- if (upsertValues.length === 0) return '';
26
- } else if (typeof upsertValues === 'object' && isEmpty(upsertValues)) {
27
- return sql + this._emptyInsertValue;
26
+ const sql = this.with() + `upsert into ${this.tableName} `;
27
+ const body = this._insertBody(upsertValues);
28
+ return body === '' ? '' : sql + body;
29
+ }
30
+
31
+ _groupOrder(item, type) {
32
+ // CockroachDB don't support PostgreSQL order nulls first/last syntax, we take the generic one.
33
+ return this._basicGroupOrder(item, type);
34
+ }
35
+
36
+ whereJsonPath(statement) {
37
+ let castValue = '';
38
+ if (parseInt(statement.value)) {
39
+ castValue = '::int';
40
+ } else if (parseFloat(statement.value)) {
41
+ castValue = '::float';
42
+ } else {
43
+ castValue = " #>> '{}'";
28
44
  }
45
+ return `json_extract_path(${this._columnClause(
46
+ statement
47
+ )}, ${this.client.toArrayPathFromJsonPath(
48
+ statement.jsonPath,
49
+ this.builder,
50
+ this.bindingsHolder
51
+ )})${castValue} ${operator_(
52
+ statement.operator,
53
+ this.builder,
54
+ this.client,
55
+ this.bindingsHolder
56
+ )} ${this._jsonValueClause(statement)}`;
57
+ }
29
58
 
30
- const upsertData = this._prepInsert(upsertValues);
31
- if (typeof upsertData === 'string') {
32
- sql += upsertData;
59
+ // Json common functions
60
+ _jsonExtract(nameFunction, params) {
61
+ let extractions;
62
+ if (Array.isArray(params.column)) {
63
+ extractions = params.column;
33
64
  } else {
34
- if (upsertData.columns.length) {
35
- sql += `(${columnize_(
36
- upsertData.columns,
65
+ extractions = [params];
66
+ }
67
+ return extractions
68
+ .map((extraction) => {
69
+ const jsonCol = `json_extract_path(${columnize_(
70
+ extraction.column || extraction[0],
37
71
  this.builder,
38
72
  this.client,
39
73
  this.bindingsHolder
40
- )}`;
41
- sql += ') values (';
42
- let i = -1;
43
- while (++i < upsertData.values.length) {
44
- if (i !== 0) sql += '), (';
45
- sql += this.client.parameterize(
46
- upsertData.values[i],
47
- this.client.valueForUndefined,
48
- this.builder,
49
- this.bindingsHolder
50
- );
51
- }
52
- sql += ')';
53
- } else if (upsertValues.length === 1 && upsertValues[0]) {
54
- sql += this._emptyInsertValue;
55
- } else {
56
- sql = '';
57
- }
58
- }
59
- return sql;
74
+ )}, ${this.client.toArrayPathFromJsonPath(
75
+ extraction.path || extraction[1],
76
+ this.builder,
77
+ this.bindingsHolder
78
+ )})`;
79
+ const alias = extraction.alias || extraction[2];
80
+ return alias
81
+ ? this.client.alias(jsonCol, this.formatter.wrap(alias))
82
+ : jsonCol;
83
+ })
84
+ .join(', ');
85
+ }
86
+
87
+ _onJsonPathEquals(nameJoinFunction, clause) {
88
+ return (
89
+ 'json_extract_path(' +
90
+ wrap_(
91
+ clause.columnFirst,
92
+ undefined,
93
+ this.builder,
94
+ this.client,
95
+ this.bindingsHolder
96
+ ) +
97
+ ', ' +
98
+ this.client.toArrayPathFromJsonPath(
99
+ clause.jsonPathFirst,
100
+ this.builder,
101
+ this.bindingsHolder
102
+ ) +
103
+ ') = json_extract_path(' +
104
+ wrap_(
105
+ clause.columnSecond,
106
+ undefined,
107
+ this.builder,
108
+ this.client,
109
+ this.bindingsHolder
110
+ ) +
111
+ ', ' +
112
+ this.client.toArrayPathFromJsonPath(
113
+ clause.jsonPathSecond,
114
+ this.builder,
115
+ this.bindingsHolder
116
+ ) +
117
+ ')'
118
+ );
60
119
  }
61
120
  }
62
121
 
@@ -7,6 +7,25 @@ class TableCompiler_CRDB extends TableCompiler {
7
7
  super(client, tableBuilder);
8
8
  }
9
9
 
10
+ addColumns(columns, prefix, colCompilers) {
11
+ if (prefix === this.alterColumnsPrefix) {
12
+ // alter columns
13
+ for (const col of colCompilers) {
14
+ this.client.logger.warn(
15
+ 'Experimental alter column in use, see issue: https://github.com/cockroachdb/cockroach/issues/49329'
16
+ );
17
+ this.pushQuery({
18
+ sql: 'SET enable_experimental_alter_column_type_general = true',
19
+ bindings: [],
20
+ });
21
+ super._addColumn(col);
22
+ }
23
+ } else {
24
+ // base class implementation for normal add
25
+ super.addColumns(columns, prefix);
26
+ }
27
+ }
28
+
10
29
  dropUnique(columns, indexName) {
11
30
  indexName = indexName
12
31
  ? this.formatter.wrap(indexName)
@@ -58,6 +58,19 @@ class Client_CockroachDB extends Client_PostgreSQL {
58
58
  connectionToKill.activeQuery
59
59
  );
60
60
  }
61
+
62
+ toArrayPathFromJsonPath(jsonPath, builder, bindingsHolder) {
63
+ return jsonPath
64
+ .replace(/^(\$\.)/, '') // remove the first dollar
65
+ .replace(/\[([0-9]+)]/, '.$1')
66
+ .split('.')
67
+ .map(
68
+ function (v) {
69
+ return this.parameter(v, builder, bindingsHolder);
70
+ }.bind(this)
71
+ )
72
+ .join(', ');
73
+ }
61
74
  }
62
75
 
63
76
  Object.assign(Client_CockroachDB.prototype, {
@@ -1,8 +1,6 @@
1
1
  // MSSQL Client
2
2
  // -------
3
- const flatten = require('lodash/flatten');
4
3
  const map = require('lodash/map');
5
- const values = require('lodash/values');
6
4
  const isNil = require('lodash/isNil');
7
5
 
8
6
  const Client = require('../../client');
@@ -472,15 +470,6 @@ class Client_MSSQL extends Client {
472
470
  if (query.returning === '@@rowcount') {
473
471
  return response[0][''];
474
472
  }
475
-
476
- if (
477
- (Array.isArray(query.returning) && query.returning.length > 1) ||
478
- query.returning[0] === '*'
479
- ) {
480
- return response;
481
- }
482
- // return an array with values if only one returning value was specified
483
- return flatten(map(response, values));
484
473
  }
485
474
  return response;
486
475
  default: