@bdkinc/knex-ibmi 0.0.3 → 0.0.5

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![npm version](http://img.shields.io/npm/v/knex-db2.svg)](https://npmjs.org/package/@bdkinc/knex-ibmi)
1
+ [![npm version](http://img.shields.io/npm/v/@bdkinc/knex-ibmi.svg)](https://npmjs.org/package/@bdkinc/knex-ibmi)
2
2
 
3
3
  **Disclaimer: this library is in early stages of development. Please submit an issue for any bugs encounter or any questions you have.**
4
4
 
@@ -19,6 +19,7 @@ Currently, this dialect has limited functionality compared to the Knex built-in
19
19
  - No streaming support
20
20
  - Possibly other missing functionality
21
21
  - Uses a pool for all connections
22
+ - Journaling must be handled separately. After a migration is ran journaling can be configured on the newly created tables. I recommend using the schema utility in the i access client solutions software.
22
23
 
23
24
  ## Installing
24
25
 
@@ -106,7 +107,7 @@ try {
106
107
 
107
108
  ## Configuring your driver
108
109
 
109
- If you don't know the name of your installed driver, then look in look in `odbcinst.ini`. You can find the full path of the file by running `odbcinst -j`.
110
+ If you don't know the name of your installed driver, then look in `odbcinst.ini`. You can find the full path of the file by running `odbcinst -j`.
110
111
  There you should see an entry like the one below:
111
112
 
112
113
  ```
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ module.exports = __toCommonJS(src_exports);
37
37
  var process = __toESM(require("process"));
38
38
  var import_knex = __toESM(require("knex"));
39
39
  var odbc = __toESM(require("odbc"));
40
- var console5 = __toESM(require("console"));
40
+ var console2 = __toESM(require("console"));
41
41
 
42
42
  // src/schema/ibmi-compiler.ts
43
43
  var import_compiler = __toESM(require("knex/lib/schema/compiler"));
@@ -48,11 +48,14 @@ var IBMiSchemaCompiler = class extends import_compiler.default {
48
48
  }
49
49
  hasTable(tableName) {
50
50
  const formattedTable = this.client.parameter(
51
+ // @ts-ignore
51
52
  prefixedTableName(this.schema, tableName),
53
+ // @ts-ignore
52
54
  this.builder,
55
+ // @ts-ignore
53
56
  this.bindingsHolder
54
57
  );
55
- const bindings = [tableName.toUpperCase()];
58
+ const bindings = [tableName];
56
59
  let sql = `SELECT TABLE_NAME FROM QSYS2.SYSTABLES WHERE TYPE = 'T' AND TABLE_NAME = ${formattedTable}`;
57
60
  if (this.schema) {
58
61
  sql += " AND TABLE_SCHEMA = ?";
@@ -83,50 +86,18 @@ var ibmi_compiler_default = IBMiSchemaCompiler;
83
86
 
84
87
  // src/schema/ibmi-tablecompiler.ts
85
88
  var import_tablecompiler = __toESM(require("knex/lib/schema/tablecompiler"));
89
+ var import_isObject = __toESM(require("lodash/isObject"));
86
90
  var IBMiTableCompiler = class extends import_tablecompiler.default {
87
- constructor(client, tableBuilder) {
88
- super(client, tableBuilder);
89
- }
90
- unique(columns, indexName) {
91
- let deferrable;
92
- let useConstraint = false;
93
- let predicate;
94
- if (typeof indexName === "object") {
95
- ({ indexName, deferrable, useConstraint, predicate } = indexName);
96
- }
97
- if (deferrable && deferrable !== "not deferrable") {
98
- this.client.logger.warn(
99
- `ibmi: unique index [${indexName}] will not be deferrable ${deferrable} because mssql does not support deferred constraints.`
100
- );
101
- }
102
- if (useConstraint && predicate) {
103
- throw new Error("ibmi cannot create constraint with predicate");
104
- }
105
- indexName = indexName ? this.formatter.wrap(indexName) : this._indexCommand("unique", this.tableNameRaw, columns);
106
- if (!Array.isArray(columns)) {
107
- columns = [columns];
108
- }
109
- if (useConstraint) {
110
- this.pushQuery(
111
- `ALTER TABLE ${this.tableName()} ADD CONSTRAINT ${indexName} UNIQUE (${this.formatter.columnize(
112
- columns
113
- )})`
114
- );
115
- } else {
116
- const predicateQuery = predicate ? " " + this.client.queryCompiler(predicate).where() : " WHERE " + columns.map((column) => this.formatter.columnize(column) + " IS NOT NULL").join(" AND ");
117
- this.pushQuery(
118
- `CREATE UNIQUE INDEX ${indexName} ON ${this.tableName()} (${this.formatter.columnize(
119
- columns
120
- )})${predicateQuery}`
121
- );
122
- }
123
- }
124
91
  createQuery(columns, ifNot, like) {
125
92
  let createStatement = ifNot ? `if object_id('${this.tableName()}', 'U') is null ` : "";
126
93
  if (like) {
127
94
  createStatement += `SELECT * INTO ${this.tableName()} FROM ${this.tableNameLike()} WHERE 0=1`;
128
95
  } else {
129
- createStatement += "CREATE TABLE " + this.tableName() + (this._formatting ? " (\n " : " (") + columns.sql.join(this._formatting ? ",\n " : ", ") + this._addChecks() + ")";
96
+ createStatement += "CREATE TABLE " + // @ts-ignore
97
+ this.tableName() + // @ts-ignore
98
+ (this._formatting ? " (\n " : " (") + // @ts-ignore
99
+ columns.sql.join(this._formatting ? ",\n " : ", ") + // @ts-ignore
100
+ this._addChecks() + ")";
130
101
  }
131
102
  this.pushQuery(createStatement);
132
103
  if (this.single.comment) {
@@ -136,6 +107,29 @@ var IBMiTableCompiler = class extends import_tablecompiler.default {
136
107
  this.addColumns(columns, this.addColumnsPrefix);
137
108
  }
138
109
  }
110
+ dropUnique(columns, indexName) {
111
+ indexName = indexName ? this.formatter.wrap(indexName) : this._indexCommand("unique", this.tableNameRaw, columns);
112
+ this.pushQuery(`drop index ${indexName}`);
113
+ }
114
+ unique(columns, indexName) {
115
+ let deferrable;
116
+ let predicate;
117
+ if ((0, import_isObject.default)(indexName)) {
118
+ ({ indexName, deferrable, predicate } = indexName);
119
+ }
120
+ if (deferrable && deferrable !== "not deferrable") {
121
+ this.client.logger.warn(
122
+ `IBMi: unique index \`${indexName}\` will not be deferrable ${deferrable}.`
123
+ );
124
+ }
125
+ indexName = indexName ? this.formatter.wrap(indexName) : this._indexCommand("unique", this.tableNameRaw, columns);
126
+ columns = this.formatter.columnize(columns);
127
+ const predicateQuery = predicate ? " " + this.client.queryCompiler(predicate).where() : "";
128
+ this.pushQuery(
129
+ // @ts-ignore
130
+ `CREATE UNIQUE INDEX ${indexName} ON ${this.tableName()} (${columns})${predicateQuery}`
131
+ );
132
+ }
139
133
  // All of the columns to "add" for the query
140
134
  addColumns(columns, prefix) {
141
135
  prefix = prefix || this.addColumnsPrefix;
@@ -144,7 +138,11 @@ var IBMiTableCompiler = class extends import_tablecompiler.default {
144
138
  return prefix + column;
145
139
  });
146
140
  this.pushQuery({
147
- sql: (this.lowerCase ? "alter table " : "ALTER TABLE ") + this.tableName() + " " + columnSql.join(" "),
141
+ sql: (
142
+ // @ts-ignore
143
+ (this.lowerCase ? "alter table " : "ALTER TABLE ") + // @ts-ignore
144
+ this.tableName() + " " + columnSql.join(" ")
145
+ ),
148
146
  bindings: columns.bindings
149
147
  });
150
148
  }
@@ -157,32 +155,16 @@ var ibmi_tablecompiler_default = IBMiTableCompiler;
157
155
 
158
156
  // src/schema/ibmi-columncompiler.ts
159
157
  var import_columncompiler = __toESM(require("knex/lib/schema/columncompiler"));
160
- var console2 = __toESM(require("console"));
161
158
  var IBMiColumnCompiler = class extends import_columncompiler.default {
162
- constructor(client, tableCompiler, columnBuilder) {
163
- super(client, tableCompiler, columnBuilder);
164
- }
165
159
  increments(options = { primaryKey: true }) {
166
- return "int not null generated always as identity (start with 1, increment by 1)" + (this.tableCompiler._canBeAddPrimaryKey(options) ? " primary key" : "");
167
- }
168
- datetime(withoutTz = false, precision) {
169
- let useTz;
170
- if (isObject(withoutTz)) {
171
- ({ useTz, precision } = withoutTz);
172
- } else {
173
- useTz = !withoutTz;
174
- }
175
- useTz = typeof useTz === "boolean" ? useTz : true;
176
- precision = precision !== void 0 && precision !== null ? "(" + precision + ")" : "";
177
- console2.log(useTz, precision);
178
- return `${useTz ? "timestamptz" : "timestamp"}${precision}`;
160
+ return "int not null generated always as identity (start with 1, increment by 1)" + // @ts-ignore
161
+ (this.tableCompiler._canBeAddPrimaryKey(options) ? " primary key" : "");
179
162
  }
180
163
  };
181
164
  var ibmi_columncompiler_default = IBMiColumnCompiler;
182
165
 
183
166
  // src/execution/ibmi-transaction.ts
184
167
  var import_transaction = __toESM(require("knex/lib/execution/transaction"));
185
- var console3 = __toESM(require("console"));
186
168
  var IBMiTransaction = class extends import_transaction.default {
187
169
  async begin(conn) {
188
170
  const connection = await conn.connect();
@@ -190,7 +172,6 @@ var IBMiTransaction = class extends import_transaction.default {
190
172
  return connection;
191
173
  }
192
174
  async rollback(conn) {
193
- console3.log({ conn });
194
175
  const connection = await conn.connect();
195
176
  await connection.rollback();
196
177
  return connection;
@@ -204,31 +185,25 @@ var ibmi_transaction_default = IBMiTransaction;
204
185
 
205
186
  // src/query/ibmi-querycompiler.ts
206
187
  var import_querycompiler = __toESM(require("knex/lib/query/querycompiler"));
207
- var import_has = __toESM(require("lodash/has"));
208
- var import_isEmpty = __toESM(require("lodash/isEmpty"));
209
- var import_omitBy = __toESM(require("lodash/omitBy"));
210
- var import_isObject = __toESM(require("lodash/isObject"));
188
+ var import_isObject2 = __toESM(require("lodash/isObject"));
211
189
  var import_wrappingFormatter = require("knex/lib/formatter/wrappingFormatter");
212
190
  var import_date_fns = require("date-fns");
213
- var console4 = __toESM(require("console"));
214
191
  var IBMiQueryCompiler = class extends import_querycompiler.default {
215
192
  _prepInsert(data) {
216
- if ((0, import_isObject.default)(data)) {
217
- console4.log("data is object", data);
193
+ if ((0, import_isObject2.default)(data)) {
218
194
  if (data.hasOwnProperty("migration_time")) {
219
- console4.log("data has migration_time", data.migration_time);
220
195
  const parsed = new Date(data.migration_time);
221
- console4.log(parsed);
222
196
  data.migration_time = (0, import_date_fns.format)(parsed, "yyyy-MM-dd HH:mm:ss");
223
- console4.log(data.migration_time);
224
197
  }
225
- console4.log("data date after change", data);
226
198
  }
227
199
  const isRaw = (0, import_wrappingFormatter.rawOrFn)(
228
200
  data,
229
201
  void 0,
202
+ // @ts-ignore
230
203
  this.builder,
204
+ // @ts-ignore
231
205
  this.client,
206
+ // @ts-ignore
232
207
  this.bindingsHolder
233
208
  );
234
209
  if (isRaw)
@@ -267,54 +242,6 @@ var IBMiQueryCompiler = class extends import_querycompiler.default {
267
242
  values
268
243
  };
269
244
  }
270
- _prepUpdate(data = {}) {
271
- const { counter = {} } = this.single;
272
- for (const column of Object.keys(counter)) {
273
- if ((0, import_has.default)(data, column)) {
274
- this.client.logger.warn(
275
- `increment/decrement called for a column that has already been specified in main .update() call. Ignoring increment/decrement and using value from .update() call.`
276
- );
277
- continue;
278
- }
279
- let value = counter[column];
280
- const symbol = value < 0 ? "-" : "+";
281
- if (symbol === "-") {
282
- value = -value;
283
- }
284
- data[column] = this.client.raw(`?? ${symbol} ?`, [column, value]);
285
- }
286
- data = (0, import_omitBy.default)(data, (value) => typeof value === "undefined");
287
- const vals = [];
288
- const columns = Object.keys(data);
289
- let i = -1;
290
- while (++i < columns.length) {
291
- vals.push(
292
- (0, import_wrappingFormatter.wrap)(
293
- columns[i],
294
- void 0,
295
- this.builder,
296
- this.client,
297
- this.bindingsHolder
298
- ) + " = " + this.client.parameter(
299
- data[columns[i]],
300
- this.builder,
301
- this.bindingsHolder
302
- )
303
- );
304
- }
305
- if ((0, import_isEmpty.default)(vals)) {
306
- throw new Error(
307
- [
308
- "Empty .update() call detected!",
309
- "Update data does not contain any values to update.",
310
- "This will result in a faulty query.",
311
- this.single.table ? `Table: ${this.single.table}.` : "",
312
- this.single.update ? `Columns: ${Object.keys(this.single.update)}.` : ""
313
- ].join(" ")
314
- );
315
- }
316
- return vals;
317
- }
318
245
  };
319
246
  var ibmi_querycompiler_default = IBMiQueryCompiler;
320
247
 
@@ -351,12 +278,6 @@ var DB2Client = class extends import_knex.default.Client {
351
278
  _driver() {
352
279
  return odbc;
353
280
  }
354
- wrapIdentifierImpl(value) {
355
- if (value.includes("knex_migrations")) {
356
- return value.toUpperCase();
357
- }
358
- return value;
359
- }
360
281
  printDebug(message) {
361
282
  if (process.env.DEBUG === "true") {
362
283
  this.logger.debug(message);
@@ -367,13 +288,13 @@ var DB2Client = class extends import_knex.default.Client {
367
288
  async acquireRawConnection() {
368
289
  this.printDebug("acquiring raw connection");
369
290
  const connectionConfig = this.config.connection;
370
- console5.log(this._getConnectionString(connectionConfig));
291
+ console2.log(this._getConnectionString(connectionConfig));
371
292
  return await this.driver.pool(this._getConnectionString(connectionConfig));
372
293
  }
373
294
  // Used to explicitly close a connection, called internally by the pool manager
374
295
  // when a connection times out or the pool is shutdown.
375
296
  async destroyRawConnection(connection) {
376
- console5.log("destroy connection");
297
+ console2.log("destroy connection");
377
298
  return await connection.close();
378
299
  }
379
300
  _getConnectionString(connectionConfig) {
@@ -407,16 +328,15 @@ var DB2Client = class extends import_knex.default.Client {
407
328
  await statement.bind(obj.bindings);
408
329
  }
409
330
  const result = await statement.execute();
410
- obj.response = { rows: [result.count], rowCount: result.count };
331
+ obj.response = { rowCount: result.count };
411
332
  } catch (err) {
412
- console5.error(err);
333
+ console2.error(err);
413
334
  throw new Error(err);
414
335
  }
415
336
  }
416
- console5.log({ obj });
417
337
  return obj;
418
338
  }
419
- transaction() {
339
+ transaction(container, config, outerTx) {
420
340
  return new ibmi_transaction_default(this, ...arguments);
421
341
  }
422
342
  schemaCompiler() {
@@ -437,16 +357,16 @@ var DB2Client = class extends import_knex.default.Client {
437
357
  const resp = obj.response;
438
358
  const method = obj.sqlMethod;
439
359
  const { rows } = resp;
360
+ console2.log({ method, rows });
440
361
  if (obj.output)
441
362
  return obj.output.call(runner, resp);
442
363
  switch (method) {
443
364
  case "select":
365
+ return rows;
444
366
  case "pluck":
445
- case "first": {
446
- if (method === "pluck")
447
- return rows.map(obj.pluck);
448
- return method === "first" ? rows[0] : rows;
449
- }
367
+ return rows.map(obj.pluck);
368
+ case "first":
369
+ return rows[0];
450
370
  case "insert":
451
371
  case "del":
452
372
  case "delete":
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import * as process from "process";
3
3
  import knex from "knex";
4
4
  import * as odbc from "odbc";
5
- import * as console5 from "console";
5
+ import * as console2 from "console";
6
6
 
7
7
  // src/schema/ibmi-compiler.ts
8
8
  import SchemaCompiler from "knex/lib/schema/compiler";
@@ -13,11 +13,14 @@ var IBMiSchemaCompiler = class extends SchemaCompiler {
13
13
  }
14
14
  hasTable(tableName) {
15
15
  const formattedTable = this.client.parameter(
16
+ // @ts-ignore
16
17
  prefixedTableName(this.schema, tableName),
18
+ // @ts-ignore
17
19
  this.builder,
20
+ // @ts-ignore
18
21
  this.bindingsHolder
19
22
  );
20
- const bindings = [tableName.toUpperCase()];
23
+ const bindings = [tableName];
21
24
  let sql = `SELECT TABLE_NAME FROM QSYS2.SYSTABLES WHERE TYPE = 'T' AND TABLE_NAME = ${formattedTable}`;
22
25
  if (this.schema) {
23
26
  sql += " AND TABLE_SCHEMA = ?";
@@ -48,50 +51,18 @@ var ibmi_compiler_default = IBMiSchemaCompiler;
48
51
 
49
52
  // src/schema/ibmi-tablecompiler.ts
50
53
  import TableCompiler from "knex/lib/schema/tablecompiler";
54
+ import isObject from "lodash/isObject";
51
55
  var IBMiTableCompiler = class extends TableCompiler {
52
- constructor(client, tableBuilder) {
53
- super(client, tableBuilder);
54
- }
55
- unique(columns, indexName) {
56
- let deferrable;
57
- let useConstraint = false;
58
- let predicate;
59
- if (typeof indexName === "object") {
60
- ({ indexName, deferrable, useConstraint, predicate } = indexName);
61
- }
62
- if (deferrable && deferrable !== "not deferrable") {
63
- this.client.logger.warn(
64
- `ibmi: unique index [${indexName}] will not be deferrable ${deferrable} because mssql does not support deferred constraints.`
65
- );
66
- }
67
- if (useConstraint && predicate) {
68
- throw new Error("ibmi cannot create constraint with predicate");
69
- }
70
- indexName = indexName ? this.formatter.wrap(indexName) : this._indexCommand("unique", this.tableNameRaw, columns);
71
- if (!Array.isArray(columns)) {
72
- columns = [columns];
73
- }
74
- if (useConstraint) {
75
- this.pushQuery(
76
- `ALTER TABLE ${this.tableName()} ADD CONSTRAINT ${indexName} UNIQUE (${this.formatter.columnize(
77
- columns
78
- )})`
79
- );
80
- } else {
81
- const predicateQuery = predicate ? " " + this.client.queryCompiler(predicate).where() : " WHERE " + columns.map((column) => this.formatter.columnize(column) + " IS NOT NULL").join(" AND ");
82
- this.pushQuery(
83
- `CREATE UNIQUE INDEX ${indexName} ON ${this.tableName()} (${this.formatter.columnize(
84
- columns
85
- )})${predicateQuery}`
86
- );
87
- }
88
- }
89
56
  createQuery(columns, ifNot, like) {
90
57
  let createStatement = ifNot ? `if object_id('${this.tableName()}', 'U') is null ` : "";
91
58
  if (like) {
92
59
  createStatement += `SELECT * INTO ${this.tableName()} FROM ${this.tableNameLike()} WHERE 0=1`;
93
60
  } else {
94
- createStatement += "CREATE TABLE " + this.tableName() + (this._formatting ? " (\n " : " (") + columns.sql.join(this._formatting ? ",\n " : ", ") + this._addChecks() + ")";
61
+ createStatement += "CREATE TABLE " + // @ts-ignore
62
+ this.tableName() + // @ts-ignore
63
+ (this._formatting ? " (\n " : " (") + // @ts-ignore
64
+ columns.sql.join(this._formatting ? ",\n " : ", ") + // @ts-ignore
65
+ this._addChecks() + ")";
95
66
  }
96
67
  this.pushQuery(createStatement);
97
68
  if (this.single.comment) {
@@ -101,6 +72,29 @@ var IBMiTableCompiler = class extends TableCompiler {
101
72
  this.addColumns(columns, this.addColumnsPrefix);
102
73
  }
103
74
  }
75
+ dropUnique(columns, indexName) {
76
+ indexName = indexName ? this.formatter.wrap(indexName) : this._indexCommand("unique", this.tableNameRaw, columns);
77
+ this.pushQuery(`drop index ${indexName}`);
78
+ }
79
+ unique(columns, indexName) {
80
+ let deferrable;
81
+ let predicate;
82
+ if (isObject(indexName)) {
83
+ ({ indexName, deferrable, predicate } = indexName);
84
+ }
85
+ if (deferrable && deferrable !== "not deferrable") {
86
+ this.client.logger.warn(
87
+ `IBMi: unique index \`${indexName}\` will not be deferrable ${deferrable}.`
88
+ );
89
+ }
90
+ indexName = indexName ? this.formatter.wrap(indexName) : this._indexCommand("unique", this.tableNameRaw, columns);
91
+ columns = this.formatter.columnize(columns);
92
+ const predicateQuery = predicate ? " " + this.client.queryCompiler(predicate).where() : "";
93
+ this.pushQuery(
94
+ // @ts-ignore
95
+ `CREATE UNIQUE INDEX ${indexName} ON ${this.tableName()} (${columns})${predicateQuery}`
96
+ );
97
+ }
104
98
  // All of the columns to "add" for the query
105
99
  addColumns(columns, prefix) {
106
100
  prefix = prefix || this.addColumnsPrefix;
@@ -109,7 +103,11 @@ var IBMiTableCompiler = class extends TableCompiler {
109
103
  return prefix + column;
110
104
  });
111
105
  this.pushQuery({
112
- sql: (this.lowerCase ? "alter table " : "ALTER TABLE ") + this.tableName() + " " + columnSql.join(" "),
106
+ sql: (
107
+ // @ts-ignore
108
+ (this.lowerCase ? "alter table " : "ALTER TABLE ") + // @ts-ignore
109
+ this.tableName() + " " + columnSql.join(" ")
110
+ ),
113
111
  bindings: columns.bindings
114
112
  });
115
113
  }
@@ -122,32 +120,16 @@ var ibmi_tablecompiler_default = IBMiTableCompiler;
122
120
 
123
121
  // src/schema/ibmi-columncompiler.ts
124
122
  import ColumnCompiler from "knex/lib/schema/columncompiler";
125
- import * as console2 from "console";
126
123
  var IBMiColumnCompiler = class extends ColumnCompiler {
127
- constructor(client, tableCompiler, columnBuilder) {
128
- super(client, tableCompiler, columnBuilder);
129
- }
130
124
  increments(options = { primaryKey: true }) {
131
- return "int not null generated always as identity (start with 1, increment by 1)" + (this.tableCompiler._canBeAddPrimaryKey(options) ? " primary key" : "");
132
- }
133
- datetime(withoutTz = false, precision) {
134
- let useTz;
135
- if (isObject(withoutTz)) {
136
- ({ useTz, precision } = withoutTz);
137
- } else {
138
- useTz = !withoutTz;
139
- }
140
- useTz = typeof useTz === "boolean" ? useTz : true;
141
- precision = precision !== void 0 && precision !== null ? "(" + precision + ")" : "";
142
- console2.log(useTz, precision);
143
- return `${useTz ? "timestamptz" : "timestamp"}${precision}`;
125
+ return "int not null generated always as identity (start with 1, increment by 1)" + // @ts-ignore
126
+ (this.tableCompiler._canBeAddPrimaryKey(options) ? " primary key" : "");
144
127
  }
145
128
  };
146
129
  var ibmi_columncompiler_default = IBMiColumnCompiler;
147
130
 
148
131
  // src/execution/ibmi-transaction.ts
149
132
  import Transaction from "knex/lib/execution/transaction";
150
- import * as console3 from "console";
151
133
  var IBMiTransaction = class extends Transaction {
152
134
  async begin(conn) {
153
135
  const connection = await conn.connect();
@@ -155,7 +137,6 @@ var IBMiTransaction = class extends Transaction {
155
137
  return connection;
156
138
  }
157
139
  async rollback(conn) {
158
- console3.log({ conn });
159
140
  const connection = await conn.connect();
160
141
  await connection.rollback();
161
142
  return connection;
@@ -169,34 +150,25 @@ var ibmi_transaction_default = IBMiTransaction;
169
150
 
170
151
  // src/query/ibmi-querycompiler.ts
171
152
  import QueryCompiler from "knex/lib/query/querycompiler";
172
- import has from "lodash/has";
173
- import isEmpty from "lodash/isEmpty";
174
- import omitBy from "lodash/omitBy";
175
153
  import isObject2 from "lodash/isObject";
176
- import {
177
- wrap as wrap_,
178
- rawOrFn as rawOrFn_
179
- } from "knex/lib/formatter/wrappingFormatter";
154
+ import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
180
155
  import { format } from "date-fns";
181
- import * as console4 from "console";
182
156
  var IBMiQueryCompiler = class extends QueryCompiler {
183
157
  _prepInsert(data) {
184
158
  if (isObject2(data)) {
185
- console4.log("data is object", data);
186
159
  if (data.hasOwnProperty("migration_time")) {
187
- console4.log("data has migration_time", data.migration_time);
188
160
  const parsed = new Date(data.migration_time);
189
- console4.log(parsed);
190
161
  data.migration_time = format(parsed, "yyyy-MM-dd HH:mm:ss");
191
- console4.log(data.migration_time);
192
162
  }
193
- console4.log("data date after change", data);
194
163
  }
195
164
  const isRaw = rawOrFn_(
196
165
  data,
197
166
  void 0,
167
+ // @ts-ignore
198
168
  this.builder,
169
+ // @ts-ignore
199
170
  this.client,
171
+ // @ts-ignore
200
172
  this.bindingsHolder
201
173
  );
202
174
  if (isRaw)
@@ -235,54 +207,6 @@ var IBMiQueryCompiler = class extends QueryCompiler {
235
207
  values
236
208
  };
237
209
  }
238
- _prepUpdate(data = {}) {
239
- const { counter = {} } = this.single;
240
- for (const column of Object.keys(counter)) {
241
- if (has(data, column)) {
242
- this.client.logger.warn(
243
- `increment/decrement called for a column that has already been specified in main .update() call. Ignoring increment/decrement and using value from .update() call.`
244
- );
245
- continue;
246
- }
247
- let value = counter[column];
248
- const symbol = value < 0 ? "-" : "+";
249
- if (symbol === "-") {
250
- value = -value;
251
- }
252
- data[column] = this.client.raw(`?? ${symbol} ?`, [column, value]);
253
- }
254
- data = omitBy(data, (value) => typeof value === "undefined");
255
- const vals = [];
256
- const columns = Object.keys(data);
257
- let i = -1;
258
- while (++i < columns.length) {
259
- vals.push(
260
- wrap_(
261
- columns[i],
262
- void 0,
263
- this.builder,
264
- this.client,
265
- this.bindingsHolder
266
- ) + " = " + this.client.parameter(
267
- data[columns[i]],
268
- this.builder,
269
- this.bindingsHolder
270
- )
271
- );
272
- }
273
- if (isEmpty(vals)) {
274
- throw new Error(
275
- [
276
- "Empty .update() call detected!",
277
- "Update data does not contain any values to update.",
278
- "This will result in a faulty query.",
279
- this.single.table ? `Table: ${this.single.table}.` : "",
280
- this.single.update ? `Columns: ${Object.keys(this.single.update)}.` : ""
281
- ].join(" ")
282
- );
283
- }
284
- return vals;
285
- }
286
210
  };
287
211
  var ibmi_querycompiler_default = IBMiQueryCompiler;
288
212
 
@@ -319,12 +243,6 @@ var DB2Client = class extends knex.Client {
319
243
  _driver() {
320
244
  return odbc;
321
245
  }
322
- wrapIdentifierImpl(value) {
323
- if (value.includes("knex_migrations")) {
324
- return value.toUpperCase();
325
- }
326
- return value;
327
- }
328
246
  printDebug(message) {
329
247
  if (process.env.DEBUG === "true") {
330
248
  this.logger.debug(message);
@@ -335,13 +253,13 @@ var DB2Client = class extends knex.Client {
335
253
  async acquireRawConnection() {
336
254
  this.printDebug("acquiring raw connection");
337
255
  const connectionConfig = this.config.connection;
338
- console5.log(this._getConnectionString(connectionConfig));
256
+ console2.log(this._getConnectionString(connectionConfig));
339
257
  return await this.driver.pool(this._getConnectionString(connectionConfig));
340
258
  }
341
259
  // Used to explicitly close a connection, called internally by the pool manager
342
260
  // when a connection times out or the pool is shutdown.
343
261
  async destroyRawConnection(connection) {
344
- console5.log("destroy connection");
262
+ console2.log("destroy connection");
345
263
  return await connection.close();
346
264
  }
347
265
  _getConnectionString(connectionConfig) {
@@ -375,16 +293,15 @@ var DB2Client = class extends knex.Client {
375
293
  await statement.bind(obj.bindings);
376
294
  }
377
295
  const result = await statement.execute();
378
- obj.response = { rows: [result.count], rowCount: result.count };
296
+ obj.response = { rowCount: result.count };
379
297
  } catch (err) {
380
- console5.error(err);
298
+ console2.error(err);
381
299
  throw new Error(err);
382
300
  }
383
301
  }
384
- console5.log({ obj });
385
302
  return obj;
386
303
  }
387
- transaction() {
304
+ transaction(container, config, outerTx) {
388
305
  return new ibmi_transaction_default(this, ...arguments);
389
306
  }
390
307
  schemaCompiler() {
@@ -405,16 +322,16 @@ var DB2Client = class extends knex.Client {
405
322
  const resp = obj.response;
406
323
  const method = obj.sqlMethod;
407
324
  const { rows } = resp;
325
+ console2.log({ method, rows });
408
326
  if (obj.output)
409
327
  return obj.output.call(runner, resp);
410
328
  switch (method) {
411
329
  case "select":
330
+ return rows;
412
331
  case "pluck":
413
- case "first": {
414
- if (method === "pluck")
415
- return rows.map(obj.pluck);
416
- return method === "first" ? rows[0] : rows;
417
- }
332
+ return rows.map(obj.pluck);
333
+ case "first":
334
+ return rows[0];
418
335
  case "insert":
419
336
  case "del":
420
337
  case "delete":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bdkinc/knex-ibmi",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Knex dialect for IBMi",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -1,6 +1,5 @@
1
1
  import Transaction from "knex/lib/execution/transaction";
2
2
  import * as console from "console";
3
- import { connect } from "odbc";
4
3
 
5
4
  class IBMiTransaction extends Transaction {
6
5
  async begin(conn) {
@@ -10,7 +9,6 @@ class IBMiTransaction extends Transaction {
10
9
  }
11
10
 
12
11
  async rollback(conn) {
13
- console.log({ conn });
14
12
  const connection = await conn.connect();
15
13
  await connection.rollback();
16
14
  return connection;
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as process from "process";
2
2
  import { Connection } from "odbc";
3
- import knex from "knex";
3
+ import knex, { Knex } from "knex";
4
4
  import * as odbc from "odbc";
5
5
  import * as console from "console";
6
6
  import SchemaCompiler from "./schema/ibmi-compiler";
@@ -12,7 +12,6 @@ import QueryCompiler from "./query/ibmi-querycompiler";
12
12
  class DB2Client extends knex.Client {
13
13
  constructor(config) {
14
14
  super(config);
15
-
16
15
  this.driverName = "odbc";
17
16
 
18
17
  if (this.dialect && !this.config.client) {
@@ -49,15 +48,6 @@ class DB2Client extends knex.Client {
49
48
  return odbc;
50
49
  }
51
50
 
52
- wrapIdentifierImpl(value: any) {
53
- // override default wrapper ("). we don't want to use it since
54
- // it makes identifiers case-sensitive in DB2
55
- if (value.includes("knex_migrations")) {
56
- return value.toUpperCase();
57
- }
58
- return value;
59
- }
60
-
61
51
  printDebug(message: string) {
62
52
  if (process.env.DEBUG === "true") {
63
53
  // @ts-ignore
@@ -128,18 +118,17 @@ class DB2Client extends knex.Client {
128
118
  await statement.bind(obj.bindings);
129
119
  }
130
120
  const result = await statement.execute();
131
- obj.response = { rows: [result.count], rowCount: result.count };
121
+ obj.response = { rowCount: result.count };
132
122
  } catch (err: any) {
133
123
  console.error(err);
134
124
  throw new Error(err);
135
125
  }
136
126
  }
137
- console.log({ obj });
138
127
 
139
128
  return obj;
140
129
  }
141
130
 
142
- transaction() {
131
+ transaction(container: any, config: any, outerTx: any): Knex.Transaction {
143
132
  // @ts-ignore
144
133
  return new Transaction(this, ...arguments);
145
134
  }
@@ -171,16 +160,17 @@ class DB2Client extends knex.Client {
171
160
  const resp = obj.response;
172
161
  const method = obj.sqlMethod;
173
162
  const { rows } = resp;
163
+ console.log({ method, rows });
174
164
 
175
165
  if (obj.output) return obj.output.call(runner, resp);
176
166
 
177
167
  switch (method) {
178
168
  case "select":
169
+ return rows;
179
170
  case "pluck":
180
- case "first": {
181
- if (method === "pluck") return rows.map(obj.pluck);
182
- return method === "first" ? rows[0] : rows;
183
- }
171
+ return rows.map(obj.pluck);
172
+ case "first":
173
+ return rows[0];
184
174
  case "insert":
185
175
  case "del":
186
176
  case "delete":
@@ -1,33 +1,26 @@
1
1
  import QueryCompiler from "knex/lib/query/querycompiler";
2
- import has from "lodash/has";
3
- import isEmpty from "lodash/isEmpty";
4
- import omitBy from "lodash/omitBy";
5
2
  import isObject from "lodash/isObject";
6
- import {
7
- wrap as wrap_,
8
- rawOrFn as rawOrFn_,
9
- } from "knex/lib/formatter/wrappingFormatter";
10
- import { format, parseISO } from "date-fns";
3
+ import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
4
+ import { format } from "date-fns";
11
5
  import * as console from "console";
12
6
 
13
7
  class IBMiQueryCompiler extends QueryCompiler {
14
8
  _prepInsert(data) {
15
9
  if (isObject(data)) {
16
- console.log("data is object", data);
17
10
  if (data.hasOwnProperty("migration_time")) {
18
- console.log("data has migration_time", data.migration_time);
19
11
  const parsed = new Date(data.migration_time);
20
- console.log(parsed);
21
12
  data.migration_time = format(parsed, "yyyy-MM-dd HH:mm:ss");
22
- console.log(data.migration_time);
23
13
  }
24
- console.log("data date after change", data);
25
14
  }
15
+
26
16
  const isRaw = rawOrFn_(
27
17
  data,
28
18
  undefined,
19
+ // @ts-ignore
29
20
  this.builder,
21
+ // @ts-ignore
30
22
  this.client,
23
+ // @ts-ignore
31
24
  this.bindingsHolder,
32
25
  );
33
26
  if (isRaw) return isRaw;
@@ -62,71 +55,6 @@ class IBMiQueryCompiler extends QueryCompiler {
62
55
  values,
63
56
  };
64
57
  }
65
-
66
- _prepUpdate(data = {}): any[] {
67
- const { counter = {} } = this.single;
68
-
69
- for (const column of Object.keys(counter)) {
70
- //Skip?
71
- if (has(data, column)) {
72
- //Needed?
73
- this.client.logger.warn(
74
- `increment/decrement called for a column that has already been specified in main .update() call. Ignoring increment/decrement and using value from .update() call.`,
75
- );
76
- continue;
77
- }
78
-
79
- let value = counter[column];
80
-
81
- const symbol = value < 0 ? "-" : "+";
82
-
83
- if (symbol === "-") {
84
- value = -value;
85
- }
86
-
87
- data[column] = this.client.raw(`?? ${symbol} ?`, [column, value]);
88
- }
89
-
90
- data = omitBy(data, (value) => typeof value === "undefined");
91
-
92
- const vals = [];
93
- const columns = Object.keys(data);
94
- let i = -1;
95
-
96
- while (++i < columns.length) {
97
- vals.push(
98
- wrap_(
99
- columns[i],
100
- undefined,
101
- this.builder,
102
- this.client,
103
- this.bindingsHolder,
104
- ) +
105
- " = " +
106
- this.client.parameter(
107
- data[columns[i]],
108
- this.builder,
109
- this.bindingsHolder,
110
- ),
111
- );
112
- }
113
-
114
- if (isEmpty(vals)) {
115
- throw new Error(
116
- [
117
- "Empty .update() call detected!",
118
- "Update data does not contain any values to update.",
119
- "This will result in a faulty query.",
120
- this.single.table ? `Table: ${this.single.table}.` : "",
121
- this.single.update
122
- ? `Columns: ${Object.keys(this.single.update)}.`
123
- : "",
124
- ].join(" "),
125
- );
126
- }
127
-
128
- return vals;
129
- }
130
58
  }
131
59
 
132
60
  export default IBMiQueryCompiler;
@@ -1,34 +1,13 @@
1
1
  import ColumnCompiler from "knex/lib/schema/columncompiler";
2
- import * as console from "console";
3
2
 
4
3
  class IBMiColumnCompiler extends ColumnCompiler {
5
- constructor(client, tableCompiler, columnBuilder) {
6
- super(client, tableCompiler, columnBuilder);
7
- }
8
-
9
4
  increments(options = { primaryKey: true }) {
10
5
  return (
11
6
  "int not null generated always as identity (start with 1, increment by 1)" +
7
+ // @ts-ignore
12
8
  (this.tableCompiler._canBeAddPrimaryKey(options) ? " primary key" : "")
13
9
  );
14
10
  }
15
-
16
- datetime(withoutTz = false, precision) {
17
- let useTz;
18
- if (isObject(withoutTz)) {
19
- ({ useTz, precision } = withoutTz);
20
- } else {
21
- useTz = !withoutTz;
22
- }
23
- useTz = typeof useTz === "boolean" ? useTz : true;
24
- precision =
25
- precision !== undefined && precision !== null
26
- ? "(" + precision + ")"
27
- : "";
28
-
29
- console.log(useTz, precision);
30
- return `${useTz ? "timestamptz" : "timestamp"}${precision}`;
31
- }
32
11
  }
33
12
 
34
13
  export default IBMiColumnCompiler;
@@ -7,20 +7,27 @@ class IBMiSchemaCompiler extends SchemaCompiler {
7
7
  }
8
8
 
9
9
  hasTable(tableName) {
10
+ // @ts-ignore
10
11
  const formattedTable = this.client.parameter(
12
+ // @ts-ignore
11
13
  prefixedTableName(this.schema, tableName),
14
+ // @ts-ignore
12
15
  this.builder,
16
+ // @ts-ignore
13
17
  this.bindingsHolder,
14
18
  );
15
- const bindings = [tableName.toUpperCase()];
19
+ const bindings = [tableName];
16
20
  let sql =
17
21
  `SELECT TABLE_NAME FROM QSYS2.SYSTABLES ` +
18
22
  `WHERE TYPE = 'T' AND TABLE_NAME = ${formattedTable}`;
23
+ // @ts-ignore
19
24
  if (this.schema) {
20
25
  sql += " AND TABLE_SCHEMA = ?";
26
+ // @ts-ignore
21
27
  bindings.push(this.schema);
22
28
  }
23
29
 
30
+ // @ts-ignore
24
31
  this.pushQuery({
25
32
  sql,
26
33
  bindings,
@@ -1,98 +1,102 @@
1
1
  import TableCompiler from "knex/lib/schema/tablecompiler";
2
+ import isObject from "lodash/isObject";
2
3
 
3
4
  class IBMiTableCompiler extends TableCompiler {
4
- constructor(client, tableBuilder) {
5
- super(client, tableBuilder);
6
- }
7
-
8
- unique(columns, indexName) {
9
- /** @type {string | undefined} */
10
- let deferrable;
11
- let useConstraint = false;
12
- let predicate;
13
- if (typeof indexName === "object") {
14
- ({ indexName, deferrable, useConstraint, predicate } = indexName);
15
- }
16
- if (deferrable && deferrable !== 'not deferrable') {
17
- this.client.logger.warn(
18
- `ibmi: unique index [${indexName}] will not be deferrable ${deferrable} because mssql does not support deferred constraints.`
19
- );
20
- }
21
- if (useConstraint && predicate) {
22
- throw new Error('ibmi cannot create constraint with predicate');
23
- }
24
- indexName = indexName
25
- ? this.formatter.wrap(indexName)
26
- : this._indexCommand('unique', this.tableNameRaw, columns);
27
-
28
- if (!Array.isArray(columns)) {
29
- columns = [columns];
30
- }
31
-
32
- if (useConstraint) {
33
- // mssql supports unique indexes and unique constraints.
34
- // unique indexes cannot be used with foreign key relationships hence unique constraints are used instead.
35
- this.pushQuery(
36
- `ALTER TABLE ${this.tableName()} ADD CONSTRAINT ${indexName} UNIQUE (${this.formatter.columnize(
37
- columns
38
- )})`
39
- );
40
- } else {
41
- // default to making unique index that allows null https://stackoverflow.com/a/767702/360060
42
- // to be more or less compatible with other DBs (if any of the columns is NULL then "duplicates" are allowed)
43
- const predicateQuery = predicate
44
- ? ' ' + this.client.queryCompiler(predicate).where()
45
- : ' WHERE ' +
46
- columns
47
- .map((column) => this.formatter.columnize(column) + ' IS NOT NULL')
48
- .join(' AND ');
49
- this.pushQuery(
50
- `CREATE UNIQUE INDEX ${indexName} ON ${this.tableName()} (${this.formatter.columnize(
51
- columns
52
- )})${predicateQuery}`
53
- );
54
- }
55
- }
56
-
57
5
  createQuery(columns, ifNot, like) {
58
6
  let createStatement = ifNot
7
+ // @ts-ignore
59
8
  ? `if object_id('${this.tableName()}', 'U') is null `
60
9
  : "";
61
10
 
62
11
  if (like) {
63
12
  // This query copy only columns and not all indexes and keys like other databases.
13
+ // @ts-ignore
64
14
  createStatement += `SELECT * INTO ${this.tableName()} FROM ${this.tableNameLike()} WHERE 0=1`;
65
15
  } else {
66
16
  createStatement +=
67
17
  "CREATE TABLE " +
18
+ // @ts-ignore
68
19
  this.tableName() +
20
+ // @ts-ignore
69
21
  (this._formatting ? " (\n " : " (") +
22
+ // @ts-ignore
70
23
  columns.sql.join(this._formatting ? ",\n " : ", ") +
24
+ // @ts-ignore
71
25
  this._addChecks() +
72
26
  ")";
73
27
  }
74
28
 
29
+ // @ts-ignore
75
30
  this.pushQuery(createStatement);
76
31
 
32
+ // @ts-ignore
77
33
  if (this.single.comment) {
34
+ // @ts-ignore
78
35
  this.comment(this.single.comment);
79
36
  }
80
37
  if (like) {
38
+ // @ts-ignore
81
39
  this.addColumns(columns, this.addColumnsPrefix);
82
40
  }
83
41
  }
84
42
 
43
+ dropUnique(columns, indexName) {
44
+ indexName = indexName
45
+ // @ts-ignore
46
+ ? this.formatter.wrap(indexName)
47
+ // @ts-ignore
48
+ : this._indexCommand('unique', this.tableNameRaw, columns);
49
+ // @ts-ignore
50
+ this.pushQuery(`drop index ${indexName}`);
51
+ }
52
+
53
+ unique(columns, indexName) {
54
+ let deferrable;
55
+ let predicate;
56
+ if (isObject(indexName)) {
57
+ ({ indexName, deferrable, predicate } = indexName);
58
+ }
59
+ if (deferrable && deferrable !== 'not deferrable') {
60
+ // @ts-ignore
61
+ this.client.logger.warn(
62
+ `IBMi: unique index \`${indexName}\` will not be deferrable ${deferrable}.`
63
+ );
64
+ }
65
+ indexName = indexName
66
+ // @ts-ignore
67
+ ? this.formatter.wrap(indexName)
68
+ // @ts-ignore
69
+ : this._indexCommand('unique', this.tableNameRaw, columns);
70
+ // @ts-ignore
71
+ columns = this.formatter.columnize(columns);
72
+
73
+ const predicateQuery = predicate
74
+ // @ts-ignore
75
+ ? ' ' + this.client.queryCompiler(predicate).where()
76
+ : '';
77
+
78
+ // @ts-ignore
79
+ this.pushQuery(
80
+ // @ts-ignore
81
+ `CREATE UNIQUE INDEX ${indexName} ON ${this.tableName()} (${columns})${predicateQuery}`
82
+ );
83
+ }
84
+
85
85
  // All of the columns to "add" for the query
86
86
  addColumns(columns, prefix) {
87
+ // @ts-ignore
87
88
  prefix = prefix || this.addColumnsPrefix;
88
89
 
89
90
  if (columns.sql.length > 0) {
90
91
  const columnSql = columns.sql.map((column) => {
91
92
  return prefix + column;
92
93
  });
94
+ // @ts-ignore
93
95
  this.pushQuery({
94
96
  sql:
97
+ // @ts-ignore
95
98
  (this.lowerCase ? 'alter table ' : 'ALTER TABLE ') +
99
+ // @ts-ignore
96
100
  this.tableName() +
97
101
  ' ' +
98
102
  columnSql.join(' '),