baja-lite 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +920 -1
- package/boot-remote.js +0 -3
- package/boot.js +0 -3
- package/error.d.ts +27 -0
- package/error.js +42 -0
- package/math.js +2 -2
- package/package.json +1 -1
- package/snowflake.js +13 -3
- package/sql.d.ts +5 -0
- package/sql.js +124 -78
- package/string.d.ts +6 -1
- package/string.js +23 -1
package/sql.js
CHANGED
|
@@ -18,12 +18,12 @@ import pino from 'pino';
|
|
|
18
18
|
import { formatDialect, mysql, postgresql, sqlite } from 'sql-formatter';
|
|
19
19
|
import tslib from 'tslib';
|
|
20
20
|
import { convert } from './convert-xml.js';
|
|
21
|
-
import { Throw } from './error.js';
|
|
21
|
+
import { DatabaseError, Throw } from './error.js';
|
|
22
22
|
import { excuteSplit, ExcuteSplitMode, sleep } from './fn.js';
|
|
23
23
|
import { add, calc, ten2Any } from './math.js';
|
|
24
24
|
import { C2P, C2P2, P2C } from './object.js';
|
|
25
25
|
import { snowflake } from './snowflake.js';
|
|
26
|
-
import { emptyString } from './string.js';
|
|
26
|
+
import { emptyString, replacePlaceholders } from './string.js';
|
|
27
27
|
const iterate = ite.iterate;
|
|
28
28
|
BigInt.prototype.toJSON = function () { return this.toString(); };
|
|
29
29
|
const BIGINT_EXT_TYPE = 0;
|
|
@@ -80,6 +80,9 @@ export const _EventBus = Symbol('EventBus');
|
|
|
80
80
|
export const _LoggerService = Symbol('LoggerService');
|
|
81
81
|
export const _path = Symbol('path');
|
|
82
82
|
export const _fs = Symbol('fs');
|
|
83
|
+
// 常量定义
|
|
84
|
+
const DEFAULT_KEEPALIVE_INTERVAL = 30000; // 30 秒
|
|
85
|
+
const DEFAULT_MAX_DEAL = 500; // 默认批量处理数量
|
|
83
86
|
// export const logger = pino({
|
|
84
87
|
// name: 'sql',
|
|
85
88
|
// transport: {
|
|
@@ -210,7 +213,7 @@ export var ColumnMode;
|
|
|
210
213
|
})(ColumnMode || (ColumnMode = {}));
|
|
211
214
|
export const SqliteMemory = ':memory:';
|
|
212
215
|
export const _defOption = {
|
|
213
|
-
maxDeal:
|
|
216
|
+
maxDeal: DEFAULT_MAX_DEAL,
|
|
214
217
|
skipUndefined: true,
|
|
215
218
|
skipNull: true,
|
|
216
219
|
skipEmptyString: true
|
|
@@ -228,7 +231,7 @@ class MysqlConnection {
|
|
|
228
231
|
}
|
|
229
232
|
;
|
|
230
233
|
if (sync === SyncMode.Sync) {
|
|
231
|
-
globalThis[_LoggerService].warn('MYSQL not
|
|
234
|
+
globalThis[_LoggerService].warn('MYSQL not supported sync mode');
|
|
232
235
|
return { affectedRows: 0, insertId: 0n };
|
|
233
236
|
}
|
|
234
237
|
;
|
|
@@ -245,12 +248,9 @@ class MysqlConnection {
|
|
|
245
248
|
resolve({ affectedRows: result.affectedRows, insertId: result.insertId });
|
|
246
249
|
}
|
|
247
250
|
catch (error) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
params: ${params}
|
|
252
|
-
`);
|
|
253
|
-
reject(error);
|
|
251
|
+
const dbError = DatabaseError.query('MySQL execute failed', sql, params, error);
|
|
252
|
+
globalThis[_LoggerService].error(dbError.getSafeMessage(), { cause: error });
|
|
253
|
+
reject(dbError);
|
|
254
254
|
}
|
|
255
255
|
});
|
|
256
256
|
}
|
|
@@ -261,7 +261,7 @@ class MysqlConnection {
|
|
|
261
261
|
}
|
|
262
262
|
;
|
|
263
263
|
if (sync === SyncMode.Sync) {
|
|
264
|
-
globalThis[_LoggerService].warn('MYSQL not
|
|
264
|
+
globalThis[_LoggerService].warn('MYSQL not supported sync mode');
|
|
265
265
|
return null;
|
|
266
266
|
}
|
|
267
267
|
;
|
|
@@ -273,12 +273,11 @@ class MysqlConnection {
|
|
|
273
273
|
const [result] = await this[_daoConnection].query(sql, params);
|
|
274
274
|
if (result && result[0]) {
|
|
275
275
|
const r = Object.values(result[0])[0];
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
276
|
+
resolve(r === null ? null : r);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
resolve(null);
|
|
280
280
|
}
|
|
281
|
-
resolve(null);
|
|
282
281
|
}
|
|
283
282
|
catch (error) {
|
|
284
283
|
globalThis[_LoggerService].error(`
|
|
@@ -297,7 +296,7 @@ class MysqlConnection {
|
|
|
297
296
|
}
|
|
298
297
|
;
|
|
299
298
|
if (sync === SyncMode.Sync) {
|
|
300
|
-
globalThis[_LoggerService].warn('MYSQL not
|
|
299
|
+
globalThis[_LoggerService].warn('MYSQL not supported sync mode');
|
|
301
300
|
return null;
|
|
302
301
|
}
|
|
303
302
|
;
|
|
@@ -331,7 +330,7 @@ class MysqlConnection {
|
|
|
331
330
|
}
|
|
332
331
|
;
|
|
333
332
|
if (sync === SyncMode.Sync) {
|
|
334
|
-
globalThis[_LoggerService].warn('MYSQL not
|
|
333
|
+
globalThis[_LoggerService].warn('MYSQL not supported sync mode');
|
|
335
334
|
return [];
|
|
336
335
|
}
|
|
337
336
|
;
|
|
@@ -365,7 +364,7 @@ class MysqlConnection {
|
|
|
365
364
|
}
|
|
366
365
|
;
|
|
367
366
|
if (sync === SyncMode.Sync) {
|
|
368
|
-
globalThis[_LoggerService].warn('MYSQL not
|
|
367
|
+
globalThis[_LoggerService].warn('MYSQL not supported sync mode');
|
|
369
368
|
return [];
|
|
370
369
|
}
|
|
371
370
|
;
|
|
@@ -404,15 +403,20 @@ class MysqlConnection {
|
|
|
404
403
|
_b = _inTransaction;
|
|
405
404
|
export class Mysql {
|
|
406
405
|
constructor(pool) {
|
|
406
|
+
this.isClosing = false;
|
|
407
407
|
this[_daoDB] = pool;
|
|
408
408
|
this.keepAlive();
|
|
409
409
|
}
|
|
410
410
|
async keepAlive() {
|
|
411
|
+
if (this.isClosing)
|
|
412
|
+
return;
|
|
411
413
|
let connection = null;
|
|
412
414
|
try {
|
|
413
415
|
connection = await this.createConnection(SyncMode.Async);
|
|
414
|
-
|
|
415
|
-
|
|
416
|
+
if (connection) {
|
|
417
|
+
const data = await connection.query(SyncMode.Async, 'SELECT 1 FROM DUAL');
|
|
418
|
+
globalThis[_LoggerService].debug?.('keepAlive->', data?.[0]?.[1]);
|
|
419
|
+
}
|
|
416
420
|
}
|
|
417
421
|
catch (error) {
|
|
418
422
|
globalThis[_LoggerService].error('keepAlive error', error);
|
|
@@ -421,12 +425,14 @@ export class Mysql {
|
|
|
421
425
|
if (connection) {
|
|
422
426
|
await connection.release(SyncMode.Async);
|
|
423
427
|
}
|
|
424
|
-
|
|
428
|
+
if (!this.isClosing) {
|
|
429
|
+
this.keepAliveTimer = setTimeout(() => this.keepAlive(), globalThis[_MysqlKeepAliveTime] ?? DEFAULT_KEEPALIVE_INTERVAL);
|
|
430
|
+
}
|
|
425
431
|
}
|
|
426
432
|
}
|
|
427
433
|
createConnection(sync) {
|
|
428
434
|
if (sync === SyncMode.Sync) {
|
|
429
|
-
globalThis[_LoggerService].error('MYSQL not
|
|
435
|
+
globalThis[_LoggerService].error('MYSQL not supported sync mode');
|
|
430
436
|
return null;
|
|
431
437
|
}
|
|
432
438
|
;
|
|
@@ -437,13 +443,15 @@ export class Mysql {
|
|
|
437
443
|
resolve(new MysqlConnection(connection));
|
|
438
444
|
}
|
|
439
445
|
catch (error) {
|
|
440
|
-
|
|
446
|
+
const dbError = DatabaseError.connection('Failed to create MySQL connection', error);
|
|
447
|
+
globalThis[_LoggerService].error(dbError.getSafeMessage(), { cause: error });
|
|
448
|
+
reject(dbError);
|
|
441
449
|
}
|
|
442
450
|
});
|
|
443
451
|
}
|
|
444
452
|
transaction(sync, fn, conn) {
|
|
445
453
|
if (sync === SyncMode.Sync) {
|
|
446
|
-
globalThis[_LoggerService].warn('MYSQL not
|
|
454
|
+
globalThis[_LoggerService].warn('MYSQL not supported sync mode');
|
|
447
455
|
return null;
|
|
448
456
|
}
|
|
449
457
|
;
|
|
@@ -466,18 +474,19 @@ export class Mysql {
|
|
|
466
474
|
if (needCommit) {
|
|
467
475
|
globalThis[_LoggerService].debug?.('commit begin!');
|
|
468
476
|
await conn[_daoConnection].commit();
|
|
469
|
-
conn[_inTransaction] = false;
|
|
470
477
|
globalThis[_LoggerService].debug?.('commit end!');
|
|
471
478
|
}
|
|
472
479
|
resolve(result);
|
|
473
480
|
}
|
|
474
481
|
catch (error) {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
482
|
+
if (needCommit) {
|
|
483
|
+
globalThis[_LoggerService].debug?.('rollback begin!');
|
|
484
|
+
await conn[_daoConnection].rollback();
|
|
485
|
+
globalThis[_LoggerService].debug?.('rollback end!');
|
|
486
|
+
}
|
|
487
|
+
const dbError = error instanceof DatabaseError ? error : DatabaseError.transaction('MySQL transaction failed', error);
|
|
488
|
+
globalThis[_LoggerService].error(dbError.getSafeMessage(), { cause: error });
|
|
489
|
+
reject(dbError);
|
|
481
490
|
}
|
|
482
491
|
finally {
|
|
483
492
|
try {
|
|
@@ -491,15 +500,18 @@ export class Mysql {
|
|
|
491
500
|
}
|
|
492
501
|
}
|
|
493
502
|
catch (error) {
|
|
503
|
+
// 释放连接失败通常不影响业务逻辑,记录日志即可
|
|
504
|
+
globalThis[_LoggerService].warn?.('Failed to release connection in finally block', error);
|
|
494
505
|
}
|
|
495
506
|
}
|
|
496
507
|
});
|
|
497
508
|
}
|
|
498
509
|
close(sync) {
|
|
499
|
-
|
|
500
|
-
|
|
510
|
+
this.isClosing = true;
|
|
511
|
+
if (this.keepAliveTimer) {
|
|
512
|
+
clearTimeout(this.keepAliveTimer);
|
|
501
513
|
}
|
|
502
|
-
;
|
|
514
|
+
return this[_daoDB]?.destroy();
|
|
503
515
|
}
|
|
504
516
|
backup(sync, name) {
|
|
505
517
|
}
|
|
@@ -520,7 +532,7 @@ class PostgresqlConnection {
|
|
|
520
532
|
}
|
|
521
533
|
;
|
|
522
534
|
if (sync === SyncMode.Sync) {
|
|
523
|
-
globalThis[_LoggerService].warn('Postgresql not
|
|
535
|
+
globalThis[_LoggerService].warn('Postgresql not supported sync mode');
|
|
524
536
|
return { affectedRows: 0, insertId: 0n };
|
|
525
537
|
}
|
|
526
538
|
;
|
|
@@ -529,16 +541,15 @@ class PostgresqlConnection {
|
|
|
529
541
|
}
|
|
530
542
|
return new Promise(async (resolve, reject) => {
|
|
531
543
|
try {
|
|
532
|
-
let index = 1;
|
|
533
544
|
const { rowCount } = await this[_daoConnection].query({
|
|
534
|
-
text: sql
|
|
545
|
+
text: replacePlaceholders(sql),
|
|
535
546
|
values: params
|
|
536
547
|
});
|
|
537
548
|
const result = rowCount;
|
|
538
549
|
if (globalThis[_GlobalSqlOption].log === 'trace') {
|
|
539
550
|
globalThis[_LoggerService].verbose?.(result);
|
|
540
551
|
}
|
|
541
|
-
resolve({ affectedRows:
|
|
552
|
+
resolve({ affectedRows: rowCount || 0, insertId: 0n });
|
|
542
553
|
}
|
|
543
554
|
catch (error) {
|
|
544
555
|
globalThis[_LoggerService].error(`
|
|
@@ -557,7 +568,7 @@ class PostgresqlConnection {
|
|
|
557
568
|
}
|
|
558
569
|
;
|
|
559
570
|
if (sync === SyncMode.Sync) {
|
|
560
|
-
globalThis[_LoggerService].warn('Postgresql not
|
|
571
|
+
globalThis[_LoggerService].warn('Postgresql not supported sync mode');
|
|
561
572
|
return null;
|
|
562
573
|
}
|
|
563
574
|
;
|
|
@@ -566,9 +577,8 @@ class PostgresqlConnection {
|
|
|
566
577
|
}
|
|
567
578
|
return new Promise(async (resolve, reject) => {
|
|
568
579
|
try {
|
|
569
|
-
let index = 1;
|
|
570
580
|
const { rows } = await this[_daoConnection].query({
|
|
571
|
-
text: sql
|
|
581
|
+
text: replacePlaceholders(sql),
|
|
572
582
|
values: params
|
|
573
583
|
});
|
|
574
584
|
if (rows && rows[0]) {
|
|
@@ -597,7 +607,7 @@ class PostgresqlConnection {
|
|
|
597
607
|
}
|
|
598
608
|
;
|
|
599
609
|
if (sync === SyncMode.Sync) {
|
|
600
|
-
globalThis[_LoggerService].warn('Postgresql not
|
|
610
|
+
globalThis[_LoggerService].warn('Postgresql not supported sync mode');
|
|
601
611
|
return null;
|
|
602
612
|
}
|
|
603
613
|
;
|
|
@@ -606,9 +616,8 @@ class PostgresqlConnection {
|
|
|
606
616
|
}
|
|
607
617
|
return new Promise(async (resolve, reject) => {
|
|
608
618
|
try {
|
|
609
|
-
let index = 1;
|
|
610
619
|
const { rows } = await this[_daoConnection].query({
|
|
611
|
-
text: sql
|
|
620
|
+
text: replacePlaceholders(sql),
|
|
612
621
|
values: params
|
|
613
622
|
});
|
|
614
623
|
if (globalThis[_GlobalSqlOption].log === 'trace') {
|
|
@@ -635,7 +644,7 @@ class PostgresqlConnection {
|
|
|
635
644
|
}
|
|
636
645
|
;
|
|
637
646
|
if (sync === SyncMode.Sync) {
|
|
638
|
-
globalThis[_LoggerService].warn('Postgresql not
|
|
647
|
+
globalThis[_LoggerService].warn('Postgresql not supported sync mode');
|
|
639
648
|
return [];
|
|
640
649
|
}
|
|
641
650
|
;
|
|
@@ -644,9 +653,8 @@ class PostgresqlConnection {
|
|
|
644
653
|
}
|
|
645
654
|
return new Promise(async (resolve, reject) => {
|
|
646
655
|
try {
|
|
647
|
-
let index = 1;
|
|
648
656
|
const { rows } = await this[_daoConnection].query({
|
|
649
|
-
text: sql
|
|
657
|
+
text: replacePlaceholders(sql),
|
|
650
658
|
values: params
|
|
651
659
|
});
|
|
652
660
|
if (globalThis[_GlobalSqlOption].log === 'trace') {
|
|
@@ -673,7 +681,7 @@ class PostgresqlConnection {
|
|
|
673
681
|
}
|
|
674
682
|
;
|
|
675
683
|
if (sync === SyncMode.Sync) {
|
|
676
|
-
globalThis[_LoggerService].warn('Postgresql not
|
|
684
|
+
globalThis[_LoggerService].warn('Postgresql not supported sync mode');
|
|
677
685
|
return [];
|
|
678
686
|
}
|
|
679
687
|
;
|
|
@@ -682,9 +690,8 @@ class PostgresqlConnection {
|
|
|
682
690
|
}
|
|
683
691
|
return new Promise(async (resolve, reject) => {
|
|
684
692
|
try {
|
|
685
|
-
let index = 1;
|
|
686
693
|
const { rows } = await this[_daoConnection].query({
|
|
687
|
-
text: sql
|
|
694
|
+
text: replacePlaceholders(sql),
|
|
688
695
|
values: params
|
|
689
696
|
});
|
|
690
697
|
if (globalThis[_GlobalSqlOption].log === 'trace') {
|
|
@@ -716,11 +723,36 @@ class PostgresqlConnection {
|
|
|
716
723
|
_c = _inTransaction;
|
|
717
724
|
export class Postgresql {
|
|
718
725
|
constructor(pool) {
|
|
726
|
+
this.isClosing = false;
|
|
719
727
|
this[_daoDB] = pool;
|
|
728
|
+
this.keepAlive();
|
|
729
|
+
}
|
|
730
|
+
async keepAlive() {
|
|
731
|
+
if (this.isClosing)
|
|
732
|
+
return;
|
|
733
|
+
let connection = null;
|
|
734
|
+
try {
|
|
735
|
+
connection = await this.createConnection(SyncMode.Async);
|
|
736
|
+
if (connection) {
|
|
737
|
+
const data = await connection.query(SyncMode.Async, 'SELECT 1 FROM DUAL');
|
|
738
|
+
globalThis[_LoggerService].debug?.('keepAlive->', data?.[0]?.[1]);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
catch (error) {
|
|
742
|
+
globalThis[_LoggerService].error('keepAlive error', error);
|
|
743
|
+
}
|
|
744
|
+
finally {
|
|
745
|
+
if (connection) {
|
|
746
|
+
await connection.release(SyncMode.Async);
|
|
747
|
+
}
|
|
748
|
+
if (!this.isClosing) {
|
|
749
|
+
this.keepAliveTimer = setTimeout(() => this.keepAlive(), globalThis[_MysqlKeepAliveTime] ?? DEFAULT_KEEPALIVE_INTERVAL);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
720
752
|
}
|
|
721
753
|
createConnection(sync) {
|
|
722
754
|
if (sync === SyncMode.Sync) {
|
|
723
|
-
globalThis[_LoggerService].error('Postgresql not
|
|
755
|
+
globalThis[_LoggerService].error('Postgresql not supported sync mode');
|
|
724
756
|
return null;
|
|
725
757
|
}
|
|
726
758
|
;
|
|
@@ -737,7 +769,7 @@ export class Postgresql {
|
|
|
737
769
|
}
|
|
738
770
|
transaction(sync, fn, conn) {
|
|
739
771
|
if (sync === SyncMode.Sync) {
|
|
740
|
-
globalThis[_LoggerService].warn('Postgresql not
|
|
772
|
+
globalThis[_LoggerService].warn('Postgresql not supported sync mode');
|
|
741
773
|
return null;
|
|
742
774
|
}
|
|
743
775
|
;
|
|
@@ -760,18 +792,19 @@ export class Postgresql {
|
|
|
760
792
|
if (needCommit) {
|
|
761
793
|
globalThis[_LoggerService].debug?.('commit begin!');
|
|
762
794
|
await conn[_daoConnection].query('COMMIT');
|
|
763
|
-
conn[_inTransaction] = false;
|
|
764
795
|
globalThis[_LoggerService].debug?.('commit end!');
|
|
765
796
|
}
|
|
766
797
|
resolve(result);
|
|
767
798
|
}
|
|
768
799
|
catch (error) {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
800
|
+
if (needCommit) {
|
|
801
|
+
globalThis[_LoggerService].debug?.('rollback begin!');
|
|
802
|
+
await conn[_daoConnection].query('ROLLBACK');
|
|
803
|
+
globalThis[_LoggerService].debug?.('rollback end!');
|
|
804
|
+
}
|
|
805
|
+
const dbError = error instanceof DatabaseError ? error : DatabaseError.transaction('PostgreSQL transaction failed', error);
|
|
806
|
+
globalThis[_LoggerService].error(dbError.getSafeMessage(), { cause: error });
|
|
807
|
+
reject(dbError);
|
|
775
808
|
}
|
|
776
809
|
finally {
|
|
777
810
|
try {
|
|
@@ -785,15 +818,18 @@ export class Postgresql {
|
|
|
785
818
|
}
|
|
786
819
|
}
|
|
787
820
|
catch (error) {
|
|
821
|
+
// 释放连接失败通常不影响业务逻辑,记录日志即可
|
|
822
|
+
globalThis[_LoggerService].warn?.('Failed to release connection in finally block', error);
|
|
788
823
|
}
|
|
789
824
|
}
|
|
790
825
|
});
|
|
791
826
|
}
|
|
792
827
|
close(sync) {
|
|
793
|
-
|
|
794
|
-
|
|
828
|
+
this.isClosing = true;
|
|
829
|
+
if (this.keepAliveTimer) {
|
|
830
|
+
clearTimeout(this.keepAliveTimer);
|
|
795
831
|
}
|
|
796
|
-
;
|
|
832
|
+
this[_daoDB]?.end();
|
|
797
833
|
}
|
|
798
834
|
backup(sync, name) {
|
|
799
835
|
}
|
|
@@ -815,7 +851,7 @@ class SqliteConnection {
|
|
|
815
851
|
}
|
|
816
852
|
;
|
|
817
853
|
if (sync === SyncMode.Async) {
|
|
818
|
-
globalThis[_LoggerService].warn(`SQLITE not
|
|
854
|
+
globalThis[_LoggerService].warn(`SQLITE not supported async mode`);
|
|
819
855
|
return { affectedRows: 0, insertId: 0n };
|
|
820
856
|
}
|
|
821
857
|
;
|
|
@@ -846,7 +882,7 @@ class SqliteConnection {
|
|
|
846
882
|
}
|
|
847
883
|
;
|
|
848
884
|
if (sync === SyncMode.Async) {
|
|
849
|
-
globalThis[_LoggerService].warn(`SQLITE not
|
|
885
|
+
globalThis[_LoggerService].warn(`SQLITE not supported async mode`);
|
|
850
886
|
return null;
|
|
851
887
|
}
|
|
852
888
|
;
|
|
@@ -897,7 +933,7 @@ class SqliteConnection {
|
|
|
897
933
|
}
|
|
898
934
|
;
|
|
899
935
|
if (sync === SyncMode.Async) {
|
|
900
|
-
globalThis[_LoggerService].warn(`SQLITE not
|
|
936
|
+
globalThis[_LoggerService].warn(`SQLITE not supported async mode`);
|
|
901
937
|
return [];
|
|
902
938
|
}
|
|
903
939
|
;
|
|
@@ -923,7 +959,7 @@ class SqliteConnection {
|
|
|
923
959
|
}
|
|
924
960
|
;
|
|
925
961
|
if (sync === SyncMode.Async) {
|
|
926
|
-
globalThis[_LoggerService].warn(`SQLITE not
|
|
962
|
+
globalThis[_LoggerService].warn(`SQLITE not supported async mode`);
|
|
927
963
|
return [];
|
|
928
964
|
}
|
|
929
965
|
;
|
|
@@ -961,7 +997,13 @@ export class Sqlite {
|
|
|
961
997
|
`);
|
|
962
998
|
this[_daoDB].function('UUID_SHORT', { deterministic: false }, () => snowflake.generate());
|
|
963
999
|
this[_daoDB].function('UUID', { deterministic: false }, () => snowflake.generate());
|
|
964
|
-
this[_daoDB].function('TIME_TO_SEC', { deterministic: true }, (time) =>
|
|
1000
|
+
this[_daoDB].function('TIME_TO_SEC', { deterministic: true }, (time) => {
|
|
1001
|
+
const parts = time.split(':');
|
|
1002
|
+
const hours = parseInt(parts[0] || '0');
|
|
1003
|
+
const minutes = parseInt(parts[1] || '0');
|
|
1004
|
+
const seconds = parseInt(parts[2] || '0');
|
|
1005
|
+
return hours * 3600 + minutes * 60 + seconds;
|
|
1006
|
+
});
|
|
965
1007
|
this[_daoDB].function('IF', { deterministic: true }, (condition, v1, v2) => condition ? v1 : v2);
|
|
966
1008
|
this[_daoDB].function('RIGHT', { deterministic: true }, (src, p) => src.slice(p * -1));
|
|
967
1009
|
this[_daoDB].function('LEFT', { deterministic: true }, (str, len) => str?.substring(0, len) || null);
|
|
@@ -984,7 +1026,7 @@ export class Sqlite {
|
|
|
984
1026
|
}
|
|
985
1027
|
createConnection(sync) {
|
|
986
1028
|
if (sync === SyncMode.Async) {
|
|
987
|
-
globalThis[_LoggerService].error(`SQLITE not
|
|
1029
|
+
globalThis[_LoggerService].error(`SQLITE not supported async mode`);
|
|
988
1030
|
return null;
|
|
989
1031
|
}
|
|
990
1032
|
;
|
|
@@ -992,7 +1034,7 @@ export class Sqlite {
|
|
|
992
1034
|
}
|
|
993
1035
|
transaction(sync, fn, conn) {
|
|
994
1036
|
if (sync === SyncMode.Async) {
|
|
995
|
-
globalThis[_LoggerService].warn(`SQLITE not
|
|
1037
|
+
globalThis[_LoggerService].warn(`SQLITE not supported async mode`);
|
|
996
1038
|
return null;
|
|
997
1039
|
}
|
|
998
1040
|
;
|
|
@@ -1042,7 +1084,7 @@ export class SqliteRemoteConnection {
|
|
|
1042
1084
|
}
|
|
1043
1085
|
;
|
|
1044
1086
|
if (sync === SyncMode.Sync) {
|
|
1045
|
-
globalThis[_LoggerService].warn('SqliteRemote not
|
|
1087
|
+
globalThis[_LoggerService].warn('SqliteRemote not supported sync mode');
|
|
1046
1088
|
return { affectedRows: 0, insertId: 0n };
|
|
1047
1089
|
}
|
|
1048
1090
|
;
|
|
@@ -1072,7 +1114,7 @@ export class SqliteRemoteConnection {
|
|
|
1072
1114
|
}
|
|
1073
1115
|
;
|
|
1074
1116
|
if (sync === SyncMode.Sync) {
|
|
1075
|
-
globalThis[_LoggerService].warn('SqliteRemote not
|
|
1117
|
+
globalThis[_LoggerService].warn('SqliteRemote not supported sync mode');
|
|
1076
1118
|
return null;
|
|
1077
1119
|
}
|
|
1078
1120
|
;
|
|
@@ -1102,7 +1144,7 @@ export class SqliteRemoteConnection {
|
|
|
1102
1144
|
}
|
|
1103
1145
|
;
|
|
1104
1146
|
if (sync === SyncMode.Sync) {
|
|
1105
|
-
globalThis[_LoggerService].warn('SqliteRemote not
|
|
1147
|
+
globalThis[_LoggerService].warn('SqliteRemote not supported sync mode');
|
|
1106
1148
|
return null;
|
|
1107
1149
|
}
|
|
1108
1150
|
;
|
|
@@ -1132,7 +1174,7 @@ export class SqliteRemoteConnection {
|
|
|
1132
1174
|
}
|
|
1133
1175
|
;
|
|
1134
1176
|
if (sync === SyncMode.Sync) {
|
|
1135
|
-
globalThis[_LoggerService].warn('SqliteRemote not
|
|
1177
|
+
globalThis[_LoggerService].warn('SqliteRemote not supported sync mode');
|
|
1136
1178
|
return [];
|
|
1137
1179
|
}
|
|
1138
1180
|
;
|
|
@@ -1162,7 +1204,7 @@ export class SqliteRemoteConnection {
|
|
|
1162
1204
|
}
|
|
1163
1205
|
;
|
|
1164
1206
|
if (sync === SyncMode.Sync) {
|
|
1165
|
-
globalThis[_LoggerService].warn('SqliteRemote not
|
|
1207
|
+
globalThis[_LoggerService].warn('SqliteRemote not supported sync mode');
|
|
1166
1208
|
return [];
|
|
1167
1209
|
}
|
|
1168
1210
|
;
|
|
@@ -1196,7 +1238,7 @@ export class SqliteRemote {
|
|
|
1196
1238
|
}
|
|
1197
1239
|
createConnection(sync) {
|
|
1198
1240
|
if (sync === SyncMode.Sync) {
|
|
1199
|
-
globalThis[_LoggerService].error('SQLITEREMOTE not
|
|
1241
|
+
globalThis[_LoggerService].error('SQLITEREMOTE not supported sync mode');
|
|
1200
1242
|
return null;
|
|
1201
1243
|
}
|
|
1202
1244
|
;
|
|
@@ -1213,7 +1255,7 @@ export class SqliteRemote {
|
|
|
1213
1255
|
});
|
|
1214
1256
|
}
|
|
1215
1257
|
transaction(sync, fn, conn) {
|
|
1216
|
-
globalThis[_LoggerService].warn(`SQLITEREMOTE not
|
|
1258
|
+
globalThis[_LoggerService].warn(`SQLITEREMOTE not supported transaction`);
|
|
1217
1259
|
return null;
|
|
1218
1260
|
}
|
|
1219
1261
|
close(sync) {
|
|
@@ -1832,7 +1874,11 @@ function P(skipConn = false) {
|
|
|
1832
1874
|
return result;
|
|
1833
1875
|
}
|
|
1834
1876
|
catch (error) {
|
|
1835
|
-
|
|
1877
|
+
let args = '';
|
|
1878
|
+
if (args.length > 0 && args[0].params) {
|
|
1879
|
+
args = JSON.stringify(args[0].params);
|
|
1880
|
+
}
|
|
1881
|
+
console.error(`${option.sqlId ?? option.tableName} service ${propertyKey} have an error:${error}, it's argumens: ${args}`);
|
|
1836
1882
|
throw error;
|
|
1837
1883
|
}
|
|
1838
1884
|
finally {
|
package/string.d.ts
CHANGED
|
@@ -18,7 +18,10 @@ export declare const emptyString: (source: any, skipEmptyString?: boolean) => bo
|
|
|
18
18
|
*/
|
|
19
19
|
export declare const notEmptyString: (source: any, skipEmptyString?: boolean) => boolean;
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* 安全字符串处理(移除单引号)
|
|
22
|
+
* @deprecated 不推荐用于 SQL 注入防护,请使用参数化查询
|
|
23
|
+
* @param source 源字符串
|
|
24
|
+
* @returns 移除单引号后的字符串
|
|
22
25
|
*/
|
|
23
26
|
export declare const safeString: (source?: string) => string;
|
|
24
27
|
/**
|
|
@@ -42,3 +45,5 @@ export declare const buildWxStr: (data: {
|
|
|
42
45
|
* 将字符串中的中文标点符号统一替换为对应的英文标点
|
|
43
46
|
*/
|
|
44
47
|
export declare const replaceChineseCode: (str: string) => string;
|
|
48
|
+
/** 更安全的sql 参数占位符替换 */
|
|
49
|
+
export declare function replacePlaceholders(sql: string): string;
|
package/string.js
CHANGED
|
@@ -30,7 +30,10 @@ export const notEmptyString = (source, skipEmptyString = true) => {
|
|
|
30
30
|
return emptyString(source, skipEmptyString) === false;
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* 安全字符串处理(移除单引号)
|
|
34
|
+
* @deprecated 不推荐用于 SQL 注入防护,请使用参数化查询
|
|
35
|
+
* @param source 源字符串
|
|
36
|
+
* @returns 移除单引号后的字符串
|
|
34
37
|
*/
|
|
35
38
|
export const safeString = (source) => {
|
|
36
39
|
if (source) {
|
|
@@ -130,3 +133,22 @@ const table = {
|
|
|
130
133
|
export const replaceChineseCode = (str) => {
|
|
131
134
|
return str.replace(chinese, (a) => table[a] || '');
|
|
132
135
|
};
|
|
136
|
+
/** 更安全的sql 参数占位符替换 */
|
|
137
|
+
export function replacePlaceholders(sql) {
|
|
138
|
+
let index = 1;
|
|
139
|
+
let inString = false;
|
|
140
|
+
let result = '';
|
|
141
|
+
for (let i = 0; i < sql.length; i++) {
|
|
142
|
+
const char = sql[i];
|
|
143
|
+
if (char === "'" && sql[i - 1] !== '\\') {
|
|
144
|
+
inString = !inString;
|
|
145
|
+
}
|
|
146
|
+
if (char === '?' && !inString) {
|
|
147
|
+
result += `$${index++}`;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
result += char;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
}
|