Skip to content

Commit

Permalink
feat: add support for registering hooks with the transaction client
Browse files Browse the repository at this point in the history
The hooks are a make shift arragement to run async code around commit and
rollback. Soon, we will add support for middleware for almost all db
operations
  • Loading branch information
thetutlage committed Sep 23, 2021
1 parent 132efa9 commit bf8f83f
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
2 changes: 2 additions & 0 deletions adonis-typings/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ declare module '@ioc:Adonis/Lucid/Database' {

once(event: 'commit', handler: (client: this) => void): this
once(event: 'rollback', handler: (client: this) => void): this

after(event: 'rollback' | 'commit', handler: () => void | Promise<void>): this
}

/**
Expand Down
21 changes: 21 additions & 0 deletions src/TransactionClient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import { Knex } from 'knex'
import { EventEmitter } from 'events'
import { Hooks } from '@poppinss/hooks'
import { EmitterContract } from '@ioc:Adonis/Core/Event'
import { ProfilerRowContract } from '@ioc:Adonis/Core/Profiler'
import {
Expand Down Expand Up @@ -47,6 +48,8 @@ export class TransactionClient extends EventEmitter implements TransactionClient
*/
public profiler?: ProfilerRowContract

private hooks = new Hooks()

constructor(
public knexClient: Knex.Transaction,
public dialect: DialectContract,
Expand Down Expand Up @@ -234,6 +237,14 @@ export class TransactionClient extends EventEmitter implements TransactionClient
return this.insertQuery().table(table)
}

/**
* Register after commit or rollback hook
*/
public after(event: 'rollback' | 'commit', handler: () => void | Promise<void>) {
this.hooks.add('after', event, handler)
return this
}

/**
* Commit the transaction
*/
Expand All @@ -248,6 +259,11 @@ export class TransactionClient extends EventEmitter implements TransactionClient
this.removeAllListeners()
throw error
}

try {
await this.hooks.exec('after', 'commit')
this.hooks.clear('after')
} catch {}
}

/**
Expand All @@ -264,6 +280,11 @@ export class TransactionClient extends EventEmitter implements TransactionClient
this.removeAllListeners()
throw error
}

try {
await this.hooks.exec('after', 'rollback')
this.hooks.clear('after')
} catch {}
}

/**
Expand Down
48 changes: 47 additions & 1 deletion test/database/transactions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ test.group('Transaction | query', (group) => {
await connection.disconnect()
})

test('execute before and after rollback hooks', async (assert) => {
test('emit after rollback event', async (assert) => {
const stack: string[] = []
const connection = new Connection('primary', getConfig(), app.logger)
connection.connect()
Expand Down Expand Up @@ -373,4 +373,50 @@ test.group('Transaction | query', (group) => {

await connection.disconnect()
})

test('execute after commit hook', async (assert) => {
const stack: string[] = []
const connection = new Connection('primary', getConfig(), app.logger)
connection.connect()

const db = await new QueryClient(
'dual',
connection,
app.container.use('Adonis/Core/Event')
).transaction()

db.after('commit', async () => {
stack.push('commit')
})

await db.insertQuery().table('users').insert({ username: 'virk' })
await db.commit()
assert.deepEqual(stack, ['commit'])

await connection.disconnect()
})

test('execute after rollback hook', async (assert) => {
const stack: string[] = []
const connection = new Connection('primary', getConfig(), app.logger)
connection.connect()

const db = await new QueryClient(
'dual',
connection,
app.container.use('Adonis/Core/Event')
).transaction()

db.after('rollback', async () => {
stack.push('rollback')
})

await db.insertQuery().table('users').insert({ username: 'virk' })
await db.rollback()
assert.deepEqual(db.listenerCount('commit'), 0)
assert.deepEqual(db.listenerCount('rollback'), 0)
assert.deepEqual(stack, ['rollback'])

await connection.disconnect()
})
})

0 comments on commit bf8f83f

Please sign in to comment.