@bdkinc/knex-ibmi 0.0.16 → 0.0.18
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 +0 -1
- package/dist/index.d.mts +3 -91
- package/dist/index.d.ts +3 -91
- package/dist/index.js +69 -53
- package/dist/index.mjs +69 -53
- package/package.json +4 -2
- package/src/execution/ibmi-transaction.ts +1 -0
- package/src/index.d.ts +4 -0
- package/src/index.ts +18 -63
- package/src/query/ibmi-querycompiler.ts +76 -2
- package/src/schema/ibmi-columncompiler.ts +1 -0
- package/src/schema/ibmi-compiler.ts +1 -0
- package/src/schema/ibmi-tablecompiler.ts +1 -0
package/README.md
CHANGED
|
@@ -17,7 +17,6 @@ This is an external dialect for [knex](https://github.com/tgriesser/knex). This
|
|
|
17
17
|
Currently, this dialect has limited functionality compared to the Knex built-in dialects. Below are some of the limitations:
|
|
18
18
|
|
|
19
19
|
- No streaming support
|
|
20
|
-
- Updates return the value of the first column in that row. Make sure your identifier is the first column in the table. The returning option does not work on updates.
|
|
21
20
|
- Possibly other missing functionality
|
|
22
21
|
- 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.
|
|
23
22
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,91 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import SchemaCompiler from 'knex/lib/schema/compiler';
|
|
5
|
-
import TableCompiler from 'knex/lib/schema/tablecompiler';
|
|
6
|
-
import ColumnCompiler from 'knex/lib/schema/columncompiler';
|
|
7
|
-
import QueryCompiler from 'knex/lib/query/querycompiler';
|
|
8
|
-
|
|
9
|
-
declare class IBMiSchemaCompiler extends SchemaCompiler {
|
|
10
|
-
hasTable(tableName: any): void;
|
|
11
|
-
toSQL(): any;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
declare class IBMiTableCompiler extends TableCompiler {
|
|
15
|
-
createQuery(columns: any, ifNot: any, like: any): void;
|
|
16
|
-
dropUnique(columns: any, indexName: any): void;
|
|
17
|
-
unique(columns: any, indexName: any): void;
|
|
18
|
-
addColumns(columns: any, prefix: any): void;
|
|
19
|
-
commit(conn: any, value: any): Promise<any>;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
declare class IBMiColumnCompiler extends ColumnCompiler {
|
|
23
|
-
increments(options?: {
|
|
24
|
-
primaryKey: boolean;
|
|
25
|
-
}): string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
declare class IBMiQueryCompiler extends QueryCompiler {
|
|
29
|
-
insert(): "" | {
|
|
30
|
-
sql: string;
|
|
31
|
-
returning: any;
|
|
32
|
-
};
|
|
33
|
-
_buildInsertData(insertValues: any, returningSql: any): string;
|
|
34
|
-
_prepInsert(data: any): any;
|
|
35
|
-
_returning(method: any, value: any, withTrigger: any): string | undefined;
|
|
36
|
-
columnizeWithPrefix(prefix: any, target: any): string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
declare class DB2Client extends knex.Client {
|
|
40
|
-
constructor(config: any);
|
|
41
|
-
_driver(): typeof odbc;
|
|
42
|
-
printDebug(message: string): void;
|
|
43
|
-
acquireRawConnection(): Promise<any>;
|
|
44
|
-
destroyRawConnection(connection: Connection): Promise<void>;
|
|
45
|
-
_getConnectionString(connectionConfig: any): string;
|
|
46
|
-
_query(connection: any, obj: any): Promise<any>;
|
|
47
|
-
_selectAfterUpdate(): string;
|
|
48
|
-
transaction(container: any, config: any, outerTx: any): Knex.Transaction;
|
|
49
|
-
schemaCompiler(): IBMiSchemaCompiler;
|
|
50
|
-
tableCompiler(): IBMiTableCompiler;
|
|
51
|
-
columnCompiler(): IBMiColumnCompiler;
|
|
52
|
-
queryCompiler(): IBMiQueryCompiler;
|
|
53
|
-
processResponse(obj: any, runner: any): any;
|
|
54
|
-
}
|
|
55
|
-
interface DB2PoolConfig {
|
|
56
|
-
min: number;
|
|
57
|
-
max: number;
|
|
58
|
-
}
|
|
59
|
-
interface DB2ConnectionParams {
|
|
60
|
-
CMT?: number;
|
|
61
|
-
CONNTYPE?: number;
|
|
62
|
-
DBQ?: string;
|
|
63
|
-
MAXDECPREC?: 31 | 63;
|
|
64
|
-
MAXDECSCALE?: number;
|
|
65
|
-
MINDIVSCALE?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
66
|
-
NAM?: 0 | 1;
|
|
67
|
-
DFT?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
68
|
-
DSP?: 0 | 1 | 2 | 3 | 4;
|
|
69
|
-
DEC?: 0 | 1;
|
|
70
|
-
DECFLOATERROROPTION?: 0 | 1;
|
|
71
|
-
DECFLOATROUNDMODE?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
72
|
-
MAPDECIMALFLOATDESCRIBE?: 1 | 3;
|
|
73
|
-
}
|
|
74
|
-
interface DB2ConnectionConfig {
|
|
75
|
-
database: string;
|
|
76
|
-
host: string;
|
|
77
|
-
port: 50000 | number;
|
|
78
|
-
user: string;
|
|
79
|
-
password: string;
|
|
80
|
-
driver: "IBM i Access ODBC Driver" | string;
|
|
81
|
-
connectionStringParams?: DB2ConnectionParams;
|
|
82
|
-
pool?: DB2PoolConfig;
|
|
83
|
-
}
|
|
84
|
-
interface DB2Config {
|
|
85
|
-
client: any;
|
|
86
|
-
connection: DB2ConnectionConfig;
|
|
87
|
-
pool?: DB2PoolConfig;
|
|
88
|
-
}
|
|
89
|
-
declare const DB2Dialect: typeof DB2Client;
|
|
90
|
-
|
|
91
|
-
export { DB2Config, DB2Dialect, DB2Client as default };
|
|
1
|
+
declare module "knex/lib/query/querycompiler" {}
|
|
2
|
+
declare module "knex/lib/schema/tablecompiler" {}
|
|
3
|
+
declare module "knex/lib/schema/compiler" {}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,91 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import SchemaCompiler from 'knex/lib/schema/compiler';
|
|
5
|
-
import TableCompiler from 'knex/lib/schema/tablecompiler';
|
|
6
|
-
import ColumnCompiler from 'knex/lib/schema/columncompiler';
|
|
7
|
-
import QueryCompiler from 'knex/lib/query/querycompiler';
|
|
8
|
-
|
|
9
|
-
declare class IBMiSchemaCompiler extends SchemaCompiler {
|
|
10
|
-
hasTable(tableName: any): void;
|
|
11
|
-
toSQL(): any;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
declare class IBMiTableCompiler extends TableCompiler {
|
|
15
|
-
createQuery(columns: any, ifNot: any, like: any): void;
|
|
16
|
-
dropUnique(columns: any, indexName: any): void;
|
|
17
|
-
unique(columns: any, indexName: any): void;
|
|
18
|
-
addColumns(columns: any, prefix: any): void;
|
|
19
|
-
commit(conn: any, value: any): Promise<any>;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
declare class IBMiColumnCompiler extends ColumnCompiler {
|
|
23
|
-
increments(options?: {
|
|
24
|
-
primaryKey: boolean;
|
|
25
|
-
}): string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
declare class IBMiQueryCompiler extends QueryCompiler {
|
|
29
|
-
insert(): "" | {
|
|
30
|
-
sql: string;
|
|
31
|
-
returning: any;
|
|
32
|
-
};
|
|
33
|
-
_buildInsertData(insertValues: any, returningSql: any): string;
|
|
34
|
-
_prepInsert(data: any): any;
|
|
35
|
-
_returning(method: any, value: any, withTrigger: any): string | undefined;
|
|
36
|
-
columnizeWithPrefix(prefix: any, target: any): string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
declare class DB2Client extends knex.Client {
|
|
40
|
-
constructor(config: any);
|
|
41
|
-
_driver(): typeof odbc;
|
|
42
|
-
printDebug(message: string): void;
|
|
43
|
-
acquireRawConnection(): Promise<any>;
|
|
44
|
-
destroyRawConnection(connection: Connection): Promise<void>;
|
|
45
|
-
_getConnectionString(connectionConfig: any): string;
|
|
46
|
-
_query(connection: any, obj: any): Promise<any>;
|
|
47
|
-
_selectAfterUpdate(): string;
|
|
48
|
-
transaction(container: any, config: any, outerTx: any): Knex.Transaction;
|
|
49
|
-
schemaCompiler(): IBMiSchemaCompiler;
|
|
50
|
-
tableCompiler(): IBMiTableCompiler;
|
|
51
|
-
columnCompiler(): IBMiColumnCompiler;
|
|
52
|
-
queryCompiler(): IBMiQueryCompiler;
|
|
53
|
-
processResponse(obj: any, runner: any): any;
|
|
54
|
-
}
|
|
55
|
-
interface DB2PoolConfig {
|
|
56
|
-
min: number;
|
|
57
|
-
max: number;
|
|
58
|
-
}
|
|
59
|
-
interface DB2ConnectionParams {
|
|
60
|
-
CMT?: number;
|
|
61
|
-
CONNTYPE?: number;
|
|
62
|
-
DBQ?: string;
|
|
63
|
-
MAXDECPREC?: 31 | 63;
|
|
64
|
-
MAXDECSCALE?: number;
|
|
65
|
-
MINDIVSCALE?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
66
|
-
NAM?: 0 | 1;
|
|
67
|
-
DFT?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
68
|
-
DSP?: 0 | 1 | 2 | 3 | 4;
|
|
69
|
-
DEC?: 0 | 1;
|
|
70
|
-
DECFLOATERROROPTION?: 0 | 1;
|
|
71
|
-
DECFLOATROUNDMODE?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
72
|
-
MAPDECIMALFLOATDESCRIBE?: 1 | 3;
|
|
73
|
-
}
|
|
74
|
-
interface DB2ConnectionConfig {
|
|
75
|
-
database: string;
|
|
76
|
-
host: string;
|
|
77
|
-
port: 50000 | number;
|
|
78
|
-
user: string;
|
|
79
|
-
password: string;
|
|
80
|
-
driver: "IBM i Access ODBC Driver" | string;
|
|
81
|
-
connectionStringParams?: DB2ConnectionParams;
|
|
82
|
-
pool?: DB2PoolConfig;
|
|
83
|
-
}
|
|
84
|
-
interface DB2Config {
|
|
85
|
-
client: any;
|
|
86
|
-
connection: DB2ConnectionConfig;
|
|
87
|
-
pool?: DB2PoolConfig;
|
|
88
|
-
}
|
|
89
|
-
declare const DB2Dialect: typeof DB2Client;
|
|
90
|
-
|
|
91
|
-
export { DB2Config, DB2Dialect, DB2Client as default };
|
|
1
|
+
declare module "knex/lib/query/querycompiler" {}
|
|
2
|
+
declare module "knex/lib/schema/tablecompiler" {}
|
|
3
|
+
declare module "knex/lib/schema/compiler" {}
|
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 = require("knex");
|
|
39
39
|
var odbc = __toESM(require("odbc"));
|
|
40
|
-
var
|
|
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"));
|
|
@@ -182,6 +182,7 @@ var import_isObject2 = __toESM(require("lodash/isObject"));
|
|
|
182
182
|
var import_wrappingFormatter = require("knex/lib/formatter/wrappingFormatter");
|
|
183
183
|
var import_date_fns = require("date-fns");
|
|
184
184
|
var import_isEmpty = __toESM(require("lodash/isEmpty"));
|
|
185
|
+
var console = __toESM(require("console"));
|
|
185
186
|
var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
186
187
|
insert() {
|
|
187
188
|
const insertValues = this.single.insert || [];
|
|
@@ -285,7 +286,51 @@ var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
|
285
286
|
values
|
|
286
287
|
};
|
|
287
288
|
}
|
|
289
|
+
update() {
|
|
290
|
+
const withSQL = this.with();
|
|
291
|
+
const updates = this._prepUpdate(this.single.update);
|
|
292
|
+
const where = this.where();
|
|
293
|
+
const order = this.order();
|
|
294
|
+
const limit = this.limit();
|
|
295
|
+
const { returning } = this.single;
|
|
296
|
+
const values = Object.values(this.single.update).map((a) => `${a}`).join(", ");
|
|
297
|
+
console.log({
|
|
298
|
+
returning,
|
|
299
|
+
// @ts-ignore
|
|
300
|
+
where,
|
|
301
|
+
// @ts-ignore
|
|
302
|
+
updates,
|
|
303
|
+
// @ts-ignore
|
|
304
|
+
single: this.single.update,
|
|
305
|
+
// @ts-ignore
|
|
306
|
+
grouped: this.grouped.where,
|
|
307
|
+
values
|
|
308
|
+
});
|
|
309
|
+
const moreWheres = (
|
|
310
|
+
// @ts-ignore
|
|
311
|
+
this.grouped.where && this.grouped.where.length > 0 ? (
|
|
312
|
+
// @ts-ignore
|
|
313
|
+
this.grouped.where.map((w) => {
|
|
314
|
+
if (this.single.update.hasOwnProperty(w.column))
|
|
315
|
+
return;
|
|
316
|
+
if (!w.value)
|
|
317
|
+
return;
|
|
318
|
+
return `"${w.column}" ${w.not ? "!" : ""}${w.operator} ${w.value}`;
|
|
319
|
+
})
|
|
320
|
+
) : []
|
|
321
|
+
);
|
|
322
|
+
let selectReturning = returning ? `select ${returning.map((a) => `"${a}"`).join(", ")} from ${// @ts-ignore
|
|
323
|
+
this.tableName} where ${Object.entries(this.single.update).map(([key, value]) => `"${key}" = '${value}'`).join(" and ")}${moreWheres.length > 0 && " and "}${moreWheres.join(
|
|
324
|
+
" and "
|
|
325
|
+
)}` : "";
|
|
326
|
+
console.log({ selectReturning });
|
|
327
|
+
const sql = withSQL + // @ts-ignore
|
|
328
|
+
`update ${this.single.only ? "only " : ""}${this.tableName} set ` + // @ts-ignore
|
|
329
|
+
updates.join(", ") + (where ? ` ${where}` : "") + (order ? ` ${order}` : "") + (limit ? ` ${limit}` : "");
|
|
330
|
+
return { sql, returning, selectReturning };
|
|
331
|
+
}
|
|
288
332
|
_returning(method, value, withTrigger) {
|
|
333
|
+
console.log("_returning", value);
|
|
289
334
|
switch (method) {
|
|
290
335
|
case "update":
|
|
291
336
|
case "insert":
|
|
@@ -299,7 +344,7 @@ var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
|
299
344
|
`${withTrigger ? " into #out" : ""}`
|
|
300
345
|
) : "";
|
|
301
346
|
case "rowcount":
|
|
302
|
-
return value ? "
|
|
347
|
+
return value ? "select @@rowcount" : "";
|
|
303
348
|
}
|
|
304
349
|
}
|
|
305
350
|
columnizeWithPrefix(prefix, target) {
|
|
@@ -358,7 +403,7 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
358
403
|
async acquireRawConnection() {
|
|
359
404
|
this.printDebug("acquiring raw connection");
|
|
360
405
|
const connectionConfig = this.config.connection;
|
|
361
|
-
|
|
406
|
+
console2.log(this._getConnectionString(connectionConfig));
|
|
362
407
|
if (this.config?.connection?.pool) {
|
|
363
408
|
const poolConfig = {
|
|
364
409
|
connectionString: this._getConnectionString(connectionConfig),
|
|
@@ -382,7 +427,7 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
382
427
|
// Used to explicitly close a connection, called internally by the pool manager
|
|
383
428
|
// when a connection times out or the pool is shutdown.
|
|
384
429
|
async destroyRawConnection(connection) {
|
|
385
|
-
|
|
430
|
+
console2.log("destroy connection");
|
|
386
431
|
return await connection.close();
|
|
387
432
|
}
|
|
388
433
|
_getConnectionString(connectionConfig) {
|
|
@@ -409,7 +454,7 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
409
454
|
}
|
|
410
455
|
} else {
|
|
411
456
|
await connection.beginTransaction();
|
|
412
|
-
|
|
457
|
+
console2.log("transaction begun");
|
|
413
458
|
try {
|
|
414
459
|
const statement = await connection.createStatement();
|
|
415
460
|
await statement.prepare(obj.sql);
|
|
@@ -420,70 +465,38 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
420
465
|
if (result.statement.includes("IDENTITY_VAL_LOCAL()")) {
|
|
421
466
|
obj.response = {
|
|
422
467
|
rows: result.map(
|
|
423
|
-
(row) => result.columns.length > 0 ? row[result.columns[0].name] : row
|
|
468
|
+
(row) => result.columns && result.columns?.length > 0 ? row[result.columns[0].name] : row
|
|
424
469
|
),
|
|
425
|
-
rowCount: result.
|
|
470
|
+
rowCount: result.count
|
|
426
471
|
};
|
|
427
472
|
} else if (method === "update") {
|
|
428
|
-
if (obj.
|
|
429
|
-
|
|
430
|
-
const rows = await connection.query(
|
|
431
|
-
// @ts-ignore
|
|
432
|
-
`select * from "knex_migrations_lock"`
|
|
433
|
-
);
|
|
434
|
-
console.log({ rows });
|
|
435
|
-
console.log(rows.map((row) => row.index));
|
|
473
|
+
if (obj.selectReturning) {
|
|
474
|
+
const returningSelect = await connection.query(obj.selectReturning);
|
|
436
475
|
obj.response = {
|
|
437
|
-
rows:
|
|
438
|
-
rowCount:
|
|
476
|
+
rows: returningSelect,
|
|
477
|
+
rowCount: result.count
|
|
439
478
|
};
|
|
440
479
|
} else {
|
|
441
|
-
let returningSelect = obj.sql.replace("update", "select * from ");
|
|
442
|
-
returningSelect = returningSelect.replace("where", "and");
|
|
443
|
-
returningSelect = returningSelect.replace("set", "where");
|
|
444
|
-
returningSelect = returningSelect.replace(this.tableName, "where");
|
|
445
|
-
const selectStatement = await connection.createStatement();
|
|
446
|
-
await selectStatement.prepare(returningSelect);
|
|
447
|
-
console.log({ returningSelect });
|
|
448
|
-
if (obj.bindings) {
|
|
449
|
-
await selectStatement.bind(obj.bindings);
|
|
450
|
-
}
|
|
451
|
-
const selected = await selectStatement.execute();
|
|
452
480
|
obj.response = {
|
|
453
|
-
rows:
|
|
454
|
-
|
|
455
|
-
),
|
|
456
|
-
rowCount: selected.length
|
|
481
|
+
rows: result,
|
|
482
|
+
rowCount: result.count
|
|
457
483
|
};
|
|
458
484
|
}
|
|
459
485
|
} else {
|
|
460
|
-
obj.response = { rows: result, rowCount: result.
|
|
486
|
+
obj.response = { rows: result, rowCount: result.count };
|
|
461
487
|
}
|
|
462
488
|
} catch (err) {
|
|
463
|
-
|
|
489
|
+
console2.error(err);
|
|
464
490
|
await connection.rollback();
|
|
465
491
|
throw new Error(err);
|
|
466
492
|
} finally {
|
|
467
|
-
|
|
493
|
+
console2.log("transaction committed");
|
|
468
494
|
await connection.commit();
|
|
469
495
|
}
|
|
470
496
|
}
|
|
471
|
-
|
|
497
|
+
console2.log({ obj });
|
|
472
498
|
return obj;
|
|
473
499
|
}
|
|
474
|
-
_selectAfterUpdate() {
|
|
475
|
-
const returnSelect = `; SELECT ${// @ts-ignore
|
|
476
|
-
this.single.returning ? (
|
|
477
|
-
// @ts-ignore
|
|
478
|
-
this.formatter.columnize(this.single.returning)
|
|
479
|
-
) : "*"} from ${this.tableName} `;
|
|
480
|
-
let whereStatement = [this.where()];
|
|
481
|
-
console.log({ whereStatement });
|
|
482
|
-
for (const [key, value] of Object.entries(this.single.update)) {
|
|
483
|
-
whereStatement.push(`WHERE ${key} = ${value}`);
|
|
484
|
-
}
|
|
485
|
-
return returnSelect + whereStatement.join(" and ");
|
|
486
|
-
}
|
|
487
500
|
transaction(container, config, outerTx) {
|
|
488
501
|
return new ibmi_transaction_default(this, ...arguments);
|
|
489
502
|
}
|
|
@@ -504,7 +517,7 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
504
517
|
return null;
|
|
505
518
|
const resp = obj.response;
|
|
506
519
|
const method = obj.sqlMethod;
|
|
507
|
-
const { rows } = resp;
|
|
520
|
+
const { rows, rowCount } = resp;
|
|
508
521
|
if (obj.output)
|
|
509
522
|
return obj.output.call(runner, resp);
|
|
510
523
|
switch (method) {
|
|
@@ -519,11 +532,14 @@ var DB2Client = class extends import_knex.knex.Client {
|
|
|
519
532
|
case "del":
|
|
520
533
|
case "delete":
|
|
521
534
|
case "update":
|
|
522
|
-
|
|
535
|
+
if (obj.selectReturning) {
|
|
536
|
+
return rows;
|
|
537
|
+
}
|
|
538
|
+
return rowCount;
|
|
523
539
|
case "counter":
|
|
524
|
-
return
|
|
540
|
+
return rowCount;
|
|
525
541
|
default:
|
|
526
|
-
return
|
|
542
|
+
return rows;
|
|
527
543
|
}
|
|
528
544
|
}
|
|
529
545
|
};
|
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
|
|
5
|
+
import * as console2 from "console";
|
|
6
6
|
|
|
7
7
|
// src/schema/ibmi-compiler.ts
|
|
8
8
|
import SchemaCompiler from "knex/lib/schema/compiler";
|
|
@@ -147,6 +147,7 @@ import isObject2 from "lodash/isObject";
|
|
|
147
147
|
import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
|
|
148
148
|
import { format } from "date-fns";
|
|
149
149
|
import isEmpty from "lodash/isEmpty";
|
|
150
|
+
import * as console from "console";
|
|
150
151
|
var IBMiQueryCompiler = class extends QueryCompiler {
|
|
151
152
|
insert() {
|
|
152
153
|
const insertValues = this.single.insert || [];
|
|
@@ -250,7 +251,51 @@ var IBMiQueryCompiler = class extends QueryCompiler {
|
|
|
250
251
|
values
|
|
251
252
|
};
|
|
252
253
|
}
|
|
254
|
+
update() {
|
|
255
|
+
const withSQL = this.with();
|
|
256
|
+
const updates = this._prepUpdate(this.single.update);
|
|
257
|
+
const where = this.where();
|
|
258
|
+
const order = this.order();
|
|
259
|
+
const limit = this.limit();
|
|
260
|
+
const { returning } = this.single;
|
|
261
|
+
const values = Object.values(this.single.update).map((a) => `${a}`).join(", ");
|
|
262
|
+
console.log({
|
|
263
|
+
returning,
|
|
264
|
+
// @ts-ignore
|
|
265
|
+
where,
|
|
266
|
+
// @ts-ignore
|
|
267
|
+
updates,
|
|
268
|
+
// @ts-ignore
|
|
269
|
+
single: this.single.update,
|
|
270
|
+
// @ts-ignore
|
|
271
|
+
grouped: this.grouped.where,
|
|
272
|
+
values
|
|
273
|
+
});
|
|
274
|
+
const moreWheres = (
|
|
275
|
+
// @ts-ignore
|
|
276
|
+
this.grouped.where && this.grouped.where.length > 0 ? (
|
|
277
|
+
// @ts-ignore
|
|
278
|
+
this.grouped.where.map((w) => {
|
|
279
|
+
if (this.single.update.hasOwnProperty(w.column))
|
|
280
|
+
return;
|
|
281
|
+
if (!w.value)
|
|
282
|
+
return;
|
|
283
|
+
return `"${w.column}" ${w.not ? "!" : ""}${w.operator} ${w.value}`;
|
|
284
|
+
})
|
|
285
|
+
) : []
|
|
286
|
+
);
|
|
287
|
+
let selectReturning = returning ? `select ${returning.map((a) => `"${a}"`).join(", ")} from ${// @ts-ignore
|
|
288
|
+
this.tableName} where ${Object.entries(this.single.update).map(([key, value]) => `"${key}" = '${value}'`).join(" and ")}${moreWheres.length > 0 && " and "}${moreWheres.join(
|
|
289
|
+
" and "
|
|
290
|
+
)}` : "";
|
|
291
|
+
console.log({ selectReturning });
|
|
292
|
+
const sql = withSQL + // @ts-ignore
|
|
293
|
+
`update ${this.single.only ? "only " : ""}${this.tableName} set ` + // @ts-ignore
|
|
294
|
+
updates.join(", ") + (where ? ` ${where}` : "") + (order ? ` ${order}` : "") + (limit ? ` ${limit}` : "");
|
|
295
|
+
return { sql, returning, selectReturning };
|
|
296
|
+
}
|
|
253
297
|
_returning(method, value, withTrigger) {
|
|
298
|
+
console.log("_returning", value);
|
|
254
299
|
switch (method) {
|
|
255
300
|
case "update":
|
|
256
301
|
case "insert":
|
|
@@ -264,7 +309,7 @@ var IBMiQueryCompiler = class extends QueryCompiler {
|
|
|
264
309
|
`${withTrigger ? " into #out" : ""}`
|
|
265
310
|
) : "";
|
|
266
311
|
case "rowcount":
|
|
267
|
-
return value ? "
|
|
312
|
+
return value ? "select @@rowcount" : "";
|
|
268
313
|
}
|
|
269
314
|
}
|
|
270
315
|
columnizeWithPrefix(prefix, target) {
|
|
@@ -323,7 +368,7 @@ var DB2Client = class extends knex.Client {
|
|
|
323
368
|
async acquireRawConnection() {
|
|
324
369
|
this.printDebug("acquiring raw connection");
|
|
325
370
|
const connectionConfig = this.config.connection;
|
|
326
|
-
|
|
371
|
+
console2.log(this._getConnectionString(connectionConfig));
|
|
327
372
|
if (this.config?.connection?.pool) {
|
|
328
373
|
const poolConfig = {
|
|
329
374
|
connectionString: this._getConnectionString(connectionConfig),
|
|
@@ -347,7 +392,7 @@ var DB2Client = class extends knex.Client {
|
|
|
347
392
|
// Used to explicitly close a connection, called internally by the pool manager
|
|
348
393
|
// when a connection times out or the pool is shutdown.
|
|
349
394
|
async destroyRawConnection(connection) {
|
|
350
|
-
|
|
395
|
+
console2.log("destroy connection");
|
|
351
396
|
return await connection.close();
|
|
352
397
|
}
|
|
353
398
|
_getConnectionString(connectionConfig) {
|
|
@@ -374,7 +419,7 @@ var DB2Client = class extends knex.Client {
|
|
|
374
419
|
}
|
|
375
420
|
} else {
|
|
376
421
|
await connection.beginTransaction();
|
|
377
|
-
|
|
422
|
+
console2.log("transaction begun");
|
|
378
423
|
try {
|
|
379
424
|
const statement = await connection.createStatement();
|
|
380
425
|
await statement.prepare(obj.sql);
|
|
@@ -385,70 +430,38 @@ var DB2Client = class extends knex.Client {
|
|
|
385
430
|
if (result.statement.includes("IDENTITY_VAL_LOCAL()")) {
|
|
386
431
|
obj.response = {
|
|
387
432
|
rows: result.map(
|
|
388
|
-
(row) => result.columns.length > 0 ? row[result.columns[0].name] : row
|
|
433
|
+
(row) => result.columns && result.columns?.length > 0 ? row[result.columns[0].name] : row
|
|
389
434
|
),
|
|
390
|
-
rowCount: result.
|
|
435
|
+
rowCount: result.count
|
|
391
436
|
};
|
|
392
437
|
} else if (method === "update") {
|
|
393
|
-
if (obj.
|
|
394
|
-
|
|
395
|
-
const rows = await connection.query(
|
|
396
|
-
// @ts-ignore
|
|
397
|
-
`select * from "knex_migrations_lock"`
|
|
398
|
-
);
|
|
399
|
-
console.log({ rows });
|
|
400
|
-
console.log(rows.map((row) => row.index));
|
|
438
|
+
if (obj.selectReturning) {
|
|
439
|
+
const returningSelect = await connection.query(obj.selectReturning);
|
|
401
440
|
obj.response = {
|
|
402
|
-
rows:
|
|
403
|
-
rowCount:
|
|
441
|
+
rows: returningSelect,
|
|
442
|
+
rowCount: result.count
|
|
404
443
|
};
|
|
405
444
|
} else {
|
|
406
|
-
let returningSelect = obj.sql.replace("update", "select * from ");
|
|
407
|
-
returningSelect = returningSelect.replace("where", "and");
|
|
408
|
-
returningSelect = returningSelect.replace("set", "where");
|
|
409
|
-
returningSelect = returningSelect.replace(this.tableName, "where");
|
|
410
|
-
const selectStatement = await connection.createStatement();
|
|
411
|
-
await selectStatement.prepare(returningSelect);
|
|
412
|
-
console.log({ returningSelect });
|
|
413
|
-
if (obj.bindings) {
|
|
414
|
-
await selectStatement.bind(obj.bindings);
|
|
415
|
-
}
|
|
416
|
-
const selected = await selectStatement.execute();
|
|
417
445
|
obj.response = {
|
|
418
|
-
rows:
|
|
419
|
-
|
|
420
|
-
),
|
|
421
|
-
rowCount: selected.length
|
|
446
|
+
rows: result,
|
|
447
|
+
rowCount: result.count
|
|
422
448
|
};
|
|
423
449
|
}
|
|
424
450
|
} else {
|
|
425
|
-
obj.response = { rows: result, rowCount: result.
|
|
451
|
+
obj.response = { rows: result, rowCount: result.count };
|
|
426
452
|
}
|
|
427
453
|
} catch (err) {
|
|
428
|
-
|
|
454
|
+
console2.error(err);
|
|
429
455
|
await connection.rollback();
|
|
430
456
|
throw new Error(err);
|
|
431
457
|
} finally {
|
|
432
|
-
|
|
458
|
+
console2.log("transaction committed");
|
|
433
459
|
await connection.commit();
|
|
434
460
|
}
|
|
435
461
|
}
|
|
436
|
-
|
|
462
|
+
console2.log({ obj });
|
|
437
463
|
return obj;
|
|
438
464
|
}
|
|
439
|
-
_selectAfterUpdate() {
|
|
440
|
-
const returnSelect = `; SELECT ${// @ts-ignore
|
|
441
|
-
this.single.returning ? (
|
|
442
|
-
// @ts-ignore
|
|
443
|
-
this.formatter.columnize(this.single.returning)
|
|
444
|
-
) : "*"} from ${this.tableName} `;
|
|
445
|
-
let whereStatement = [this.where()];
|
|
446
|
-
console.log({ whereStatement });
|
|
447
|
-
for (const [key, value] of Object.entries(this.single.update)) {
|
|
448
|
-
whereStatement.push(`WHERE ${key} = ${value}`);
|
|
449
|
-
}
|
|
450
|
-
return returnSelect + whereStatement.join(" and ");
|
|
451
|
-
}
|
|
452
465
|
transaction(container, config, outerTx) {
|
|
453
466
|
return new ibmi_transaction_default(this, ...arguments);
|
|
454
467
|
}
|
|
@@ -469,7 +482,7 @@ var DB2Client = class extends knex.Client {
|
|
|
469
482
|
return null;
|
|
470
483
|
const resp = obj.response;
|
|
471
484
|
const method = obj.sqlMethod;
|
|
472
|
-
const { rows } = resp;
|
|
485
|
+
const { rows, rowCount } = resp;
|
|
473
486
|
if (obj.output)
|
|
474
487
|
return obj.output.call(runner, resp);
|
|
475
488
|
switch (method) {
|
|
@@ -484,11 +497,14 @@ var DB2Client = class extends knex.Client {
|
|
|
484
497
|
case "del":
|
|
485
498
|
case "delete":
|
|
486
499
|
case "update":
|
|
487
|
-
|
|
500
|
+
if (obj.selectReturning) {
|
|
501
|
+
return rows;
|
|
502
|
+
}
|
|
503
|
+
return rowCount;
|
|
488
504
|
case "counter":
|
|
489
|
-
return
|
|
505
|
+
return rowCount;
|
|
490
506
|
default:
|
|
491
|
-
return
|
|
507
|
+
return rows;
|
|
492
508
|
}
|
|
493
509
|
}
|
|
494
510
|
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bdkinc/knex-ibmi",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "Knex dialect for IBMi",
|
|
5
|
-
"main": "dist/index
|
|
5
|
+
"main": "dist/index",
|
|
6
|
+
"types": "dist/index",
|
|
6
7
|
"module": "dist/index.mjs",
|
|
7
8
|
"exports": {
|
|
8
9
|
"import": "./dist/index.mjs",
|
|
@@ -14,6 +15,7 @@
|
|
|
14
15
|
"engineStrict": true,
|
|
15
16
|
"scripts": {
|
|
16
17
|
"build": "tsup src/index.ts --dts --format esm,cjs",
|
|
18
|
+
"build:dev": "tsup src/index.ts --format esm,cjs",
|
|
17
19
|
"lint:scripts": "eslint . --ext .ts",
|
|
18
20
|
"format:scripts": "prettier . --write"
|
|
19
21
|
},
|
package/src/index.d.ts
ADDED
package/src/index.ts
CHANGED
|
@@ -145,56 +145,27 @@ class DB2Client extends knex.Client {
|
|
|
145
145
|
if (result.statement.includes("IDENTITY_VAL_LOCAL()")) {
|
|
146
146
|
obj.response = {
|
|
147
147
|
rows: result.map((row) =>
|
|
148
|
-
result.columns
|
|
148
|
+
result.columns && result.columns?.length > 0
|
|
149
|
+
? row[result.columns[0].name]
|
|
150
|
+
: row,
|
|
149
151
|
),
|
|
150
|
-
rowCount: result.
|
|
152
|
+
rowCount: result.count,
|
|
151
153
|
};
|
|
152
|
-
// @ts-ignore
|
|
153
154
|
} else if (method === "update") {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
// it would be a lot easier if the table-reference function
|
|
157
|
-
// worked the same for updates as it does inserts
|
|
158
|
-
// on DB2 LUW it does work so if they ever add it we need to fix
|
|
159
|
-
// @ts-ignore
|
|
160
|
-
if (obj.sql.includes("knex_migrations_lock")) {
|
|
161
|
-
// even more hacky for migrations
|
|
162
|
-
console.log("migrations_lock");
|
|
163
|
-
// @ts-ignore
|
|
164
|
-
const rows = await connection.query(
|
|
165
|
-
// @ts-ignore
|
|
166
|
-
`select * from \"knex_migrations_lock\"`,
|
|
167
|
-
);
|
|
168
|
-
console.log({ rows });
|
|
169
|
-
console.log(rows.map((row) => row.index));
|
|
155
|
+
if (obj.selectReturning) {
|
|
156
|
+
const returningSelect = await connection.query(obj.selectReturning);
|
|
170
157
|
obj.response = {
|
|
171
|
-
rows:
|
|
172
|
-
rowCount:
|
|
158
|
+
rows: returningSelect,
|
|
159
|
+
rowCount: result.count,
|
|
173
160
|
};
|
|
174
161
|
} else {
|
|
175
|
-
let returningSelect = obj.sql.replace("update", "select * from ");
|
|
176
|
-
returningSelect = returningSelect.replace("where", "and");
|
|
177
|
-
returningSelect = returningSelect.replace("set", "where");
|
|
178
|
-
// @ts-ignore
|
|
179
|
-
returningSelect = returningSelect.replace(this.tableName, "where");
|
|
180
|
-
const selectStatement = await connection.createStatement();
|
|
181
|
-
await selectStatement.prepare(returningSelect);
|
|
182
|
-
console.log({ returningSelect });
|
|
183
|
-
if (obj.bindings) {
|
|
184
|
-
await selectStatement.bind(obj.bindings);
|
|
185
|
-
}
|
|
186
|
-
const selected = await selectStatement.execute();
|
|
187
162
|
obj.response = {
|
|
188
|
-
rows:
|
|
189
|
-
|
|
190
|
-
? row[selected.columns[0].name]
|
|
191
|
-
: row,
|
|
192
|
-
),
|
|
193
|
-
rowCount: selected.length,
|
|
163
|
+
rows: result,
|
|
164
|
+
rowCount: result.count,
|
|
194
165
|
};
|
|
195
166
|
}
|
|
196
167
|
} else {
|
|
197
|
-
obj.response = { rows: result, rowCount: result.
|
|
168
|
+
obj.response = { rows: result, rowCount: result.count };
|
|
198
169
|
}
|
|
199
170
|
} catch (err: any) {
|
|
200
171
|
console.error(err);
|
|
@@ -210,25 +181,6 @@ class DB2Client extends knex.Client {
|
|
|
210
181
|
return obj;
|
|
211
182
|
}
|
|
212
183
|
|
|
213
|
-
_selectAfterUpdate() {
|
|
214
|
-
const returnSelect = `; SELECT ${
|
|
215
|
-
// @ts-ignore
|
|
216
|
-
this.single.returning
|
|
217
|
-
? // @ts-ignore
|
|
218
|
-
this.formatter.columnize(this.single.returning)
|
|
219
|
-
: "*"
|
|
220
|
-
// @ts-ignore
|
|
221
|
-
} from ${this.tableName} `;
|
|
222
|
-
// @ts-ignore
|
|
223
|
-
let whereStatement = [this.where()];
|
|
224
|
-
console.log({ whereStatement });
|
|
225
|
-
// @ts-ignore
|
|
226
|
-
for (const [key, value] of Object.entries(this.single.update)) {
|
|
227
|
-
whereStatement.push(`WHERE ${key} = ${value}`);
|
|
228
|
-
}
|
|
229
|
-
return returnSelect + whereStatement.join(" and ");
|
|
230
|
-
}
|
|
231
|
-
|
|
232
184
|
transaction(container: any, config: any, outerTx: any): Knex.Transaction {
|
|
233
185
|
// @ts-ignore
|
|
234
186
|
return new Transaction(this, ...arguments);
|
|
@@ -259,7 +211,7 @@ class DB2Client extends knex.Client {
|
|
|
259
211
|
|
|
260
212
|
const resp = obj.response;
|
|
261
213
|
const method = obj.sqlMethod;
|
|
262
|
-
const { rows } = resp;
|
|
214
|
+
const { rows, rowCount } = resp;
|
|
263
215
|
|
|
264
216
|
if (obj.output) return obj.output.call(runner, resp);
|
|
265
217
|
|
|
@@ -275,11 +227,14 @@ class DB2Client extends knex.Client {
|
|
|
275
227
|
case "del":
|
|
276
228
|
case "delete":
|
|
277
229
|
case "update":
|
|
278
|
-
|
|
230
|
+
if (obj.selectReturning) {
|
|
231
|
+
return rows;
|
|
232
|
+
}
|
|
233
|
+
return rowCount;
|
|
279
234
|
case "counter":
|
|
280
|
-
return
|
|
235
|
+
return rowCount;
|
|
281
236
|
default:
|
|
282
|
-
return
|
|
237
|
+
return rows;
|
|
283
238
|
}
|
|
284
239
|
}
|
|
285
240
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
// @ts-ignore
|
|
1
2
|
import QueryCompiler from "knex/lib/query/querycompiler";
|
|
2
3
|
import isObject from "lodash/isObject";
|
|
3
4
|
import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
|
|
4
5
|
import { format } from "date-fns";
|
|
5
|
-
import * as console from "console";
|
|
6
6
|
import isEmpty from "lodash/isEmpty";
|
|
7
|
+
import * as console from "console";
|
|
7
8
|
|
|
8
9
|
class IBMiQueryCompiler extends QueryCompiler {
|
|
9
10
|
insert() {
|
|
@@ -127,8 +128,81 @@ class IBMiQueryCompiler extends QueryCompiler {
|
|
|
127
128
|
};
|
|
128
129
|
}
|
|
129
130
|
|
|
131
|
+
update() {
|
|
132
|
+
// @ts-ignore
|
|
133
|
+
const withSQL = this.with();
|
|
134
|
+
// @ts-ignore
|
|
135
|
+
const updates = this._prepUpdate(this.single.update);
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
const where = this.where();
|
|
138
|
+
// @ts-ignore
|
|
139
|
+
const order = this.order();
|
|
140
|
+
// @ts-ignore
|
|
141
|
+
const limit = this.limit();
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
const { returning } = this.single;
|
|
144
|
+
// @ts-ignore
|
|
145
|
+
const values = Object.values(this.single.update)
|
|
146
|
+
.map((a) => `${a}`)
|
|
147
|
+
.join(", ");
|
|
148
|
+
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
console.log({
|
|
151
|
+
returning,
|
|
152
|
+
// @ts-ignore
|
|
153
|
+
where,
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
updates,
|
|
156
|
+
// @ts-ignore
|
|
157
|
+
single: this.single.update,
|
|
158
|
+
// @ts-ignore
|
|
159
|
+
grouped: this.grouped.where,
|
|
160
|
+
values,
|
|
161
|
+
});
|
|
162
|
+
// @ts-ignore
|
|
163
|
+
const moreWheres =
|
|
164
|
+
// @ts-ignore
|
|
165
|
+
this.grouped.where && this.grouped.where.length > 0
|
|
166
|
+
? // @ts-ignore
|
|
167
|
+
this.grouped.where.map((w) => {
|
|
168
|
+
// @ts-ignore
|
|
169
|
+
if (this.single.update.hasOwnProperty(w.column)) return;
|
|
170
|
+
if (!w.value) return;
|
|
171
|
+
return `"${w.column}" ${w.not ? "!" : ""}${w.operator} ${w.value}`;
|
|
172
|
+
})
|
|
173
|
+
: [];
|
|
174
|
+
|
|
175
|
+
let selectReturning = returning
|
|
176
|
+
? `select ${returning.map((a) => `"${a}"`).join(", ")} from ${
|
|
177
|
+
// @ts-ignore
|
|
178
|
+
this.tableName
|
|
179
|
+
// @ts-ignore
|
|
180
|
+
} where ${Object.entries(this.single.update)
|
|
181
|
+
.map(([key, value]) => `"${key}" = '${value}'`)
|
|
182
|
+
.join(" and ")}${moreWheres.length > 0 && " and "}${moreWheres.join(
|
|
183
|
+
" and ",
|
|
184
|
+
)}`
|
|
185
|
+
: "";
|
|
186
|
+
|
|
187
|
+
console.log({ selectReturning });
|
|
188
|
+
|
|
189
|
+
const sql =
|
|
190
|
+
withSQL +
|
|
191
|
+
// @ts-ignore
|
|
192
|
+
`update ${this.single.only ? "only " : ""}${this.tableName}` +
|
|
193
|
+
" set " +
|
|
194
|
+
// @ts-ignore
|
|
195
|
+
updates.join(", ") +
|
|
196
|
+
(where ? ` ${where}` : "") +
|
|
197
|
+
(order ? ` ${order}` : "") +
|
|
198
|
+
(limit ? ` ${limit}` : "");
|
|
199
|
+
|
|
200
|
+
return { sql, returning, selectReturning };
|
|
201
|
+
}
|
|
202
|
+
|
|
130
203
|
_returning(method, value, withTrigger) {
|
|
131
204
|
// currently a placeholder in case I need to update return values
|
|
205
|
+
console.log("_returning", value);
|
|
132
206
|
switch (method) {
|
|
133
207
|
case "update":
|
|
134
208
|
case "insert":
|
|
@@ -142,7 +216,7 @@ class IBMiQueryCompiler extends QueryCompiler {
|
|
|
142
216
|
`${withTrigger ? " into #out" : ""}`
|
|
143
217
|
: "";
|
|
144
218
|
case "rowcount":
|
|
145
|
-
return value ? "
|
|
219
|
+
return value ? "select @@rowcount" : "";
|
|
146
220
|
}
|
|
147
221
|
}
|
|
148
222
|
|