rado 0.2.38 → 0.2.40
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/driver/better-sqlite3.d.ts +3 -3
- package/dist/driver/better-sqlite3.js +5 -10
- package/dist/driver/bun-sqlite.d.ts +3 -3
- package/dist/driver/bun-sqlite.js +5 -10
- package/dist/driver/sql.js.d.ts +3 -3
- package/dist/driver/sql.js.js +9 -14
- package/dist/driver/sqlite3.d.ts +3 -3
- package/dist/driver/sqlite3.js +8 -11
- package/dist/index.d.ts +1 -1
- package/dist/lib/Driver.d.ts +11 -3
- package/dist/lib/Driver.js +77 -12
- package/dist/lib/Formatter.js +5 -5
- package/dist/lib/SqlError.d.ts +1 -1
- package/dist/lib/Statement.d.ts +77 -2
- package/dist/lib/Statement.js +89 -9
- package/package.json +2 -2
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { Database } from 'better-sqlite3';
|
|
2
2
|
import { SchemaInstructions } from '../define/Schema.js';
|
|
3
|
-
import { Driver } from '../lib/Driver.js';
|
|
3
|
+
import { Driver, DriverOptions } from '../lib/Driver.js';
|
|
4
4
|
import { Statement } from '../lib/Statement.js';
|
|
5
5
|
import { SqliteSchema } from '../sqlite/SqliteSchema.js';
|
|
6
6
|
export declare class BetterSqlite3Driver extends Driver.Sync {
|
|
7
7
|
db: Database;
|
|
8
8
|
tableData: (tableName: string) => Array<SqliteSchema.Column>;
|
|
9
9
|
indexData: (tableName: string) => Array<SqliteSchema.Index>;
|
|
10
|
-
constructor(db: Database);
|
|
10
|
+
constructor(db: Database, options?: DriverOptions);
|
|
11
11
|
prepareStatement(stmt: Statement): Driver.Sync.PreparedStatement;
|
|
12
12
|
schemaInstructions(tableName: string): SchemaInstructions | undefined;
|
|
13
13
|
export(): Uint8Array;
|
|
14
14
|
}
|
|
15
|
-
export declare function connect(db: Database): BetterSqlite3Driver;
|
|
15
|
+
export declare function connect(db: Database, options?: DriverOptions): BetterSqlite3Driver;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Driver } from "../lib/Driver.js";
|
|
2
|
-
import { SqlError } from "../lib/SqlError.js";
|
|
3
2
|
import { SqliteFormatter } from "../sqlite/SqliteFormatter.js";
|
|
4
3
|
import { SqliteSchema } from "../sqlite/SqliteSchema.js";
|
|
5
4
|
class PreparedStatement {
|
|
@@ -23,8 +22,8 @@ class PreparedStatement {
|
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
class BetterSqlite3Driver extends Driver.Sync {
|
|
26
|
-
constructor(db) {
|
|
27
|
-
super(new SqliteFormatter());
|
|
25
|
+
constructor(db, options) {
|
|
26
|
+
super(new SqliteFormatter(), options);
|
|
28
27
|
this.db = db;
|
|
29
28
|
this.tableData = this.prepare(SqliteSchema.tableData);
|
|
30
29
|
this.indexData = this.prepare(SqliteSchema.indexData);
|
|
@@ -32,11 +31,7 @@ class BetterSqlite3Driver extends Driver.Sync {
|
|
|
32
31
|
tableData;
|
|
33
32
|
indexData;
|
|
34
33
|
prepareStatement(stmt) {
|
|
35
|
-
|
|
36
|
-
return new PreparedStatement(this.db.prepare(stmt.sql));
|
|
37
|
-
} catch (e) {
|
|
38
|
-
throw new SqlError(e, stmt.sql);
|
|
39
|
-
}
|
|
34
|
+
return new PreparedStatement(this.db.prepare(stmt.sql));
|
|
40
35
|
}
|
|
41
36
|
schemaInstructions(tableName) {
|
|
42
37
|
const columnData = this.tableData(tableName);
|
|
@@ -47,8 +42,8 @@ class BetterSqlite3Driver extends Driver.Sync {
|
|
|
47
42
|
return this.db.serialize();
|
|
48
43
|
}
|
|
49
44
|
}
|
|
50
|
-
function connect(db) {
|
|
51
|
-
return new BetterSqlite3Driver(db);
|
|
45
|
+
function connect(db, options) {
|
|
46
|
+
return new BetterSqlite3Driver(db, options);
|
|
52
47
|
}
|
|
53
48
|
export {
|
|
54
49
|
BetterSqlite3Driver,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="bun-types" />
|
|
2
2
|
import type { Database } from 'bun:sqlite';
|
|
3
3
|
import { SchemaInstructions } from '../define/Schema.js';
|
|
4
|
-
import { Driver } from '../lib/Driver.js';
|
|
4
|
+
import { Driver, DriverOptions } from '../lib/Driver.js';
|
|
5
5
|
import { Statement } from '../lib/Statement.js';
|
|
6
6
|
import { SqliteSchema } from '../sqlite/SqliteSchema.js';
|
|
7
7
|
export declare class BunSqliteDriver extends Driver.Sync {
|
|
@@ -11,8 +11,8 @@ export declare class BunSqliteDriver extends Driver.Sync {
|
|
|
11
11
|
lastChanges: () => {
|
|
12
12
|
rowsAffected: number;
|
|
13
13
|
};
|
|
14
|
-
constructor(db: Database);
|
|
14
|
+
constructor(db: Database, options?: DriverOptions);
|
|
15
15
|
prepareStatement(stmt: Statement): Driver.Sync.PreparedStatement;
|
|
16
16
|
schemaInstructions(tableName: string): SchemaInstructions | undefined;
|
|
17
17
|
}
|
|
18
|
-
export declare function connect(db: Database): BunSqliteDriver;
|
|
18
|
+
export declare function connect(db: Database, options?: DriverOptions): BunSqliteDriver;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { QueryData } from "../define/Query.js";
|
|
2
2
|
import { SelectFirst } from "../define/query/Select.js";
|
|
3
3
|
import { Driver } from "../lib/Driver.js";
|
|
4
|
-
import { SqlError } from "../lib/SqlError.js";
|
|
5
4
|
import { SqliteFormatter } from "../sqlite/SqliteFormatter.js";
|
|
6
5
|
import { SqliteSchema } from "../sqlite/SqliteSchema.js";
|
|
7
6
|
class PreparedStatement {
|
|
@@ -28,8 +27,8 @@ class PreparedStatement {
|
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
class BunSqliteDriver extends Driver.Sync {
|
|
31
|
-
constructor(db) {
|
|
32
|
-
super(new SqliteFormatter());
|
|
30
|
+
constructor(db, options) {
|
|
31
|
+
super(new SqliteFormatter(), options);
|
|
33
32
|
this.db = db;
|
|
34
33
|
this.tableData = this.prepare(SqliteSchema.tableData);
|
|
35
34
|
this.indexData = this.prepare(SqliteSchema.indexData);
|
|
@@ -47,11 +46,7 @@ class BunSqliteDriver extends Driver.Sync {
|
|
|
47
46
|
indexData;
|
|
48
47
|
lastChanges;
|
|
49
48
|
prepareStatement(stmt) {
|
|
50
|
-
|
|
51
|
-
return new PreparedStatement(this.lastChanges, this.db.prepare(stmt.sql));
|
|
52
|
-
} catch (e) {
|
|
53
|
-
throw new SqlError(e, stmt.sql);
|
|
54
|
-
}
|
|
49
|
+
return new PreparedStatement(this.lastChanges, this.db.prepare(stmt.sql));
|
|
55
50
|
}
|
|
56
51
|
schemaInstructions(tableName) {
|
|
57
52
|
const columnData = this.tableData(tableName);
|
|
@@ -59,8 +54,8 @@ class BunSqliteDriver extends Driver.Sync {
|
|
|
59
54
|
return SqliteSchema.createInstructions(columnData, indexData);
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
|
-
function connect(db) {
|
|
63
|
-
return new BunSqliteDriver(db);
|
|
57
|
+
function connect(db, options) {
|
|
58
|
+
return new BunSqliteDriver(db, options);
|
|
64
59
|
}
|
|
65
60
|
export {
|
|
66
61
|
BunSqliteDriver,
|
package/dist/driver/sql.js.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { Database } from 'sql.js';
|
|
2
2
|
import { SchemaInstructions } from '../define/Schema.js';
|
|
3
|
-
import { Driver } from '../lib/Driver.js';
|
|
3
|
+
import { Driver, DriverOptions } from '../lib/Driver.js';
|
|
4
4
|
import { Statement } from '../lib/Statement.js';
|
|
5
5
|
import { SqliteSchema } from '../sqlite/SqliteSchema.js';
|
|
6
6
|
export declare class SqlJsDriver extends Driver.Sync {
|
|
7
7
|
db: Database;
|
|
8
8
|
tableData?: (tableName: string) => Array<SqliteSchema.Column>;
|
|
9
9
|
indexData?: (tableName: string) => Array<SqliteSchema.Index>;
|
|
10
|
-
constructor(db: Database);
|
|
10
|
+
constructor(db: Database, options?: DriverOptions);
|
|
11
11
|
prepareStatement(stmt: Statement, discardAfter: boolean): Driver.Sync.PreparedStatement;
|
|
12
12
|
schemaInstructions(tableName: string): SchemaInstructions | undefined;
|
|
13
13
|
export(): Uint8Array;
|
|
14
14
|
}
|
|
15
|
-
export declare function connect(db: Database): SqlJsDriver;
|
|
15
|
+
export declare function connect(db: Database, options?: DriverOptions): SqlJsDriver;
|
package/dist/driver/sql.js.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Driver } from "../lib/Driver.js";
|
|
2
|
-
import { SqlError } from "../lib/SqlError.js";
|
|
3
2
|
import { SqliteFormatter } from "../sqlite/SqliteFormatter.js";
|
|
4
3
|
import { SqliteSchema } from "../sqlite/SqliteSchema.js";
|
|
5
4
|
class PreparedStatement {
|
|
@@ -34,22 +33,18 @@ class PreparedStatement {
|
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
35
|
class SqlJsDriver extends Driver.Sync {
|
|
37
|
-
constructor(db) {
|
|
38
|
-
super(new SqliteFormatter());
|
|
36
|
+
constructor(db, options) {
|
|
37
|
+
super(new SqliteFormatter(), options);
|
|
39
38
|
this.db = db;
|
|
40
39
|
}
|
|
41
40
|
tableData;
|
|
42
41
|
indexData;
|
|
43
42
|
prepareStatement(stmt, discardAfter) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
);
|
|
50
|
-
} catch (e) {
|
|
51
|
-
throw new SqlError(e, stmt.sql);
|
|
52
|
-
}
|
|
43
|
+
return new PreparedStatement(
|
|
44
|
+
this.db,
|
|
45
|
+
this.db.prepare(stmt.sql),
|
|
46
|
+
discardAfter
|
|
47
|
+
);
|
|
53
48
|
}
|
|
54
49
|
schemaInstructions(tableName) {
|
|
55
50
|
this.tableData = this.tableData || (this.tableData = this.prepare(SqliteSchema.tableData));
|
|
@@ -62,8 +57,8 @@ class SqlJsDriver extends Driver.Sync {
|
|
|
62
57
|
return this.db.export();
|
|
63
58
|
}
|
|
64
59
|
}
|
|
65
|
-
function connect(db) {
|
|
66
|
-
return new SqlJsDriver(db);
|
|
60
|
+
function connect(db, options) {
|
|
61
|
+
return new SqlJsDriver(db, options);
|
|
67
62
|
}
|
|
68
63
|
export {
|
|
69
64
|
SqlJsDriver,
|
package/dist/driver/sqlite3.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Database } from 'sqlite3';
|
|
2
2
|
import { QueryData } from '../define/Query.js';
|
|
3
3
|
import { SchemaInstructions } from '../define/Schema.js';
|
|
4
|
-
import { Driver } from '../lib/Driver.js';
|
|
4
|
+
import { Driver, DriverOptions } from '../lib/Driver.js';
|
|
5
5
|
import { Statement } from '../lib/Statement.js';
|
|
6
6
|
import { SqliteSchema } from '../sqlite/SqliteSchema.js';
|
|
7
7
|
export declare class Sqlite3Driver extends Driver.Async {
|
|
@@ -9,10 +9,10 @@ export declare class Sqlite3Driver extends Driver.Async {
|
|
|
9
9
|
lock: Promise<void> | undefined;
|
|
10
10
|
tableData: (tableName: string) => Promise<Array<SqliteSchema.Column>>;
|
|
11
11
|
indexData: (tableName: string) => Promise<Array<SqliteSchema.Index>>;
|
|
12
|
-
constructor(db: Database);
|
|
12
|
+
constructor(db: Database, options?: DriverOptions);
|
|
13
13
|
executeQuery(query: QueryData, stmt?: Driver.Async.PreparedStatement, params?: any[] | undefined): Promise<unknown>;
|
|
14
14
|
prepareStatement(stmt: Statement): Driver.Async.PreparedStatement;
|
|
15
15
|
schemaInstructions(tableName: string): Promise<SchemaInstructions | undefined>;
|
|
16
16
|
isolate(): [connection: Driver.Async, release: () => Promise<void>];
|
|
17
17
|
}
|
|
18
|
-
export declare function connect(db: Database): Sqlite3Driver;
|
|
18
|
+
export declare function connect(db: Database, options?: DriverOptions): Sqlite3Driver;
|
package/dist/driver/sqlite3.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Driver } from "../lib/Driver.js";
|
|
2
|
-
import { SqlError } from "../lib/SqlError.js";
|
|
3
2
|
import { SqliteFormatter } from "../sqlite/SqliteFormatter.js";
|
|
4
3
|
import { SqliteSchema } from "../sqlite/SqliteSchema.js";
|
|
5
4
|
class PreparedStatement {
|
|
@@ -7,7 +6,9 @@ class PreparedStatement {
|
|
|
7
6
|
this.stmt = stmt;
|
|
8
7
|
}
|
|
9
8
|
async *iterate(params) {
|
|
10
|
-
let rows = []
|
|
9
|
+
let rows = [];
|
|
10
|
+
let done = false;
|
|
11
|
+
let error;
|
|
11
12
|
let resolve;
|
|
12
13
|
let promise = new Promise((r) => resolve = r);
|
|
13
14
|
this.stmt.each(
|
|
@@ -79,8 +80,8 @@ class PreparedStatement {
|
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
class Sqlite3Driver extends Driver.Async {
|
|
82
|
-
constructor(db) {
|
|
83
|
-
super(new SqliteFormatter());
|
|
83
|
+
constructor(db, options) {
|
|
84
|
+
super(new SqliteFormatter(), options);
|
|
84
85
|
this.db = db;
|
|
85
86
|
this.tableData = this.prepare(SqliteSchema.tableData);
|
|
86
87
|
this.indexData = this.prepare(SqliteSchema.indexData);
|
|
@@ -93,11 +94,7 @@ class Sqlite3Driver extends Driver.Async {
|
|
|
93
94
|
return super.executeQuery(query, stmt, params);
|
|
94
95
|
}
|
|
95
96
|
prepareStatement(stmt) {
|
|
96
|
-
|
|
97
|
-
return new PreparedStatement(this.db.prepare(stmt.sql));
|
|
98
|
-
} catch (e) {
|
|
99
|
-
throw new SqlError(e, stmt.sql);
|
|
100
|
-
}
|
|
97
|
+
return new PreparedStatement(this.db.prepare(stmt.sql));
|
|
101
98
|
}
|
|
102
99
|
async schemaInstructions(tableName) {
|
|
103
100
|
const columnData = await this.tableData(tableName);
|
|
@@ -113,8 +110,8 @@ class Sqlite3Driver extends Driver.Async {
|
|
|
113
110
|
return [connection, release];
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
|
-
function connect(db) {
|
|
117
|
-
return new Sqlite3Driver(db);
|
|
113
|
+
function connect(db, options) {
|
|
114
|
+
return new Sqlite3Driver(db, options);
|
|
118
115
|
}
|
|
119
116
|
export {
|
|
120
117
|
Sqlite3Driver,
|
package/dist/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export * from './define/query/Select.js';
|
|
|
22
22
|
export * from './define/query/TableSelect.js';
|
|
23
23
|
export * from './define/query/Union.js';
|
|
24
24
|
export * from './define/query/Update.js';
|
|
25
|
-
export type { Driver } from './lib/Driver.js';
|
|
25
|
+
export type { Driver, DriverOptions } from './lib/Driver.js';
|
|
26
26
|
export type { FormatContext, Formatter } from './lib/Formatter.js';
|
|
27
27
|
export type { Sanitizer } from './lib/Sanitizer.js';
|
|
28
28
|
export * from './lib/SqlError.js';
|
package/dist/lib/Driver.d.ts
CHANGED
|
@@ -6,9 +6,13 @@ import { Select } from '../define/query/Select.js';
|
|
|
6
6
|
import { Callable } from '../util/Callable.js';
|
|
7
7
|
import { Formatter } from './Formatter.js';
|
|
8
8
|
import { Statement } from './Statement.js';
|
|
9
|
+
export interface DriverOptions {
|
|
10
|
+
logQuery?: (stmt: Statement, durationMs: number) => void;
|
|
11
|
+
}
|
|
9
12
|
declare abstract class DriverBase extends Callable {
|
|
10
13
|
formatter: Formatter;
|
|
11
|
-
|
|
14
|
+
options: DriverOptions;
|
|
15
|
+
constructor(formatter: Formatter, options: DriverOptions);
|
|
12
16
|
compile<T extends Array<Expr<any>>, R>(create: (...params: T) => Query<R>): [QueryData, Statement];
|
|
13
17
|
executeTemplate(expectedReturn: QueryData.RawReturn, strings: TemplateStringsArray, ...params: Array<any>): any;
|
|
14
18
|
abstract executeQuery(query: QueryData): any;
|
|
@@ -25,9 +29,11 @@ interface SyncDriver {
|
|
|
25
29
|
}
|
|
26
30
|
declare abstract class SyncDriver extends DriverBase {
|
|
27
31
|
transactionId: number;
|
|
28
|
-
constructor(formatter: Formatter);
|
|
32
|
+
constructor(formatter: Formatter, options?: DriverOptions);
|
|
29
33
|
abstract prepareStatement(stmt: Statement, discardAfter: boolean): SyncPreparedStatement;
|
|
30
34
|
abstract schemaInstructions(tableName: string): SchemaInstructions | undefined;
|
|
35
|
+
createStatement(stmt: Statement, discardAfter: boolean): SyncPreparedStatement;
|
|
36
|
+
handle(stmt: Statement, prepared: SyncPreparedStatement): SyncPreparedStatement;
|
|
31
37
|
prepare<T extends Array<Expr<any>>, R>(create: (...params: T) => Query<R>): (...params: ParamTypes<T>) => R;
|
|
32
38
|
migrateSchema(...tables: Array<Table<any>>): unknown;
|
|
33
39
|
executeQuery(query: QueryData, stmt?: SyncPreparedStatement, params?: Array<any>): unknown;
|
|
@@ -51,10 +57,12 @@ interface AsyncDriver {
|
|
|
51
57
|
}
|
|
52
58
|
declare abstract class AsyncDriver extends DriverBase {
|
|
53
59
|
transactionId: number;
|
|
54
|
-
constructor(formatter: Formatter);
|
|
60
|
+
constructor(formatter: Formatter, options?: DriverOptions);
|
|
55
61
|
abstract isolate(): [connection: AsyncDriver, release: () => Promise<void>];
|
|
56
62
|
abstract prepareStatement(stmt: Statement, discardAfter: boolean): AsyncPreparedStatement;
|
|
57
63
|
abstract schemaInstructions(tableName: string): Promise<SchemaInstructions | undefined>;
|
|
64
|
+
createStatement(stmt: Statement, discardAfter: boolean): AsyncPreparedStatement;
|
|
65
|
+
handle(stmt: Statement, prepared: AsyncPreparedStatement): AsyncPreparedStatement;
|
|
58
66
|
prepare<T extends Array<Expr<any>>, R>(create: (...params: T) => Query<R>): (...params: ParamTypes<T>) => Promise<R>;
|
|
59
67
|
migrateSchema(...tables: Array<Table<any>>): Promise<unknown>;
|
|
60
68
|
executeQuery(query: QueryData, stmt?: AsyncPreparedStatement, params?: Array<any>): Promise<unknown>;
|
package/dist/lib/Driver.js
CHANGED
|
@@ -4,11 +4,12 @@ import { Query, QueryData, QueryType } from "../define/Query.js";
|
|
|
4
4
|
import { Schema } from "../define/Schema.js";
|
|
5
5
|
import { Table } from "../define/Table.js";
|
|
6
6
|
import { Callable } from "../util/Callable.js";
|
|
7
|
+
import { SqlError } from "./SqlError.js";
|
|
7
8
|
function isTemplateStringsArray(input) {
|
|
8
9
|
return Boolean(Array.isArray(input) && input.raw);
|
|
9
10
|
}
|
|
10
11
|
class DriverBase extends Callable {
|
|
11
|
-
constructor(formatter) {
|
|
12
|
+
constructor(formatter, options) {
|
|
12
13
|
super((...args) => {
|
|
13
14
|
const [input, ...rest] = args;
|
|
14
15
|
if (Query.isQuery(input) && rest.length === 0)
|
|
@@ -22,6 +23,7 @@ class DriverBase extends Callable {
|
|
|
22
23
|
);
|
|
23
24
|
});
|
|
24
25
|
this.formatter = formatter;
|
|
26
|
+
this.options = options;
|
|
25
27
|
}
|
|
26
28
|
compile(create) {
|
|
27
29
|
const { length } = create;
|
|
@@ -41,13 +43,41 @@ class DriverBase extends Callable {
|
|
|
41
43
|
}
|
|
42
44
|
class SyncDriver extends DriverBase {
|
|
43
45
|
transactionId;
|
|
44
|
-
constructor(formatter) {
|
|
45
|
-
super(formatter);
|
|
46
|
+
constructor(formatter, options = {}) {
|
|
47
|
+
super(formatter, options);
|
|
46
48
|
this.transactionId = 0;
|
|
47
49
|
}
|
|
50
|
+
createStatement(stmt, discardAfter) {
|
|
51
|
+
try {
|
|
52
|
+
return this.handle(stmt, this.prepareStatement(stmt, discardAfter));
|
|
53
|
+
} catch (e) {
|
|
54
|
+
throw new SqlError(e, stmt.sql);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
handle(stmt, prepared) {
|
|
58
|
+
const { logQuery } = this.options;
|
|
59
|
+
const wrap = (fn) => (...args) => {
|
|
60
|
+
const startTime = performance.now();
|
|
61
|
+
try {
|
|
62
|
+
const res = fn(...args);
|
|
63
|
+
if (logQuery)
|
|
64
|
+
logQuery(stmt, performance.now() - startTime);
|
|
65
|
+
return res;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
throw new SqlError(e, stmt.sql);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
run: wrap(prepared.run.bind(prepared)),
|
|
72
|
+
iterate: wrap(prepared.iterate.bind(prepared)),
|
|
73
|
+
all: wrap(prepared.all.bind(prepared)),
|
|
74
|
+
get: wrap(prepared.get.bind(prepared)),
|
|
75
|
+
execute: wrap(prepared.execute.bind(prepared))
|
|
76
|
+
};
|
|
77
|
+
}
|
|
48
78
|
prepare(create) {
|
|
49
79
|
const [query, compiled] = this.compile(create);
|
|
50
|
-
const prepared = this.
|
|
80
|
+
const prepared = this.createStatement(compiled, false);
|
|
51
81
|
return (...params) => {
|
|
52
82
|
const namedParams = Object.fromEntries(
|
|
53
83
|
params.map((value, i) => [`p${i}`, value])
|
|
@@ -90,7 +120,7 @@ class SyncDriver extends DriverBase {
|
|
|
90
120
|
});
|
|
91
121
|
default:
|
|
92
122
|
const compiled = stmt ? void 0 : this.formatter.compile(query);
|
|
93
|
-
stmt = stmt || this.
|
|
123
|
+
stmt = stmt || this.createStatement(compiled, true);
|
|
94
124
|
params = params || compiled.params();
|
|
95
125
|
if ("selection" in query || query.type === QueryType.Union) {
|
|
96
126
|
const res = stmt.all(params).map((row) => JSON.parse(row.result).result);
|
|
@@ -117,7 +147,7 @@ class SyncDriver extends DriverBase {
|
|
|
117
147
|
}
|
|
118
148
|
}
|
|
119
149
|
*iterate(cursor) {
|
|
120
|
-
const stmt = this.
|
|
150
|
+
const stmt = this.createStatement(
|
|
121
151
|
this.formatter.compile(cursor[Query.Data]),
|
|
122
152
|
true
|
|
123
153
|
);
|
|
@@ -155,13 +185,48 @@ class SyncDriver extends DriverBase {
|
|
|
155
185
|
}
|
|
156
186
|
class AsyncDriver extends DriverBase {
|
|
157
187
|
transactionId;
|
|
158
|
-
constructor(formatter) {
|
|
159
|
-
super(formatter);
|
|
188
|
+
constructor(formatter, options = {}) {
|
|
189
|
+
super(formatter, options);
|
|
160
190
|
this.transactionId = 0;
|
|
161
191
|
}
|
|
192
|
+
createStatement(stmt, discardAfter) {
|
|
193
|
+
try {
|
|
194
|
+
return this.handle(stmt, this.prepareStatement(stmt, discardAfter));
|
|
195
|
+
} catch (e) {
|
|
196
|
+
throw new SqlError(e, stmt.sql);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
handle(stmt, prepared) {
|
|
200
|
+
const { logQuery } = this.options;
|
|
201
|
+
const wrap = (fn) => async (...args) => {
|
|
202
|
+
const startTime = performance.now();
|
|
203
|
+
try {
|
|
204
|
+
const res = await fn(...args);
|
|
205
|
+
if (logQuery)
|
|
206
|
+
logQuery(stmt, (performance.now() - startTime) / 1e3);
|
|
207
|
+
return res;
|
|
208
|
+
} catch (e) {
|
|
209
|
+
throw new SqlError(e, stmt.sql);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
return {
|
|
213
|
+
run: wrap(prepared.run.bind(prepared)),
|
|
214
|
+
async *iterate(params) {
|
|
215
|
+
const iterator = prepared.iterate(params);
|
|
216
|
+
try {
|
|
217
|
+
yield* iterator;
|
|
218
|
+
} catch (e) {
|
|
219
|
+
throw new SqlError(e, stmt.sql);
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
all: wrap(prepared.all.bind(prepared)),
|
|
223
|
+
get: wrap(prepared.get.bind(prepared)),
|
|
224
|
+
execute: wrap(prepared.execute.bind(prepared))
|
|
225
|
+
};
|
|
226
|
+
}
|
|
162
227
|
prepare(create) {
|
|
163
228
|
const [query, compiled] = this.compile(create);
|
|
164
|
-
const prepared = this.
|
|
229
|
+
const prepared = this.createStatement(compiled, false);
|
|
165
230
|
return (...params) => {
|
|
166
231
|
const namedParams = Object.fromEntries(
|
|
167
232
|
params.map((value, i) => [`p${i}`, value])
|
|
@@ -204,7 +269,7 @@ class AsyncDriver extends DriverBase {
|
|
|
204
269
|
});
|
|
205
270
|
default:
|
|
206
271
|
const compiled = stmt ? void 0 : this.formatter.compile(query);
|
|
207
|
-
stmt = stmt || this.
|
|
272
|
+
stmt = stmt || this.createStatement(compiled, true);
|
|
208
273
|
params = params || compiled.params();
|
|
209
274
|
if ("selection" in query || query.type === QueryType.Union) {
|
|
210
275
|
const res = (await stmt.all(params)).map(
|
|
@@ -233,7 +298,7 @@ class AsyncDriver extends DriverBase {
|
|
|
233
298
|
}
|
|
234
299
|
}
|
|
235
300
|
async *iterate(cursor) {
|
|
236
|
-
const stmt = this.
|
|
301
|
+
const stmt = this.createStatement(
|
|
237
302
|
this.formatter.compile(cursor[Query.Data]),
|
|
238
303
|
true
|
|
239
304
|
);
|
|
@@ -292,7 +357,7 @@ class SyncPreparedStatementWrapper {
|
|
|
292
357
|
}
|
|
293
358
|
class SyncWrapper extends AsyncDriver {
|
|
294
359
|
constructor(sync) {
|
|
295
|
-
super(sync.formatter);
|
|
360
|
+
super(sync.formatter, sync.options);
|
|
296
361
|
this.sync = sync;
|
|
297
362
|
}
|
|
298
363
|
lock;
|
package/dist/lib/Formatter.js
CHANGED
|
@@ -424,7 +424,7 @@ class Formatter {
|
|
|
424
424
|
const { stmt } = ctx;
|
|
425
425
|
if (!expr)
|
|
426
426
|
return stmt;
|
|
427
|
-
stmt.
|
|
427
|
+
stmt.addLine("WHERE").space();
|
|
428
428
|
this.formatExprValue(ctx, expr);
|
|
429
429
|
return stmt;
|
|
430
430
|
}
|
|
@@ -432,7 +432,7 @@ class Formatter {
|
|
|
432
432
|
const { stmt } = ctx;
|
|
433
433
|
if (!expr)
|
|
434
434
|
return stmt;
|
|
435
|
-
stmt.
|
|
435
|
+
stmt.addLine("HAVING");
|
|
436
436
|
this.formatExprValue(ctx, expr);
|
|
437
437
|
return stmt;
|
|
438
438
|
}
|
|
@@ -440,7 +440,7 @@ class Formatter {
|
|
|
440
440
|
const { stmt } = ctx;
|
|
441
441
|
if (!groupBy)
|
|
442
442
|
return stmt;
|
|
443
|
-
stmt.
|
|
443
|
+
stmt.addLine("GROUP BY").space();
|
|
444
444
|
for (const expr of stmt.separate(groupBy))
|
|
445
445
|
this.formatExprValue(ctx, expr);
|
|
446
446
|
return stmt;
|
|
@@ -449,7 +449,7 @@ class Formatter {
|
|
|
449
449
|
const { stmt } = ctx;
|
|
450
450
|
if (!orderBy)
|
|
451
451
|
return stmt;
|
|
452
|
-
stmt.
|
|
452
|
+
stmt.addLine("ORDER BY").space();
|
|
453
453
|
for (const { expr, order } of stmt.separate(orderBy)) {
|
|
454
454
|
this.formatExprValue(ctx, expr);
|
|
455
455
|
stmt.add(order === OrderDirection.Asc ? "ASC" : "DESC");
|
|
@@ -460,7 +460,7 @@ class Formatter {
|
|
|
460
460
|
const { stmt, forceInline } = ctx;
|
|
461
461
|
if (!limit && !offset && !singleResult)
|
|
462
462
|
return stmt;
|
|
463
|
-
stmt.
|
|
463
|
+
stmt.addLine("LIMIT").space();
|
|
464
464
|
this.formatValue(ctx, singleResult ? 1 : limit);
|
|
465
465
|
if (offset && offset > 0) {
|
|
466
466
|
stmt.add("OFFSET").space();
|
package/dist/lib/SqlError.d.ts
CHANGED
package/dist/lib/Statement.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { ParamData } from '../define/Param.js';
|
|
2
2
|
import { Sanitizer } from './Sanitizer.js';
|
|
3
3
|
export interface StatementOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Do not add any newlines while composing the statement
|
|
6
|
+
*/
|
|
4
7
|
skipNewlines?: boolean;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* A statement is a query string builder with parameter placeholders, and a list
|
|
11
|
+
* of parameter values.
|
|
12
|
+
*/
|
|
6
13
|
export declare class Statement {
|
|
7
14
|
sanitizer: Sanitizer;
|
|
8
15
|
options: StatementOptions;
|
|
@@ -10,24 +17,92 @@ export declare class Statement {
|
|
|
10
17
|
paramData: Array<ParamData>;
|
|
11
18
|
currentIndent: string;
|
|
12
19
|
constructor(sanitizer: Sanitizer, options?: StatementOptions);
|
|
13
|
-
|
|
20
|
+
/**
|
|
21
|
+
* UNSAFE
|
|
22
|
+
* Adds a string without applying escaping
|
|
23
|
+
*/
|
|
24
|
+
raw(query: string): this;
|
|
25
|
+
/**
|
|
26
|
+
* UNSAFE
|
|
27
|
+
* Adds a space if the statement is not empty, and then adds the given string
|
|
28
|
+
* without applying escaping
|
|
29
|
+
*/
|
|
14
30
|
add(addition: undefined | string): this;
|
|
31
|
+
/**
|
|
32
|
+
* UNSAFE
|
|
33
|
+
* Adds a newline if the statement is not empty, and then adds the given
|
|
34
|
+
* string without applying escaping
|
|
35
|
+
*/
|
|
15
36
|
addLine(addition: undefined | string): this;
|
|
37
|
+
/**
|
|
38
|
+
* Adds a space if the statement is not empty
|
|
39
|
+
*/
|
|
40
|
+
space(): this;
|
|
41
|
+
/**
|
|
42
|
+
* Increases the indentation level
|
|
43
|
+
*/
|
|
16
44
|
indent(): this;
|
|
45
|
+
/**
|
|
46
|
+
* Decreases the indentation level
|
|
47
|
+
*/
|
|
17
48
|
dedent(): this;
|
|
49
|
+
/**
|
|
50
|
+
* Adds a newline
|
|
51
|
+
*/
|
|
18
52
|
newline(): this;
|
|
53
|
+
/**
|
|
54
|
+
* Adds an identifier, applies escaping
|
|
55
|
+
*/
|
|
19
56
|
identifier(name: string): this;
|
|
57
|
+
/**
|
|
58
|
+
* Adds a space if the statement is not empty, and then adds an identifier
|
|
59
|
+
*/
|
|
20
60
|
addIdentifier(name: string): this;
|
|
61
|
+
/**
|
|
62
|
+
* Adds a value, applies escaping
|
|
63
|
+
*/
|
|
21
64
|
value(value: any): this;
|
|
65
|
+
/**
|
|
66
|
+
* Adds a space if the statement is not empty, and then adds a value
|
|
67
|
+
*/
|
|
22
68
|
addValue(value: any): this;
|
|
69
|
+
/**
|
|
70
|
+
* Adds a parameter
|
|
71
|
+
*/
|
|
23
72
|
param(data: ParamData): this;
|
|
73
|
+
/**
|
|
74
|
+
* Adds a space if the statement is not empty, and then adds a parameter
|
|
75
|
+
*/
|
|
24
76
|
addParam(data: ParamData): this;
|
|
25
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Opens a parenthesis and indents the next line
|
|
79
|
+
*/
|
|
26
80
|
openParenthesis(): this;
|
|
81
|
+
/**
|
|
82
|
+
* Closes a parenthesis and dedents the next line
|
|
83
|
+
*/
|
|
27
84
|
closeParenthesis(): this;
|
|
85
|
+
/**
|
|
86
|
+
* Adds parenthesis on start and end, and a seperator to the output on
|
|
87
|
+
* each iteration
|
|
88
|
+
*/
|
|
28
89
|
call<T>(parts: Array<T>, separator?: string): Generator<T, this | undefined, unknown>;
|
|
90
|
+
/**
|
|
91
|
+
* Adds seperator to the output on each iteration
|
|
92
|
+
*/
|
|
29
93
|
separate<T>(parts: Array<T>, separator?: string): Generator<T, void, unknown>;
|
|
94
|
+
/**
|
|
95
|
+
* Returns true if the statement is empty
|
|
96
|
+
*/
|
|
30
97
|
isEmpty(): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Returns the parameter values in the order they appear in the query string
|
|
100
|
+
*/
|
|
31
101
|
params(input?: Record<string, any>): Array<any>;
|
|
102
|
+
/**
|
|
103
|
+
* For debug purposes this will apply parameter values to the query string,
|
|
104
|
+
* and return the result
|
|
105
|
+
*/
|
|
106
|
+
inlineParams(): string;
|
|
32
107
|
toString(): string;
|
|
33
108
|
}
|
package/dist/lib/Statement.js
CHANGED
|
@@ -11,66 +11,120 @@ class Statement {
|
|
|
11
11
|
sql = "";
|
|
12
12
|
paramData = [];
|
|
13
13
|
currentIndent = "";
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* UNSAFE
|
|
16
|
+
* Adds a string without applying escaping
|
|
17
|
+
*/
|
|
18
|
+
raw(query) {
|
|
19
|
+
if (!query)
|
|
16
20
|
return this;
|
|
17
|
-
|
|
21
|
+
this.sql += query;
|
|
22
|
+
return this;
|
|
18
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* UNSAFE
|
|
26
|
+
* Adds a space if the statement is not empty, and then adds the given string
|
|
27
|
+
* without applying escaping
|
|
28
|
+
*/
|
|
19
29
|
add(addition) {
|
|
20
30
|
if (!addition)
|
|
21
31
|
return this;
|
|
22
32
|
return this.space().raw(addition);
|
|
23
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* UNSAFE
|
|
36
|
+
* Adds a newline if the statement is not empty, and then adds the given
|
|
37
|
+
* string without applying escaping
|
|
38
|
+
*/
|
|
24
39
|
addLine(addition) {
|
|
25
40
|
if (!addition)
|
|
26
41
|
return this;
|
|
27
42
|
return this.newline().raw(addition);
|
|
28
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Adds a space if the statement is not empty
|
|
46
|
+
*/
|
|
47
|
+
space() {
|
|
48
|
+
if (this.sql === "")
|
|
49
|
+
return this;
|
|
50
|
+
return this.raw(WHITESPACE);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Increases the indentation level
|
|
54
|
+
*/
|
|
29
55
|
indent() {
|
|
30
56
|
this.currentIndent = this.currentIndent + " ";
|
|
31
57
|
return this;
|
|
32
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Decreases the indentation level
|
|
61
|
+
*/
|
|
33
62
|
dedent() {
|
|
34
63
|
this.currentIndent = this.currentIndent.slice(0, -2);
|
|
35
64
|
return this;
|
|
36
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Adds a newline
|
|
68
|
+
*/
|
|
37
69
|
newline() {
|
|
38
70
|
if (this.options.skipNewlines)
|
|
39
71
|
return this;
|
|
40
72
|
return this.raw(NEWLINE + this.currentIndent);
|
|
41
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Adds an identifier, applies escaping
|
|
76
|
+
*/
|
|
42
77
|
identifier(name) {
|
|
43
78
|
return this.raw(this.sanitizer.escapeIdentifier(name));
|
|
44
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Adds a space if the statement is not empty, and then adds an identifier
|
|
82
|
+
*/
|
|
45
83
|
addIdentifier(name) {
|
|
46
84
|
return this.space().identifier(name);
|
|
47
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Adds a value, applies escaping
|
|
88
|
+
*/
|
|
48
89
|
value(value) {
|
|
49
90
|
this.paramData.push(new ParamData.Value(value));
|
|
50
91
|
return this.raw(INSERT_PARAM);
|
|
51
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Adds a space if the statement is not empty, and then adds a value
|
|
95
|
+
*/
|
|
52
96
|
addValue(value) {
|
|
53
97
|
return this.space().value(value);
|
|
54
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Adds a parameter
|
|
101
|
+
*/
|
|
55
102
|
param(data) {
|
|
56
103
|
this.paramData.push(data);
|
|
57
104
|
return this.raw(INSERT_PARAM);
|
|
58
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Adds a space if the statement is not empty, and then adds a parameter
|
|
108
|
+
*/
|
|
59
109
|
addParam(data) {
|
|
60
110
|
return this.space().param(data);
|
|
61
111
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.sql += query;
|
|
66
|
-
return this;
|
|
67
|
-
}
|
|
112
|
+
/**
|
|
113
|
+
* Opens a parenthesis and indents the next line
|
|
114
|
+
*/
|
|
68
115
|
openParenthesis() {
|
|
69
116
|
return this.raw("(").indent().newline();
|
|
70
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Closes a parenthesis and dedents the next line
|
|
120
|
+
*/
|
|
71
121
|
closeParenthesis() {
|
|
72
122
|
return this.dedent().newline().raw(")");
|
|
73
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Adds parenthesis on start and end, and a seperator to the output on
|
|
126
|
+
* each iteration
|
|
127
|
+
*/
|
|
74
128
|
*call(parts, separator = SEPARATE) {
|
|
75
129
|
if (parts.length === 0)
|
|
76
130
|
return this.raw("()");
|
|
@@ -78,6 +132,9 @@ class Statement {
|
|
|
78
132
|
yield* this.separate(parts, separator);
|
|
79
133
|
this.closeParenthesis();
|
|
80
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Adds seperator to the output on each iteration
|
|
137
|
+
*/
|
|
81
138
|
*separate(parts, separator = SEPARATE) {
|
|
82
139
|
for (let i = 0; i < parts.length; i++) {
|
|
83
140
|
if (i > 0)
|
|
@@ -85,9 +142,15 @@ class Statement {
|
|
|
85
142
|
yield parts[i];
|
|
86
143
|
}
|
|
87
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Returns true if the statement is empty
|
|
147
|
+
*/
|
|
88
148
|
isEmpty() {
|
|
89
149
|
return this.sql === "";
|
|
90
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Returns the parameter values in the order they appear in the query string
|
|
153
|
+
*/
|
|
91
154
|
params(input) {
|
|
92
155
|
return this.paramData.map((param) => {
|
|
93
156
|
if (param.type === ParamType.Named) {
|
|
@@ -98,6 +161,23 @@ class Statement {
|
|
|
98
161
|
return this.sanitizer.formatParamValue(param.value);
|
|
99
162
|
});
|
|
100
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* For debug purposes this will apply parameter values to the query string,
|
|
166
|
+
* and return the result
|
|
167
|
+
*/
|
|
168
|
+
inlineParams() {
|
|
169
|
+
let index = 0;
|
|
170
|
+
return this.sql.replace(/\?/g, () => {
|
|
171
|
+
const param = this.paramData[index];
|
|
172
|
+
index++;
|
|
173
|
+
switch (param.type) {
|
|
174
|
+
case ParamType.Named:
|
|
175
|
+
return `?${param.name}`;
|
|
176
|
+
case ParamType.Value:
|
|
177
|
+
return this.sanitizer.escapeValue(param.value);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
101
181
|
toString() {
|
|
102
182
|
return this.sql;
|
|
103
183
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rado",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.40",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"sade": "^1.8.1",
|
|
60
60
|
"speedscope": "^1.15.0",
|
|
61
61
|
"sql.js": "^1.8.0",
|
|
62
|
-
"sqlite3": "^5.1.
|
|
62
|
+
"sqlite3": "^5.1.6",
|
|
63
63
|
"tsx": "^3.12.3",
|
|
64
64
|
"typescript": "beta",
|
|
65
65
|
"uvu": "^0.5.6"
|