Skip to content

Commit

Permalink
feat: add support for query isolation
Browse files Browse the repository at this point in the history
FIXES: #679
  • Loading branch information
thetutlage committed Jun 2, 2021
1 parent 48dc522 commit b808f03
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 10 deletions.
18 changes: 16 additions & 2 deletions adonis-typings/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ declare module '@ioc:Adonis/Lucid/Database' {

export { SimplePaginatorContract, SimplePaginatorMetaKeys }

/**
* Same as knex. Need to redefine, as knex doesn't export this
* type
*/
export type IsolationLevels =
| 'read uncommitted'
| 'read committed'
| 'snapshot'
| 'repeatable read'
| 'serializable'

/**
* Migration node returned by the migration source
* implementation
Expand Down Expand Up @@ -64,8 +75,11 @@ declare module '@ioc:Adonis/Lucid/Database' {
* Shape of the transaction function to create a new transaction
*/
export interface TransactionFn {
<T extends any>(callback: (trx: TransactionClientContract) => Promise<T>): Promise<T>
(): Promise<TransactionClientContract>
<T extends any>(
callback: (trx: TransactionClientContract) => Promise<T>,
options?: { isolationLevel?: IsolationLevels }
): Promise<T>
(options?: { isolationLevel?: IsolationLevels }): Promise<TransactionClientContract>
}

/**
Expand Down
16 changes: 13 additions & 3 deletions src/Database/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
DatabaseClientOptions,
TransactionClientContract,
ConnectionManagerContract,
IsolationLevels,
QueryClientContract,
} from '@ioc:Adonis/Lucid/Database'

import { QueryClient } from '../QueryClient'
Expand Down Expand Up @@ -123,7 +125,7 @@ export class Database implements DatabaseContract {
public connection(
connection: string = this.primaryConnectionName,
options?: DatabaseClientOptions
) {
): QueryClientContract | TransactionClientContract {
options = options || {}

/**
Expand Down Expand Up @@ -256,8 +258,16 @@ export class Database implements DatabaseContract {
* Returns a transaction instance on the default
* connection
*/
public transaction(callback?: (trx: TransactionClientContract) => Promise<any>) {
return this.connection().transaction(callback)
public transaction(
callback?:
| { isolationLevel?: IsolationLevels }
| ((trx: TransactionClientContract) => Promise<any>),
options?: { isolationLevel?: IsolationLevels }
) {
const client = this.connection()
return typeof callback === 'function'
? client.transaction(callback, options)
: client.transaction(callback)
}

/**
Expand Down
8 changes: 6 additions & 2 deletions src/QueryClient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { EmitterContract } from '@ioc:Adonis/Core/Event'
import { ProfilerRowContract, ProfilerContract } from '@ioc:Adonis/Core/Profiler'

import {
IsolationLevels,
DialectContract,
ConnectionContract,
QueryClientContract,
Expand Down Expand Up @@ -130,9 +131,12 @@ export class QueryClient implements QueryClientContract {
* query and hold a single connection for all queries.
*/
public async transaction(
callback?: (trx: TransactionClientContract) => Promise<any>
callback?:
| { isolationLevel?: IsolationLevels }
| ((trx: TransactionClientContract) => Promise<any>),
options?: { isolationLevel?: IsolationLevels }
): Promise<any> {
const trx = await this.getWriteClient().transaction()
const trx = await this.getWriteClient().transaction(options)
const transaction = new TransactionClient(
trx,
this.dialect,
Expand Down
13 changes: 10 additions & 3 deletions src/TransactionClient/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import { Knex } from 'knex'
import { EventEmitter } from 'events'
import { EmitterContract } from '@ioc:Adonis/Core/Event'
import { ProfilerRowContract } from '@ioc:Adonis/Core/Profiler'
import { TransactionClientContract, DialectContract } from '@ioc:Adonis/Lucid/Database'
import {
IsolationLevels,
DialectContract,
TransactionClientContract,
} from '@ioc:Adonis/Lucid/Database'

import { ModelQueryBuilder } from '../Orm/QueryBuilder'
import { RawBuilder } from '../Database/StaticBuilder/Raw'
Expand Down Expand Up @@ -180,9 +184,12 @@ export class TransactionClient extends EventEmitter implements TransactionClient
* Returns another instance of transaction with save point
*/
public async transaction(
callback?: (trx: TransactionClientContract) => Promise<any>
callback?:
| { isolationLevel?: IsolationLevels }
| ((trx: TransactionClientContract) => Promise<any>),
options?: { isolationLevel?: IsolationLevels }
): Promise<any> {
const trx = await this.knexClient.transaction()
const trx = await this.knexClient.transaction(options)
const transaction = new TransactionClient(
trx,
this.dialect,
Expand Down

0 comments on commit b808f03

Please sign in to comment.