rado 1.0.7 → 1.0.9
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/README.md +1 -0
- package/dist/core/Column.js +3 -4
- package/dist/core/Database.d.ts +0 -1
- package/dist/core/Database.js +2 -5
- package/dist/core/Emitter.d.ts +2 -1
- package/dist/core/Emitter.js +8 -16
- package/dist/core/Query.js +2 -4
- package/dist/core/Resolver.js +5 -10
- package/dist/core/Selection.js +9 -14
- package/dist/core/Sql.d.ts +4 -1
- package/dist/core/Sql.js +29 -27
- package/dist/core/Table.js +2 -4
- package/dist/core/Virtual.js +3 -6
- package/dist/core/expr/Conditions.js +7 -14
- package/dist/core/expr/Include.js +1 -2
- package/dist/core/expr/Input.js +3 -6
- package/dist/core/expr/Json.d.ts +9 -3
- package/dist/core/expr/Json.js +16 -5
- package/dist/core/query/Delete.js +1 -2
- package/dist/core/query/Insert.js +2 -4
- package/dist/core/query/Select.js +1 -2
- package/dist/core/query/Update.js +1 -2
- package/dist/driver/better-sqlite3.js +1 -2
- package/dist/driver/mysql2.d.ts +1 -0
- package/dist/driver/mysql2.js +14 -9
- package/dist/driver/pg.js +4 -8
- package/dist/driver/pglite.js +1 -2
- package/dist/driver/sql.js.js +2 -4
- package/dist/mysql/columns.d.ts +2 -1
- package/dist/mysql/columns.js +4 -0
- package/dist/mysql/dialect.js +7 -6
- package/dist/mysql/transactions.js +1 -2
- package/dist/postgres/columns.d.ts +2 -2
- package/dist/postgres/columns.js +3 -3
- package/dist/postgres/dialect.js +9 -13
- package/dist/sqlite/dialect.js +9 -10
- package/dist/sqlite/diff.js +1 -2
- package/dist/sqlite/functions.d.ts +0 -2
- package/dist/sqlite/functions.js +0 -2
- package/dist/sqlite/transactions.js +2 -4
- package/dist/universal/columns.d.ts +7 -1
- package/dist/universal/columns.js +39 -6
- package/dist/universal/transactions.js +1 -2
- package/package.json +12 -15
package/README.md
CHANGED
package/dist/core/Column.js
CHANGED
|
@@ -68,10 +68,9 @@ var column = new Proxy(createColumn, {
|
|
|
68
68
|
get(target, method) {
|
|
69
69
|
return target[method] ??= (...args) => {
|
|
70
70
|
while (args.length > 0)
|
|
71
|
-
if (args.at(-1) === void 0)
|
|
72
|
-
|
|
73
|
-
if (args.length === 0)
|
|
74
|
-
return sql.unsafe(method);
|
|
71
|
+
if (args.at(-1) === void 0) args.pop();
|
|
72
|
+
else break;
|
|
73
|
+
if (args.length === 0) return sql.unsafe(method);
|
|
75
74
|
return sql`${sql.unsafe(method)}(${sql.join(
|
|
76
75
|
args.map(sql.inline),
|
|
77
76
|
sql`, `
|
package/dist/core/Database.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ 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;
|
|
12
11
|
driver: Driver;
|
|
13
12
|
dialect: Dialect;
|
|
14
13
|
diff: Diff;
|
package/dist/core/Database.js
CHANGED
|
@@ -49,8 +49,7 @@ var Database = class extends Builder {
|
|
|
49
49
|
txGenerator(function* (tx) {
|
|
50
50
|
for (const table of tables) {
|
|
51
51
|
const diff = yield* computeDiff(table);
|
|
52
|
-
if (diff.length > 0)
|
|
53
|
-
yield* tx.batch(diff.map(sql.unsafe));
|
|
52
|
+
if (diff.length > 0) yield* tx.batch(diff.map(sql.unsafe));
|
|
54
53
|
}
|
|
55
54
|
})
|
|
56
55
|
);
|
|
@@ -60,11 +59,9 @@ var Database = class extends Builder {
|
|
|
60
59
|
}
|
|
61
60
|
execute(input) {
|
|
62
61
|
const emitter = this.dialect.emit(input);
|
|
63
|
-
if (emitter.hasParams)
|
|
64
|
-
throw new Error("Query has parameters");
|
|
62
|
+
if (emitter.hasParams) throw new Error("Query has parameters");
|
|
65
63
|
return this.driver.exec(emitter.sql);
|
|
66
64
|
}
|
|
67
|
-
#transactionLock;
|
|
68
65
|
transaction(run, options = {}) {
|
|
69
66
|
return this.driver.transaction(
|
|
70
67
|
(inner) => {
|
package/dist/core/Emitter.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { Sql } from './Sql.js';
|
|
|
6
6
|
import type { TableApi } from './Table.js';
|
|
7
7
|
import type { FieldData } from './expr/Field.js';
|
|
8
8
|
import type { IncludeData } from './expr/Include.js';
|
|
9
|
+
import { type JsonPath } from './expr/Json.js';
|
|
9
10
|
import type { Delete } from './query/Delete.js';
|
|
10
11
|
import type { Insert } from './query/Insert.js';
|
|
11
12
|
import type { SelectData } from './query/Select.js';
|
|
@@ -21,7 +22,7 @@ export declare abstract class Emitter {
|
|
|
21
22
|
abstract emitIdentifier(value: string): void;
|
|
22
23
|
abstract emitValue(value: unknown): void;
|
|
23
24
|
abstract emitInline(value: unknown): void;
|
|
24
|
-
abstract emitJsonPath(
|
|
25
|
+
abstract emitJsonPath(path: JsonPath): void;
|
|
25
26
|
abstract emitPlaceholder(value: string): void;
|
|
26
27
|
emitIdentifierOrSelf(value: string): void;
|
|
27
28
|
selfName?: string;
|
package/dist/core/Emitter.js
CHANGED
|
@@ -17,8 +17,7 @@ var Emitter = class {
|
|
|
17
17
|
}
|
|
18
18
|
bind(inputs) {
|
|
19
19
|
return this.params.map((param) => {
|
|
20
|
-
if (param instanceof ValueParam)
|
|
21
|
-
return this.processValue(param.value);
|
|
20
|
+
if (param instanceof ValueParam) return this.processValue(param.value);
|
|
22
21
|
if (inputs && param.name in inputs)
|
|
23
22
|
return this.processValue(inputs[param.name]);
|
|
24
23
|
throw new Error(`Missing input for named parameter: ${param.name}`);
|
|
@@ -29,8 +28,7 @@ var Emitter = class {
|
|
|
29
28
|
}
|
|
30
29
|
emitIdentifierOrSelf(value) {
|
|
31
30
|
if (value === Sql.SELF_TARGET) {
|
|
32
|
-
if (!this.selfName)
|
|
33
|
-
throw new Error("Self target not defined");
|
|
31
|
+
if (!this.selfName) throw new Error("Self target not defined");
|
|
34
32
|
this.emitIdentifier(this.selfName);
|
|
35
33
|
} else {
|
|
36
34
|
this.emitIdentifier(value);
|
|
@@ -78,8 +76,7 @@ var Emitter = class {
|
|
|
78
76
|
}
|
|
79
77
|
emitDelete(deleteOp) {
|
|
80
78
|
const { cte, from, where, returning } = getData(deleteOp);
|
|
81
|
-
if (cte)
|
|
82
|
-
this.emitWith(cte);
|
|
79
|
+
if (cte) this.emitWith(cte);
|
|
83
80
|
const table = getTable(from);
|
|
84
81
|
sql.query({
|
|
85
82
|
deleteFrom: sql.identifier(table.name),
|
|
@@ -89,8 +86,7 @@ var Emitter = class {
|
|
|
89
86
|
}
|
|
90
87
|
emitInsert(insert) {
|
|
91
88
|
const { cte, into, values, select, onConflict, returning } = getData(insert);
|
|
92
|
-
if (cte)
|
|
93
|
-
this.emitWith(cte);
|
|
89
|
+
if (cte) this.emitWith(cte);
|
|
94
90
|
const table = getTable(into);
|
|
95
91
|
const tableName = sql.identifier(table.name);
|
|
96
92
|
sql.query({
|
|
@@ -113,8 +109,7 @@ var Emitter = class {
|
|
|
113
109
|
limit,
|
|
114
110
|
offset
|
|
115
111
|
}) {
|
|
116
|
-
if (cte)
|
|
117
|
-
this.emitWith(cte);
|
|
112
|
+
if (cte) this.emitWith(cte);
|
|
118
113
|
const prefix = distinctOn ? sql`distinct on (${sql.join(distinctOn, sql`, `)})` : distinct && sql`distinct`;
|
|
119
114
|
sql.query({
|
|
120
115
|
select: sql.join([prefix, select]),
|
|
@@ -133,8 +128,7 @@ var Emitter = class {
|
|
|
133
128
|
emitUpdate(update) {
|
|
134
129
|
const { cte, table, set, where, returning } = getData(update);
|
|
135
130
|
const tableApi = getTable(table);
|
|
136
|
-
if (cte)
|
|
137
|
-
this.emitWith(cte);
|
|
131
|
+
if (cte) this.emitWith(cte);
|
|
138
132
|
sql.query({
|
|
139
133
|
update: sql.identifier(tableApi.name),
|
|
140
134
|
set,
|
|
@@ -158,8 +152,7 @@ var Emitter = class {
|
|
|
158
152
|
const wrapQuery = Boolean(data.limit || data.offset || data.orderBy);
|
|
159
153
|
const innerQuery = sql.chunk("emitSelect", data);
|
|
160
154
|
const inner = wrapQuery ? sql`select * from (${innerQuery})` : innerQuery;
|
|
161
|
-
if (!data.select)
|
|
162
|
-
throw new Error("No selection defined");
|
|
155
|
+
if (!data.select) throw new Error("No selection defined");
|
|
163
156
|
const fields = data.select.fieldNames();
|
|
164
157
|
const subject = jsonArray(
|
|
165
158
|
...fields.map((name) => sql`_.${sql.identifier(name)}`)
|
|
@@ -168,8 +161,7 @@ var Emitter = class {
|
|
|
168
161
|
}
|
|
169
162
|
emitUniversal(runtimes) {
|
|
170
163
|
const sql2 = runtimes[this.runtime] ?? runtimes.default;
|
|
171
|
-
if (!sql2)
|
|
172
|
-
throw new Error("Unsupported runtime");
|
|
164
|
+
if (!sql2) throw new Error("Unsupported runtime");
|
|
173
165
|
sql2.emitTo(this);
|
|
174
166
|
}
|
|
175
167
|
};
|
package/dist/core/Query.js
CHANGED
|
@@ -17,8 +17,7 @@ var Executable = class {
|
|
|
17
17
|
*[Symbol.iterator]() {
|
|
18
18
|
const interim = this.#execute();
|
|
19
19
|
const isAsync = interim instanceof Promise;
|
|
20
|
-
if (!isAsync)
|
|
21
|
-
return interim;
|
|
20
|
+
if (!isAsync) return interim;
|
|
22
21
|
let result;
|
|
23
22
|
yield interim.then((v) => result = v);
|
|
24
23
|
return result;
|
|
@@ -82,8 +81,7 @@ var Query = class extends Executable {
|
|
|
82
81
|
}
|
|
83
82
|
toSQL(db) {
|
|
84
83
|
const resolver = db ? getResolver(db) : getData(this).resolver;
|
|
85
|
-
if (!resolver)
|
|
86
|
-
throw new Error("Query has no resolver");
|
|
84
|
+
if (!resolver) throw new Error("Query has no resolver");
|
|
87
85
|
return resolver.toSQL(this);
|
|
88
86
|
}
|
|
89
87
|
};
|
package/dist/core/Resolver.js
CHANGED
|
@@ -51,8 +51,7 @@ var Batch = class {
|
|
|
51
51
|
};
|
|
52
52
|
for (let i = 0; i < this.#queries.length; i++) {
|
|
53
53
|
const { mapRow } = this.#queries[i];
|
|
54
|
-
if (!mapRow)
|
|
55
|
-
continue;
|
|
54
|
+
if (!mapRow) continue;
|
|
56
55
|
const rows = results[i];
|
|
57
56
|
for (let j = 0; j < results[i].length; j++) {
|
|
58
57
|
ctx.values = rows[i];
|
|
@@ -64,8 +63,7 @@ var Batch = class {
|
|
|
64
63
|
};
|
|
65
64
|
execute() {
|
|
66
65
|
const results = this.#driver.batch(this.#queries);
|
|
67
|
-
if (results instanceof Promise)
|
|
68
|
-
return results.then(this.#transform);
|
|
66
|
+
if (results instanceof Promise) return results.then(this.#transform);
|
|
69
67
|
return this.#transform(results);
|
|
70
68
|
}
|
|
71
69
|
};
|
|
@@ -81,8 +79,7 @@ var PreparedStatement = class {
|
|
|
81
79
|
this.#specs = specs;
|
|
82
80
|
}
|
|
83
81
|
#transform = (rows) => {
|
|
84
|
-
if (!this.#mapRow)
|
|
85
|
-
return rows;
|
|
82
|
+
if (!this.#mapRow) return rows;
|
|
86
83
|
const ctx = {
|
|
87
84
|
values: void 0,
|
|
88
85
|
index: 0,
|
|
@@ -97,14 +94,12 @@ var PreparedStatement = class {
|
|
|
97
94
|
};
|
|
98
95
|
all(inputs) {
|
|
99
96
|
const rows = this.#stmt.values(this.#emitter.bind(inputs));
|
|
100
|
-
if (rows instanceof Promise)
|
|
101
|
-
return rows.then(this.#transform);
|
|
97
|
+
if (rows instanceof Promise) return rows.then(this.#transform);
|
|
102
98
|
return this.#transform(rows);
|
|
103
99
|
}
|
|
104
100
|
get(inputs) {
|
|
105
101
|
const rows = this.all(inputs);
|
|
106
|
-
if (rows instanceof Promise)
|
|
107
|
-
return rows.then((rows2) => rows2[0]);
|
|
102
|
+
if (rows instanceof Promise) return rows.then((rows2) => rows2[0]);
|
|
108
103
|
return rows[0];
|
|
109
104
|
}
|
|
110
105
|
run(inputs) {
|
package/dist/core/Selection.js
CHANGED
|
@@ -15,8 +15,7 @@ var SqlColumn = class {
|
|
|
15
15
|
}
|
|
16
16
|
result(ctx) {
|
|
17
17
|
const value = ctx.values[ctx.index++];
|
|
18
|
-
if (!this.sql.mapFromDriverValue)
|
|
19
|
-
return value;
|
|
18
|
+
if (!this.sql.mapFromDriverValue) return value;
|
|
20
19
|
return this.sql.mapFromDriverValue(value, ctx.specs);
|
|
21
20
|
}
|
|
22
21
|
};
|
|
@@ -42,8 +41,7 @@ var ObjectColumn = class {
|
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
|
-
if (isNullable)
|
|
46
|
-
return null;
|
|
44
|
+
if (isNullable) return null;
|
|
47
45
|
return result;
|
|
48
46
|
}
|
|
49
47
|
};
|
|
@@ -60,8 +58,7 @@ var Selection = class {
|
|
|
60
58
|
}
|
|
61
59
|
#defineColumn(nullable, input) {
|
|
62
60
|
const expr = getSql(input);
|
|
63
|
-
if (expr)
|
|
64
|
-
return new SqlColumn(expr, getField(input)?.targetName);
|
|
61
|
+
if (expr) return new SqlColumn(expr, getField(input)?.targetName);
|
|
65
62
|
return new ObjectColumn(
|
|
66
63
|
nullable,
|
|
67
64
|
Object.entries(input).map(([name, value]) => [
|
|
@@ -76,9 +73,9 @@ var Selection = class {
|
|
|
76
73
|
#fieldNames(input, names, name) {
|
|
77
74
|
const expr = getSql(input);
|
|
78
75
|
if (expr) {
|
|
79
|
-
|
|
80
|
-
if (!exprName)
|
|
81
|
-
|
|
76
|
+
let exprName = name ?? expr.alias;
|
|
77
|
+
if (!exprName) throw new Error("Missing field name");
|
|
78
|
+
while (names.has(exprName)) exprName = `${exprName}_`;
|
|
82
79
|
return [exprName];
|
|
83
80
|
}
|
|
84
81
|
return Object.entries(input).flatMap(
|
|
@@ -90,15 +87,13 @@ var Selection = class {
|
|
|
90
87
|
if (expr) {
|
|
91
88
|
let exprName = name ?? expr.alias;
|
|
92
89
|
if (exprName) {
|
|
93
|
-
while (names.has(exprName))
|
|
94
|
-
exprName = `${exprName}_`;
|
|
90
|
+
while (names.has(exprName)) exprName = `${exprName}_`;
|
|
95
91
|
names.add(exprName);
|
|
96
92
|
if (hasField(input)) {
|
|
97
93
|
const field = getField(input);
|
|
98
|
-
if (field.fieldName === exprName)
|
|
99
|
-
return expr;
|
|
94
|
+
if (field.fieldName === exprName) return expr;
|
|
100
95
|
}
|
|
101
|
-
return sql`${expr} as ${sql.identifier(exprName)}`;
|
|
96
|
+
return sql`${expr.forSelection()} as ${sql.identifier(exprName)}`;
|
|
102
97
|
}
|
|
103
98
|
return expr;
|
|
104
99
|
}
|
package/dist/core/Sql.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { Emitter } from './Emitter.js';
|
|
|
3
3
|
import { type HasSql, internalSql } from './Internal.js';
|
|
4
4
|
import type { Runtime } from './MetaData.js';
|
|
5
5
|
import type { FieldData } from './expr/Field.js';
|
|
6
|
+
import type { JsonPath } from './expr/Json.js';
|
|
6
7
|
type EmitMethods = {
|
|
7
8
|
[K in keyof Emitter as K extends `emit${string}` ? K : never]: Emitter[K];
|
|
8
9
|
};
|
|
@@ -31,7 +32,8 @@ export declare class Sql<Value = unknown> implements HasSql<Value> {
|
|
|
31
32
|
value(value: unknown): Sql<Value>;
|
|
32
33
|
getValue(): Value | undefined;
|
|
33
34
|
inline(value: unknown): Sql<Value>;
|
|
34
|
-
jsonPath(path:
|
|
35
|
+
jsonPath(path: JsonPath): Sql<Value>;
|
|
36
|
+
forSelection(): Sql<Value>;
|
|
35
37
|
placeholder(name: string): Sql<Value>;
|
|
36
38
|
identifier(identifier: string): Sql<Value>;
|
|
37
39
|
inlineValues(): Sql<Value>;
|
|
@@ -48,6 +50,7 @@ export declare namespace sql {
|
|
|
48
50
|
export function placeholder<T>(name: string): Sql<T>;
|
|
49
51
|
export function identifier<T>(identifier: string): Sql<T>;
|
|
50
52
|
export function field<T>(field: FieldData): Sql<T>;
|
|
53
|
+
export function jsonPath<T>(path: JsonPath): Sql<T>;
|
|
51
54
|
export function chunk<Type extends keyof EmitMethods>(type: Type, inner: Parameters<EmitMethods[Type]>[0]): Sql;
|
|
52
55
|
export function universal<T>(runtimes: Partial<Record<Runtime | 'default', Sql<T>>>): Sql<T>;
|
|
53
56
|
type QueryChunk = HasSql | undefined;
|
package/dist/core/Sql.js
CHANGED
|
@@ -29,8 +29,7 @@ var Sql = class _Sql {
|
|
|
29
29
|
return this;
|
|
30
30
|
}
|
|
31
31
|
unsafe(sql2) {
|
|
32
|
-
if (sql2.length > 0)
|
|
33
|
-
this.chunk("emitUnsafe", sql2);
|
|
32
|
+
if (sql2.length > 0) this.chunk("emitUnsafe", sql2);
|
|
34
33
|
return this;
|
|
35
34
|
}
|
|
36
35
|
field(field) {
|
|
@@ -38,8 +37,7 @@ var Sql = class _Sql {
|
|
|
38
37
|
}
|
|
39
38
|
add(sql2) {
|
|
40
39
|
const inner = getSql(sql2);
|
|
41
|
-
if (!(inner instanceof _Sql))
|
|
42
|
-
throw new Error("Invalid SQL");
|
|
40
|
+
if (!(inner instanceof _Sql)) throw new Error("Invalid SQL");
|
|
43
41
|
this.#chunks.push(...inner.#chunks);
|
|
44
42
|
return this;
|
|
45
43
|
}
|
|
@@ -47,21 +45,28 @@ var Sql = class _Sql {
|
|
|
47
45
|
return this.chunk("emitValue", value);
|
|
48
46
|
}
|
|
49
47
|
getValue() {
|
|
50
|
-
if (this.#chunks.length !== 1)
|
|
51
|
-
return;
|
|
48
|
+
if (this.#chunks.length !== 1) return;
|
|
52
49
|
const chunk = this.#chunks[0];
|
|
53
|
-
if (chunk?.type === "emitValue")
|
|
54
|
-
return chunk.inner;
|
|
50
|
+
if (chunk?.type === "emitValue") return chunk.inner;
|
|
55
51
|
}
|
|
56
52
|
inline(value) {
|
|
57
53
|
return this.chunk("emitInline", value);
|
|
58
54
|
}
|
|
59
55
|
jsonPath(path) {
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
const inner = path.target.#chunks[0];
|
|
57
|
+
if (inner?.type !== "emitJsonPath") return this.chunk("emitJsonPath", path);
|
|
58
|
+
const innerPath = inner.inner;
|
|
59
|
+
return this.chunk("emitJsonPath", {
|
|
60
|
+
...innerPath,
|
|
61
|
+
segments: [...innerPath.segments, ...path.segments]
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
forSelection() {
|
|
65
|
+
if (this.#chunks.length === 1) {
|
|
66
|
+
const first = this.#chunks[0];
|
|
67
|
+
if (first.type === "emitJsonPath")
|
|
68
|
+
return sql.jsonPath({ ...first.inner, asSql: false }).mapWith(this);
|
|
69
|
+
}
|
|
65
70
|
return this;
|
|
66
71
|
}
|
|
67
72
|
placeholder(name) {
|
|
@@ -73,8 +78,7 @@ var Sql = class _Sql {
|
|
|
73
78
|
inlineValues() {
|
|
74
79
|
return new _Sql(
|
|
75
80
|
this.#chunks.map((chunk) => {
|
|
76
|
-
if (chunk.type !== "emitValue")
|
|
77
|
-
return chunk;
|
|
81
|
+
if (chunk.type !== "emitValue") return chunk;
|
|
78
82
|
return new Chunk("emitInline", chunk.inner);
|
|
79
83
|
})
|
|
80
84
|
);
|
|
@@ -82,8 +86,7 @@ var Sql = class _Sql {
|
|
|
82
86
|
inlineFields(withTableName) {
|
|
83
87
|
return new _Sql(
|
|
84
88
|
this.#chunks.flatMap((chunk) => {
|
|
85
|
-
if (chunk.type !== "emitField")
|
|
86
|
-
return [chunk];
|
|
89
|
+
if (chunk.type !== "emitField") return [chunk];
|
|
87
90
|
const data = chunk.inner;
|
|
88
91
|
if (withTableName)
|
|
89
92
|
return [
|
|
@@ -99,8 +102,7 @@ var Sql = class _Sql {
|
|
|
99
102
|
return sql.chunk("emitSelf", { name, inner: this });
|
|
100
103
|
}
|
|
101
104
|
emitTo(emitter) {
|
|
102
|
-
for (const chunk of this.#chunks)
|
|
103
|
-
emitter[chunk.type](chunk.inner);
|
|
105
|
+
for (const chunk of this.#chunks) emitter[chunk.type](chunk.inner);
|
|
104
106
|
}
|
|
105
107
|
};
|
|
106
108
|
function sql(strings, ...inner) {
|
|
@@ -143,6 +145,10 @@ function sql(strings, ...inner) {
|
|
|
143
145
|
return empty().field(field2);
|
|
144
146
|
}
|
|
145
147
|
sql2.field = field;
|
|
148
|
+
function jsonPath(path) {
|
|
149
|
+
return empty().jsonPath(path);
|
|
150
|
+
}
|
|
151
|
+
sql2.jsonPath = jsonPath;
|
|
146
152
|
function chunk(type, inner) {
|
|
147
153
|
return empty().chunk(type, inner);
|
|
148
154
|
}
|
|
@@ -155,12 +161,9 @@ function sql(strings, ...inner) {
|
|
|
155
161
|
return join(
|
|
156
162
|
Object.entries(ast).map(([key, value2]) => {
|
|
157
163
|
const statement = key.replace(/([A-Z])/g, " $1").toLocaleLowerCase();
|
|
158
|
-
if (value2 === true)
|
|
159
|
-
|
|
160
|
-
if (
|
|
161
|
-
value2 = join(value2);
|
|
162
|
-
if (!key)
|
|
163
|
-
return value2;
|
|
164
|
+
if (value2 === true) return sql2.unsafe(statement);
|
|
165
|
+
if (Array.isArray(value2)) value2 = join(value2);
|
|
166
|
+
if (!key) return value2;
|
|
164
167
|
return value2 && sql2`${sql2.unsafe(statement)} ${value2}`;
|
|
165
168
|
})
|
|
166
169
|
);
|
|
@@ -170,8 +173,7 @@ function sql(strings, ...inner) {
|
|
|
170
173
|
const parts = items.filter(Boolean);
|
|
171
174
|
const sql3 = new Sql();
|
|
172
175
|
for (let i = 0; i < parts.length; i++) {
|
|
173
|
-
if (i > 0)
|
|
174
|
-
sql3.add(separator);
|
|
176
|
+
if (i > 0) sql3.add(separator);
|
|
175
177
|
sql3.add(parts[i]);
|
|
176
178
|
}
|
|
177
179
|
return sql3;
|
package/dist/core/Table.js
CHANGED
|
@@ -71,8 +71,7 @@ var TableApi = class extends TableData {
|
|
|
71
71
|
const columnApi = getData(column);
|
|
72
72
|
const { name: givenName } = columnApi;
|
|
73
73
|
const field = new Field(this.aliased, givenName ?? name, columnApi);
|
|
74
|
-
if (columnApi.json)
|
|
75
|
-
return [name, jsonExpr(field)];
|
|
74
|
+
if (columnApi.json) return [name, jsonExpr(field)];
|
|
76
75
|
return [name, field];
|
|
77
76
|
})
|
|
78
77
|
);
|
|
@@ -114,8 +113,7 @@ function table(name, columns, config, schemaName) {
|
|
|
114
113
|
[internalTarget]: api.target(),
|
|
115
114
|
...api.fields()
|
|
116
115
|
};
|
|
117
|
-
if (config)
|
|
118
|
-
api.config = config(table2);
|
|
116
|
+
if (config) api.config = config(table2);
|
|
119
117
|
return table2;
|
|
120
118
|
}
|
|
121
119
|
function alias(table2, alias2) {
|
package/dist/core/Virtual.js
CHANGED
|
@@ -7,17 +7,14 @@ function virtual(alias, source) {
|
|
|
7
7
|
if (source && hasSql(source)) {
|
|
8
8
|
const expr = getSql(source);
|
|
9
9
|
const name = expr.alias;
|
|
10
|
-
if (!name)
|
|
11
|
-
throw new Error("Cannot alias a virtual field without a name");
|
|
10
|
+
if (!name) throw new Error("Cannot alias a virtual field without a name");
|
|
12
11
|
return Object.assign(new Field(alias, name, expr), target);
|
|
13
12
|
}
|
|
14
13
|
return new Proxy(target, {
|
|
15
14
|
get(target2, field) {
|
|
16
|
-
if (field in target2)
|
|
17
|
-
return target2[field];
|
|
15
|
+
if (field in target2) return target2[field];
|
|
18
16
|
const from = source?.[field];
|
|
19
|
-
if (typeof field !== "string")
|
|
20
|
-
return from;
|
|
17
|
+
if (typeof field !== "string") return from;
|
|
21
18
|
return target2[field] = new Field(
|
|
22
19
|
alias,
|
|
23
20
|
field,
|
|
@@ -23,18 +23,14 @@ var arrayContained = binop("<@");
|
|
|
23
23
|
var arrayOverlaps = binop("&&");
|
|
24
24
|
function and(...conditions) {
|
|
25
25
|
const inputs = conditions.filter((v) => v !== void 0).map(input);
|
|
26
|
-
if (inputs.length === 0)
|
|
27
|
-
|
|
28
|
-
if (inputs.length === 1)
|
|
29
|
-
return bool(inputs[0]);
|
|
26
|
+
if (inputs.length === 0) return bool(sql`true`);
|
|
27
|
+
if (inputs.length === 1) return bool(inputs[0]);
|
|
30
28
|
return bool(sql`(${sql.join(inputs, sql` and `)})`);
|
|
31
29
|
}
|
|
32
30
|
function or(...conditions) {
|
|
33
31
|
const inputs = conditions.filter((v) => v !== void 0).map(input);
|
|
34
|
-
if (inputs.length === 0)
|
|
35
|
-
|
|
36
|
-
if (inputs.length === 1)
|
|
37
|
-
return bool(inputs[0]);
|
|
32
|
+
if (inputs.length === 0) return bool(sql`true`);
|
|
33
|
+
if (inputs.length === 1) return bool(inputs[0]);
|
|
38
34
|
return bool(sql`(${sql.join(inputs, sql` or `)})`);
|
|
39
35
|
}
|
|
40
36
|
function not(condition) {
|
|
@@ -43,8 +39,7 @@ function not(condition) {
|
|
|
43
39
|
function inArray(left, right) {
|
|
44
40
|
const value = (hasSql(right) ? getSql(right).getValue() : void 0) ?? right;
|
|
45
41
|
if (Array.isArray(value)) {
|
|
46
|
-
if (value.length === 0)
|
|
47
|
-
return sql`false`;
|
|
42
|
+
if (value.length === 0) return sql`false`;
|
|
48
43
|
return bool(sql`${input(left)} in (${sql.join(value.map(input), sql`, `)})`);
|
|
49
44
|
}
|
|
50
45
|
return bool(sql`${input(left)} in ${input(right)}`);
|
|
@@ -52,8 +47,7 @@ function inArray(left, right) {
|
|
|
52
47
|
function notInArray(left, right) {
|
|
53
48
|
const value = (hasSql(right) ? getSql(right).getValue() : void 0) ?? right;
|
|
54
49
|
if (Array.isArray(value)) {
|
|
55
|
-
if (value.length === 0)
|
|
56
|
-
return sql`true`;
|
|
50
|
+
if (value.length === 0) return sql`true`;
|
|
57
51
|
return bool(
|
|
58
52
|
sql`${input(left)} not in (${sql.join(value.map(input), sql`, `)})`
|
|
59
53
|
);
|
|
@@ -94,8 +88,7 @@ function when(...cases) {
|
|
|
94
88
|
const [condition, result] = pair;
|
|
95
89
|
return sql`when ${input(condition)} then ${input(result)}`;
|
|
96
90
|
}
|
|
97
|
-
if (index === cases.length - 1)
|
|
98
|
-
return sql`else ${input(pair)}`;
|
|
91
|
+
if (index === cases.length - 1) return sql`else ${input(pair)}`;
|
|
99
92
|
throw new Error("Unexpected else condition");
|
|
100
93
|
})
|
|
101
94
|
),
|
|
@@ -15,8 +15,7 @@ var Include = class {
|
|
|
15
15
|
const parsed = specs.parsesJson ? value : JSON.parse(value);
|
|
16
16
|
if (first)
|
|
17
17
|
return parsed ? select.mapRow({ values: parsed, index: 0, specs }) : null;
|
|
18
|
-
if (!parsed)
|
|
19
|
-
return [];
|
|
18
|
+
if (!parsed) return [];
|
|
20
19
|
const rows = parsed;
|
|
21
20
|
const ctx = {
|
|
22
21
|
values: void 0,
|
package/dist/core/expr/Input.js
CHANGED
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
import { getSql, getTable, hasSql, hasTable } from "../Internal.js";
|
|
3
3
|
import { sql } from "../Sql.js";
|
|
4
4
|
function input(value) {
|
|
5
|
-
if (typeof value !== "object" || value === null)
|
|
6
|
-
|
|
7
|
-
if (
|
|
8
|
-
return sql.identifier(getTable(value).name);
|
|
9
|
-
if (hasSql(value))
|
|
10
|
-
return getSql(value);
|
|
5
|
+
if (typeof value !== "object" || value === null) return sql.value(value);
|
|
6
|
+
if (hasTable(value)) return sql.identifier(getTable(value).name);
|
|
7
|
+
if (hasSql(value)) return getSql(value);
|
|
11
8
|
return sql.value(value);
|
|
12
9
|
}
|
|
13
10
|
export {
|
package/dist/core/expr/Json.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type HasSql } from '../Internal.js';
|
|
2
|
+
import { type Sql } from '../Sql.js';
|
|
2
3
|
import type { Input } from './Input.js';
|
|
3
4
|
export interface JsonArrayHasSql<Value> extends HasSql<Array<Value>> {
|
|
4
5
|
[index: number]: JsonExpr<Value>;
|
|
@@ -10,7 +11,12 @@ type NullableEach<T> = {
|
|
|
10
11
|
[P in keyof T]: T[P] | null;
|
|
11
12
|
};
|
|
12
13
|
export type JsonExpr<Value> = [NonNullable<Value>] extends [Array<infer V>] ? JsonArrayHasSql<null extends Value ? V | null : V> : [NonNullable<Value>] extends [object] ? JsonRecordHasSql<null extends Value ? NullableEach<Value> : Value> : HasSql<Value>;
|
|
14
|
+
export interface JsonPath {
|
|
15
|
+
target: Sql;
|
|
16
|
+
segments: Array<number | string>;
|
|
17
|
+
asSql: boolean;
|
|
18
|
+
}
|
|
13
19
|
export declare function jsonExpr<Value>(e: HasSql<Value>): JsonExpr<Value>;
|
|
14
|
-
export declare function jsonAggregateArray(...args: Array<Input<unknown>>):
|
|
15
|
-
export declare function jsonArray(...args: Array<Input<unknown>>):
|
|
20
|
+
export declare function jsonAggregateArray(...args: Array<Input<unknown>>): Sql<unknown>;
|
|
21
|
+
export declare function jsonArray(...args: Array<Input<unknown>>): Sql<unknown>;
|
|
16
22
|
export {};
|
package/dist/core/expr/Json.js
CHANGED
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
// src/core/expr/Json.ts
|
|
2
|
+
import { getSql } from "../Internal.js";
|
|
2
3
|
import { sql } from "../Sql.js";
|
|
3
4
|
import { callFunction } from "./Functions.js";
|
|
4
5
|
var INDEX_PROPERTY = /^\d+$/;
|
|
5
6
|
function jsonExpr(e) {
|
|
6
7
|
return new Proxy(e, {
|
|
7
8
|
get(target, prop) {
|
|
8
|
-
if (typeof prop !== "string")
|
|
9
|
-
return Reflect.get(target, prop);
|
|
9
|
+
if (typeof prop !== "string") return Reflect.get(target, prop);
|
|
10
10
|
const isNumber = INDEX_PROPERTY.test(prop);
|
|
11
|
-
return jsonExpr(
|
|
11
|
+
return jsonExpr(
|
|
12
|
+
sql.jsonPath({
|
|
13
|
+
target: getSql(target),
|
|
14
|
+
asSql: true,
|
|
15
|
+
segments: [isNumber ? Number(prop) : prop]
|
|
16
|
+
}).mapWith({
|
|
17
|
+
mapFromDriverValue(value, specs) {
|
|
18
|
+
return specs.parsesJson ? value : JSON.parse(value);
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
);
|
|
12
22
|
}
|
|
13
23
|
});
|
|
14
24
|
}
|
|
15
25
|
function jsonAggregateArray(...args) {
|
|
16
26
|
return callFunction(
|
|
17
27
|
sql.universal({
|
|
28
|
+
// Once sqlite 3.45+ is more commonplace we can use jsonb_group_array
|
|
18
29
|
sqlite: sql`json_group_array`,
|
|
19
|
-
postgres: sql`
|
|
30
|
+
postgres: sql`jsonb_agg`,
|
|
20
31
|
mysql: sql`json_arrayagg`
|
|
21
32
|
}),
|
|
22
33
|
args
|
|
@@ -25,7 +36,7 @@ function jsonAggregateArray(...args) {
|
|
|
25
36
|
function jsonArray(...args) {
|
|
26
37
|
return callFunction(
|
|
27
38
|
sql.universal({
|
|
28
|
-
postgres: sql`
|
|
39
|
+
postgres: sql`jsonb_build_array`,
|
|
29
40
|
default: sql`json_array`
|
|
30
41
|
}),
|
|
31
42
|
args
|
|
@@ -16,8 +16,7 @@ var Delete = class extends Query {
|
|
|
16
16
|
constructor(data) {
|
|
17
17
|
super(data);
|
|
18
18
|
this[internalData] = data;
|
|
19
|
-
if (data.returning)
|
|
20
|
-
this[internalSelection] = data.returning;
|
|
19
|
+
if (data.returning) this[internalSelection] = data.returning;
|
|
21
20
|
}
|
|
22
21
|
get [internalQuery]() {
|
|
23
22
|
return sql.chunk("emitDelete", this);
|
|
@@ -18,8 +18,7 @@ var Insert = class extends Query {
|
|
|
18
18
|
constructor(data) {
|
|
19
19
|
super(data);
|
|
20
20
|
this[internalData] = data;
|
|
21
|
-
if (data.returning)
|
|
22
|
-
this[internalSelection] = data.returning;
|
|
21
|
+
if (data.returning) this[internalSelection] = data.returning;
|
|
23
22
|
}
|
|
24
23
|
get [internalQuery]() {
|
|
25
24
|
return sql.chunk("emitInsert", this);
|
|
@@ -87,8 +86,7 @@ var InsertInto = class {
|
|
|
87
86
|
const { $default, mapToDriverValue } = getData(column);
|
|
88
87
|
if (value !== void 0)
|
|
89
88
|
return input(mapToDriverValue?.(value) ?? value);
|
|
90
|
-
if ($default)
|
|
91
|
-
return $default();
|
|
89
|
+
if ($default) return $default();
|
|
92
90
|
return defaultKeyword;
|
|
93
91
|
}),
|
|
94
92
|
sql`, `
|
|
@@ -102,8 +102,7 @@ var Select = class _Select extends UnionBase {
|
|
|
102
102
|
}
|
|
103
103
|
get [internalSelection]() {
|
|
104
104
|
const { select } = getData(this);
|
|
105
|
-
if (!select)
|
|
106
|
-
throw new Error("No selection defined");
|
|
105
|
+
if (!select) throw new Error("No selection defined");
|
|
107
106
|
return select;
|
|
108
107
|
}
|
|
109
108
|
get [internalQuery]() {
|
|
@@ -18,8 +18,7 @@ var Update = class extends Query {
|
|
|
18
18
|
constructor(data) {
|
|
19
19
|
super(data);
|
|
20
20
|
this[internalData] = data;
|
|
21
|
-
if (data.returning)
|
|
22
|
-
this[internalSelection] = data.returning;
|
|
21
|
+
if (data.returning) this[internalSelection] = data.returning;
|
|
23
22
|
}
|
|
24
23
|
get [internalQuery]() {
|
|
25
24
|
return sql.chunk("emitUpdate", this);
|
|
@@ -18,8 +18,7 @@ var PreparedStatement = class {
|
|
|
18
18
|
return this.stmt.get(...params);
|
|
19
19
|
}
|
|
20
20
|
values(params) {
|
|
21
|
-
if (this.isSelection)
|
|
22
|
-
return this.stmt.raw(true).all(...params);
|
|
21
|
+
if (this.isSelection) return this.stmt.raw(true).all(...params);
|
|
23
22
|
this.stmt.run(...params);
|
|
24
23
|
return [];
|
|
25
24
|
}
|
package/dist/driver/mysql2.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { AsyncDatabase, type TransactionOptions } from '../core/Database.js';
|
|
|
4
4
|
import type { AsyncDriver, AsyncStatement, BatchQuery, PrepareOptions } from '../core/Driver.js';
|
|
5
5
|
type Queryable = PromiseConnection | Pool | PoolConnection;
|
|
6
6
|
declare class PreparedStatement implements AsyncStatement {
|
|
7
|
+
#private;
|
|
7
8
|
private client;
|
|
8
9
|
private sql;
|
|
9
10
|
private name?;
|
package/dist/driver/mysql2.js
CHANGED
|
@@ -9,17 +9,25 @@ var PreparedStatement = class {
|
|
|
9
9
|
this.sql = sql;
|
|
10
10
|
this.name = name;
|
|
11
11
|
}
|
|
12
|
+
#transformParam = (param) => {
|
|
13
|
+
if (param instanceof Uint8Array) return Buffer.from(param);
|
|
14
|
+
return param;
|
|
15
|
+
};
|
|
12
16
|
all(params) {
|
|
13
|
-
return this.client.query(this.sql, params).then((res) => res[0]);
|
|
17
|
+
return this.client.query(this.sql, params.map(this.#transformParam)).then((res) => res[0]);
|
|
14
18
|
}
|
|
15
19
|
async run(params) {
|
|
16
|
-
await this.client.query(this.sql, params);
|
|
20
|
+
await this.client.query(this.sql, params.map(this.#transformParam));
|
|
17
21
|
}
|
|
18
22
|
get(params) {
|
|
19
23
|
return this.all(params).then((rows) => rows[0] ?? null);
|
|
20
24
|
}
|
|
21
25
|
values(params) {
|
|
22
|
-
return this.client.query({
|
|
26
|
+
return this.client.query({
|
|
27
|
+
sql: this.sql,
|
|
28
|
+
values: params.map(this.#transformParam),
|
|
29
|
+
rowsAsArray: true
|
|
30
|
+
}).then((res) => res[0]);
|
|
23
31
|
}
|
|
24
32
|
free() {
|
|
25
33
|
}
|
|
@@ -37,8 +45,7 @@ var Mysql2Driver = class _Mysql2Driver {
|
|
|
37
45
|
return new PreparedStatement(this.client, sql, options?.name);
|
|
38
46
|
}
|
|
39
47
|
async close() {
|
|
40
|
-
if ("end" in this.client)
|
|
41
|
-
return this.client.end();
|
|
48
|
+
if ("end" in this.client) return this.client.end();
|
|
42
49
|
}
|
|
43
50
|
async batch(queries) {
|
|
44
51
|
const transact = async (tx) => {
|
|
@@ -47,8 +54,7 @@ var Mysql2Driver = class _Mysql2Driver {
|
|
|
47
54
|
results.push(await tx.prepare(sql).values(params));
|
|
48
55
|
return results;
|
|
49
56
|
};
|
|
50
|
-
if (this.depth > 0)
|
|
51
|
-
return transact(this);
|
|
57
|
+
if (this.depth > 0) return transact(this);
|
|
52
58
|
return this.transaction(transact, {});
|
|
53
59
|
}
|
|
54
60
|
async transaction(run, options) {
|
|
@@ -60,8 +66,7 @@ var Mysql2Driver = class _Mysql2Driver {
|
|
|
60
66
|
);
|
|
61
67
|
if (this.depth === 0) {
|
|
62
68
|
const setOptions = setTransaction(options);
|
|
63
|
-
if (setOptions)
|
|
64
|
-
await client.query(setOptions);
|
|
69
|
+
if (setOptions) await client.query(setOptions);
|
|
65
70
|
}
|
|
66
71
|
const result = await run(driver);
|
|
67
72
|
await client.query(
|
package/dist/driver/pg.js
CHANGED
|
@@ -53,10 +53,8 @@ var PgDriver = class _PgDriver {
|
|
|
53
53
|
return new PreparedStatement(this.client, sql, options?.name);
|
|
54
54
|
}
|
|
55
55
|
async close() {
|
|
56
|
-
if ("end" in this.client)
|
|
57
|
-
|
|
58
|
-
if ("release" in this.client)
|
|
59
|
-
return this.client.release();
|
|
56
|
+
if ("end" in this.client) return this.client.end();
|
|
57
|
+
if ("release" in this.client) return this.client.release();
|
|
60
58
|
}
|
|
61
59
|
async batch(queries) {
|
|
62
60
|
return this.transaction(async (tx) => {
|
|
@@ -70,8 +68,7 @@ var PgDriver = class _PgDriver {
|
|
|
70
68
|
const client = "totalCount" in this.client ? await this.client.connect() : this.client;
|
|
71
69
|
try {
|
|
72
70
|
await client.query(this.depth > 0 ? `savepoint d${this.depth}` : "begin");
|
|
73
|
-
if (this.depth === 0)
|
|
74
|
-
await client.query(setTransaction(options));
|
|
71
|
+
if (this.depth === 0) await client.query(setTransaction(options));
|
|
75
72
|
const result = await run(new _PgDriver(client, this.depth + 1));
|
|
76
73
|
await client.query(
|
|
77
74
|
this.depth > 0 ? `release savepoint d${this.depth}` : "commit"
|
|
@@ -83,8 +80,7 @@ var PgDriver = class _PgDriver {
|
|
|
83
80
|
);
|
|
84
81
|
throw error;
|
|
85
82
|
} finally {
|
|
86
|
-
if ("release" in client)
|
|
87
|
-
client.release();
|
|
83
|
+
if ("release" in client) client.release();
|
|
88
84
|
}
|
|
89
85
|
}
|
|
90
86
|
};
|
package/dist/driver/pglite.js
CHANGED
|
@@ -54,8 +54,7 @@ var PGliteDriver = class _PGliteDriver {
|
|
|
54
54
|
results.push(await tx.prepare(sql).values(params));
|
|
55
55
|
return results;
|
|
56
56
|
};
|
|
57
|
-
if (this.depth > 0)
|
|
58
|
-
return transact(this);
|
|
57
|
+
if (this.depth > 0) return transact(this);
|
|
59
58
|
return this.transaction(transact, {});
|
|
60
59
|
}
|
|
61
60
|
async transaction(run, options) {
|
package/dist/driver/sql.js.js
CHANGED
|
@@ -10,14 +10,12 @@ var PreparedStatement = class {
|
|
|
10
10
|
}
|
|
11
11
|
*iterate(params) {
|
|
12
12
|
this.stmt.bind(params);
|
|
13
|
-
while (this.stmt.step())
|
|
14
|
-
yield this.stmt.getAsObject();
|
|
13
|
+
while (this.stmt.step()) yield this.stmt.getAsObject();
|
|
15
14
|
this.stmt.reset();
|
|
16
15
|
}
|
|
17
16
|
*iterateValues(params) {
|
|
18
17
|
this.stmt.bind(params);
|
|
19
|
-
while (this.stmt.step())
|
|
20
|
-
yield this.stmt.get();
|
|
18
|
+
while (this.stmt.step()) yield this.stmt.get();
|
|
21
19
|
this.stmt.reset();
|
|
22
20
|
}
|
|
23
21
|
all(params) {
|
package/dist/mysql/columns.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Column
|
|
1
|
+
import { JsonColumn, type Column } from '../core/Column.js';
|
|
2
2
|
type Precision = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
3
3
|
export declare function bigint(name: string | undefined, options: {
|
|
4
4
|
mode: 'number';
|
|
@@ -11,6 +11,7 @@ export declare function binary(name?: string, options?: {
|
|
|
11
11
|
length?: number;
|
|
12
12
|
}): Column<Uint8Array | null>;
|
|
13
13
|
export declare function boolean(name?: string): Column<boolean | null>;
|
|
14
|
+
export declare function blob(name?: string): Column<Uint8Array | null>;
|
|
14
15
|
export declare function char(name?: string, options?: {
|
|
15
16
|
length: number;
|
|
16
17
|
}): Column<string | null>;
|
package/dist/mysql/columns.js
CHANGED
|
@@ -13,6 +13,9 @@ function binary(name, options) {
|
|
|
13
13
|
function boolean(name) {
|
|
14
14
|
return column({ name, type: column.boolean() });
|
|
15
15
|
}
|
|
16
|
+
function blob(name) {
|
|
17
|
+
return column({ name, type: column.blob() });
|
|
18
|
+
}
|
|
16
19
|
function char(name, options) {
|
|
17
20
|
return column({ name, type: column.char(options?.length) });
|
|
18
21
|
}
|
|
@@ -125,6 +128,7 @@ function year(name) {
|
|
|
125
128
|
export {
|
|
126
129
|
bigint,
|
|
127
130
|
binary,
|
|
131
|
+
blob,
|
|
128
132
|
boolean,
|
|
129
133
|
char,
|
|
130
134
|
date,
|
package/dist/mysql/dialect.js
CHANGED
|
@@ -16,14 +16,15 @@ var mysqlDialect = new Dialect(
|
|
|
16
16
|
this.sql += "?";
|
|
17
17
|
this.params.push(new ValueParam(value));
|
|
18
18
|
}
|
|
19
|
-
emitJsonPath(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
emitJsonPath({ target, asSql, segments }) {
|
|
20
|
+
target.emitTo(this);
|
|
21
|
+
this.sql += asSql ? "->>" : "->";
|
|
22
|
+
this.sql += this.quoteString(
|
|
23
|
+
`$${segments.map((p) => typeof p === "number" ? `[${p}]` : `.${p}`).join("")}`
|
|
24
|
+
);
|
|
23
25
|
}
|
|
24
26
|
emitInline(value) {
|
|
25
|
-
if (value === null || value === void 0)
|
|
26
|
-
return this.sql += "null";
|
|
27
|
+
if (value === null || value === void 0) return this.sql += "null";
|
|
27
28
|
if (typeof value === "number" || typeof value === "boolean")
|
|
28
29
|
return this.sql += value;
|
|
29
30
|
if (typeof value === "string")
|
|
@@ -7,8 +7,7 @@ function startTransaction(options) {
|
|
|
7
7
|
].filter(Boolean).join(" ");
|
|
8
8
|
}
|
|
9
9
|
function setTransaction(options) {
|
|
10
|
-
if (!options.isolationLevel)
|
|
11
|
-
return;
|
|
10
|
+
if (!options.isolationLevel) return;
|
|
12
11
|
return [
|
|
13
12
|
"set transaction",
|
|
14
13
|
options.isolationLevel && `isolation level ${options.isolationLevel}`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Column
|
|
1
|
+
import { JsonColumn, type Column } from '../core/Column.js';
|
|
2
2
|
type Precision = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
3
3
|
type IntervalFields = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'year to month' | 'day to hour' | 'day to minute' | 'day to second' | 'hour to minute' | 'hour to second' | 'minute to second';
|
|
4
4
|
export declare function bigint(name: string | undefined, options: {
|
|
@@ -30,7 +30,7 @@ export declare function interval(name?: string, options?: {
|
|
|
30
30
|
}): Column<string | null>;
|
|
31
31
|
export declare function serial(name?: string): Column<number>;
|
|
32
32
|
export declare function boolean(name?: string): Column<boolean | null>;
|
|
33
|
-
export declare function
|
|
33
|
+
export declare function bytea(name?: string): Column<Uint8Array | null>;
|
|
34
34
|
export declare function text(name?: string): Column<string | null>;
|
|
35
35
|
export declare function json<T>(name?: string): JsonColumn<T | null>;
|
|
36
36
|
export declare function jsonb<T>(name?: string): JsonColumn<T | null>;
|
package/dist/postgres/columns.js
CHANGED
|
@@ -68,8 +68,8 @@ function serial(name) {
|
|
|
68
68
|
function boolean(name) {
|
|
69
69
|
return column({ name, type: column.boolean() });
|
|
70
70
|
}
|
|
71
|
-
function
|
|
72
|
-
return column({ name, type: column.
|
|
71
|
+
function bytea(name) {
|
|
72
|
+
return column({ name, type: column.bytea() });
|
|
73
73
|
}
|
|
74
74
|
function text(name) {
|
|
75
75
|
return column({ name, type: column.text() });
|
|
@@ -157,8 +157,8 @@ function varchar(name, options) {
|
|
|
157
157
|
export {
|
|
158
158
|
bigint,
|
|
159
159
|
bigserial,
|
|
160
|
-
blob,
|
|
161
160
|
boolean,
|
|
161
|
+
bytea,
|
|
162
162
|
char,
|
|
163
163
|
cidr,
|
|
164
164
|
date,
|
package/dist/postgres/dialect.js
CHANGED
|
@@ -16,22 +16,18 @@ var postgresDialect = new Dialect(
|
|
|
16
16
|
this.sql += `$${++this.paramIndex}`;
|
|
17
17
|
this.params.push(new ValueParam(value));
|
|
18
18
|
}
|
|
19
|
-
emitJsonPath(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
else if (i ===
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.sql += access;
|
|
28
|
-
else
|
|
29
|
-
this.sql += this.quoteString(access);
|
|
19
|
+
emitJsonPath({ target, asSql, segments }) {
|
|
20
|
+
target.emitTo(this);
|
|
21
|
+
for (let i = 0; i < segments.length; i++) {
|
|
22
|
+
const access = segments[i];
|
|
23
|
+
if (i <= segments.length - 2) this.sql += "->";
|
|
24
|
+
else if (i === segments.length - 1) this.sql += asSql ? "->>" : "->";
|
|
25
|
+
if (typeof access === "number") this.sql += access;
|
|
26
|
+
else this.sql += this.quoteString(access);
|
|
30
27
|
}
|
|
31
28
|
}
|
|
32
29
|
emitInline(value) {
|
|
33
|
-
if (value === null || value === void 0)
|
|
34
|
-
return this.sql += "null";
|
|
30
|
+
if (value === null || value === void 0) return this.sql += "null";
|
|
35
31
|
if (typeof value === "number" || typeof value === "boolean")
|
|
36
32
|
return this.sql += value;
|
|
37
33
|
if (typeof value === "string")
|
package/dist/sqlite/dialect.js
CHANGED
|
@@ -18,20 +18,19 @@ var sqliteDialect = new Dialect(
|
|
|
18
18
|
this.sql += "?";
|
|
19
19
|
this.params.push(new ValueParam(value));
|
|
20
20
|
}
|
|
21
|
-
emitJsonPath(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
emitJsonPath({ target, asSql, segments }) {
|
|
22
|
+
target.emitTo(this);
|
|
23
|
+
this.sql += asSql ? "->>" : "->";
|
|
24
|
+
this.sql += this.quoteString(
|
|
25
|
+
`$${segments.map((p) => typeof p === "number" ? `[${p}]` : `.${p}`).join("")}`
|
|
26
|
+
);
|
|
25
27
|
}
|
|
26
28
|
emitInline(value) {
|
|
27
|
-
if (value === null || value === void 0)
|
|
28
|
-
|
|
29
|
-
if (typeof value === "number")
|
|
30
|
-
return this.sql += value;
|
|
29
|
+
if (value === null || value === void 0) return this.sql += "null";
|
|
30
|
+
if (typeof value === "number") return this.sql += value;
|
|
31
31
|
if (typeof value === "string")
|
|
32
32
|
return this.sql += this.quoteString(value);
|
|
33
|
-
if (typeof value === "boolean")
|
|
34
|
-
return this.sql += value ? "1" : "0";
|
|
33
|
+
if (typeof value === "boolean") return this.sql += value ? "1" : "0";
|
|
35
34
|
this.sql += `json(${this.quoteString(JSON.stringify(value))})`;
|
|
36
35
|
}
|
|
37
36
|
emitPlaceholder(name) {
|
package/dist/sqlite/diff.js
CHANGED
|
@@ -104,8 +104,7 @@ var sqliteDiff = (hasTable) => {
|
|
|
104
104
|
sp.rollback(tableInfo);
|
|
105
105
|
});
|
|
106
106
|
} catch (err) {
|
|
107
|
-
if (!(err instanceof Rollback))
|
|
108
|
-
throw err;
|
|
107
|
+
if (!(err instanceof Rollback)) throw err;
|
|
109
108
|
const localInstruction = err.data;
|
|
110
109
|
const schemaInstruction = inline(tableApi.createTable());
|
|
111
110
|
const stripStmt = (q) => q.slice("create table ".length);
|
|
@@ -5,8 +5,6 @@ import { type Input } from '../core/expr/Input.js';
|
|
|
5
5
|
export declare const count: (x?: HasSql) => Sql<number>;
|
|
6
6
|
/** The iif(X,Y,Z) function returns the value Y if X is true, and Z otherwise. The iif(X,Y,Z) function is logically equivalent to and generates the same bytecode as the CASE HasSql "CASE WHEN X THEN Y ELSE Z END".*/
|
|
7
7
|
export declare const iif: <T>(x: Input<boolean>, y: Input<T>, z: Input<T>) => Sql<T>;
|
|
8
|
-
/** Use the match operator for the FTS5 module */
|
|
9
|
-
export declare const match: (table: HasTable, searchTerm: Input<string>) => Sql<boolean>;
|
|
10
8
|
/** Returns a real value reflecting the accuracy of the current match */
|
|
11
9
|
export declare const bm25: (table: HasTable, ...weights: Array<Input<number>>) => Sql<number>;
|
|
12
10
|
/** The highlight() function returns a copy of the text from a specified column of the current row with extra markup text inserted to mark the start and end of phrase matches. */
|
package/dist/sqlite/functions.js
CHANGED
|
@@ -4,7 +4,6 @@ import { Functions } from "../core/expr/Functions.js";
|
|
|
4
4
|
import { input } from "../core/expr/Input.js";
|
|
5
5
|
var count = Functions.count;
|
|
6
6
|
var iif = Functions.iif;
|
|
7
|
-
var match = Functions.match;
|
|
8
7
|
var bm25 = Functions.bm25;
|
|
9
8
|
var highlight = Functions.highlight;
|
|
10
9
|
var snippet = Functions.snippet;
|
|
@@ -118,7 +117,6 @@ export {
|
|
|
118
117
|
log2,
|
|
119
118
|
lower,
|
|
120
119
|
ltrim,
|
|
121
|
-
match,
|
|
122
120
|
max,
|
|
123
121
|
min,
|
|
124
122
|
mod,
|
|
@@ -3,8 +3,7 @@ var locks = /* @__PURE__ */ new WeakMap();
|
|
|
3
3
|
function execTransaction(driver, depth, wrap, run, options) {
|
|
4
4
|
const needsLock = options.async;
|
|
5
5
|
const behavior = options.behavior ?? "deferred";
|
|
6
|
-
if (!needsLock)
|
|
7
|
-
return transact();
|
|
6
|
+
if (!needsLock) return transact();
|
|
8
7
|
let trigger;
|
|
9
8
|
const lock = new Promise((resolve) => trigger = resolve);
|
|
10
9
|
const current = Promise.resolve(locks.get(driver));
|
|
@@ -14,8 +13,7 @@ function execTransaction(driver, depth, wrap, run, options) {
|
|
|
14
13
|
try {
|
|
15
14
|
driver.exec(depth > 0 ? `savepoint d${depth}` : `begin ${behavior}`);
|
|
16
15
|
const result = run(wrap(depth + 1));
|
|
17
|
-
if (result instanceof Promise)
|
|
18
|
-
return result.then(release, rollback);
|
|
16
|
+
if (result instanceof Promise) return result.then(release, rollback);
|
|
19
17
|
return release(result);
|
|
20
18
|
} catch (error) {
|
|
21
19
|
return rollback(error);
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import { type Column
|
|
1
|
+
import { JsonColumn, type Column } from '../core/Column.js';
|
|
2
2
|
export declare function id(name?: string): Column<number>;
|
|
3
3
|
export declare function text(name?: string): Column<string | null>;
|
|
4
|
+
export declare function varchar(name?: string, options?: {
|
|
5
|
+
length: number;
|
|
6
|
+
}): Column<string | null>;
|
|
4
7
|
export declare function integer(name?: string): Column<number | null>;
|
|
8
|
+
export declare function number(name?: string): Column<number | null>;
|
|
5
9
|
export declare function boolean(name?: string): Column<boolean | null>;
|
|
6
10
|
export declare function json<T>(name?: string): JsonColumn<T>;
|
|
11
|
+
export declare function jsonb<T>(name?: string): JsonColumn<T>;
|
|
12
|
+
export declare function blob(name?: string): Column<Uint8Array | null>;
|
|
@@ -6,6 +6,18 @@ var idType = sql.universal({
|
|
|
6
6
|
postgres: sql`integer generated always as identity`,
|
|
7
7
|
mysql: sql`int not null auto_increment`
|
|
8
8
|
});
|
|
9
|
+
var blobType = sql.universal({
|
|
10
|
+
postgres: sql`bytea`,
|
|
11
|
+
default: sql`blob`
|
|
12
|
+
});
|
|
13
|
+
var numberType = sql.universal({
|
|
14
|
+
mysql: sql`double`,
|
|
15
|
+
default: sql`numeric`
|
|
16
|
+
});
|
|
17
|
+
var jsonbType = sql.universal({
|
|
18
|
+
mysql: sql`json`,
|
|
19
|
+
default: sql`jsonb`
|
|
20
|
+
});
|
|
9
21
|
function id(name) {
|
|
10
22
|
return column({
|
|
11
23
|
name,
|
|
@@ -16,18 +28,20 @@ function id(name) {
|
|
|
16
28
|
function text(name) {
|
|
17
29
|
return column({ name, type: column.text() });
|
|
18
30
|
}
|
|
31
|
+
function varchar(name, options) {
|
|
32
|
+
return column({ name, type: column.varchar(options?.length) });
|
|
33
|
+
}
|
|
19
34
|
function integer(name) {
|
|
20
35
|
return column({ name, type: column.integer() });
|
|
21
36
|
}
|
|
37
|
+
function number(name) {
|
|
38
|
+
return column({ name, type: numberType, mapFromDriverValue: Number });
|
|
39
|
+
}
|
|
22
40
|
function boolean(name) {
|
|
23
41
|
return column({
|
|
24
42
|
name,
|
|
25
43
|
type: column.boolean(),
|
|
26
|
-
mapFromDriverValue
|
|
27
|
-
if (typeof value === "number")
|
|
28
|
-
return value === 1;
|
|
29
|
-
return Boolean(value);
|
|
30
|
-
}
|
|
44
|
+
mapFromDriverValue: Boolean
|
|
31
45
|
});
|
|
32
46
|
}
|
|
33
47
|
function json(name) {
|
|
@@ -42,10 +56,29 @@ function json(name) {
|
|
|
42
56
|
}
|
|
43
57
|
});
|
|
44
58
|
}
|
|
59
|
+
function jsonb(name) {
|
|
60
|
+
return new JsonColumn({
|
|
61
|
+
name,
|
|
62
|
+
type: jsonbType,
|
|
63
|
+
mapToDriverValue(value) {
|
|
64
|
+
return JSON.stringify(value);
|
|
65
|
+
},
|
|
66
|
+
mapFromDriverValue(value, { parsesJson }) {
|
|
67
|
+
return parsesJson ? value : JSON.parse(value);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function blob(name) {
|
|
72
|
+
return column({ name, type: blobType });
|
|
73
|
+
}
|
|
45
74
|
export {
|
|
75
|
+
blob,
|
|
46
76
|
boolean,
|
|
47
77
|
id,
|
|
48
78
|
integer,
|
|
49
79
|
json,
|
|
50
|
-
|
|
80
|
+
jsonb,
|
|
81
|
+
number,
|
|
82
|
+
text,
|
|
83
|
+
varchar
|
|
51
84
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rado",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -26,8 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"files": ["dist"],
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"@biomejs/biome": "^1.6.1",
|
|
29
|
+
"@biomejs/biome": "^1.8.3",
|
|
31
30
|
"@cloudflare/workers-types": "^4.20230628.0",
|
|
32
31
|
"@electric-sql/pglite": "^0.1.5",
|
|
33
32
|
"@sqlite.org/sqlite-wasm": "^3.42.0-build4",
|
|
@@ -36,19 +35,17 @@
|
|
|
36
35
|
"@types/glob": "^8.0.0",
|
|
37
36
|
"@types/pg": "^8.11.5",
|
|
38
37
|
"@types/sql.js": "^1.4.2",
|
|
39
|
-
"better-sqlite3": "^11.
|
|
40
|
-
"esbuild": "^0.
|
|
41
|
-
"glob": "^
|
|
38
|
+
"better-sqlite3": "^11.2.1",
|
|
39
|
+
"esbuild": "^0.23.1",
|
|
40
|
+
"glob": "^11.0.0",
|
|
42
41
|
"madge": "^8.0.0",
|
|
43
|
-
"mysql2": "^3.
|
|
44
|
-
"pg": "^8.
|
|
45
|
-
"rimraf": "^4.1.2",
|
|
46
|
-
"sade": "^1.8.1",
|
|
42
|
+
"mysql2": "^3.11.0",
|
|
43
|
+
"pg": "^8.12.0",
|
|
47
44
|
"speedscope": "^1.15.0",
|
|
48
|
-
"sql.js": "^1.
|
|
49
|
-
"sqlite3": "^5.1.
|
|
50
|
-
"tsx": "^4.
|
|
51
|
-
"typescript": "^5.4
|
|
52
|
-
"
|
|
45
|
+
"sql.js": "^1.11.0",
|
|
46
|
+
"sqlite3": "^5.1.7",
|
|
47
|
+
"tsx": "^4.19.0",
|
|
48
|
+
"typescript": "^5.5.4",
|
|
49
|
+
"@alinea/suite": "^0.4.0"
|
|
53
50
|
}
|
|
54
51
|
}
|