@bdkinc/knex-ibmi 0.0.3 → 0.0.4
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 +2 -2
- package/dist/index.js +26 -121
- package/dist/index.mjs +29 -127
- package/package.json +1 -1
- package/src/execution/ibmi-transaction.ts +0 -1
- package/src/index.ts +2 -2
- package/src/query/ibmi-querycompiler.ts +6 -79
- package/src/schema/ibmi-columncompiler.ts +1 -22
- package/src/schema/ibmi-compiler.ts +7 -0
- package/src/schema/ibmi-tablecompiler.ts +14 -53
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](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
|
|
|
@@ -106,7 +106,7 @@ try {
|
|
|
106
106
|
|
|
107
107
|
## Configuring your driver
|
|
108
108
|
|
|
109
|
-
If you don't know the name of your installed driver, then look in
|
|
109
|
+
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
110
|
There you should see an entry like the one below:
|
|
111
111
|
|
|
112
112
|
```
|
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
|
|
40
|
+
var console3 = __toESM(require("console"));
|
|
41
41
|
|
|
42
42
|
// src/schema/ibmi-compiler.ts
|
|
43
43
|
var import_compiler = __toESM(require("knex/lib/schema/compiler"));
|
|
@@ -48,8 +48,11 @@ 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
58
|
const bindings = [tableName.toUpperCase()];
|
|
@@ -84,49 +87,16 @@ var ibmi_compiler_default = IBMiSchemaCompiler;
|
|
|
84
87
|
// src/schema/ibmi-tablecompiler.ts
|
|
85
88
|
var import_tablecompiler = __toESM(require("knex/lib/schema/tablecompiler"));
|
|
86
89
|
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
90
|
createQuery(columns, ifNot, like) {
|
|
125
91
|
let createStatement = ifNot ? `if object_id('${this.tableName()}', 'U') is null ` : "";
|
|
126
92
|
if (like) {
|
|
127
93
|
createStatement += `SELECT * INTO ${this.tableName()} FROM ${this.tableNameLike()} WHERE 0=1`;
|
|
128
94
|
} else {
|
|
129
|
-
createStatement += "CREATE TABLE " +
|
|
95
|
+
createStatement += "CREATE TABLE " + // @ts-ignore
|
|
96
|
+
this.tableName() + // @ts-ignore
|
|
97
|
+
(this._formatting ? " (\n " : " (") + // @ts-ignore
|
|
98
|
+
columns.sql.join(this._formatting ? ",\n " : ", ") + // @ts-ignore
|
|
99
|
+
this._addChecks() + ")";
|
|
130
100
|
}
|
|
131
101
|
this.pushQuery(createStatement);
|
|
132
102
|
if (this.single.comment) {
|
|
@@ -144,7 +114,11 @@ var IBMiTableCompiler = class extends import_tablecompiler.default {
|
|
|
144
114
|
return prefix + column;
|
|
145
115
|
});
|
|
146
116
|
this.pushQuery({
|
|
147
|
-
sql: (
|
|
117
|
+
sql: (
|
|
118
|
+
// @ts-ignore
|
|
119
|
+
(this.lowerCase ? "alter table " : "ALTER TABLE ") + // @ts-ignore
|
|
120
|
+
this.tableName() + " " + columnSql.join(" ")
|
|
121
|
+
),
|
|
148
122
|
bindings: columns.bindings
|
|
149
123
|
});
|
|
150
124
|
}
|
|
@@ -157,32 +131,17 @@ var ibmi_tablecompiler_default = IBMiTableCompiler;
|
|
|
157
131
|
|
|
158
132
|
// src/schema/ibmi-columncompiler.ts
|
|
159
133
|
var import_columncompiler = __toESM(require("knex/lib/schema/columncompiler"));
|
|
160
|
-
var console2 = __toESM(require("console"));
|
|
161
134
|
var IBMiColumnCompiler = class extends import_columncompiler.default {
|
|
162
|
-
constructor(client, tableCompiler, columnBuilder) {
|
|
163
|
-
super(client, tableCompiler, columnBuilder);
|
|
164
|
-
}
|
|
165
135
|
increments(options = { primaryKey: true }) {
|
|
166
|
-
return "int not null generated always as identity (start with 1, increment by 1)" +
|
|
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}`;
|
|
136
|
+
return "int not null generated always as identity (start with 1, increment by 1)" + // @ts-ignore
|
|
137
|
+
(this.tableCompiler._canBeAddPrimaryKey(options) ? " primary key" : "");
|
|
179
138
|
}
|
|
180
139
|
};
|
|
181
140
|
var ibmi_columncompiler_default = IBMiColumnCompiler;
|
|
182
141
|
|
|
183
142
|
// src/execution/ibmi-transaction.ts
|
|
184
143
|
var import_transaction = __toESM(require("knex/lib/execution/transaction"));
|
|
185
|
-
var
|
|
144
|
+
var console2 = __toESM(require("console"));
|
|
186
145
|
var IBMiTransaction = class extends import_transaction.default {
|
|
187
146
|
async begin(conn) {
|
|
188
147
|
const connection = await conn.connect();
|
|
@@ -190,7 +149,7 @@ var IBMiTransaction = class extends import_transaction.default {
|
|
|
190
149
|
return connection;
|
|
191
150
|
}
|
|
192
151
|
async rollback(conn) {
|
|
193
|
-
|
|
152
|
+
console2.log({ conn });
|
|
194
153
|
const connection = await conn.connect();
|
|
195
154
|
await connection.rollback();
|
|
196
155
|
return connection;
|
|
@@ -204,31 +163,25 @@ var ibmi_transaction_default = IBMiTransaction;
|
|
|
204
163
|
|
|
205
164
|
// src/query/ibmi-querycompiler.ts
|
|
206
165
|
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
166
|
var import_isObject = __toESM(require("lodash/isObject"));
|
|
211
167
|
var import_wrappingFormatter = require("knex/lib/formatter/wrappingFormatter");
|
|
212
168
|
var import_date_fns = require("date-fns");
|
|
213
|
-
var console4 = __toESM(require("console"));
|
|
214
169
|
var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
215
170
|
_prepInsert(data) {
|
|
216
171
|
if ((0, import_isObject.default)(data)) {
|
|
217
|
-
console4.log("data is object", data);
|
|
218
172
|
if (data.hasOwnProperty("migration_time")) {
|
|
219
|
-
console4.log("data has migration_time", data.migration_time);
|
|
220
173
|
const parsed = new Date(data.migration_time);
|
|
221
|
-
console4.log(parsed);
|
|
222
174
|
data.migration_time = (0, import_date_fns.format)(parsed, "yyyy-MM-dd HH:mm:ss");
|
|
223
|
-
console4.log(data.migration_time);
|
|
224
175
|
}
|
|
225
|
-
console4.log("data date after change", data);
|
|
226
176
|
}
|
|
227
177
|
const isRaw = (0, import_wrappingFormatter.rawOrFn)(
|
|
228
178
|
data,
|
|
229
179
|
void 0,
|
|
180
|
+
// @ts-ignore
|
|
230
181
|
this.builder,
|
|
182
|
+
// @ts-ignore
|
|
231
183
|
this.client,
|
|
184
|
+
// @ts-ignore
|
|
232
185
|
this.bindingsHolder
|
|
233
186
|
);
|
|
234
187
|
if (isRaw)
|
|
@@ -267,54 +220,6 @@ var IBMiQueryCompiler = class extends import_querycompiler.default {
|
|
|
267
220
|
values
|
|
268
221
|
};
|
|
269
222
|
}
|
|
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
223
|
};
|
|
319
224
|
var ibmi_querycompiler_default = IBMiQueryCompiler;
|
|
320
225
|
|
|
@@ -367,13 +272,13 @@ var DB2Client = class extends import_knex.default.Client {
|
|
|
367
272
|
async acquireRawConnection() {
|
|
368
273
|
this.printDebug("acquiring raw connection");
|
|
369
274
|
const connectionConfig = this.config.connection;
|
|
370
|
-
|
|
275
|
+
console3.log(this._getConnectionString(connectionConfig));
|
|
371
276
|
return await this.driver.pool(this._getConnectionString(connectionConfig));
|
|
372
277
|
}
|
|
373
278
|
// Used to explicitly close a connection, called internally by the pool manager
|
|
374
279
|
// when a connection times out or the pool is shutdown.
|
|
375
280
|
async destroyRawConnection(connection) {
|
|
376
|
-
|
|
281
|
+
console3.log("destroy connection");
|
|
377
282
|
return await connection.close();
|
|
378
283
|
}
|
|
379
284
|
_getConnectionString(connectionConfig) {
|
|
@@ -409,14 +314,14 @@ var DB2Client = class extends import_knex.default.Client {
|
|
|
409
314
|
const result = await statement.execute();
|
|
410
315
|
obj.response = { rows: [result.count], rowCount: result.count };
|
|
411
316
|
} catch (err) {
|
|
412
|
-
|
|
317
|
+
console3.error(err);
|
|
413
318
|
throw new Error(err);
|
|
414
319
|
}
|
|
415
320
|
}
|
|
416
|
-
|
|
321
|
+
console3.log({ obj });
|
|
417
322
|
return obj;
|
|
418
323
|
}
|
|
419
|
-
transaction() {
|
|
324
|
+
transaction(container, config, outerTx) {
|
|
420
325
|
return new ibmi_transaction_default(this, ...arguments);
|
|
421
326
|
}
|
|
422
327
|
schemaCompiler() {
|
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 console3 from "console";
|
|
6
6
|
|
|
7
7
|
// src/schema/ibmi-compiler.ts
|
|
8
8
|
import SchemaCompiler from "knex/lib/schema/compiler";
|
|
@@ -13,8 +13,11 @@ 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
23
|
const bindings = [tableName.toUpperCase()];
|
|
@@ -49,49 +52,16 @@ var ibmi_compiler_default = IBMiSchemaCompiler;
|
|
|
49
52
|
// src/schema/ibmi-tablecompiler.ts
|
|
50
53
|
import TableCompiler from "knex/lib/schema/tablecompiler";
|
|
51
54
|
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
55
|
createQuery(columns, ifNot, like) {
|
|
90
56
|
let createStatement = ifNot ? `if object_id('${this.tableName()}', 'U') is null ` : "";
|
|
91
57
|
if (like) {
|
|
92
58
|
createStatement += `SELECT * INTO ${this.tableName()} FROM ${this.tableNameLike()} WHERE 0=1`;
|
|
93
59
|
} else {
|
|
94
|
-
createStatement += "CREATE TABLE " +
|
|
60
|
+
createStatement += "CREATE TABLE " + // @ts-ignore
|
|
61
|
+
this.tableName() + // @ts-ignore
|
|
62
|
+
(this._formatting ? " (\n " : " (") + // @ts-ignore
|
|
63
|
+
columns.sql.join(this._formatting ? ",\n " : ", ") + // @ts-ignore
|
|
64
|
+
this._addChecks() + ")";
|
|
95
65
|
}
|
|
96
66
|
this.pushQuery(createStatement);
|
|
97
67
|
if (this.single.comment) {
|
|
@@ -109,7 +79,11 @@ var IBMiTableCompiler = class extends TableCompiler {
|
|
|
109
79
|
return prefix + column;
|
|
110
80
|
});
|
|
111
81
|
this.pushQuery({
|
|
112
|
-
sql: (
|
|
82
|
+
sql: (
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
(this.lowerCase ? "alter table " : "ALTER TABLE ") + // @ts-ignore
|
|
85
|
+
this.tableName() + " " + columnSql.join(" ")
|
|
86
|
+
),
|
|
113
87
|
bindings: columns.bindings
|
|
114
88
|
});
|
|
115
89
|
}
|
|
@@ -122,32 +96,17 @@ var ibmi_tablecompiler_default = IBMiTableCompiler;
|
|
|
122
96
|
|
|
123
97
|
// src/schema/ibmi-columncompiler.ts
|
|
124
98
|
import ColumnCompiler from "knex/lib/schema/columncompiler";
|
|
125
|
-
import * as console2 from "console";
|
|
126
99
|
var IBMiColumnCompiler = class extends ColumnCompiler {
|
|
127
|
-
constructor(client, tableCompiler, columnBuilder) {
|
|
128
|
-
super(client, tableCompiler, columnBuilder);
|
|
129
|
-
}
|
|
130
100
|
increments(options = { primaryKey: true }) {
|
|
131
|
-
return "int not null generated always as identity (start with 1, increment by 1)" +
|
|
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}`;
|
|
101
|
+
return "int not null generated always as identity (start with 1, increment by 1)" + // @ts-ignore
|
|
102
|
+
(this.tableCompiler._canBeAddPrimaryKey(options) ? " primary key" : "");
|
|
144
103
|
}
|
|
145
104
|
};
|
|
146
105
|
var ibmi_columncompiler_default = IBMiColumnCompiler;
|
|
147
106
|
|
|
148
107
|
// src/execution/ibmi-transaction.ts
|
|
149
108
|
import Transaction from "knex/lib/execution/transaction";
|
|
150
|
-
import * as
|
|
109
|
+
import * as console2 from "console";
|
|
151
110
|
var IBMiTransaction = class extends Transaction {
|
|
152
111
|
async begin(conn) {
|
|
153
112
|
const connection = await conn.connect();
|
|
@@ -155,7 +114,7 @@ var IBMiTransaction = class extends Transaction {
|
|
|
155
114
|
return connection;
|
|
156
115
|
}
|
|
157
116
|
async rollback(conn) {
|
|
158
|
-
|
|
117
|
+
console2.log({ conn });
|
|
159
118
|
const connection = await conn.connect();
|
|
160
119
|
await connection.rollback();
|
|
161
120
|
return connection;
|
|
@@ -169,34 +128,25 @@ var ibmi_transaction_default = IBMiTransaction;
|
|
|
169
128
|
|
|
170
129
|
// src/query/ibmi-querycompiler.ts
|
|
171
130
|
import QueryCompiler from "knex/lib/query/querycompiler";
|
|
172
|
-
import
|
|
173
|
-
import
|
|
174
|
-
import omitBy from "lodash/omitBy";
|
|
175
|
-
import isObject2 from "lodash/isObject";
|
|
176
|
-
import {
|
|
177
|
-
wrap as wrap_,
|
|
178
|
-
rawOrFn as rawOrFn_
|
|
179
|
-
} from "knex/lib/formatter/wrappingFormatter";
|
|
131
|
+
import isObject from "lodash/isObject";
|
|
132
|
+
import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
|
|
180
133
|
import { format } from "date-fns";
|
|
181
|
-
import * as console4 from "console";
|
|
182
134
|
var IBMiQueryCompiler = class extends QueryCompiler {
|
|
183
135
|
_prepInsert(data) {
|
|
184
|
-
if (
|
|
185
|
-
console4.log("data is object", data);
|
|
136
|
+
if (isObject(data)) {
|
|
186
137
|
if (data.hasOwnProperty("migration_time")) {
|
|
187
|
-
console4.log("data has migration_time", data.migration_time);
|
|
188
138
|
const parsed = new Date(data.migration_time);
|
|
189
|
-
console4.log(parsed);
|
|
190
139
|
data.migration_time = format(parsed, "yyyy-MM-dd HH:mm:ss");
|
|
191
|
-
console4.log(data.migration_time);
|
|
192
140
|
}
|
|
193
|
-
console4.log("data date after change", data);
|
|
194
141
|
}
|
|
195
142
|
const isRaw = rawOrFn_(
|
|
196
143
|
data,
|
|
197
144
|
void 0,
|
|
145
|
+
// @ts-ignore
|
|
198
146
|
this.builder,
|
|
147
|
+
// @ts-ignore
|
|
199
148
|
this.client,
|
|
149
|
+
// @ts-ignore
|
|
200
150
|
this.bindingsHolder
|
|
201
151
|
);
|
|
202
152
|
if (isRaw)
|
|
@@ -235,54 +185,6 @@ var IBMiQueryCompiler = class extends QueryCompiler {
|
|
|
235
185
|
values
|
|
236
186
|
};
|
|
237
187
|
}
|
|
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
188
|
};
|
|
287
189
|
var ibmi_querycompiler_default = IBMiQueryCompiler;
|
|
288
190
|
|
|
@@ -335,13 +237,13 @@ var DB2Client = class extends knex.Client {
|
|
|
335
237
|
async acquireRawConnection() {
|
|
336
238
|
this.printDebug("acquiring raw connection");
|
|
337
239
|
const connectionConfig = this.config.connection;
|
|
338
|
-
|
|
240
|
+
console3.log(this._getConnectionString(connectionConfig));
|
|
339
241
|
return await this.driver.pool(this._getConnectionString(connectionConfig));
|
|
340
242
|
}
|
|
341
243
|
// Used to explicitly close a connection, called internally by the pool manager
|
|
342
244
|
// when a connection times out or the pool is shutdown.
|
|
343
245
|
async destroyRawConnection(connection) {
|
|
344
|
-
|
|
246
|
+
console3.log("destroy connection");
|
|
345
247
|
return await connection.close();
|
|
346
248
|
}
|
|
347
249
|
_getConnectionString(connectionConfig) {
|
|
@@ -377,14 +279,14 @@ var DB2Client = class extends knex.Client {
|
|
|
377
279
|
const result = await statement.execute();
|
|
378
280
|
obj.response = { rows: [result.count], rowCount: result.count };
|
|
379
281
|
} catch (err) {
|
|
380
|
-
|
|
282
|
+
console3.error(err);
|
|
381
283
|
throw new Error(err);
|
|
382
284
|
}
|
|
383
285
|
}
|
|
384
|
-
|
|
286
|
+
console3.log({ obj });
|
|
385
287
|
return obj;
|
|
386
288
|
}
|
|
387
|
-
transaction() {
|
|
289
|
+
transaction(container, config, outerTx) {
|
|
388
290
|
return new ibmi_transaction_default(this, ...arguments);
|
|
389
291
|
}
|
|
390
292
|
schemaCompiler() {
|
package/package.json
CHANGED
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";
|
|
@@ -139,7 +139,7 @@ class DB2Client extends knex.Client {
|
|
|
139
139
|
return obj;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
transaction() {
|
|
142
|
+
transaction(container: any, config: any, outerTx: any): Knex.Transaction {
|
|
143
143
|
// @ts-ignore
|
|
144
144
|
return new Transaction(this, ...arguments);
|
|
145
145
|
}
|
|
@@ -1,33 +1,25 @@
|
|
|
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
|
-
|
|
8
|
-
rawOrFn as rawOrFn_,
|
|
9
|
-
} from "knex/lib/formatter/wrappingFormatter";
|
|
10
|
-
import { format, parseISO } from "date-fns";
|
|
11
|
-
import * as console from "console";
|
|
3
|
+
import { rawOrFn as rawOrFn_ } from "knex/lib/formatter/wrappingFormatter";
|
|
4
|
+
import { format } from "date-fns";
|
|
12
5
|
|
|
13
6
|
class IBMiQueryCompiler extends QueryCompiler {
|
|
14
7
|
_prepInsert(data) {
|
|
15
8
|
if (isObject(data)) {
|
|
16
|
-
console.log("data is object", data);
|
|
17
9
|
if (data.hasOwnProperty("migration_time")) {
|
|
18
|
-
console.log("data has migration_time", data.migration_time);
|
|
19
10
|
const parsed = new Date(data.migration_time);
|
|
20
|
-
console.log(parsed);
|
|
21
11
|
data.migration_time = format(parsed, "yyyy-MM-dd HH:mm:ss");
|
|
22
|
-
console.log(data.migration_time);
|
|
23
12
|
}
|
|
24
|
-
console.log("data date after change", data);
|
|
25
13
|
}
|
|
14
|
+
|
|
26
15
|
const isRaw = rawOrFn_(
|
|
27
16
|
data,
|
|
28
17
|
undefined,
|
|
18
|
+
// @ts-ignore
|
|
29
19
|
this.builder,
|
|
20
|
+
// @ts-ignore
|
|
30
21
|
this.client,
|
|
22
|
+
// @ts-ignore
|
|
31
23
|
this.bindingsHolder,
|
|
32
24
|
);
|
|
33
25
|
if (isRaw) return isRaw;
|
|
@@ -62,71 +54,6 @@ class IBMiQueryCompiler extends QueryCompiler {
|
|
|
62
54
|
values,
|
|
63
55
|
};
|
|
64
56
|
}
|
|
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
57
|
}
|
|
131
58
|
|
|
132
59
|
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
19
|
const bindings = [tableName.toUpperCase()];
|
|
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,59 @@
|
|
|
1
1
|
import TableCompiler from "knex/lib/schema/tablecompiler";
|
|
2
2
|
|
|
3
3
|
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
4
|
createQuery(columns, ifNot, like) {
|
|
58
5
|
let createStatement = ifNot
|
|
6
|
+
// @ts-ignore
|
|
59
7
|
? `if object_id('${this.tableName()}', 'U') is null `
|
|
60
8
|
: "";
|
|
61
9
|
|
|
62
10
|
if (like) {
|
|
63
11
|
// This query copy only columns and not all indexes and keys like other databases.
|
|
12
|
+
// @ts-ignore
|
|
64
13
|
createStatement += `SELECT * INTO ${this.tableName()} FROM ${this.tableNameLike()} WHERE 0=1`;
|
|
65
14
|
} else {
|
|
66
15
|
createStatement +=
|
|
67
16
|
"CREATE TABLE " +
|
|
17
|
+
// @ts-ignore
|
|
68
18
|
this.tableName() +
|
|
19
|
+
// @ts-ignore
|
|
69
20
|
(this._formatting ? " (\n " : " (") +
|
|
21
|
+
// @ts-ignore
|
|
70
22
|
columns.sql.join(this._formatting ? ",\n " : ", ") +
|
|
23
|
+
// @ts-ignore
|
|
71
24
|
this._addChecks() +
|
|
72
25
|
")";
|
|
73
26
|
}
|
|
74
27
|
|
|
28
|
+
// @ts-ignore
|
|
75
29
|
this.pushQuery(createStatement);
|
|
76
30
|
|
|
31
|
+
// @ts-ignore
|
|
77
32
|
if (this.single.comment) {
|
|
33
|
+
// @ts-ignore
|
|
78
34
|
this.comment(this.single.comment);
|
|
79
35
|
}
|
|
80
36
|
if (like) {
|
|
37
|
+
// @ts-ignore
|
|
81
38
|
this.addColumns(columns, this.addColumnsPrefix);
|
|
82
39
|
}
|
|
83
40
|
}
|
|
84
41
|
|
|
85
42
|
// All of the columns to "add" for the query
|
|
86
43
|
addColumns(columns, prefix) {
|
|
44
|
+
// @ts-ignore
|
|
87
45
|
prefix = prefix || this.addColumnsPrefix;
|
|
88
46
|
|
|
89
47
|
if (columns.sql.length > 0) {
|
|
90
48
|
const columnSql = columns.sql.map((column) => {
|
|
91
49
|
return prefix + column;
|
|
92
50
|
});
|
|
51
|
+
// @ts-ignore
|
|
93
52
|
this.pushQuery({
|
|
94
53
|
sql:
|
|
54
|
+
// @ts-ignore
|
|
95
55
|
(this.lowerCase ? 'alter table ' : 'ALTER TABLE ') +
|
|
56
|
+
// @ts-ignore
|
|
96
57
|
this.tableName() +
|
|
97
58
|
' ' +
|
|
98
59
|
columnSql.join(' '),
|