Skip to content

Commit

Permalink
Add support to transaction metadata that allows sharing of informatio…
Browse files Browse the repository at this point in the history
…n across the application within a transaction
  • Loading branch information
juanluispaz committed Aug 24, 2024
1 parent 9470e65 commit 14af2a9
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 3 deletions.
18 changes: 16 additions & 2 deletions docs/queries/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand All @@ -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.
**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<unknown, unknown>` 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')
```
1 change: 1 addition & 0 deletions docs/supported-operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ interface Connection {
executeAfterNextCommit(fn: ()=> Promise<void>): void
executeAfterNextRollback(fn: ()=> void): void
executeAfterNextRollback(fn: ()=> Promise<void>): void
getTransactionMetadata(): Map<unknown, unknown>

// Querying
insertInto(table: Table): InsertExpression
Expand Down
28 changes: 27 additions & 1 deletion src/connections/AbstractConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ export abstract class AbstractConnection<DB extends AnyDB> implements IConnectio
private beforeCommit?: Array<() => void | Promise<void>> | null
private onCommit?: Array<() => void | Promise<void>> | null
private onRollback?: Array<() => void | Promise<void>> | null
private transactionMetadata?: Map<unknown, unknown>
private beforeCommitStack?: Array<Array<() => void | Promise<void>> | undefined>
private onCommitStack?: Array<Array<() => void | Promise<void>> | undefined>
private onRollbackStack?: Array<Array<() => void | Promise<void>> | undefined>
private transactionMetadataStack?: Array<Map<unknown, unknown> | 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 = []
}
Expand All @@ -77,6 +79,12 @@ export abstract class AbstractConnection<DB extends AnyDB> 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
}
}

Expand Down Expand Up @@ -105,6 +113,14 @@ export abstract class AbstractConnection<DB extends AnyDB> 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
Expand Down Expand Up @@ -161,6 +177,16 @@ export abstract class AbstractConnection<DB extends AnyDB> implements IConnectio
this.onRollback.push(fn)
}

getTransactionMetadata(): Map<unknown, unknown> {
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<P extends Promise<any>[]>(fn: () => [...P]): Promise<UnwrapPromiseTuple<P>>
transaction<T>(fn: () => Promise<T>): Promise<T>
transaction(fn: () => Promise<any>[] | Promise<any>): Promise<any> {
Expand Down
1 change: 1 addition & 0 deletions src/simplifiedDefinition.txt
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ interface Connection {
executeAfterNextCommit(fn: ()=> Promise<void>): void
executeAfterNextRollback(fn: ()=> void): void
executeAfterNextRollback(fn: ()=> Promise<void>): void
getTransactionMetadata(): Map<unknown, unknown>

// Querying
insertInto(table: Table): InsertExpression
Expand Down

0 comments on commit 14af2a9

Please sign in to comment.