knex 1.0.1 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
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
+
3
27
  # 1.0.1 - 16 January, 2022
4
28
 
5
29
  ### Bug fixes:
package/UPGRADING.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ### Upgrading to version 1.0.0+
4
4
 
5
5
  * Node.js older than 12 is no longer supported, make sure to update your environment;
6
- * If you are using `sqlite3` driver, please replace it with `@vscode/sqlite3`;
6
+ * If you are using `sqlite3` driver dependency, please replace it with `@vscode/sqlite3` in your `package.json`;
7
7
  * `RETURNING` operations now always return an object with column names;
8
8
  * Migrator now returns list of migrations as objects.
9
9
 
@@ -56,7 +56,7 @@ class Client_BetterSQLite3 extends Client_SQLite3 {
56
56
  }
57
57
 
58
58
  if (typeof binding === 'boolean') {
59
- return String(binding);
59
+ return Number(binding);
60
60
  }
61
61
 
62
62
  return binding;
@@ -28,6 +28,11 @@ class QueryCompiler_CRDB extends QueryCompiler_PG {
28
28
  return body === '' ? '' : sql + body;
29
29
  }
30
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
+
31
36
  whereJsonPath(statement) {
32
37
  let castValue = '';
33
38
  if (parseInt(statement.value)) {
@@ -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
 
@@ -80,12 +80,14 @@ class QueryCompiler_MySQL extends QueryCompiler {
80
80
 
81
81
  // Update method, including joins, wheres, order & limits.
82
82
  update() {
83
+ const withSQL = this.with();
83
84
  const join = this.join();
84
85
  const updates = this._prepUpdate(this.single.update);
85
86
  const where = this.where();
86
87
  const order = this.order();
87
88
  const limit = this.limit();
88
89
  return (
90
+ withSQL +
89
91
  `update ${this.tableName}` +
90
92
  (join ? ` ${join}` : '') +
91
93
  ' set ' +
@@ -73,7 +73,7 @@ class TableCompiler_MySQL extends TableCompiler {
73
73
 
74
74
  this.pushQuery({
75
75
  sql:
76
- `show fields from ${table} where field = ` +
76
+ `show full fields from ${table} where field = ` +
77
77
  this.client.parameter(from, this.tableBuilder, this.bindingsHolder),
78
78
  output(resp) {
79
79
  const column = resp[0];
@@ -101,7 +101,10 @@ class TableCompiler_MySQL extends TableCompiler {
101
101
  if (column.Default !== void 0 && column.Default !== null) {
102
102
  sql += ` DEFAULT '${column.Default}'`;
103
103
  }
104
- // Add back the auto increment if the column had it, fix issue #2767
104
+ if (column.Collation !== void 0 && column.Collation !== null) {
105
+ sql += ` COLLATE '${column.Collation}'`;
106
+ }
107
+ // Add back the auto increment if the column it, fix issue #2767
105
108
  if (column.Extra == 'auto_increment') {
106
109
  sql += ` AUTO_INCREMENT`;
107
110
  }
@@ -8,9 +8,7 @@ const BlobHelper = require('../utils').BlobHelper;
8
8
  const { isString } = require('../../../util/is');
9
9
  const {
10
10
  columnize: columnize_,
11
- direction: direction_,
12
11
  } = require('../../../formatter/wrappingFormatter');
13
- const Raw = require('../../../raw');
14
12
 
15
13
  class Oracledb_Compiler extends Oracle_Compiler {
16
14
  // Compiles an "insert" query, allowing for multiple
@@ -318,20 +316,7 @@ class Oracledb_Compiler extends Oracle_Compiler {
318
316
  }
319
317
 
320
318
  _groupOrder(item, type) {
321
- const column = super._formatGroupsItemValue(item.value);
322
- const direction =
323
- type === 'order' && item.type !== 'orderByRaw'
324
- ? ` ${direction_(
325
- item.direction,
326
- this.builder,
327
- this.client,
328
- this.bindingsHolder
329
- )}`
330
- : '';
331
- if (item.nulls && !(item.value instanceof Raw)) {
332
- return `${column}${direction ? direction : ''} nulls ${item.nulls}`;
333
- }
334
- return column + direction;
319
+ return super._groupOrderNulls(item, type);
335
320
  }
336
321
 
337
322
  update() {
@@ -5,4 +5,34 @@ module.exports = class QueryBuilder_PostgreSQL extends QueryBuilder {
5
5
  this._single.using = tables;
6
6
  return this;
7
7
  }
8
+
9
+ withMaterialized(alias, statementOrColumnList, nothingOrStatement) {
10
+ this._validateWithArgs(
11
+ alias,
12
+ statementOrColumnList,
13
+ nothingOrStatement,
14
+ 'with'
15
+ );
16
+ return this.withWrapped(
17
+ alias,
18
+ statementOrColumnList,
19
+ nothingOrStatement,
20
+ true
21
+ );
22
+ }
23
+
24
+ withNotMaterialized(alias, statementOrColumnList, nothingOrStatement) {
25
+ this._validateWithArgs(
26
+ alias,
27
+ statementOrColumnList,
28
+ nothingOrStatement,
29
+ 'with'
30
+ );
31
+ return this.withWrapped(
32
+ alias,
33
+ statementOrColumnList,
34
+ nothingOrStatement,
35
+ false
36
+ );
37
+ }
8
38
  };
@@ -145,13 +145,11 @@ class QueryCompiler_PG extends QueryCompiler {
145
145
  if (columns === true) {
146
146
  return ' on conflict do nothing';
147
147
  }
148
- return ` on conflict (${this.formatter.columnize(columns)}) do nothing`;
148
+ return ` on conflict ${this._onConflictClause(columns)} do nothing`;
149
149
  }
150
150
 
151
151
  _merge(updates, columns, insert) {
152
- let sql = ` on conflict (${this.formatter.columnize(
153
- columns
154
- )}) do update set `;
152
+ let sql = ` on conflict ${this._onConflictClause(columns)} do update set `;
155
153
  if (updates && Array.isArray(updates)) {
156
154
  sql += updates
157
155
  .map((column) =>
@@ -219,6 +217,10 @@ class QueryCompiler_PG extends QueryCompiler {
219
217
  return lockMode + (tables.length ? ' of ' + this._tableNames(tables) : '');
220
218
  }
221
219
 
220
+ _groupOrder(item, type) {
221
+ return super._groupOrderNulls(item, type);
222
+ }
223
+
222
224
  forUpdate() {
223
225
  return this._lockingClause('for update');
224
226
  }
@@ -91,21 +91,28 @@ class TableCompiler_PG extends TableCompiler {
91
91
 
92
92
  // To alter enum columns they must be cast to text first
93
93
  const isEnum = col.type === 'enu';
94
-
95
94
  this.pushQuery({
96
95
  sql: `alter table ${quotedTableName} alter column ${colName} drop default`,
97
96
  bindings: [],
98
97
  });
99
- this.pushQuery({
100
- sql: `alter table ${quotedTableName} alter column ${colName} drop not null`,
101
- bindings: [],
102
- });
103
- this.pushQuery({
104
- sql: `alter table ${quotedTableName} alter column ${colName} type ${type} using (${colName}${
105
- isEnum ? '::text::' : '::'
106
- }${type})`,
107
- bindings: [],
108
- });
98
+
99
+ const alterNullable = col.columnBuilder.alterNullable;
100
+ if (alterNullable) {
101
+ this.pushQuery({
102
+ sql: `alter table ${quotedTableName} alter column ${colName} drop not null`,
103
+ bindings: [],
104
+ });
105
+ }
106
+
107
+ const alterType = col.columnBuilder.alterType;
108
+ if (alterType) {
109
+ this.pushQuery({
110
+ sql: `alter table ${quotedTableName} alter column ${colName} type ${type} using (${colName}${
111
+ isEnum ? '::text::' : '::'
112
+ }${type})`,
113
+ bindings: [],
114
+ });
115
+ }
109
116
 
110
117
  const defaultTo = col.modified['defaultTo'];
111
118
  if (defaultTo) {
@@ -116,12 +123,14 @@ class TableCompiler_PG extends TableCompiler {
116
123
  });
117
124
  }
118
125
 
119
- const nullable = col.modified['nullable'];
120
- if (nullable && nullable[0] === false) {
121
- this.pushQuery({
122
- sql: `alter table ${quotedTableName} alter column ${colName} set not null`,
123
- bindings: [],
124
- });
126
+ if (alterNullable) {
127
+ const nullable = col.modified['nullable'];
128
+ if (nullable && nullable[0] === false) {
129
+ this.pushQuery({
130
+ sql: `alter table ${quotedTableName} alter column ${colName} set not null`,
131
+ bindings: [],
132
+ });
133
+ }
125
134
  }
126
135
  }
127
136
 
@@ -15,6 +15,7 @@ const TableCompiler = require('./schema/sqlite-tablecompiler');
15
15
  const ViewCompiler = require('./schema/sqlite-viewcompiler');
16
16
  const SQLite3_DDL = require('./schema/ddl');
17
17
  const Formatter = require('../../formatter');
18
+ const QueryBuilder = require('./query/sqlite-querybuilder');
18
19
 
19
20
  class Client_SQLite3 extends Client {
20
21
  constructor(config) {
@@ -44,6 +45,10 @@ class Client_SQLite3 extends Client {
44
45
  return new SqliteQueryCompiler(this, builder, formatter);
45
46
  }
46
47
 
48
+ queryBuilder() {
49
+ return new QueryBuilder(this);
50
+ }
51
+
47
52
  viewCompiler(builder, formatter) {
48
53
  return new ViewCompiler(this, builder, formatter);
49
54
  }
@@ -0,0 +1,33 @@
1
+ const QueryBuilder = require('../../../query/querybuilder.js');
2
+
3
+ module.exports = class QueryBuilder_SQLite3 extends QueryBuilder {
4
+ withMaterialized(alias, statementOrColumnList, nothingOrStatement) {
5
+ this._validateWithArgs(
6
+ alias,
7
+ statementOrColumnList,
8
+ nothingOrStatement,
9
+ 'with'
10
+ );
11
+ return this.withWrapped(
12
+ alias,
13
+ statementOrColumnList,
14
+ nothingOrStatement,
15
+ true
16
+ );
17
+ }
18
+
19
+ withNotMaterialized(alias, statementOrColumnList, nothingOrStatement) {
20
+ this._validateWithArgs(
21
+ alias,
22
+ statementOrColumnList,
23
+ nothingOrStatement,
24
+ 'with'
25
+ );
26
+ return this.withWrapped(
27
+ alias,
28
+ statementOrColumnList,
29
+ nothingOrStatement,
30
+ false
31
+ );
32
+ }
33
+ };
@@ -153,13 +153,11 @@ class QueryCompiler_SQLite3 extends QueryCompiler {
153
153
  if (columns === true) {
154
154
  return ' on conflict do nothing';
155
155
  }
156
- return ` on conflict (${this.formatter.columnize(columns)}) do nothing`;
156
+ return ` on conflict ${this._onConflictClause(columns)} do nothing`;
157
157
  }
158
158
 
159
159
  _merge(updates, columns, insert) {
160
- let sql = ` on conflict (${this.formatter.columnize(
161
- columns
162
- )}) do update set `;
160
+ let sql = ` on conflict ${this._onConflictClause(columns)} do update set `;
163
161
  if (updates && Array.isArray(updates)) {
164
162
  sql += updates
165
163
  .map((column) =>
@@ -14,25 +14,40 @@ class FunctionHelper {
14
14
  return this.client.raw('CURRENT_TIMESTAMP');
15
15
  }
16
16
 
17
- uuidToBin(uuid) {
17
+ uuidToBin(uuid, ordered = true) {
18
18
  const buf = Buffer.from(uuid.replace(/-/g, ''), 'hex');
19
- return Buffer.concat([
20
- buf.slice(6, 8),
21
- buf.slice(4, 6),
22
- buf.slice(0, 4),
23
- buf.slice(8, 16),
24
- ]);
19
+ return ordered
20
+ ? Buffer.concat([
21
+ buf.slice(6, 8),
22
+ buf.slice(4, 6),
23
+ buf.slice(0, 4),
24
+ buf.slice(8, 16),
25
+ ])
26
+ : Buffer.concat([
27
+ buf.slice(0, 4),
28
+ buf.slice(4, 6),
29
+ buf.slice(6, 8),
30
+ buf.slice(8, 16),
31
+ ]);
25
32
  }
26
33
 
27
- binToUuid(bin) {
28
- const buf = new Buffer(bin, 'hex');
29
- return [
30
- buf.toString('hex', 4, 8),
31
- buf.toString('hex', 2, 4),
32
- buf.toString('hex', 0, 2),
33
- buf.toString('hex', 8, 10),
34
- buf.toString('hex', 10, 16),
35
- ].join('-');
34
+ binToUuid(bin, ordered = true) {
35
+ const buf = Buffer.from(bin, 'hex');
36
+ return ordered
37
+ ? [
38
+ buf.toString('hex', 4, 8),
39
+ buf.toString('hex', 2, 4),
40
+ buf.toString('hex', 0, 2),
41
+ buf.toString('hex', 8, 10),
42
+ buf.toString('hex', 10, 16),
43
+ ].join('-')
44
+ : [
45
+ buf.toString('hex', 0, 4),
46
+ buf.toString('hex', 4, 6),
47
+ buf.toString('hex', 6, 8),
48
+ buf.toString('hex', 8, 10),
49
+ buf.toString('hex', 10, 16),
50
+ ].join('-');
36
51
  }
37
52
  }
38
53
 
@@ -562,8 +562,9 @@ function validateMigrationList(migrationSource, migrations) {
562
562
  const [all, completed] = migrations;
563
563
  const diff = getMissingMigrations(migrationSource, completed, all);
564
564
  if (!isEmpty(diff)) {
565
+ const names = diff.map((d) => d.name);
565
566
  throw new Error(
566
- `The migration directory is corrupt, the following files are missing: ${diff.join(
567
+ `The migration directory is corrupt, the following files are missing: ${names.join(
567
568
  ', '
568
569
  )}`
569
570
  );
@@ -118,25 +118,82 @@ class Builder extends EventEmitter {
118
118
 
119
119
  // With
120
120
  // ------
121
+ isValidStatementArg(statement) {
122
+ return (
123
+ typeof statement === 'function' ||
124
+ statement instanceof Builder ||
125
+ (statement && statement.isRawInstance)
126
+ );
127
+ }
128
+
129
+ _validateWithArgs(alias, statementOrColumnList, nothingOrStatement, method) {
130
+ const [query, columnList] =
131
+ typeof nothingOrStatement === 'undefined'
132
+ ? [statementOrColumnList, undefined]
133
+ : [nothingOrStatement, statementOrColumnList];
134
+ if (typeof alias !== 'string') {
135
+ throw new Error(`${method}() first argument must be a string`);
136
+ }
137
+
138
+ if (this.isValidStatementArg(query) && typeof columnList === 'undefined') {
139
+ // Validated as two-arg variant (alias, statement).
140
+ return;
141
+ }
142
+
143
+ // Attempt to interpret as three-arg variant (alias, columnList, statement).
144
+ const isNonEmptyNameList =
145
+ Array.isArray(columnList) &&
146
+ columnList.length > 0 &&
147
+ columnList.every((it) => typeof it === 'string');
148
+ if (!isNonEmptyNameList) {
149
+ throw new Error(
150
+ `${method}() second argument must be a statement or non-empty column name list.`
151
+ );
152
+ }
153
+
154
+ if (this.isValidStatementArg(query)) {
155
+ return;
156
+ }
157
+ throw new Error(
158
+ `${method}() third argument must be a function / QueryBuilder or a raw when its second argument is a column name list`
159
+ );
160
+ }
121
161
 
122
162
  with(alias, statementOrColumnList, nothingOrStatement) {
123
- validateWithArgs(alias, statementOrColumnList, nothingOrStatement, 'with');
163
+ this._validateWithArgs(
164
+ alias,
165
+ statementOrColumnList,
166
+ nothingOrStatement,
167
+ 'with'
168
+ );
124
169
  return this.withWrapped(alias, statementOrColumnList, nothingOrStatement);
125
170
  }
126
171
 
172
+ withMaterialized(alias, statementOrColumnList, nothingOrStatement) {
173
+ throw new Error('With materialized is not supported by this dialect');
174
+ }
175
+
176
+ withNotMaterialized(alias, statementOrColumnList, nothingOrStatement) {
177
+ throw new Error('With materialized is not supported by this dialect');
178
+ }
179
+
127
180
  // Helper for compiling any advanced `with` queries.
128
- withWrapped(alias, statementOrColumnList, nothingOrStatement) {
181
+ withWrapped(alias, statementOrColumnList, nothingOrStatement, materialized) {
129
182
  const [query, columnList] =
130
183
  typeof nothingOrStatement === 'undefined'
131
184
  ? [statementOrColumnList, undefined]
132
185
  : [nothingOrStatement, statementOrColumnList];
133
- this._statements.push({
186
+ const statement = {
134
187
  grouping: 'with',
135
188
  type: 'withWrapped',
136
189
  alias: alias,
137
190
  columnList,
138
191
  value: query,
139
- });
192
+ };
193
+ if (materialized !== undefined) {
194
+ statement.materialized = materialized;
195
+ }
196
+ this._statements.push(statement);
140
197
  return this;
141
198
  }
142
199
 
@@ -144,7 +201,7 @@ class Builder extends EventEmitter {
144
201
  // ------
145
202
 
146
203
  withRecursive(alias, statementOrColumnList, nothingOrStatement) {
147
- validateWithArgs(
204
+ this._validateWithArgs(
148
205
  alias,
149
206
  statementOrColumnList,
150
207
  nothingOrStatement,
@@ -1656,49 +1713,6 @@ class Builder extends EventEmitter {
1656
1713
  }
1657
1714
  }
1658
1715
 
1659
- const isValidStatementArg = (statement) =>
1660
- typeof statement === 'function' ||
1661
- statement instanceof Builder ||
1662
- (statement && statement.isRawInstance);
1663
-
1664
- const validateWithArgs = function (
1665
- alias,
1666
- statementOrColumnList,
1667
- nothingOrStatement,
1668
- method
1669
- ) {
1670
- const [query, columnList] =
1671
- typeof nothingOrStatement === 'undefined'
1672
- ? [statementOrColumnList, undefined]
1673
- : [nothingOrStatement, statementOrColumnList];
1674
- if (typeof alias !== 'string') {
1675
- throw new Error(`${method}() first argument must be a string`);
1676
- }
1677
-
1678
- if (isValidStatementArg(query) && typeof columnList === 'undefined') {
1679
- // Validated as two-arg variant (alias, statement).
1680
- return;
1681
- }
1682
-
1683
- // Attempt to interpret as three-arg variant (alias, columnList, statement).
1684
- const isNonEmptyNameList =
1685
- Array.isArray(columnList) &&
1686
- columnList.length > 0 &&
1687
- columnList.every((it) => typeof it === 'string');
1688
- if (!isNonEmptyNameList) {
1689
- throw new Error(
1690
- `${method}() second argument must be a statement or non-empty column name list.`
1691
- );
1692
- }
1693
-
1694
- if (isValidStatementArg(query)) {
1695
- return;
1696
- }
1697
- throw new Error(
1698
- `${method}() third argument must be a function / QueryBuilder or a raw when its second argument is a column name list`
1699
- );
1700
- };
1701
-
1702
1716
  Builder.prototype.select = Builder.prototype.columns;
1703
1717
  Builder.prototype.column = Builder.prototype.columns;
1704
1718
  Builder.prototype.andWhereNot = Builder.prototype.whereNot;
@@ -149,6 +149,12 @@ class QueryCompiler {
149
149
  return body === '' ? '' : sql + body;
150
150
  }
151
151
 
152
+ _onConflictClause(columns) {
153
+ return columns instanceof Raw
154
+ ? this.formatter.wrap(columns)
155
+ : `(${this.formatter.columnize(columns)})`;
156
+ }
157
+
152
158
  _buildInsertValues(insertData) {
153
159
  let sql = '';
154
160
  let i = -1;
@@ -1070,10 +1076,14 @@ class QueryCompiler {
1070
1076
  }
1071
1077
 
1072
1078
  _jsonWrapValue(jsonValue) {
1073
- if (this.builder._isJsonObject(jsonValue)) {
1074
- return JSON.stringify(jsonValue);
1079
+ if (!this.builder._isJsonObject(jsonValue)) {
1080
+ try {
1081
+ return JSON.stringify(JSON.parse(jsonValue.replace(/\n|\t/g, '')));
1082
+ } catch (e) {
1083
+ return jsonValue;
1084
+ }
1075
1085
  }
1076
- return jsonValue;
1086
+ return JSON.stringify(jsonValue);
1077
1087
  }
1078
1088
 
1079
1089
  _jsonValueClause(statement) {
@@ -1170,6 +1180,12 @@ class QueryCompiler {
1170
1180
  ) +
1171
1181
  ')'
1172
1182
  : '';
1183
+ const materialized =
1184
+ statement.materialized === undefined
1185
+ ? ''
1186
+ : statement.materialized
1187
+ ? 'materialized '
1188
+ : 'not materialized ';
1173
1189
  return (
1174
1190
  (val &&
1175
1191
  columnize_(
@@ -1179,7 +1195,9 @@ class QueryCompiler {
1179
1195
  this.bindingsHolder
1180
1196
  ) +
1181
1197
  columnList +
1182
- ' as (' +
1198
+ ' as ' +
1199
+ materialized +
1200
+ '(' +
1183
1201
  val +
1184
1202
  ')') ||
1185
1203
  ''
@@ -1325,7 +1343,7 @@ class QueryCompiler {
1325
1343
  return groupOrder;
1326
1344
  }
1327
1345
 
1328
- _groupOrder(item, type) {
1346
+ _basicGroupOrder(item, type) {
1329
1347
  const column = this._formatGroupsItemValue(item.value, item.nulls);
1330
1348
  const direction =
1331
1349
  type === 'order' && item.type !== 'orderByRaw'
@@ -1339,6 +1357,27 @@ class QueryCompiler {
1339
1357
  return column + direction;
1340
1358
  }
1341
1359
 
1360
+ _groupOrder(item, type) {
1361
+ return this._basicGroupOrder(item, type);
1362
+ }
1363
+
1364
+ _groupOrderNulls(item, type) {
1365
+ const column = this._formatGroupsItemValue(item.value);
1366
+ const direction =
1367
+ type === 'order' && item.type !== 'orderByRaw'
1368
+ ? ` ${direction_(
1369
+ item.direction,
1370
+ this.builder,
1371
+ this.client,
1372
+ this.bindingsHolder
1373
+ )}`
1374
+ : '';
1375
+ if (item.nulls && !(item.value instanceof Raw)) {
1376
+ return `${column}${direction ? direction : ''} nulls ${item.nulls}`;
1377
+ }
1378
+ return column + direction;
1379
+ }
1380
+
1342
1381
  // Compiles the `order by` statements.
1343
1382
  _groupsOrders(type) {
1344
1383
  const items = this.grouped[type];
@@ -110,8 +110,13 @@ AlterMethods.alterType = function (type) {
110
110
  };
111
111
 
112
112
  // Set column method to alter (default is add).
113
- AlterMethods.alter = function () {
113
+ AlterMethods.alter = function ({
114
+ alterNullable = true,
115
+ alterType = true,
116
+ } = {}) {
114
117
  this._method = 'alter';
118
+ this.alterNullable = alterNullable;
119
+ this.alterType = alterType;
115
120
 
116
121
  return this;
117
122
  };
@@ -127,9 +127,9 @@ class TableCompiler {
127
127
  ' (' +
128
128
  references +
129
129
  ')' +
130
- deferrable +
131
130
  onUpdate +
132
- onDelete
131
+ onDelete +
132
+ deferrable
133
133
  );
134
134
  } else {
135
135
  this.pushQuery(
@@ -144,9 +144,9 @@ class TableCompiler {
144
144
  ' (' +
145
145
  references +
146
146
  ')' +
147
- deferrable +
148
147
  onUpdate +
149
- onDelete
148
+ onDelete +
149
+ deferrable
150
150
  );
151
151
  }
152
152
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knex",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A batteries-included SQL query & schema builder for PostgresSQL, MySQL, CockroachDB, MSSQL and SQLite3",
5
5
  "main": "knex",
6
6
  "types": "types/index.d.ts",
@@ -84,9 +84,6 @@
84
84
  "pg-native": {
85
85
  "optional": true
86
86
  },
87
- "sqlite3": {
88
- "optional": true
89
- },
90
87
  "@vscode/sqlite3": {
91
88
  "optional": true
92
89
  },
@@ -101,24 +98,24 @@
101
98
  ]
102
99
  },
103
100
  "devDependencies": {
104
- "@types/node": "^16.11.19",
101
+ "@types/node": "^16.11.22",
105
102
  "@vscode/sqlite3": "^5.0.7",
106
- "better-sqlite3": "^7.4.6",
107
- "chai": "^4.3.4",
103
+ "better-sqlite3": "^7.5.0",
104
+ "chai": "^4.3.6",
108
105
  "chai-as-promised": "^7.1.1",
109
106
  "chai-subset-in-order": "^3.1.0",
110
107
  "cli-testlab": "^2.2.0",
111
108
  "coveralls": "^3.1.1",
112
109
  "cross-env": "^7.0.3",
113
110
  "dtslint": "4.2.1",
114
- "eslint": "^8.1.0",
111
+ "eslint": "^8.8.0",
115
112
  "eslint-config-prettier": "^8.3.0",
116
- "eslint-plugin-import": "^2.25.2",
113
+ "eslint-plugin-import": "^2.25.4",
117
114
  "husky": "^4.3.8",
118
115
  "jake": "^8.1.1",
119
116
  "JSONStream": "^1.3.5",
120
117
  "lint-staged": "^11.1.2",
121
- "mocha": "^9.1.4",
118
+ "mocha": "^9.2.0",
122
119
  "mock-fs": "^5.1.2",
123
120
  "mysql": "^2.18.1",
124
121
  "mysql2": "^2.3.3",
@@ -128,16 +125,16 @@
128
125
  "pg-query-stream": "^4.2.1",
129
126
  "prettier": "2.4.1",
130
127
  "rimraf": "^3.0.2",
131
- "sinon": "^12.0.1",
128
+ "sinon": "^13.0.1",
132
129
  "sinon-chai": "^3.7.0",
133
130
  "source-map-support": "^0.5.21",
134
131
  "tap-spec": "^5.0.0",
135
- "tape": "^5.4.0",
136
- "tedious": "^12.2.0",
132
+ "tape": "^5.5.0",
133
+ "tedious": "^12.3.0",
137
134
  "toxiproxy-node-client": "^2.0.6",
138
135
  "ts-node": "^10.4.0",
139
136
  "tsd": "^0.19.1",
140
- "typescript": "4.5.4"
137
+ "typescript": "4.5.5"
141
138
  },
142
139
  "buildDependencies": [
143
140
  "rimraf"
package/types/index.d.ts CHANGED
@@ -520,6 +520,8 @@ export declare namespace Knex {
520
520
 
521
521
  // Withs
522
522
  with: With<TRecord, TResult>;
523
+ withMaterialized: With<TRecord, TResult>;
524
+ withNotMaterialized: With<TRecord, TResult>;
523
525
  withRecursive: With<TRecord, TResult>;
524
526
  withRaw: WithRaw<TRecord, TResult>;
525
527
  withSchema: WithSchema<TRecord, TResult>;
@@ -546,7 +548,7 @@ export declare namespace Knex {
546
548
  whereNotIn: WhereIn<TRecord, TResult>;
547
549
  orWhereNotIn: WhereIn<TRecord, TResult>;
548
550
  whereLike: Where<TRecord, TResult>;
549
- whereIlike: Where<TRecord, TResult>;
551
+ whereILike: Where<TRecord, TResult>;
550
552
  whereNull: WhereNull<TRecord, TResult>;
551
553
  orWhereNull: WhereNull<TRecord, TResult>;
552
554
  whereNotNull: WhereNull<TRecord, TResult>;
@@ -977,6 +979,10 @@ export declare namespace Knex {
977
979
  columns: string[]
978
980
  ): OnConflictQueryBuilder<TRecord, TResult>;
979
981
 
982
+ onConflict(
983
+ raw: Raw
984
+ ): OnConflictQueryBuilder<TRecord, TResult>;
985
+
980
986
  onConflict(): OnConflictQueryBuilder<TRecord, TResult>;
981
987
 
982
988
  del(
@@ -2204,7 +2210,7 @@ export declare namespace Knex {
2204
2210
  notNullable(): ColumnBuilder;
2205
2211
  nullable(): ColumnBuilder;
2206
2212
  comment(value: string): ColumnBuilder;
2207
- alter(): ColumnBuilder;
2213
+ alter(options: Readonly<{alterNullable?: boolean, alterType?: boolean}>): ColumnBuilder;
2208
2214
  queryContext(context: any): ColumnBuilder;
2209
2215
  after(columnName: string): ColumnBuilder;
2210
2216
  first(): ColumnBuilder;
@@ -2717,6 +2723,8 @@ export declare namespace Knex {
2717
2723
 
2718
2724
  interface FunctionHelper {
2719
2725
  now(precision?: number): Raw;
2726
+ uuidToBin(uuid: string, ordered?: boolean): Buffer;
2727
+ binToUuid(bin: Buffer, ordered?: boolean): string;
2720
2728
  }
2721
2729
 
2722
2730
  interface EnumOptions {