pwi-plata-type 0.4.166 → 0.4.167
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/__BUILD__/libs/sql.js +4 -1
- package/__BUILD__/libs/sql.js.map +1 -1
- package/package.json +53 -53
- package/src/@types/build.d.ts +26 -26
- package/src/@types/cluster.actions.d.ts +27 -27
- package/src/@types/cluster.d.ts +55 -55
- package/src/@types/create-cli.d.ts +8 -8
- package/src/@types/exported.d.ts +31 -31
- package/src/@types/fs.d.ts +6 -6
- package/src/@types/global.d.ts +113 -113
- package/src/@types/knex.d.ts +13 -13
- package/src/@types/model.d.ts +143 -143
- package/src/@types/router.d.ts +107 -107
- package/src/@types/sql.d.ts +75 -75
- package/src/@types/swagger.d.ts +22 -22
- package/src/bin/extras/create-api-cli.ts +218 -218
- package/src/bin/extras/create-cluster-cli.ts +160 -160
- package/src/bin/extras/create-lib-cli.ts +84 -84
- package/src/bin/extras/plata-create-tools.ts +97 -97
- package/src/bin/plata-api.ts +189 -189
- package/src/bin/plata-build.ts +17 -17
- package/src/bin/plata-cluster.ts +42 -42
- package/src/bin/plata-cmd.ts +18 -18
- package/src/bin/plata-create.ts +49 -49
- package/src/bin/plata-runtime.ts +131 -131
- package/src/bin/plata-swagger.ts +99 -99
- package/src/bin/runtime/_setupRuntime.ts +48 -48
- package/src/bin/runtime/_types.d.ts +7 -7
- package/src/bin/runtime/class.ts +20 -20
- package/src/bin/runtime/dirs.ts +25 -25
- package/src/bin/runtime/effect.ts +60 -60
- package/src/bin/runtime/fs.ts +10 -10
- package/src/bin/runtime/promises.ts +18 -18
- package/src/bin/runtime/require.ts +113 -113
- package/src/bin/runtime/sql.ts +12 -12
- package/src/bin/runtime/switch.ts +60 -60
- package/src/index.ts +19 -19
- package/src/libs/axios.ts +51 -51
- package/src/libs/build.ts +162 -162
- package/src/libs/cluster/cluster-controller.ts +93 -93
- package/src/libs/cluster.ts +330 -330
- package/src/libs/custom.ts +15 -15
- package/src/libs/env.ts +10 -10
- package/src/libs/fs.ts +399 -399
- package/src/libs/hot-reload.ts +63 -63
- package/src/libs/models/index.ts +4 -4
- package/src/libs/models/model-template-combine.ts +93 -93
- package/src/libs/models/model-template-env.ts +58 -58
- package/src/libs/models/model-template-union.ts +83 -83
- package/src/libs/models/model-template.ts +107 -107
- package/src/libs/models/model-validations.ts +443 -443
- package/src/libs/models/tools.ts +194 -194
- package/src/libs/router.ts +185 -185
- package/src/libs/sql.ts +792 -788
- package/src/libs/swagger.ts +81 -81
- package/src/libs/tools.ts +240 -240
- package/src/scripts/post-install/api.ts +32 -32
- package/src/scripts/post-install/cluster.ts +28 -28
- package/src/scripts/post-install/lib.ts +25 -25
- package/src/scripts/post-install.ts +64 -64
- package/src/scripts/pre-test.ts +33 -33
- package/src/tests/assets/sql/example.sql +76 -76
- package/src/tests/config.test.ts +12 -12
- package/src/tests/effect.test.ts +62 -62
- package/src/tests/model.env.test.ts +66 -66
- package/src/tests/model.test.ts +141 -141
- package/src/tests/model.union.test.ts +160 -160
- package/src/tests/router.test.ts +44 -44
- package/src/tests/sql.test.ts +502 -502
- package/src/tests/switch.test.ts +76 -76
- package/templates/create-cli/class.ts +13 -13
- package/templates/create-cli/cluster.ts +14 -14
- package/templates/create-cli/cmd.ts +3 -3
- package/templates/create-cli/config.ts +2 -2
- package/templates/create-cli/lib.ts +3 -3
- package/templates/create-cli/model.ts +14 -14
- package/templates/create-cli/route.ts +8 -8
- package/templates/create-cli/task.ts +13 -13
- package/templates/postinstall/api/.vscode/launch.json +20 -20
- package/templates/postinstall/api/Dockerfile +24 -24
- package/templates/postinstall/api/configs/env.ts +2 -2
- package/templates/postinstall/api/envs/debug.env +15 -15
- package/templates/postinstall/api/envs/homolog.env +15 -15
- package/templates/postinstall/api/envs/prod.env +15 -15
- package/templates/postinstall/api/tsconfig.json +24 -24
- package/templates/postinstall/cluster/.vscode/launch.json +20 -20
- package/templates/postinstall/cluster/Dockerfile +24 -24
- package/templates/postinstall/cluster/configs/env.ts +2 -2
- package/templates/postinstall/cluster/envs/debug.env +10 -10
- package/templates/postinstall/cluster/envs/homolog.env +10 -10
- package/templates/postinstall/cluster/envs/prod.env +10 -10
- package/templates/postinstall/cluster/tsconfig.json +24 -24
- package/templates/postinstall/lib/postinstall-tools.mjs +111 -111
- package/templates/postinstall/lib/postinstall.js +33 -33
- package/templates/postinstall/lib/tsconfig.json +22 -22
- package/templates/swagger-cli/header.json +21 -21
- package/templates/swagger-cli/route/body.json +14 -14
- package/templates/swagger-cli/route/header.json +18 -18
- package/templates/swagger-cli/route/response.json +53 -53
- package/tsconfig.json +28 -28
package/src/libs/sql.ts
CHANGED
|
@@ -1,789 +1,793 @@
|
|
|
1
|
-
import knex, { Knex } from "knex"
|
|
2
|
-
import { ModelTemplate } from "./models"
|
|
3
|
-
import schemaInspector from 'knex-schema-inspector';
|
|
4
|
-
import { randomUUID } from "node:crypto"
|
|
5
|
-
|
|
6
|
-
export namespace Internals {
|
|
7
|
-
export function context<T extends {} | undefined>(c: T): T extends undefined ? void : T {
|
|
8
|
-
const context = this.queryContext() ?? Object.create(null)
|
|
9
|
-
|
|
10
|
-
if (context._userContext === undefined) {
|
|
11
|
-
context._userContext = Object.create(null)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (c === undefined) {
|
|
15
|
-
return context._userContext
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
context._userContext = c
|
|
19
|
-
|
|
20
|
-
return this.queryContext(context)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function includeOne(table: string, type: Sql.Joins,s: Knex.JoinCallback) {
|
|
24
|
-
const t: Knex.QueryBuilder = this
|
|
25
|
-
const context = t.queryContext() ?? Object.create(null)
|
|
26
|
-
|
|
27
|
-
if (context._joins === undefined) {
|
|
28
|
-
context._joins = []
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
context._joins.push(table)
|
|
32
|
-
|
|
33
|
-
const q = t.queryContext(context)
|
|
34
|
-
|
|
35
|
-
switch(type) {
|
|
36
|
-
case 'CROSS JOIN':
|
|
37
|
-
return q.crossJoin(table, s)
|
|
38
|
-
break
|
|
39
|
-
case 'FULL OUTER JOIN':
|
|
40
|
-
return q.fullOuterJoin(table, s)
|
|
41
|
-
break
|
|
42
|
-
case 'INNER JOIN':
|
|
43
|
-
return q.innerJoin(table, s)
|
|
44
|
-
break
|
|
45
|
-
case 'JOIN':
|
|
46
|
-
return q.join(table, s)
|
|
47
|
-
break
|
|
48
|
-
case 'LEFT JOIN':
|
|
49
|
-
return q.leftJoin(table, s)
|
|
50
|
-
break
|
|
51
|
-
case 'LEFT OUTER JOIN':
|
|
52
|
-
return q.leftOuterJoin(table, s)
|
|
53
|
-
break
|
|
54
|
-
case 'OUTER JOIN':
|
|
55
|
-
return q.outerJoin(table, s)
|
|
56
|
-
break
|
|
57
|
-
case 'RIGHT JOIN':
|
|
58
|
-
return q.rightJoin(table, s)
|
|
59
|
-
break
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function getConnTable(this: Knex.QueryBuilder, table: string, trxName?: string) {
|
|
64
|
-
let conn = this.table(table)
|
|
65
|
-
|
|
66
|
-
if (trxName !== undefined && conn.comment !== undefined) {
|
|
67
|
-
conn = conn.comment(`TRX: ${trxName}`)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return conn
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export class Driver<InTransaction extends boolean> {
|
|
75
|
-
public readonly config: Knex.Config
|
|
76
|
-
public readonly inTransaction: InTransaction
|
|
77
|
-
public readonly conn: InTransaction extends true ? Knex.Transaction : Knex
|
|
78
|
-
public readonly trxConn: InTransaction extends true ? Knex.Transaction : Knex
|
|
79
|
-
public readonly cacheTable: Map<string, Sql.CacheTable>
|
|
80
|
-
public readonly logQuerys: boolean
|
|
81
|
-
public readonly trxName: string | undefined
|
|
82
|
-
|
|
83
|
-
constructor(config: Knex.Config, inTransaction: InTransaction, trx?: Knex.Transaction, cacheTable?: Map<string, Sql.CacheTable>) {
|
|
84
|
-
this.inTransaction = inTransaction
|
|
85
|
-
this.config = config
|
|
86
|
-
|
|
87
|
-
this.logQuerys = Plata.config.ENV === 'debug' || Plata.config._PLATA_SQL_SHOWQUERY === '1'
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (!this.inTransaction) {
|
|
91
|
-
if (config.pool === undefined)
|
|
92
|
-
config.pool = {
|
|
93
|
-
min: 1,
|
|
94
|
-
max: 1
|
|
95
|
-
}
|
|
96
|
-
;
|
|
97
|
-
|
|
98
|
-
if (!Plata._knexExtended) {
|
|
99
|
-
knex.QueryBuilder.extend('context', Internals.context)
|
|
100
|
-
knex.QueryBuilder.extend('includeOne', Internals.includeOne)
|
|
101
|
-
knex.QueryBuilder.extend('getConnTable', Internals.getConnTable)
|
|
102
|
-
|
|
103
|
-
Plata._knexExtended = true
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const trxPool = {
|
|
107
|
-
min: 1,
|
|
108
|
-
max: 1
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (Plata.config.__PLATA_SQL_TRX_MIN_POOL) {
|
|
112
|
-
trxPool.min = +Plata.config.__PLATA_SQL_TRX_MIN_POOL
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (Plata.config.__PLATA_SQL_TRX_MAX_POOL) {
|
|
116
|
-
trxPool.max = +Plata.config.__PLATA_SQL_TRX_MAX_POOL
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
this.conn = knex(config) as any
|
|
120
|
-
this.trxConn = knex({
|
|
121
|
-
...config,
|
|
122
|
-
pool: trxPool
|
|
123
|
-
}) as any
|
|
124
|
-
} else {
|
|
125
|
-
this.conn = trx as any
|
|
126
|
-
this.trxConn = trx as any
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
this.trxName = this.conn?.userParams?.trxName
|
|
130
|
-
if (this.logQuerys) {
|
|
131
|
-
this.conn.on('query', (...args) => console.log(...args))
|
|
132
|
-
this.conn.on('query-error', (...args) => console.error(...args))
|
|
133
|
-
}
|
|
134
|
-
this.cacheTable = cacheTable ?? new Map()
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
public
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
err
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
return
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
case '
|
|
457
|
-
return 0
|
|
458
|
-
case '
|
|
459
|
-
return
|
|
460
|
-
case '
|
|
461
|
-
return
|
|
462
|
-
case '
|
|
463
|
-
return
|
|
464
|
-
case '
|
|
465
|
-
return
|
|
466
|
-
case '
|
|
467
|
-
return
|
|
468
|
-
case '
|
|
469
|
-
return 0
|
|
470
|
-
case '
|
|
471
|
-
return
|
|
472
|
-
case '
|
|
473
|
-
return
|
|
474
|
-
case '
|
|
475
|
-
return
|
|
476
|
-
case '
|
|
477
|
-
return
|
|
478
|
-
case '
|
|
479
|
-
return 0
|
|
480
|
-
case '
|
|
481
|
-
return
|
|
482
|
-
case '
|
|
483
|
-
return
|
|
484
|
-
case '
|
|
485
|
-
return
|
|
486
|
-
case '
|
|
487
|
-
return null
|
|
488
|
-
case '
|
|
489
|
-
return
|
|
490
|
-
case '
|
|
491
|
-
return
|
|
492
|
-
case '
|
|
493
|
-
return ''
|
|
494
|
-
case '
|
|
495
|
-
return
|
|
496
|
-
case '
|
|
497
|
-
return
|
|
498
|
-
|
|
499
|
-
return ''
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
this.
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
if (Array.isArray(template[key]
|
|
597
|
-
continue
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
if (
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
continue
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
if (Array.isArray(template[key]
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
return
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
stream.on('
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
})
|
|
672
|
-
|
|
673
|
-
stream.on('
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (
|
|
729
|
-
return
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
1
|
+
import knex, { Knex } from "knex"
|
|
2
|
+
import { ModelTemplate } from "./models"
|
|
3
|
+
import schemaInspector from 'knex-schema-inspector';
|
|
4
|
+
import { randomUUID } from "node:crypto"
|
|
5
|
+
|
|
6
|
+
export namespace Internals {
|
|
7
|
+
export function context<T extends {} | undefined>(c: T): T extends undefined ? void : T {
|
|
8
|
+
const context = this.queryContext() ?? Object.create(null)
|
|
9
|
+
|
|
10
|
+
if (context._userContext === undefined) {
|
|
11
|
+
context._userContext = Object.create(null)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (c === undefined) {
|
|
15
|
+
return context._userContext
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
context._userContext = c
|
|
19
|
+
|
|
20
|
+
return this.queryContext(context)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function includeOne(table: string, type: Sql.Joins,s: Knex.JoinCallback) {
|
|
24
|
+
const t: Knex.QueryBuilder = this
|
|
25
|
+
const context = t.queryContext() ?? Object.create(null)
|
|
26
|
+
|
|
27
|
+
if (context._joins === undefined) {
|
|
28
|
+
context._joins = []
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
context._joins.push(table)
|
|
32
|
+
|
|
33
|
+
const q = t.queryContext(context)
|
|
34
|
+
|
|
35
|
+
switch(type) {
|
|
36
|
+
case 'CROSS JOIN':
|
|
37
|
+
return q.crossJoin(table, s)
|
|
38
|
+
break
|
|
39
|
+
case 'FULL OUTER JOIN':
|
|
40
|
+
return q.fullOuterJoin(table, s)
|
|
41
|
+
break
|
|
42
|
+
case 'INNER JOIN':
|
|
43
|
+
return q.innerJoin(table, s)
|
|
44
|
+
break
|
|
45
|
+
case 'JOIN':
|
|
46
|
+
return q.join(table, s)
|
|
47
|
+
break
|
|
48
|
+
case 'LEFT JOIN':
|
|
49
|
+
return q.leftJoin(table, s)
|
|
50
|
+
break
|
|
51
|
+
case 'LEFT OUTER JOIN':
|
|
52
|
+
return q.leftOuterJoin(table, s)
|
|
53
|
+
break
|
|
54
|
+
case 'OUTER JOIN':
|
|
55
|
+
return q.outerJoin(table, s)
|
|
56
|
+
break
|
|
57
|
+
case 'RIGHT JOIN':
|
|
58
|
+
return q.rightJoin(table, s)
|
|
59
|
+
break
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function getConnTable(this: Knex.QueryBuilder, table: string, trxName?: string) {
|
|
64
|
+
let conn = this.table(table)
|
|
65
|
+
|
|
66
|
+
if (trxName !== undefined && conn.comment !== undefined) {
|
|
67
|
+
conn = conn.comment(`TRX: ${trxName}`)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return conn
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export class Driver<InTransaction extends boolean> {
|
|
75
|
+
public readonly config: Knex.Config
|
|
76
|
+
public readonly inTransaction: InTransaction
|
|
77
|
+
public readonly conn: InTransaction extends true ? Knex.Transaction : Knex
|
|
78
|
+
public readonly trxConn: InTransaction extends true ? Knex.Transaction : Knex
|
|
79
|
+
public readonly cacheTable: Map<string, Sql.CacheTable>
|
|
80
|
+
public readonly logQuerys: boolean
|
|
81
|
+
public readonly trxName: string | undefined
|
|
82
|
+
|
|
83
|
+
constructor(config: Knex.Config, inTransaction: InTransaction, trx?: Knex.Transaction, cacheTable?: Map<string, Sql.CacheTable>) {
|
|
84
|
+
this.inTransaction = inTransaction
|
|
85
|
+
this.config = config
|
|
86
|
+
|
|
87
|
+
this.logQuerys = Plata.config.ENV === 'debug' || Plata.config._PLATA_SQL_SHOWQUERY === '1'
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if (!this.inTransaction) {
|
|
91
|
+
if (config.pool === undefined)
|
|
92
|
+
config.pool = {
|
|
93
|
+
min: 1,
|
|
94
|
+
max: 1
|
|
95
|
+
}
|
|
96
|
+
;
|
|
97
|
+
|
|
98
|
+
if (!Plata._knexExtended) {
|
|
99
|
+
knex.QueryBuilder.extend('context', Internals.context)
|
|
100
|
+
knex.QueryBuilder.extend('includeOne', Internals.includeOne)
|
|
101
|
+
knex.QueryBuilder.extend('getConnTable', Internals.getConnTable)
|
|
102
|
+
|
|
103
|
+
Plata._knexExtended = true
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const trxPool = {
|
|
107
|
+
min: 1,
|
|
108
|
+
max: 1
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (Plata.config.__PLATA_SQL_TRX_MIN_POOL) {
|
|
112
|
+
trxPool.min = +Plata.config.__PLATA_SQL_TRX_MIN_POOL
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (Plata.config.__PLATA_SQL_TRX_MAX_POOL) {
|
|
116
|
+
trxPool.max = +Plata.config.__PLATA_SQL_TRX_MAX_POOL
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.conn = knex(config) as any
|
|
120
|
+
this.trxConn = knex({
|
|
121
|
+
...config,
|
|
122
|
+
pool: trxPool
|
|
123
|
+
}) as any
|
|
124
|
+
} else {
|
|
125
|
+
this.conn = trx as any
|
|
126
|
+
this.trxConn = trx as any
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this.trxName = this.conn?.userParams?.trxName
|
|
130
|
+
if (this.logQuerys) {
|
|
131
|
+
this.conn.on('query', (...args) => console.log(...args))
|
|
132
|
+
this.conn.on('query-error', (...args) => console.error(...args))
|
|
133
|
+
}
|
|
134
|
+
this.cacheTable = cacheTable ?? new Map()
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public async onOpenTrx(trx: Driver<true>): PlataPromise<Driver<true>> {
|
|
138
|
+
return trx
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public runRawWithComment(query: { sql: string, bindings: readonly any[] }) {
|
|
142
|
+
if (this.trxName === undefined) {
|
|
143
|
+
return this.conn.raw(query.sql, query.bindings)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return this.conn.raw(`/*TRX: ${this.trxName}*/${query.sql}`, query.bindings)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public select<T extends Model.Template, C extends Model.Converters<T>>(table: string, model: ModelTemplate<T, C>) {
|
|
150
|
+
return {
|
|
151
|
+
build: (builder: Sql.Builder<T>) =>
|
|
152
|
+
new Query(
|
|
153
|
+
builder(this.conn.queryBuilder().getConnTable(table, this.trxName)),
|
|
154
|
+
model,
|
|
155
|
+
table,
|
|
156
|
+
)
|
|
157
|
+
,
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public async insert<T extends Model.Template, C extends Model.Converters<T>>(table: string, model: ModelTemplate<T, C>, values: Model.ParcialTemplateType<T>[], options?: Sql.InsertOptions): PlataPromise<Model.ExtractTemplateType<T>[]> {
|
|
162
|
+
if (this.config.client === 'mssql') {
|
|
163
|
+
const sql = this.conn.queryBuilder().getConnTable(table, this.trxName).insert(
|
|
164
|
+
values,
|
|
165
|
+
'*',
|
|
166
|
+
{
|
|
167
|
+
includeTriggerModifications: options?.ignoreTrigger === undefined
|
|
168
|
+
}
|
|
169
|
+
).toSQL()
|
|
170
|
+
|
|
171
|
+
return this.runRawWithComment(sql).then(
|
|
172
|
+
r => r,
|
|
173
|
+
err => Plata.BuildPlataError({
|
|
174
|
+
errorID: 'PLSQL001',
|
|
175
|
+
msg: 'Unexpected error while inserting',
|
|
176
|
+
error:{
|
|
177
|
+
message: err?.toString(),
|
|
178
|
+
stack: new Error().stack
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// TODO ver a necessidade de comentario de trx nas outras conexões
|
|
185
|
+
|
|
186
|
+
if (options?.ignoreTrigger === true)
|
|
187
|
+
return this.conn.queryBuilder().getConnTable(table, this.trxName).insert(
|
|
188
|
+
values,
|
|
189
|
+
'*',
|
|
190
|
+
{
|
|
191
|
+
includeTriggerModifications: options?.ignoreTrigger
|
|
192
|
+
}
|
|
193
|
+
).then(
|
|
194
|
+
r => r,
|
|
195
|
+
err => Plata.BuildPlataError({
|
|
196
|
+
errorID: 'PLSQLINS001',
|
|
197
|
+
msg: 'Unexpected error while inserting',
|
|
198
|
+
error: {
|
|
199
|
+
message: err?.toString(),
|
|
200
|
+
stack: err?.stack ?? new Error().stack
|
|
201
|
+
},
|
|
202
|
+
})
|
|
203
|
+
)
|
|
204
|
+
;
|
|
205
|
+
|
|
206
|
+
const key: PlataResult<string> = await schemaInspector(this.conn).primary(table).then(
|
|
207
|
+
r => {
|
|
208
|
+
if (r === null) {
|
|
209
|
+
return Plata.BuildPlataError({
|
|
210
|
+
errorID: 'PLSQL007',
|
|
211
|
+
msg: 'Tabela não tem chave primária'
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return r
|
|
216
|
+
},
|
|
217
|
+
err => Plata.BuildPlataError({
|
|
218
|
+
errorID: 'PLSQL006',
|
|
219
|
+
msg: 'Erro ao consultar a chave primária da tabela',
|
|
220
|
+
error: {
|
|
221
|
+
message: err?.toString(),
|
|
222
|
+
stack: err?.stack ?? new Error().stack
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
if (key.errorID !== undefined) {
|
|
228
|
+
return key
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return this.transaction(
|
|
232
|
+
async (trx) => {
|
|
233
|
+
const result: number[] = await trx.conn.queryBuilder().getConnTable(table, `${trx.trxName}<->${this.trxName}`).insert(
|
|
234
|
+
values,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
return trx.conn.select('*').from(table).whereIn(key, result)
|
|
238
|
+
}
|
|
239
|
+
)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public update<T extends Model.Template, C extends Model.Converters<T>>(table: string, model: ModelTemplate<T, C>) {
|
|
243
|
+
return {
|
|
244
|
+
build: async (s: Sql.Builder<T>, set: Model.ParcialTemplateType<T>): PlataPromise<true> => {
|
|
245
|
+
const sql = s(this.conn.queryBuilder().getConnTable(table, this.trxName)).update(set as any).toSQL()
|
|
246
|
+
|
|
247
|
+
return this.runRawWithComment(sql).then(
|
|
248
|
+
() => true,
|
|
249
|
+
err => Plata.BuildPlataError({
|
|
250
|
+
errorID: 'PLSQL002',
|
|
251
|
+
msg: 'Unexpected error while update',
|
|
252
|
+
error: {
|
|
253
|
+
message: err?.toString(),
|
|
254
|
+
stack: err?.stack ?? new Error().stack
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
)
|
|
258
|
+
},
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
public log(text: string, ...extras: any[]) {
|
|
263
|
+
if (this.logQuerys === true) {
|
|
264
|
+
console.log(text, ...extras)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** @deprecated */
|
|
269
|
+
public trasation<T = any>(transaction: Sql.TransactionFunction<Driver<true>, T>, config?: Knex.TransactionConfig) {
|
|
270
|
+
return this.conn.transaction(async trx => {
|
|
271
|
+
const transactionDriver = new Driver(this.config, true, trx, this.cacheTable)
|
|
272
|
+
|
|
273
|
+
const result = await transaction(transactionDriver)
|
|
274
|
+
|
|
275
|
+
return result
|
|
276
|
+
}, config).then(
|
|
277
|
+
r => r,
|
|
278
|
+
err => {
|
|
279
|
+
if (!err) {
|
|
280
|
+
err = Object.create(null)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
err.originalError = undefined
|
|
284
|
+
|
|
285
|
+
return Plata.BuildPlataError({
|
|
286
|
+
errorID: 'PLSQL003',
|
|
287
|
+
msg: 'Unexpected error in transation',
|
|
288
|
+
error: {
|
|
289
|
+
message: err?.toString(),
|
|
290
|
+
stack: err?.stack ?? new Error().stack
|
|
291
|
+
},
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
public async getTransactionDriver(config?: Knex.TransactionConfig): PlataPromise<Driver<true>> {
|
|
298
|
+
const trxName = randomUUID()
|
|
299
|
+
const provider = await this.trxConn.transactionProvider({
|
|
300
|
+
...config,
|
|
301
|
+
doNotRejectOnRollback: true,
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
this.log(`[PLATA-SQL] [TRX-${trxName}] - Inciando provider`)
|
|
305
|
+
|
|
306
|
+
// Inicia a transação
|
|
307
|
+
const trx: PlataResult<Knex.Transaction> = await provider().catch(
|
|
308
|
+
e => ({
|
|
309
|
+
errorID: 'PLSQLGETTRX001',
|
|
310
|
+
msg: 'Erro ao iniciar a transação',
|
|
311
|
+
error: {
|
|
312
|
+
message: e?.toString(),
|
|
313
|
+
stack: e?.stack ?? new Error().stack
|
|
314
|
+
}
|
|
315
|
+
})
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
if (trx.errorID !== undefined) {
|
|
319
|
+
this.log(`[PLATA-SQL] [TRX-${trxName}] - Conexão não foi aberta`)
|
|
320
|
+
return trx
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
trx.userParams.trxName = trxName
|
|
324
|
+
|
|
325
|
+
this.log(`[PLATA-SQL] [TRX-${trxName}] - Conexão foi aberta`)
|
|
326
|
+
return this.onOpenTrx(new Driver(this.config, true, trx, this.cacheTable))
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
public async transaction<T extends Sql.TransactionReturn>(transaction: Sql.TransactionResultFunction<Driver<true>, T>, config?: Knex.TransactionConfig): PlataPromise<T> {
|
|
330
|
+
const driver = await this.getTransactionDriver(config)
|
|
331
|
+
|
|
332
|
+
if (driver.errorID !== undefined) {
|
|
333
|
+
return driver
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const transPromise = Plata.FastPromise(() => driver.conn.executionPromise.catch((...args) => console.log(...args)))
|
|
337
|
+
|
|
338
|
+
try {
|
|
339
|
+
const resultTransation = await transaction(driver)
|
|
340
|
+
|
|
341
|
+
if (resultTransation.errorID !== undefined) {
|
|
342
|
+
this.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}] - Roollback -> Erro da API na transação`)
|
|
343
|
+
await driver.conn.rollback().catch((...err) => console.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}]`, ...err))
|
|
344
|
+
await transPromise
|
|
345
|
+
this.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}] - Roollback realizado`)
|
|
346
|
+
|
|
347
|
+
return resultTransation
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
this.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}] - Commit -> Realizando Commit`)
|
|
351
|
+
const resultCommit: PlataResult<true> = await driver.conn.commit().then(
|
|
352
|
+
() => true,
|
|
353
|
+
err => ({
|
|
354
|
+
errorID: 'PLSQLTRX003',
|
|
355
|
+
msg: 'Erro inesperado ao realizar o commit',
|
|
356
|
+
error: {
|
|
357
|
+
message: err?.toString(),
|
|
358
|
+
stack: err?.stack ?? new Error().stack
|
|
359
|
+
}
|
|
360
|
+
})
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
if (resultCommit.errorID !== undefined) {
|
|
365
|
+
this.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}] - Rollback -> Erro no commit, realizando Rollback`)
|
|
366
|
+
await driver.conn.rollback().catch((...err) => console.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}]`, ...err))
|
|
367
|
+
await transPromise
|
|
368
|
+
this.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}] - Roollback realizado`)
|
|
369
|
+
return resultCommit
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
await transPromise
|
|
373
|
+
|
|
374
|
+
return resultTransation
|
|
375
|
+
} catch (err) {
|
|
376
|
+
this.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}] - Rollback -> Erro inesperado: `, err)
|
|
377
|
+
await driver.conn.rollback().catch((...err) => console.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}]`, ...err))
|
|
378
|
+
await transPromise
|
|
379
|
+
this.log(`[PLATA-SQL] [TRX-${driver.conn.userParams?.trxName}] - Rollback -> Roollback realizado`)
|
|
380
|
+
|
|
381
|
+
return {
|
|
382
|
+
errorID: 'PLSQLTRX002',
|
|
383
|
+
msg: 'Erro inesperado ao realizar a transação ',
|
|
384
|
+
error: {
|
|
385
|
+
message: err?.toString(),
|
|
386
|
+
stack: err?.stack ?? new Error().stack
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
public async getColumns(table: string): PlataPromise<Record<string | number | symbol, Knex.ColumnInfo>> {
|
|
393
|
+
if (Plata.config._PLATA_SQL_CACHETABLE !== '1')
|
|
394
|
+
return this.getColumsBanco(table)
|
|
395
|
+
;
|
|
396
|
+
|
|
397
|
+
const cache = this.cacheTable.get(table)
|
|
398
|
+
|
|
399
|
+
if (cache === undefined) {
|
|
400
|
+
const result = await this.getColumsBanco(table)
|
|
401
|
+
|
|
402
|
+
if (result.errorID !== undefined) {
|
|
403
|
+
return result
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
this.cacheTable.set(table, {
|
|
407
|
+
coluns: result,
|
|
408
|
+
date: new Date()
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
return result
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const ttl = (+(Plata.config._PLATA_SQL_CACHETABLETIME || 60) || 60) * 60 * 1000
|
|
415
|
+
|
|
416
|
+
if ((new Date().getTime() - cache.date.getTime()) > ttl) {
|
|
417
|
+
const result = await this.getColumsBanco(table)
|
|
418
|
+
|
|
419
|
+
if (result.errorID !== undefined) {
|
|
420
|
+
return result
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
this.cacheTable.set(table, {
|
|
424
|
+
coluns: result,
|
|
425
|
+
date: new Date()
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
return result
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
return cache.coluns
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
public async getColumsBanco(table: string): PlataPromise<Record<string | number | symbol, Knex.ColumnInfo>> {
|
|
435
|
+
return this.conn(table).columnInfo().catch(
|
|
436
|
+
err => Plata.BuildPlataError({
|
|
437
|
+
errorID: 'PLSQL004',
|
|
438
|
+
msg: 'Erro ao consultar a estrutura da tabela',
|
|
439
|
+
error: {
|
|
440
|
+
message: err?.toString(),
|
|
441
|
+
stack: err?.stack ?? new Error().stack
|
|
442
|
+
}
|
|
443
|
+
})
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
private getDefaultValue(type: string, value: any | null): any {
|
|
448
|
+
if (value !== null) {
|
|
449
|
+
return value
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
switch (type) {
|
|
453
|
+
case 'image':
|
|
454
|
+
return ''
|
|
455
|
+
case 'int':
|
|
456
|
+
case 'integer':
|
|
457
|
+
return 0
|
|
458
|
+
case 'datetime2':
|
|
459
|
+
return null
|
|
460
|
+
case 'decimal':
|
|
461
|
+
return 0
|
|
462
|
+
case 'varbinary':
|
|
463
|
+
return ''
|
|
464
|
+
case 'text':
|
|
465
|
+
return ''
|
|
466
|
+
case 'smallint':
|
|
467
|
+
return 0
|
|
468
|
+
case 'datetimeoffset':
|
|
469
|
+
return 0
|
|
470
|
+
case 'varchar':
|
|
471
|
+
return ''
|
|
472
|
+
case 'binary':
|
|
473
|
+
return 0
|
|
474
|
+
case 'datetime':
|
|
475
|
+
return null
|
|
476
|
+
case 'time':
|
|
477
|
+
return null
|
|
478
|
+
case 'numeric':
|
|
479
|
+
return 0
|
|
480
|
+
case 'uniqueidentifier':
|
|
481
|
+
return 0
|
|
482
|
+
case 'tinyint':
|
|
483
|
+
return 0
|
|
484
|
+
case 'nchar':
|
|
485
|
+
return ''
|
|
486
|
+
case 'smalldatetime':
|
|
487
|
+
return null
|
|
488
|
+
case 'float':
|
|
489
|
+
return 0
|
|
490
|
+
case 'date':
|
|
491
|
+
return null
|
|
492
|
+
case 'char':
|
|
493
|
+
return ''
|
|
494
|
+
case 'bigint':
|
|
495
|
+
return 0
|
|
496
|
+
case 'nvarchar':
|
|
497
|
+
return ''
|
|
498
|
+
case 'sysname':
|
|
499
|
+
return ''
|
|
500
|
+
case 'bit':
|
|
501
|
+
return 0
|
|
502
|
+
default:
|
|
503
|
+
return ''
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
public async autoInsert<T extends Model.Template, C extends Model.Converters<T>>(table: string, model: ModelTemplate<T, C>, values: (Model.ParcialTemplateType<T>)[], ignore: StringKeyOfObject<T>[], options?: Sql.InsertOptions): PlataPromise<Model.ExtractTemplateType<T>[]> {
|
|
508
|
+
const columns = await this.getColumns(table)
|
|
509
|
+
|
|
510
|
+
if (columns.errorID !== undefined) {
|
|
511
|
+
return columns
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
const newValues: any[] = []
|
|
515
|
+
|
|
516
|
+
for (let i = 0; i < values.length; i++) {
|
|
517
|
+
const v = Object.create(null)
|
|
518
|
+
|
|
519
|
+
for (const key in values[i]) {
|
|
520
|
+
v[key.toUpperCase()] = values[i][key]
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const insertValues = Object.create(null)
|
|
524
|
+
|
|
525
|
+
for (const key in columns) {
|
|
526
|
+
const n = key.toUpperCase()
|
|
527
|
+
|
|
528
|
+
if (ignore.find(c => c.toString().toUpperCase() === n) !== undefined) {
|
|
529
|
+
continue
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
const value = this.getDefaultValue(
|
|
533
|
+
columns[key].type.toLowerCase(),
|
|
534
|
+
v[n] ?? null
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
if (value === null) {
|
|
538
|
+
continue
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
insertValues[n] = value
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
newValues.push(insertValues)
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const inserted: PlataResult<any[]> = await this.insert(
|
|
548
|
+
table,
|
|
549
|
+
{} as any,
|
|
550
|
+
newValues,
|
|
551
|
+
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
if (inserted.errorID !== undefined) {
|
|
555
|
+
return inserted
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const insertedRows: any[] = []
|
|
559
|
+
|
|
560
|
+
for (let i = 0; i < inserted.length; i++) {
|
|
561
|
+
const item = inserted[i];
|
|
562
|
+
|
|
563
|
+
const insertedRow = Object.create(null)
|
|
564
|
+
|
|
565
|
+
for (const key in item) {
|
|
566
|
+
insertedRow[key.toUpperCase()] = item[key]
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
insertedRows.push(insertedRow)
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return insertedRows
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
export class Query<T extends Model.Template, C extends Model.Converters<T>> {
|
|
577
|
+
public query: Sql.ModelQueryBuilder<T>
|
|
578
|
+
public readonly model: ModelTemplate<T, C>
|
|
579
|
+
public readonly table: string
|
|
580
|
+
public readonly joins: string[]
|
|
581
|
+
|
|
582
|
+
constructor (query: Sql.ModelQueryBuilder<T>, model: ModelTemplate<T, C>, table: string) {
|
|
583
|
+
const context = query.queryContext() ?? Object.create(null)
|
|
584
|
+
|
|
585
|
+
this.joins = context._joins ?? []
|
|
586
|
+
|
|
587
|
+
this.table = table
|
|
588
|
+
this.model = model
|
|
589
|
+
this.query = this._buildSelect(query, this.model.template)
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
private _buildSelect<T extends Model.Template>(query: Sql.ModelQueryBuilder<T>, template: T): Sql.ModelQueryBuilder<T> {
|
|
593
|
+
const cs: string[] = []
|
|
594
|
+
|
|
595
|
+
for (const key in template) {
|
|
596
|
+
if (!Array.isArray(template[key])) {
|
|
597
|
+
continue
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (Array.isArray(template[key][0])) {
|
|
601
|
+
continue
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
if (typeof template[key][0] === 'function') {
|
|
605
|
+
cs.push(`${this.table}.${key} as ${this.table}_${key}`)
|
|
606
|
+
continue
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
if (!this.joins.includes(key)) {
|
|
610
|
+
continue
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
for (const column in template[key][0]) {
|
|
614
|
+
cs.push(`${key}.${column} as ${key}_${column}`)
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
return query.select(...cs)
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
private _buildModel<T extends Model.Template>(row: any): typeof this.model.type {
|
|
622
|
+
const template = this.model.template
|
|
623
|
+
const r: typeof this.model.type = Object.create(null) as any
|
|
624
|
+
|
|
625
|
+
for (const key in template) {
|
|
626
|
+
if (!Array.isArray(template[key])) {
|
|
627
|
+
continue
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
if (Array.isArray(template[key][0])) {
|
|
631
|
+
r[key] = [] as any
|
|
632
|
+
continue
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
if (typeof template[key][0] === 'function') {
|
|
636
|
+
r[key] = row[`${this.table}_${key}`] ?? null
|
|
637
|
+
continue
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (!this.joins.includes(key)) {
|
|
641
|
+
r[key] = [] as any
|
|
642
|
+
continue
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
r[key] = [Object.create(null)] as any
|
|
646
|
+
|
|
647
|
+
for (const column in template[key][0]) {
|
|
648
|
+
r[key][0][column] = row[`${key}_${column}`] ?? null
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
return r
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
public _handleStream<Y>(handler: Sql.StreamHandler): PlataPromise<Y> {
|
|
656
|
+
return new Promise(resolve => {
|
|
657
|
+
let shoudContinue = true
|
|
658
|
+
|
|
659
|
+
const stream = this.query.stream()
|
|
660
|
+
|
|
661
|
+
stream.on('close', async () => {
|
|
662
|
+
return resolve(handler.close<Y>())
|
|
663
|
+
})
|
|
664
|
+
|
|
665
|
+
stream.on('data', async row => {
|
|
666
|
+
if (shoudContinue) {
|
|
667
|
+
shoudContinue = await handler.row(this._buildModel(row))
|
|
668
|
+
} else {
|
|
669
|
+
stream.pause()
|
|
670
|
+
}
|
|
671
|
+
})
|
|
672
|
+
|
|
673
|
+
stream.on('pause', () => {
|
|
674
|
+
stream.destroy()
|
|
675
|
+
})
|
|
676
|
+
|
|
677
|
+
stream.on('error', async err => {
|
|
678
|
+
shoudContinue = false
|
|
679
|
+
|
|
680
|
+
if (handler.error !== undefined) await handler.error(err)
|
|
681
|
+
|
|
682
|
+
return resolve({
|
|
683
|
+
errorID: 'PLSQLQ001',
|
|
684
|
+
msg: 'Unexpected error in query',
|
|
685
|
+
error: {
|
|
686
|
+
message: err?.toString(),
|
|
687
|
+
stack: err?.stack ?? new Error().stack
|
|
688
|
+
}
|
|
689
|
+
})
|
|
690
|
+
})
|
|
691
|
+
})
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
public async toListAsync(): Sql.ModelList<T> {
|
|
695
|
+
const errors: PlataError[] = []
|
|
696
|
+
const itens: any[] = []
|
|
697
|
+
|
|
698
|
+
const result: PlataResult<boolean[]> = await this.query.then(
|
|
699
|
+
r => {
|
|
700
|
+
const promises: Promise<boolean>[] = []
|
|
701
|
+
|
|
702
|
+
for (let i = 0; i < r.length; i++) {
|
|
703
|
+
promises.push(Plata.FastPromise(async () => {
|
|
704
|
+
const v = await this.model.validate(this._buildModel(r[i]))
|
|
705
|
+
|
|
706
|
+
if (v.errors !== undefined) {
|
|
707
|
+
errors.push(...v.errors)
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
itens.push(v.value)
|
|
711
|
+
|
|
712
|
+
return true
|
|
713
|
+
}))
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
return Promise.all(promises)
|
|
717
|
+
},
|
|
718
|
+
err => Plata.BuildPlataError({
|
|
719
|
+
errorID: 'PLSQLQ005',
|
|
720
|
+
msg: 'Erro ao execultar a query',
|
|
721
|
+
error: {
|
|
722
|
+
message: err?.toString(),
|
|
723
|
+
stack: err?.stack ?? new Error().stack
|
|
724
|
+
}
|
|
725
|
+
})
|
|
726
|
+
)
|
|
727
|
+
|
|
728
|
+
if (result.errorID !== undefined) {
|
|
729
|
+
return result
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
if (errors.length !== 0) {
|
|
733
|
+
return {
|
|
734
|
+
errors,
|
|
735
|
+
itens,
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
return {
|
|
740
|
+
errors: undefined,
|
|
741
|
+
itens,
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
public async eachRowAsync(c: Sql.EachRowCallBack<T>): PlataPromise<boolean> {
|
|
746
|
+
const promises: Promise<void>[] = []
|
|
747
|
+
let shoudContinue = true
|
|
748
|
+
let error: PlataError | undefined = undefined
|
|
749
|
+
|
|
750
|
+
return this._handleStream<MaybePlataError>({
|
|
751
|
+
row: async row => {
|
|
752
|
+
promises.push(Plata.FastPromise(() => this.model.validate(row))
|
|
753
|
+
.then(
|
|
754
|
+
lineResult => {
|
|
755
|
+
c(lineResult).then(r => {
|
|
756
|
+
if (r.errorID !== undefined) {
|
|
757
|
+
shoudContinue = false
|
|
758
|
+
error = r
|
|
759
|
+
return
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
shoudContinue = shoudContinue ? r : shoudContinue
|
|
763
|
+
})
|
|
764
|
+
}
|
|
765
|
+
)
|
|
766
|
+
.catch(err => {
|
|
767
|
+
shoudContinue = false
|
|
768
|
+
error = {
|
|
769
|
+
errorID: 'PLSQLQ003',
|
|
770
|
+
msg: 'Unexpected error in callback',
|
|
771
|
+
error: {
|
|
772
|
+
message: err?.toString(),
|
|
773
|
+
stack: err?.stack ?? new Error().stack
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
})
|
|
777
|
+
)
|
|
778
|
+
|
|
779
|
+
return shoudContinue
|
|
780
|
+
},
|
|
781
|
+
close: async (): PlataPromise<boolean> => {
|
|
782
|
+
return Promise.all(promises).then(
|
|
783
|
+
() => error ?? true,
|
|
784
|
+
err => Plata.BuildPlataError({
|
|
785
|
+
errorID: 'PLSQLQ004',
|
|
786
|
+
msg: 'Unexpected Error in select',
|
|
787
|
+
error: err
|
|
788
|
+
})
|
|
789
|
+
)
|
|
790
|
+
}
|
|
791
|
+
})
|
|
792
|
+
}
|
|
789
793
|
}
|