rado 1.0.8 → 1.0.10
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 +18 -8
- package/dist/core/Column.js +3 -4
- package/dist/core/Database.js +2 -4
- package/dist/core/Emitter.js +8 -16
- package/dist/core/Query.js +9 -7
- package/dist/core/Resolver.js +5 -10
- package/dist/core/Selection.js +7 -14
- package/dist/core/Sql.js +12 -24
- 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 +5 -4
- package/dist/core/expr/Input.js +3 -6
- package/dist/core/expr/Json.js +4 -4
- 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/d1.d.ts +25 -0
- package/dist/driver/d1.js +60 -0
- 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.d.ts +1 -1
- package/dist/driver/pglite.js +2 -3
- package/dist/driver/sql.js.js +2 -4
- package/dist/driver.d.ts +7 -0
- package/dist/driver.js +23 -0
- package/dist/mysql/columns.d.ts +2 -1
- package/dist/mysql/columns.js +4 -0
- package/dist/mysql/dialect.js +1 -2
- 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 +5 -10
- package/dist/sqlite/dialect.js +3 -6
- 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 +6 -0
- package/dist/universal/columns.js +45 -6
- package/dist/universal/transactions.js +1 -2
- package/package.json +20 -20
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
[](https://npmjs.org/package/rado)
|
|
2
|
+
[](https://jsr.io/@rado/rado)
|
|
2
3
|
|
|
3
4
|
# rado
|
|
4
5
|
|
|
@@ -149,14 +150,23 @@ const PostTags = table({
|
|
|
149
150
|
|
|
150
151
|
Currently supported drivers:
|
|
151
152
|
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
| `
|
|
155
|
-
|
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
|
|
159
|
-
| `
|
|
153
|
+
| `PostgreSQL ` | `import ` |
|
|
154
|
+
| -------------------------- | ------------------------------ |
|
|
155
|
+
| `pg` | `'rado/driver/pg'` |
|
|
156
|
+
| `@electric-sql/pglite` | `'rado/driver/pglite'` |
|
|
157
|
+
| `@neondatabase/serverless` | `'rado/driver/pg'` |
|
|
158
|
+
| `@vercel/postgres` | `'rado/driver/pg'` |
|
|
159
|
+
|
|
160
|
+
| `SQLite ` | `import ` |
|
|
161
|
+
| -------------------------- | ------------------------------ |
|
|
162
|
+
| `better-sqlite3` | `'rado/driver/better-sqlite3'` |
|
|
163
|
+
| `bun:sqlite` | `'rado/driver/bun-sqlite'` |
|
|
164
|
+
| `sql.js` | `'rado/driver/sql.js'` |
|
|
165
|
+
| `Cloudflare D1` | `'rado/driver/d1'` |
|
|
166
|
+
|
|
167
|
+
| `MySQL ` | `import ` |
|
|
168
|
+
| -------------------------- | ------------------------------ |
|
|
169
|
+
| `mysql2` | `'rado/driver/mysql2'` |
|
|
160
170
|
|
|
161
171
|
Pass an instance of the database to the `connect` function to get started:
|
|
162
172
|
|
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.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,8 +59,7 @@ 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
65
|
transaction(run, options = {}) {
|
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;
|
|
@@ -27,9 +26,13 @@ var Executable = class {
|
|
|
27
26
|
return this.#execute();
|
|
28
27
|
}
|
|
29
28
|
// biome-ignore lint/suspicious/noThenProperty:
|
|
30
|
-
then(onfulfilled, onrejected) {
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
async then(onfulfilled, onrejected) {
|
|
30
|
+
try {
|
|
31
|
+
const result = await this.#execute();
|
|
32
|
+
return onfulfilled ? onfulfilled(result) : result;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return onrejected ? onrejected(error) : Promise.reject(error);
|
|
35
|
+
}
|
|
33
36
|
}
|
|
34
37
|
catch(onrejected) {
|
|
35
38
|
return this.then().catch(onrejected);
|
|
@@ -82,8 +85,7 @@ var Query = class extends Executable {
|
|
|
82
85
|
}
|
|
83
86
|
toSQL(db) {
|
|
84
87
|
const resolver = db ? getResolver(db) : getData(this).resolver;
|
|
85
|
-
if (!resolver)
|
|
86
|
-
throw new Error("Query has no resolver");
|
|
88
|
+
if (!resolver) throw new Error("Query has no resolver");
|
|
87
89
|
return resolver.toSQL(this);
|
|
88
90
|
}
|
|
89
91
|
};
|
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]) => [
|
|
@@ -77,10 +74,8 @@ var Selection = class {
|
|
|
77
74
|
const expr = getSql(input);
|
|
78
75
|
if (expr) {
|
|
79
76
|
let exprName = name ?? expr.alias;
|
|
80
|
-
if (!exprName)
|
|
81
|
-
|
|
82
|
-
while (names.has(exprName))
|
|
83
|
-
exprName = `${exprName}_`;
|
|
77
|
+
if (!exprName) throw new Error("Missing field name");
|
|
78
|
+
while (names.has(exprName)) exprName = `${exprName}_`;
|
|
84
79
|
return [exprName];
|
|
85
80
|
}
|
|
86
81
|
return Object.entries(input).flatMap(
|
|
@@ -92,13 +87,11 @@ var Selection = class {
|
|
|
92
87
|
if (expr) {
|
|
93
88
|
let exprName = name ?? expr.alias;
|
|
94
89
|
if (exprName) {
|
|
95
|
-
while (names.has(exprName))
|
|
96
|
-
exprName = `${exprName}_`;
|
|
90
|
+
while (names.has(exprName)) exprName = `${exprName}_`;
|
|
97
91
|
names.add(exprName);
|
|
98
92
|
if (hasField(input)) {
|
|
99
93
|
const field = getField(input);
|
|
100
|
-
if (field.fieldName === exprName)
|
|
101
|
-
return expr;
|
|
94
|
+
if (field.fieldName === exprName) return expr;
|
|
102
95
|
}
|
|
103
96
|
return sql`${expr.forSelection()} as ${sql.identifier(exprName)}`;
|
|
104
97
|
}
|
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,19 +45,16 @@ 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
56
|
const inner = path.target.#chunks[0];
|
|
61
|
-
if (inner?.type !== "emitJsonPath")
|
|
62
|
-
return this.chunk("emitJsonPath", path);
|
|
57
|
+
if (inner?.type !== "emitJsonPath") return this.chunk("emitJsonPath", path);
|
|
63
58
|
const innerPath = inner.inner;
|
|
64
59
|
return this.chunk("emitJsonPath", {
|
|
65
60
|
...innerPath,
|
|
@@ -83,8 +78,7 @@ var Sql = class _Sql {
|
|
|
83
78
|
inlineValues() {
|
|
84
79
|
return new _Sql(
|
|
85
80
|
this.#chunks.map((chunk) => {
|
|
86
|
-
if (chunk.type !== "emitValue")
|
|
87
|
-
return chunk;
|
|
81
|
+
if (chunk.type !== "emitValue") return chunk;
|
|
88
82
|
return new Chunk("emitInline", chunk.inner);
|
|
89
83
|
})
|
|
90
84
|
);
|
|
@@ -92,8 +86,7 @@ var Sql = class _Sql {
|
|
|
92
86
|
inlineFields(withTableName) {
|
|
93
87
|
return new _Sql(
|
|
94
88
|
this.#chunks.flatMap((chunk) => {
|
|
95
|
-
if (chunk.type !== "emitField")
|
|
96
|
-
return [chunk];
|
|
89
|
+
if (chunk.type !== "emitField") return [chunk];
|
|
97
90
|
const data = chunk.inner;
|
|
98
91
|
if (withTableName)
|
|
99
92
|
return [
|
|
@@ -109,8 +102,7 @@ var Sql = class _Sql {
|
|
|
109
102
|
return sql.chunk("emitSelf", { name, inner: this });
|
|
110
103
|
}
|
|
111
104
|
emitTo(emitter) {
|
|
112
|
-
for (const chunk of this.#chunks)
|
|
113
|
-
emitter[chunk.type](chunk.inner);
|
|
105
|
+
for (const chunk of this.#chunks) emitter[chunk.type](chunk.inner);
|
|
114
106
|
}
|
|
115
107
|
};
|
|
116
108
|
function sql(strings, ...inner) {
|
|
@@ -169,12 +161,9 @@ function sql(strings, ...inner) {
|
|
|
169
161
|
return join(
|
|
170
162
|
Object.entries(ast).map(([key, value2]) => {
|
|
171
163
|
const statement = key.replace(/([A-Z])/g, " $1").toLocaleLowerCase();
|
|
172
|
-
if (value2 === true)
|
|
173
|
-
|
|
174
|
-
if (
|
|
175
|
-
value2 = join(value2);
|
|
176
|
-
if (!key)
|
|
177
|
-
return value2;
|
|
164
|
+
if (value2 === true) return sql2.unsafe(statement);
|
|
165
|
+
if (Array.isArray(value2)) value2 = join(value2);
|
|
166
|
+
if (!key) return value2;
|
|
178
167
|
return value2 && sql2`${sql2.unsafe(statement)} ${value2}`;
|
|
179
168
|
})
|
|
180
169
|
);
|
|
@@ -184,8 +173,7 @@ function sql(strings, ...inner) {
|
|
|
184
173
|
const parts = items.filter(Boolean);
|
|
185
174
|
const sql3 = new Sql();
|
|
186
175
|
for (let i = 0; i < parts.length; i++) {
|
|
187
|
-
if (i > 0)
|
|
188
|
-
sql3.add(separator);
|
|
176
|
+
if (i > 0) sql3.add(separator);
|
|
189
177
|
sql3.add(parts[i]);
|
|
190
178
|
}
|
|
191
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
|
),
|
|
@@ -13,10 +13,11 @@ var Include = class {
|
|
|
13
13
|
#mapFromDriverValue = (value, specs) => {
|
|
14
14
|
const { select, first } = getData(this);
|
|
15
15
|
const parsed = specs.parsesJson ? value : JSON.parse(value);
|
|
16
|
-
if (first)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
if (first) {
|
|
17
|
+
const result = parsed ? select.mapRow({ values: parsed, index: 0, specs }) : null;
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
if (!parsed) return [];
|
|
20
21
|
const rows = parsed;
|
|
21
22
|
const ctx = {
|
|
22
23
|
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.js
CHANGED
|
@@ -6,8 +6,7 @@ var INDEX_PROPERTY = /^\d+$/;
|
|
|
6
6
|
function jsonExpr(e) {
|
|
7
7
|
return new Proxy(e, {
|
|
8
8
|
get(target, prop) {
|
|
9
|
-
if (typeof prop !== "string")
|
|
10
|
-
return Reflect.get(target, prop);
|
|
9
|
+
if (typeof prop !== "string") return Reflect.get(target, prop);
|
|
11
10
|
const isNumber = INDEX_PROPERTY.test(prop);
|
|
12
11
|
return jsonExpr(
|
|
13
12
|
sql.jsonPath({
|
|
@@ -26,8 +25,9 @@ function jsonExpr(e) {
|
|
|
26
25
|
function jsonAggregateArray(...args) {
|
|
27
26
|
return callFunction(
|
|
28
27
|
sql.universal({
|
|
28
|
+
// Once sqlite 3.45+ is more commonplace we can use jsonb_group_array
|
|
29
29
|
sqlite: sql`json_group_array`,
|
|
30
|
-
postgres: sql`
|
|
30
|
+
postgres: sql`jsonb_agg`,
|
|
31
31
|
mysql: sql`json_arrayagg`
|
|
32
32
|
}),
|
|
33
33
|
args
|
|
@@ -36,7 +36,7 @@ function jsonAggregateArray(...args) {
|
|
|
36
36
|
function jsonArray(...args) {
|
|
37
37
|
return callFunction(
|
|
38
38
|
sql.universal({
|
|
39
|
-
postgres: sql`
|
|
39
|
+
postgres: sql`jsonb_build_array`,
|
|
40
40
|
default: sql`json_array`
|
|
41
41
|
}),
|
|
42
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);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AsyncDatabase } from '../core/Database.js';
|
|
2
|
+
import type { AsyncDriver, AsyncStatement, BatchQuery, PrepareOptions } from '../core/Driver.js';
|
|
3
|
+
type Client = D1Database;
|
|
4
|
+
declare class PreparedStatement implements AsyncStatement {
|
|
5
|
+
private stmt;
|
|
6
|
+
private isSelection;
|
|
7
|
+
constructor(stmt: D1PreparedStatement, isSelection: boolean);
|
|
8
|
+
all(params: Array<unknown>): Promise<Array<object>>;
|
|
9
|
+
run(params: Array<unknown>): Promise<void>;
|
|
10
|
+
get(params: Array<unknown>): Promise<object | null>;
|
|
11
|
+
values(params: Array<unknown>): Promise<Array<Array<unknown>>>;
|
|
12
|
+
free(): void;
|
|
13
|
+
}
|
|
14
|
+
export declare class D1Driver implements AsyncDriver {
|
|
15
|
+
private client;
|
|
16
|
+
parsesJson: boolean;
|
|
17
|
+
constructor(client: Client);
|
|
18
|
+
exec(query: string): Promise<void>;
|
|
19
|
+
prepare(sql: string, options: PrepareOptions): PreparedStatement;
|
|
20
|
+
close(): Promise<void>;
|
|
21
|
+
batch(queries: Array<BatchQuery>): Promise<Array<Array<unknown>>>;
|
|
22
|
+
transaction<T>(): Promise<T>;
|
|
23
|
+
}
|
|
24
|
+
export declare function connect(client: Client): AsyncDatabase<'sqlite'>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// src/driver/d1.ts
|
|
2
|
+
import { AsyncDatabase } from "../core/Database.js";
|
|
3
|
+
import { sqliteDialect } from "../sqlite.js";
|
|
4
|
+
import { sqliteDiff } from "../sqlite/diff.js";
|
|
5
|
+
var PreparedStatement = class {
|
|
6
|
+
constructor(stmt, isSelection) {
|
|
7
|
+
this.stmt = stmt;
|
|
8
|
+
this.isSelection = isSelection;
|
|
9
|
+
}
|
|
10
|
+
async all(params) {
|
|
11
|
+
return this.stmt.bind(...params).all().then(({ results }) => results);
|
|
12
|
+
}
|
|
13
|
+
async run(params) {
|
|
14
|
+
const results = await this.stmt.bind(...params).run();
|
|
15
|
+
}
|
|
16
|
+
async get(params) {
|
|
17
|
+
return this.stmt.bind(...params).first();
|
|
18
|
+
}
|
|
19
|
+
async values(params) {
|
|
20
|
+
if (this.isSelection) {
|
|
21
|
+
const results = await this.stmt.bind(...params).raw();
|
|
22
|
+
console.log(results);
|
|
23
|
+
return results;
|
|
24
|
+
}
|
|
25
|
+
await this.stmt.bind(...params).run();
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
free() {
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var D1Driver = class {
|
|
32
|
+
constructor(client) {
|
|
33
|
+
this.client = client;
|
|
34
|
+
}
|
|
35
|
+
parsesJson = false;
|
|
36
|
+
async exec(query) {
|
|
37
|
+
await this.client.exec(query);
|
|
38
|
+
}
|
|
39
|
+
prepare(sql, options) {
|
|
40
|
+
return new PreparedStatement(this.client.prepare(sql), options.isSelection);
|
|
41
|
+
}
|
|
42
|
+
async close() {
|
|
43
|
+
}
|
|
44
|
+
async batch(queries) {
|
|
45
|
+
const results = [];
|
|
46
|
+
for (const { sql, params, isSelection } of queries)
|
|
47
|
+
results.push(await this.prepare(sql, { isSelection }).values(params));
|
|
48
|
+
return results;
|
|
49
|
+
}
|
|
50
|
+
async transaction() {
|
|
51
|
+
throw new Error("Transactions are not supported in D1");
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
function connect(client) {
|
|
55
|
+
return new AsyncDatabase(new D1Driver(client), sqliteDialect, sqliteDiff);
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
D1Driver,
|
|
59
|
+
connect
|
|
60
|
+
};
|
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.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PGlite, Transaction } from '@electric-sql/pglite';
|
|
2
|
+
import { AsyncDatabase, type TransactionOptions } from '../core/Database.js';
|
|
2
3
|
import type { AsyncDriver, AsyncStatement, BatchQuery } from '../core/Driver.js';
|
|
3
|
-
import { AsyncDatabase, type TransactionOptions } from '../index.js';
|
|
4
4
|
type Queryable = PGlite | Transaction;
|
|
5
5
|
declare class PreparedStatement implements AsyncStatement {
|
|
6
6
|
private client;
|
package/dist/driver/pglite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/driver/pglite.ts
|
|
2
|
-
import { AsyncDatabase } from "../
|
|
2
|
+
import { AsyncDatabase } from "../core/Database.js";
|
|
3
3
|
import { postgresDialect } from "../postgres/dialect.js";
|
|
4
4
|
import { postgresDiff } from "../postgres/diff.js";
|
|
5
5
|
import { setTransaction } from "../postgres/transactions.js";
|
|
@@ -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/driver.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { connect as 'better-sqlite3' } from './driver/better-sqlite3.js';
|
|
2
|
+
export { connect as 'bun:sqlite' } from './driver/bun-sqlite.js';
|
|
3
|
+
export { connect as 'd1' } from './driver/d1.js';
|
|
4
|
+
export { connect as 'mysql2' } from './driver/mysql2.js';
|
|
5
|
+
export { connect as '@neondatabase/serverless', connect as '@vercel/postgres', connect as 'pg' } from './driver/pg.js';
|
|
6
|
+
export { connect as '@electric-sql/pglite' } from './driver/pglite.js';
|
|
7
|
+
export { connect as 'sql.js' } from './driver/sql.js.js';
|
package/dist/driver.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/driver.ts
|
|
2
|
+
import { connect } from "./driver/better-sqlite3.js";
|
|
3
|
+
import { connect as connect2 } from "./driver/bun-sqlite.js";
|
|
4
|
+
import { connect as connect3 } from "./driver/d1.js";
|
|
5
|
+
import { connect as connect4 } from "./driver/mysql2.js";
|
|
6
|
+
import {
|
|
7
|
+
connect as connect5,
|
|
8
|
+
connect as connect6,
|
|
9
|
+
connect as connect7
|
|
10
|
+
} from "./driver/pg.js";
|
|
11
|
+
import { connect as connect8 } from "./driver/pglite.js";
|
|
12
|
+
import { connect as connect9 } from "./driver/sql.js.js";
|
|
13
|
+
export {
|
|
14
|
+
connect8 as "@electric-sql/pglite",
|
|
15
|
+
connect5 as "@neondatabase/serverless",
|
|
16
|
+
connect6 as "@vercel/postgres",
|
|
17
|
+
connect as "better-sqlite3",
|
|
18
|
+
connect2 as "bun:sqlite",
|
|
19
|
+
connect3 as d1,
|
|
20
|
+
connect4 as mysql2,
|
|
21
|
+
connect7 as pg,
|
|
22
|
+
connect9 as "sql.js"
|
|
23
|
+
};
|
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
|
@@ -24,8 +24,7 @@ var mysqlDialect = new Dialect(
|
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
emitInline(value) {
|
|
27
|
-
if (value === null || value === void 0)
|
|
28
|
-
return this.sql += "null";
|
|
27
|
+
if (value === null || value === void 0) return this.sql += "null";
|
|
29
28
|
if (typeof value === "number" || typeof value === "boolean")
|
|
30
29
|
return this.sql += value;
|
|
31
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
|
@@ -20,19 +20,14 @@ var postgresDialect = new Dialect(
|
|
|
20
20
|
target.emitTo(this);
|
|
21
21
|
for (let i = 0; i < segments.length; i++) {
|
|
22
22
|
const access = segments[i];
|
|
23
|
-
if (i <= segments.length - 2)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (typeof access === "number")
|
|
28
|
-
this.sql += access;
|
|
29
|
-
else
|
|
30
|
-
this.sql += this.quoteString(access);
|
|
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);
|
|
31
27
|
}
|
|
32
28
|
}
|
|
33
29
|
emitInline(value) {
|
|
34
|
-
if (value === null || value === void 0)
|
|
35
|
-
return this.sql += "null";
|
|
30
|
+
if (value === null || value === void 0) return this.sql += "null";
|
|
36
31
|
if (typeof value === "number" || typeof value === "boolean")
|
|
37
32
|
return this.sql += value;
|
|
38
33
|
if (typeof value === "string")
|
package/dist/sqlite/dialect.js
CHANGED
|
@@ -26,14 +26,11 @@ var sqliteDialect = new Dialect(
|
|
|
26
26
|
);
|
|
27
27
|
}
|
|
28
28
|
emitInline(value) {
|
|
29
|
-
if (value === null || value === void 0)
|
|
30
|
-
|
|
31
|
-
if (typeof value === "number")
|
|
32
|
-
return this.sql += value;
|
|
29
|
+
if (value === null || value === void 0) return this.sql += "null";
|
|
30
|
+
if (typeof value === "number") return this.sql += value;
|
|
33
31
|
if (typeof value === "string")
|
|
34
32
|
return this.sql += this.quoteString(value);
|
|
35
|
-
if (typeof value === "boolean")
|
|
36
|
-
return this.sql += value ? "1" : "0";
|
|
33
|
+
if (typeof value === "boolean") return this.sql += value ? "1" : "0";
|
|
37
34
|
this.sql += `json(${this.quoteString(JSON.stringify(value))})`;
|
|
38
35
|
}
|
|
39
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
1
|
import { type Column, JsonColumn } 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,35 @@ 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({
|
|
73
|
+
name,
|
|
74
|
+
type: blobType,
|
|
75
|
+
mapFromDriverValue(value) {
|
|
76
|
+
return new Uint8Array(value);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
45
80
|
export {
|
|
81
|
+
blob,
|
|
46
82
|
boolean,
|
|
47
83
|
id,
|
|
48
84
|
integer,
|
|
49
85
|
json,
|
|
50
|
-
|
|
86
|
+
jsonb,
|
|
87
|
+
number,
|
|
88
|
+
text,
|
|
89
|
+
varchar
|
|
51
90
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rado",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"cycles": "madge --circular src/index.ts src/sqlite.ts src/mysql.ts src/postgres.ts",
|
|
12
12
|
"test:bun": "bun test",
|
|
13
13
|
"test:node": "node --test-force-exit --test-concurrency=1 --import tsx --test \"**/*.test.ts\"",
|
|
14
|
-
"test:deno": "deno test --no-check --
|
|
14
|
+
"test:deno": "deno test --no-check -A --unstable-ffi"
|
|
15
15
|
},
|
|
16
16
|
"sideEffects": false,
|
|
17
17
|
"exports": {
|
|
@@ -26,29 +26,29 @@
|
|
|
26
26
|
},
|
|
27
27
|
"files": ["dist"],
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@
|
|
29
|
+
"@alinea/suite": "^0.4.0",
|
|
30
30
|
"@biomejs/biome": "^1.8.3",
|
|
31
31
|
"@cloudflare/workers-types": "^4.20230628.0",
|
|
32
32
|
"@electric-sql/pglite": "^0.1.5",
|
|
33
|
+
"@miniflare/d1": "^2.14.2",
|
|
34
|
+
"@miniflare/shared": "^2.14.2",
|
|
33
35
|
"@sqlite.org/sqlite-wasm": "^3.42.0-build4",
|
|
34
|
-
"@types/better-sqlite3": "^
|
|
35
|
-
"@types/bun": "^1.1.
|
|
36
|
-
"@types/glob": "^8.
|
|
37
|
-
"@types/pg": "^8.11.
|
|
38
|
-
"@types/sql.js": "^1.4.
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
36
|
+
"@types/better-sqlite3": "^7.6.11",
|
|
37
|
+
"@types/bun": "^1.1.8",
|
|
38
|
+
"@types/glob": "^8.1.0",
|
|
39
|
+
"@types/pg": "^8.11.8",
|
|
40
|
+
"@types/sql.js": "^1.4.9",
|
|
41
|
+
"@vercel/postgres": "^0.10.0",
|
|
42
|
+
"better-sqlite3": "^11.3.0",
|
|
43
|
+
"esbuild": "^0.23.1",
|
|
44
|
+
"glob": "^11.0.0",
|
|
42
45
|
"madge": "^8.0.0",
|
|
43
|
-
"mysql2": "^3.
|
|
44
|
-
"pg": "^8.
|
|
45
|
-
"rimraf": "^4.1.2",
|
|
46
|
-
"sade": "^1.8.1",
|
|
46
|
+
"mysql2": "^3.11.0",
|
|
47
|
+
"pg": "^8.12.0",
|
|
47
48
|
"speedscope": "^1.15.0",
|
|
48
|
-
"sql.js": "^1.
|
|
49
|
-
"sqlite3": "^5.1.
|
|
50
|
-
"tsx": "^4.
|
|
51
|
-
"typescript": "^5.
|
|
52
|
-
"uvu": "^0.5.6"
|
|
49
|
+
"sql.js": "^1.11.0",
|
|
50
|
+
"sqlite3": "^5.1.7",
|
|
51
|
+
"tsx": "^4.19.0",
|
|
52
|
+
"typescript": "^5.6.2"
|
|
53
53
|
}
|
|
54
54
|
}
|