diff --git a/docs/queries/transaction.md b/docs/queries/transaction.md index bfd4681..68f2f46 100644 --- a/docs/queries/transaction.md +++ b/docs/queries/transaction.md @@ -48,7 +48,7 @@ When you use these methods, you must ensure the transaction begin before call co ## Defering execution till transaction ends -You can defer the execution of a logic till the end of the transaction. This defered logic can be set calling the `executeAfterNextCommit` or `executeAfterNextRollback` of the ts-sql-query connection in any momment of the application execution; the only condition is there must be an active transaction. ts-sql-query offer as well defer the execution of a logic till just before the commit calling `executeBeforeNextCommit`. +You can defer the execution of a logic till the end of the transaction. This defered logic can be set calling the `executeAfterNextCommit` or `executeAfterNextRollback` of the ts-sql-query connection at any moment of the application execution; the only condition is there must be an active transaction. ts-sql-query offer as well defer the execution of a logic till just before the commit calling `executeBeforeNextCommit`. ```ts connection.executeAfterNextCommit(async () => { @@ -67,4 +67,18 @@ connection.executeBeforeNextCommit(async () => { }) ``` -**Note**: The provided function can be a sync function that returns void or an async function that returns a promise of void. \ No newline at end of file +**Note**: The provided function can be a sync function that returns void or an async function that returns a promise of void. + +## Transaction metadata + +You can set additional information to be consumed in other parts of the application during the same transaction. For this, you can call `getTransactionMetadata` of the ts-sql-query connection at any moment of the application execution; the only condition is there must be an active transaction. The `getTransactionMetadata` method will return a `Map` where you can get or set values. + +```ts +// Setting a value +connection.getTransactionMetadata().set('my key', 'my value') +``` + +```ts +// Getting a value +const myKeyValue: unknown = connection.getTransactionMetadata().get('my key') +``` \ No newline at end of file diff --git a/docs/supported-operations.md b/docs/supported-operations.md index 0889e67..cd32df4 100644 --- a/docs/supported-operations.md +++ b/docs/supported-operations.md @@ -534,6 +534,7 @@ interface Connection { executeAfterNextCommit(fn: ()=> Promise): void executeAfterNextRollback(fn: ()=> void): void executeAfterNextRollback(fn: ()=> Promise): void + getTransactionMetadata(): Map // Querying insertInto(table: Table): InsertExpression diff --git a/src/connections/AbstractConnection.ts b/src/connections/AbstractConnection.ts index c2536da..9a35cd9 100644 --- a/src/connections/AbstractConnection.ts +++ b/src/connections/AbstractConnection.ts @@ -54,12 +54,14 @@ export abstract class AbstractConnection implements IConnectio private beforeCommit?: Array<() => void | Promise> | null private onCommit?: Array<() => void | Promise> | null private onRollback?: Array<() => void | Promise> | null + private transactionMetadata?: Map private beforeCommitStack?: Array void | Promise> | undefined> private onCommitStack?: Array void | Promise> | undefined> private onRollbackStack?: Array void | Promise> | undefined> + private transactionMetadataStack?: Array | undefined> private pushTransactionStack() { - if (this.onCommit || this.onCommitStack || this.onRollback || this.onRollbackStack || this.beforeCommit || this.beforeCommitStack) { + if (this.onCommit || this.onCommitStack || this.onRollback || this.onRollbackStack || this.beforeCommit || this.beforeCommitStack || this.transactionMetadata || this.transactionMetadataStack) { if (!this.beforeCommitStack) { this.beforeCommitStack = [] } @@ -77,6 +79,12 @@ export abstract class AbstractConnection implements IConnectio } this.onRollbackStack.push(this.onRollback || undefined) this.onRollback = undefined + + if (!this.transactionMetadataStack) { + this.transactionMetadataStack = [] + } + this.transactionMetadataStack.push(this.transactionMetadata || undefined) + this.transactionMetadata = undefined } } @@ -105,6 +113,14 @@ export abstract class AbstractConnection implements IConnectio } else { this.onRollback = undefined } + if (this.transactionMetadataStack) { + this.transactionMetadata = this.transactionMetadataStack.pop() + if (this.transactionMetadataStack.length <= 0) { + this.transactionMetadataStack = undefined + } + } else { + this.transactionMetadata = undefined + } } executeBeforeNextCommit(fn: ()=> void): void @@ -161,6 +177,16 @@ export abstract class AbstractConnection implements IConnectio this.onRollback.push(fn) } + getTransactionMetadata(): Map { + if (!this.queryRunner.isMocked() && !this.isTransactionActive()) { + throw new Error('There is no open transaction') + } + if (!this.transactionMetadata) { + this.transactionMetadata = new Map() + } + return this.transactionMetadata + } + transaction

[]>(fn: () => [...P]): Promise> transaction(fn: () => Promise): Promise transaction(fn: () => Promise[] | Promise): Promise { diff --git a/src/simplifiedDefinition.txt b/src/simplifiedDefinition.txt index 94d278c..8d8e793 100644 --- a/src/simplifiedDefinition.txt +++ b/src/simplifiedDefinition.txt @@ -516,6 +516,7 @@ interface Connection { executeAfterNextCommit(fn: ()=> Promise): void executeAfterNextRollback(fn: ()=> void): void executeAfterNextRollback(fn: ()=> Promise): void + getTransactionMetadata(): Map // Querying insertInto(table: Table): InsertExpression