rado 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/Database.d.ts +8 -4
- package/dist/core/Database.js +8 -4
- package/dist/core/Driver.d.ts +3 -2
- package/dist/driver/better-sqlite3.js +11 -7
- package/dist/driver/bun-sqlite.js +11 -7
- package/dist/driver/sql.js.js +8 -10
- package/dist/sqlite/transactions.d.ts +3 -0
- package/dist/sqlite/transactions.js +35 -0
- package/package.json +1 -1
package/dist/core/Database.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { QueryBatch } from './Query.js';
|
|
|
8
8
|
import { Resolver } from './Resolver.js';
|
|
9
9
|
import type { Table } from './Table.js';
|
|
10
10
|
export declare class Database<Meta extends QueryMeta = Either> extends Builder<Meta> implements HasResolver<Meta> {
|
|
11
|
+
#private;
|
|
11
12
|
driver: Driver;
|
|
12
13
|
dialect: Dialect;
|
|
13
14
|
diff: Diff;
|
|
@@ -26,17 +27,20 @@ export declare class Database<Meta extends QueryMeta = Either> extends Builder<M
|
|
|
26
27
|
transaction<T>(this: Database<Async>, run: (tx: Transaction<Meta>) => Promise<T>, options?: TransactionOptions[Meta['dialect']]): Promise<T>;
|
|
27
28
|
transaction<T>(run: (tx: Transaction<Meta>) => T | Promise<T>, options?: TransactionOptions[Meta['dialect']]): Deliver<Meta, T>;
|
|
28
29
|
}
|
|
30
|
+
export interface TransactionUniversalOptions {
|
|
31
|
+
async?: boolean;
|
|
32
|
+
}
|
|
29
33
|
export interface TransactionOptions {
|
|
30
|
-
universal:
|
|
31
|
-
sqlite: {
|
|
34
|
+
universal: TransactionUniversalOptions;
|
|
35
|
+
sqlite: TransactionUniversalOptions & {
|
|
32
36
|
behavior?: 'deferred' | 'immediate' | 'exclusive';
|
|
33
37
|
};
|
|
34
|
-
postgres: {
|
|
38
|
+
postgres: TransactionUniversalOptions & {
|
|
35
39
|
isolationLevel?: 'read uncommitted' | 'read committed' | 'repeatable read' | 'serializable';
|
|
36
40
|
accessMode?: 'read only' | 'read write';
|
|
37
41
|
deferrable?: boolean;
|
|
38
42
|
};
|
|
39
|
-
mysql: {
|
|
43
|
+
mysql: TransactionUniversalOptions & {
|
|
40
44
|
isolationLevel?: 'read uncommitted' | 'read committed' | 'repeatable read' | 'serializable';
|
|
41
45
|
accessMode?: 'read only' | 'read write';
|
|
42
46
|
withConsistentSnapshot?: boolean;
|
package/dist/core/Database.js
CHANGED
|
@@ -64,11 +64,15 @@ var Database = class extends Builder {
|
|
|
64
64
|
throw new Error("Query has parameters");
|
|
65
65
|
return this.driver.exec(emitter.sql);
|
|
66
66
|
}
|
|
67
|
+
#transactionLock;
|
|
67
68
|
transaction(run, options = {}) {
|
|
68
|
-
return this.driver.transaction(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
return this.driver.transaction(
|
|
70
|
+
(inner) => {
|
|
71
|
+
const tx = new Transaction(inner, this.dialect, this.diff);
|
|
72
|
+
return run(tx);
|
|
73
|
+
},
|
|
74
|
+
{ async: run.constructor.name === "AsyncFunction", ...options }
|
|
75
|
+
);
|
|
72
76
|
}
|
|
73
77
|
};
|
|
74
78
|
var Rollback = class extends Error {
|
package/dist/core/Driver.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TransactionUniversalOptions } from './Database.js';
|
|
1
2
|
export type Driver = SyncDriver | AsyncDriver;
|
|
2
3
|
export type Statement = SyncStatement | AsyncStatement;
|
|
3
4
|
export interface BatchQuery {
|
|
@@ -16,7 +17,7 @@ export interface SyncDriver extends DriverSpecs {
|
|
|
16
17
|
close(): void;
|
|
17
18
|
exec(query: string): void;
|
|
18
19
|
prepare(query: string, options?: PrepareOptions): SyncStatement;
|
|
19
|
-
transaction<T>(run: (inner: SyncDriver) => T, options:
|
|
20
|
+
transaction<T>(run: (inner: SyncDriver) => T, options: TransactionUniversalOptions): T;
|
|
20
21
|
batch(queries: Array<BatchQuery>): Array<Array<unknown>>;
|
|
21
22
|
}
|
|
22
23
|
export interface SyncStatement {
|
|
@@ -30,7 +31,7 @@ export interface AsyncDriver extends DriverSpecs {
|
|
|
30
31
|
close(): Promise<void>;
|
|
31
32
|
exec(query: string): Promise<void>;
|
|
32
33
|
prepare(query: string, options?: PrepareOptions): AsyncStatement;
|
|
33
|
-
transaction<T>(run: (inner: AsyncDriver) => Promise<T>, options:
|
|
34
|
+
transaction<T>(run: (inner: AsyncDriver) => Promise<T>, options: TransactionUniversalOptions): Promise<T>;
|
|
34
35
|
batch(queries: Array<BatchQuery>): Promise<Array<Array<unknown>>>;
|
|
35
36
|
}
|
|
36
37
|
export interface AsyncStatement {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { SyncDatabase } from "../core/Database.js";
|
|
3
3
|
import { sqliteDialect } from "../sqlite.js";
|
|
4
4
|
import { sqliteDiff } from "../sqlite/diff.js";
|
|
5
|
+
import { execTransaction } from "../sqlite/transactions.js";
|
|
5
6
|
var PreparedStatement = class {
|
|
6
7
|
constructor(stmt, isSelection) {
|
|
7
8
|
this.stmt = stmt;
|
|
@@ -25,9 +26,10 @@ var PreparedStatement = class {
|
|
|
25
26
|
free() {
|
|
26
27
|
}
|
|
27
28
|
};
|
|
28
|
-
var BetterSqlite3Driver = class {
|
|
29
|
-
constructor(client) {
|
|
29
|
+
var BetterSqlite3Driver = class _BetterSqlite3Driver {
|
|
30
|
+
constructor(client, depth = 0) {
|
|
30
31
|
this.client = client;
|
|
32
|
+
this.depth = depth;
|
|
31
33
|
}
|
|
32
34
|
parsesJson = false;
|
|
33
35
|
exec(query) {
|
|
@@ -48,11 +50,13 @@ var BetterSqlite3Driver = class {
|
|
|
48
50
|
);
|
|
49
51
|
}
|
|
50
52
|
transaction(run, options) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
return execTransaction(
|
|
54
|
+
this,
|
|
55
|
+
this.depth,
|
|
56
|
+
(depth) => new _BetterSqlite3Driver(this.client, depth),
|
|
57
|
+
run,
|
|
58
|
+
options
|
|
59
|
+
);
|
|
56
60
|
}
|
|
57
61
|
};
|
|
58
62
|
function connect(db) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { SyncDatabase } from "../core/Database.js";
|
|
3
3
|
import { sqliteDialect } from "../sqlite.js";
|
|
4
4
|
import { sqliteDiff } from "../sqlite/diff.js";
|
|
5
|
+
import { execTransaction } from "../sqlite/transactions.js";
|
|
5
6
|
var PreparedStatement = class {
|
|
6
7
|
constructor(stmt) {
|
|
7
8
|
this.stmt = stmt;
|
|
@@ -22,9 +23,10 @@ var PreparedStatement = class {
|
|
|
22
23
|
this.stmt.finalize();
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
|
-
var BunSqliteDriver = class {
|
|
26
|
-
constructor(client) {
|
|
26
|
+
var BunSqliteDriver = class _BunSqliteDriver {
|
|
27
|
+
constructor(client, depth = 0) {
|
|
27
28
|
this.client = client;
|
|
29
|
+
this.depth = depth;
|
|
28
30
|
}
|
|
29
31
|
parsesJson = false;
|
|
30
32
|
exec(query) {
|
|
@@ -42,11 +44,13 @@ var BunSqliteDriver = class {
|
|
|
42
44
|
}, {});
|
|
43
45
|
}
|
|
44
46
|
transaction(run, options) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
return execTransaction(
|
|
48
|
+
this,
|
|
49
|
+
this.depth,
|
|
50
|
+
(depth) => new _BunSqliteDriver(this.client, depth),
|
|
51
|
+
run,
|
|
52
|
+
options
|
|
53
|
+
);
|
|
50
54
|
}
|
|
51
55
|
};
|
|
52
56
|
function connect(db) {
|
package/dist/driver/sql.js.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { SyncDatabase } from "../core/Database.js";
|
|
3
3
|
import { sqliteDialect } from "../sqlite.js";
|
|
4
4
|
import { sqliteDiff } from "../sqlite/diff.js";
|
|
5
|
+
import { execTransaction } from "../sqlite/transactions.js";
|
|
5
6
|
var PreparedStatement = class {
|
|
6
7
|
constructor(client, stmt) {
|
|
7
8
|
this.client = client;
|
|
@@ -59,16 +60,13 @@ var SqlJsDriver = class _SqlJsDriver {
|
|
|
59
60
|
);
|
|
60
61
|
}
|
|
61
62
|
transaction(run, options) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.exec(this.depth > 0 ? `rollback to d${this.depth}` : "rollback");
|
|
70
|
-
throw error;
|
|
71
|
-
}
|
|
63
|
+
return execTransaction(
|
|
64
|
+
this,
|
|
65
|
+
this.depth,
|
|
66
|
+
(depth) => new _SqlJsDriver(this.client, depth),
|
|
67
|
+
run,
|
|
68
|
+
options
|
|
69
|
+
);
|
|
72
70
|
}
|
|
73
71
|
};
|
|
74
72
|
function connect(db) {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { TransactionOptions } from '../core/Database.js';
|
|
2
|
+
import type { SyncDriver } from '../core/Driver.js';
|
|
3
|
+
export declare function execTransaction<T>(driver: SyncDriver, depth: number, wrap: (depth: number) => SyncDriver, run: (inner: SyncDriver) => T, options: TransactionOptions['sqlite']): T;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/sqlite/transactions.ts
|
|
2
|
+
var locks = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
function execTransaction(driver, depth, wrap, run, options) {
|
|
4
|
+
const needsLock = options.async;
|
|
5
|
+
const behavior = options.behavior ?? "deferred";
|
|
6
|
+
if (!needsLock)
|
|
7
|
+
return transact();
|
|
8
|
+
let trigger;
|
|
9
|
+
const lock = new Promise((resolve) => trigger = resolve);
|
|
10
|
+
const current = Promise.resolve(locks.get(driver));
|
|
11
|
+
locks.set(driver, lock);
|
|
12
|
+
return current.then(transact).finally(trigger);
|
|
13
|
+
function transact() {
|
|
14
|
+
try {
|
|
15
|
+
driver.exec(depth > 0 ? `savepoint d${depth}` : `begin ${behavior}`);
|
|
16
|
+
const result = run(wrap(depth + 1));
|
|
17
|
+
if (result instanceof Promise)
|
|
18
|
+
return result.then(release, rollback);
|
|
19
|
+
return release(result);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
return rollback(error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function release(result) {
|
|
25
|
+
driver.exec(depth > 0 ? `release d${depth}` : "commit");
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
function rollback(error) {
|
|
29
|
+
driver.exec(depth > 0 ? `rollback to d${depth}` : "rollback");
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
execTransaction
|
|
35
|
+
};
|