Skip to content

Commit

Permalink
Interim
Browse files Browse the repository at this point in the history
  • Loading branch information
benmerckx committed May 8, 2024
1 parent b3bad95 commit b929c7d
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 29 deletions.
18 changes: 4 additions & 14 deletions src/core/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,6 @@ export class Database<Meta extends QueryMeta = Either>
return this.close()
}

transact<T>(
gen: (tx: Transaction<Meta>) => Generator<Promise<unknown>, T>,
options?: TransactionOptions[Meta['dialect']]
): Promise<T> {
return (<Database<any>>this).transaction(async (tx: Transaction<Meta>) => {
const iter = gen(tx)
let current: IteratorResult<Promise<unknown>>
while ((current = iter.next(tx))) {
if (current.done) return current.value
await current.value
}
}, options)
}

transaction<T>(
this: Database<Sync>,
run: (tx: Transaction<Meta>) => T,
Expand All @@ -61,6 +47,10 @@ export class Database<Meta extends QueryMeta = Either>
run: (tx: Transaction<Meta>) => Promise<T>,
options?: TransactionOptions[Meta['dialect']]
): Promise<T>
transaction<T>(
run: (tx: Transaction<Meta>) => T | Promise<T>,
options?: TransactionOptions[Meta['dialect']]
): T | Promise<T>
transaction(run: Function, options = {}) {
return this.#driver.transaction(
inner => {
Expand Down
6 changes: 3 additions & 3 deletions src/driver/pg.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {Client, Pool, PoolClient} from 'pg'
import {Pool, type Client, type PoolClient} from 'pg'
import {AsyncDatabase, type TransactionOptions} from '../core/Database.ts'
import type {AsyncDriver, AsyncStatement} from '../core/Driver.ts'
import {postgresDialect} from '../postgres/PostgresDialect.ts'
Expand Down Expand Up @@ -72,8 +72,8 @@ export class PgDriver implements AsyncDriver {
options: TransactionOptions['postgres'],
depth: number
): Promise<T> {
const poolClient = await this.client.connect()
const client = poolClient ?? this.client
const client =
this.client instanceof Pool ? await this.client.connect() : this.client
try {
await client.query(depth > 0 ? `savepoint d${depth}` : 'begin')
const result = await run(new PgDriver(client))
Expand Down
1 change: 1 addition & 0 deletions src/universal.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './universal/UniversalColumns.ts'
export * from './universal/UniversalTransaction.ts'
18 changes: 18 additions & 0 deletions src/universal/UniversalTransaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type {Transaction} from '../core/Database.ts'
import type {QueryMeta} from '../core/MetaData.ts'

export function generateTransaction<
T = void,
Meta extends QueryMeta = QueryMeta
>(
gen: (tx: Transaction<Meta>) => Generator<Promise<unknown>, T>
): (tx: Transaction<Meta>) => Promise<T> {
return async (tx: Transaction<Meta>) => {
const iter = gen(tx)
let current: IteratorResult<Promise<unknown>>
while ((current = iter.next(tx))) {
if (current.done) return current.value
await current.value
}
}
}
33 changes: 21 additions & 12 deletions test/TestDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import {
} from '../src/core/Database.ts'
import {table} from '../src/core/Table.ts'
import {eq, foreignKey, primaryKey, sql, unique} from '../src/index.ts'
import {boolean, id, int, json, text} from '../src/universal.ts'
import {
boolean,
generateTransaction,
id,
int,
json,
text
} from '../src/universal.ts'

const Node = table('Node', {
id: id(),
Expand Down Expand Up @@ -220,18 +227,20 @@ export async function testDriver(
}
})

Test.it('universal transactions', async () => {
const result = await db.transact(function* (tx) {
yield* tx.createTable(Node)
yield* tx.insert(Node).values({
textField: 'hello',
bool: true
Test.it('generator transactions', async () => {
const result = await db.transaction(
generateTransaction(function* (tx) {
yield* tx.createTable(Node)
yield* tx.insert(Node).values({
textField: 'hello',
bool: true
})
const nodes = yield* tx.select().from(Node)
Assert.isEqual(nodes, [{id: 1, textField: 'hello', bool: true}])
yield* tx.dropTable(Node)
return 1
})
const nodes = yield* tx.select().from(Node)
Assert.isEqual(nodes, [{id: 1, textField: 'hello', bool: true}])
yield* tx.dropTable(Node)
return 1
})
)
Assert.isEqual(result, 1)
})

Expand Down

0 comments on commit b929c7d

Please sign in to comment.