Skip to content

Commit

Permalink
fix: support multi lifecricle hooks (ali-sdk#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 authored Mar 5, 2023
1 parent 5312fa2 commit 53b0a70
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 27 deletions.
24 changes: 16 additions & 8 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,15 @@ export class RDSClient extends Operator {
try {
const _conn = await this.#pool.getConnection();
const conn = new RDSConnection(_conn);
if (this.beforeQueryHandler) {
conn.beforeQuery(this.beforeQueryHandler);
if (this.beforeQueryHandlers.length > 0) {
for (const handler of this.beforeQueryHandlers) {
conn.beforeQuery(handler);
}
}
if (this.afterQueryHandler) {
conn.afterQuery(this.afterQueryHandler);
if (this.afterQueryHandlers.length > 0) {
for (const handler of this.afterQueryHandlers) {
conn.afterQuery(handler);
}
}
return conn;
} catch (err) {
Expand All @@ -88,11 +92,15 @@ export class RDSClient extends Operator {
throw err;
}
const tran = new RDSTransaction(conn);
if (this.beforeQueryHandler) {
tran.beforeQuery(this.beforeQueryHandler);
if (this.beforeQueryHandlers.length > 0) {
for (const handler of this.beforeQueryHandlers) {
tran.beforeQuery(handler);
}
}
if (this.afterQueryHandler) {
tran.afterQuery(this.afterQueryHandler);
if (this.afterQueryHandlers.length > 0) {
for (const handler of this.afterQueryHandlers) {
tran.afterQuery(handler);
}
}
return tran;
}
Expand Down
39 changes: 21 additions & 18 deletions src/operator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ const debug = debuglog('ali-rds:operator');
* Operator Interface
*/
export abstract class Operator {
protected beforeQueryHandler?: BeforeQueryHandler;
protected afterQueryHandler?: AfterQueryHandler;
protected beforeQueryHandlers: BeforeQueryHandler[] = [];
protected afterQueryHandlers: AfterQueryHandler[] = [];

get literals() { return literals; }

beforeQuery(beforeQueryHandler: BeforeQueryHandler) {
this.beforeQueryHandler = beforeQueryHandler;
this.beforeQueryHandlers.push(beforeQueryHandler);
}

afterQuery(afterQueryHandler: AfterQueryHandler) {
this.afterQueryHandler = afterQueryHandler;
this.afterQueryHandlers.push(afterQueryHandler);
}

escape(value: any, stringifyObjects?: boolean, timeZone?: string): string {
Expand Down Expand Up @@ -57,35 +57,38 @@ export abstract class Operator {
if (values) {
sql = this.format(sql, values);
}
if (this.beforeQueryHandler) {
const newSql = this.beforeQueryHandler(sql);
if (newSql) {
sql = newSql;
if (this.beforeQueryHandlers.length > 0) {
for (const beforeQueryHandler of this.beforeQueryHandlers) {
const newSql = beforeQueryHandler(sql);
if (newSql) {
sql = newSql;
}
}
}
debug('query %o', sql);
let execDuration: number;
const queryStart = Date.now();
let rows: any;
let lastError: Error | undefined;
try {
const rows = await this._query(sql);
execDuration = Date.now() - queryStart;
if (this.afterQueryHandler) {
this.afterQueryHandler(sql, rows, execDuration);
}
rows = await this._query(sql);
if (Array.isArray(rows)) {
debug('query get %o rows', rows.length);
} else {
debug('query result: %o', rows);
}
return rows;
} catch (err) {
execDuration = Date.now() - queryStart;
lastError = err;
err.stack = `${err.stack}\n sql: ${sql}`;
if (this.afterQueryHandler) {
this.afterQueryHandler(sql, null, execDuration, err);
}
debug('query error: %o', err);
throw err;
} finally {
if (this.afterQueryHandlers.length > 0) {
const execDuration = Date.now() - queryStart;
for (const afterQueryHandler of this.afterQueryHandlers) {
afterQueryHandler(sql, rows, execDuration, lastError);
}
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1209,14 +1209,22 @@ describe('test/client.test.ts', () => {
const db = new RDSClient(config);
let count = 0;
let lastSql = '';
let counter2Before = 0;
let counter2After = 0;
db.beforeQuery(sql => {
count++;
lastSql = sql;
});
db.beforeQuery(() => {
counter2Before++;
});
let lastArgs: any;
db.afterQuery((...args) => {
lastArgs = args;
});
db.afterQuery(() => {
counter2After++;
});
await db.query('select * from ?? limit 10', [ table ]);
assert.equal(lastSql, 'select * from `ali-sdk-test-user` limit 10');
assert.equal(lastArgs[0], lastSql);
Expand Down Expand Up @@ -1256,6 +1264,8 @@ describe('test/client.test.ts', () => {
assert.equal(lastArgs[0], lastSql);
assert.equal(lastArgs[1].affectedRows, 1);
assert.equal(count, 4);
assert.equal(counter2Before, 4);
assert.equal(counter2After, 4);
});
});
});
5 changes: 4 additions & 1 deletion test/operator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,25 @@ describe('test/operator.test.ts', () => {

it('should get query result on after hook', async () => {
const op = new CustomOperator();
let called = false;
op.afterQuery((sql, result, execDuration, err) => {
assert.equal(sql, 'foo');
assert.deepEqual(result, { sql });
assert.equal(typeof execDuration, 'number');
assert(execDuration >= 0);
assert.equal(err, undefined);
called = true;
});
const result = await op.query('foo');
assert.equal(result.sql, 'foo');
assert(called);
});

it('should get query error on after hook', async () => {
const op = new CustomOperator();
op.afterQuery((sql, result, execDuration, err) => {
assert.equal(sql, 'error');
assert.equal(result, null);
assert.equal(result, undefined);
assert.equal(typeof execDuration, 'number');
assert(execDuration >= 0);
assert(err instanceof Error);
Expand Down

0 comments on commit 53b0a70

Please sign in to comment.