Skip to content

Commit

Permalink
fix: Model.transaction always create a transaction and do not re-use …
Browse files Browse the repository at this point in the history
…existing one
  • Loading branch information
thetutlage committed Dec 9, 2024
1 parent ac3b400 commit 1afdd81
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 13 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
},
"devDependencies": {
"@adonisjs/assembler": "^7.8.2",
"@adonisjs/core": "^6.15.2",
"@adonisjs/core": "^6.16.0",
"@adonisjs/eslint-config": "^2.0.0-beta.7",
"@adonisjs/prettier-config": "^1.4.0",
"@adonisjs/tsconfig": "^1.4.0",
Expand All @@ -69,14 +69,14 @@
"@japa/runner": "^3.1.4",
"@libsql/sqlite3": "^0.3.1",
"@release-it/conventional-changelog": "^9.0.3",
"@swc/core": "^1.9.3",
"@swc/core": "^1.10.0",
"@types/chance": "^1.1.6",
"@types/luxon": "^3.4.2",
"@types/node": "^22.10.1",
"@types/pretty-hrtime": "^1.0.3",
"@types/qs": "^6.9.17",
"@vinejs/vine": "^3.0.0",
"better-sqlite3": "^11.6.0",
"better-sqlite3": "^11.7.0",
"c8": "^10.1.2",
"chance": "^1.1.12",
"copyfiles": "^2.4.1",
Expand All @@ -88,7 +88,7 @@
"luxon": "^3.5.0",
"mysql2": "^3.11.5",
"pg": "^8.13.1",
"prettier": "^3.4.1",
"prettier": "^3.4.2",
"reflect-metadata": "^0.2.2",
"release-it": "^17.10.0",
"sqlite3": "^5.1.7",
Expand Down
25 changes: 19 additions & 6 deletions src/orm/base_model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,28 @@ class BaseModelImpl implements LucidRow {
/**
* Returns the model query instance for the given model
*/
static async transaction(
static transaction<T>(
callback: (trx: TransactionClientContract) => Promise<T>,
options?: ModelAdapterOptions & { isolationLevel?: IsolationLevels }
): Promise<TransactionClientContract> {
const client = this.$adapter.modelConstructorClient(this, options)
if (client.isTransaction) {
return client as TransactionClientContract
): Promise<T>
static transaction(
options?: ModelAdapterOptions & {
isolationLevel?: IsolationLevels
}
): Promise<TransactionClientContract>
static async transaction<T>(
callbackOrOptions?:
| ((trx: TransactionClientContract) => Promise<T>)
| (ModelAdapterOptions & { isolationLevel?: IsolationLevels }),
options?: ModelAdapterOptions & { isolationLevel?: IsolationLevels }
): Promise<TransactionClientContract | T> {
if (typeof callbackOrOptions === 'function') {
const client = this.$adapter.modelConstructorClient(this, options)
return client.transaction(callbackOrOptions, options)
}

return client.transaction()
const client = this.$adapter.modelConstructorClient(this, callbackOrOptions)
return client.transaction(callbackOrOptions)
}

/**
Expand Down
5 changes: 2 additions & 3 deletions src/types/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
IsolationLevels,

Check failure on line 14 in src/types/model.ts

View workflow job for this annotation

GitHub Actions / typecheck

'IsolationLevels' is declared but its value is never read.
QueryClientContract,
TransactionClientContract,
TransactionFn,
} from './database.js'

import {
Expand Down Expand Up @@ -1154,9 +1155,7 @@ export interface LucidModel {
* Returns transaction client from the model. It is same as
* calling "db.transaction"
*/
transaction(
options?: ModelAdapterOptions & { isolationLevel?: IsolationLevels }
): Promise<TransactionClientContract>
transaction: TransactionFn

/**
* Truncate model table
Expand Down
26 changes: 26 additions & 0 deletions test/orm/base_model.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8346,4 +8346,30 @@ test.group('Base Model | transaction', (group) => {

assert.isNull(user)
})

test('auto manage transaction when callback is provided', async ({ fs, assert }) => {
const app = new AppFactory().create(fs.baseUrl, () => {})
await app.init()
const db = getDb()
const adapter = ormAdapter(db)

const BaseModel = getBaseModel(adapter)

class User extends BaseModel {
@column({ isPrimary: true })
declare id: number

@column()
declare username: string

@column()
declare email: string
}

const [userId] = await User.transaction(async (trx) => {
return trx.insertQuery().table('users').insert({ username: 'virk' }).returning('id')
})
const user = await User.find(userId)
assert.equal(user!.username, 'virk')
})
})

0 comments on commit 1afdd81

Please sign in to comment.