Skip to content

Commit ba7cd37

Browse files
authored
feat: auto use transaction in db.query (#5)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced database query flexibility by allowing the use of transactions or specific connections. - **Tests** - Implemented new tests to verify database queries within transactions and with specified connections. - **Chores** - Updated `.gitignore` to exclude IDE-specific settings files. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent cd5a759 commit ba7cd37

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ coverage
1616
lib
1717
.eslintcache
1818
package-lock.json
19+
.idea

Diff for: src/client.ts

+23-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ interface PoolPromisify extends Omit<Pool, 'query'> {
2525
};
2626
}
2727

28+
export interface QueryOptions {
29+
conn?: RDSConnection | RDSTransaction;
30+
}
31+
2832
export class RDSClient extends Operator {
2933
static get literals() { return literals; }
3034
static get escape() { return mysql.escape; }
@@ -83,12 +87,28 @@ export class RDSClient extends Operator {
8387
});
8488
}
8589

86-
async query<T = any>(sql: string, values?: object | any[]): Promise<T> {
87-
const conn = await this.getConnection();
90+
async query<T = any>(sql: string, values?: object | any[], options?: QueryOptions): Promise<T> {
91+
let conn: RDSConnection | RDSTransaction;
92+
let shouldReleaseConn = false;
93+
if (options?.conn) {
94+
conn = options.conn;
95+
} else {
96+
const ctx = this.#connectionStorage.getStore();
97+
const ctxConn = ctx?.[this.#connectionStorageKey];
98+
if (ctxConn) {
99+
conn = ctxConn;
100+
} else {
101+
conn = await this.getConnection();
102+
shouldReleaseConn = true;
103+
}
104+
}
105+
88106
try {
89107
return await conn.query(sql, values);
90108
} finally {
91-
conn.release();
109+
if (shouldReleaseConn) {
110+
(conn as RDSConnection).release();
111+
}
92112
}
93113
}
94114

Diff for: test/client.test.ts

+36
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,42 @@ describe('test/client.test.ts', () => {
647647
await db1.end();
648648
await db2.end();
649649
});
650+
651+
it('should db.query in transaction scope works', async () => {
652+
let querySql: string | undefined;
653+
mm(RDSTransaction.prototype, 'query', async (sql: string) => {
654+
querySql = sql;
655+
});
656+
await db.beginTransactionScope(async () => {
657+
await db.query(`insert into ??(name, email, gmt_create, gmt_modified)
658+
values(?, ?, now(), now())`,
659+
[ table, prefix + 'multiple-instance1', prefix + '[email protected]' ]);
660+
return db;
661+
});
662+
assert(querySql);
663+
});
664+
665+
it('should db.query specify conn in transaction scope works', async () => {
666+
let transactionQuerySql: string | undefined;
667+
let connQuerySql: string | undefined;
668+
mm(RDSTransaction.prototype, 'query', async (sql: string) => {
669+
transactionQuerySql = sql;
670+
});
671+
const conn = await db.getConnection();
672+
mm(conn, 'query', async (sql: string) => {
673+
connQuerySql = sql;
674+
});
675+
await db.beginTransactionScope(async () => {
676+
await db.query(`insert into ??(name, email, gmt_create, gmt_modified)
677+
values(?, ?, now(), now())`,
678+
[ table, prefix + 'multiple-instance1', prefix + '[email protected]' ], {
679+
conn,
680+
});
681+
return db;
682+
});
683+
assert(connQuerySql);
684+
assert(!transactionQuerySql);
685+
});
650686
});
651687

652688
describe('beginDoomedTransactionScope(scope)', () => {

0 commit comments

Comments
 (0)