@primate/sqlite 0.8.0 → 0.9.0
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/lib/private/SQLite.d.ts +13 -3
- package/lib/private/SQLite.js +48 -2
- package/package.json +8 -8
package/lib/private/SQLite.d.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import type { As, DataDict,
|
|
1
|
+
import type { As, CheckPlaceholders, DataDict, ExtractPlaceholders, Schema, Sort, SQLDB, With } from "@primate/core/db";
|
|
2
|
+
import Client from "@rcompat/sqlite";
|
|
2
3
|
import type { Dict } from "@rcompat/type";
|
|
3
|
-
|
|
4
|
+
import type { ObjectType, Parsed } from "pema";
|
|
5
|
+
declare const schema: ObjectType<import("pema").NormalizeSchemaObject<{
|
|
4
6
|
readonly database: import("pema").DefaultType<import("pema").StringType, ":memory:">;
|
|
5
7
|
}>, {
|
|
6
8
|
database: string;
|
|
7
9
|
}>;
|
|
8
|
-
export default class SQLite implements
|
|
10
|
+
export default class SQLite implements SQLDB<Client> {
|
|
9
11
|
#private;
|
|
10
12
|
static config: typeof schema.input;
|
|
11
13
|
constructor(config?: typeof schema.input, options?: {
|
|
12
14
|
debug?: boolean;
|
|
13
15
|
});
|
|
16
|
+
get client(): Client;
|
|
14
17
|
get explain(): Dict<{
|
|
15
18
|
query: string;
|
|
16
19
|
plans: string[];
|
|
@@ -37,6 +40,13 @@ export default class SQLite implements DB {
|
|
|
37
40
|
where: DataDict;
|
|
38
41
|
}): Promise<number>;
|
|
39
42
|
close(): void;
|
|
43
|
+
sql<Q extends string, I extends ObjectType<{
|
|
44
|
+
[K in ExtractPlaceholders<Q>]: Parsed<unknown>;
|
|
45
|
+
}> | undefined, O extends Parsed<unknown> | undefined>(options: {
|
|
46
|
+
input?: I extends ObjectType<any> ? CheckPlaceholders<I, Q> : I;
|
|
47
|
+
query: Q;
|
|
48
|
+
output?: O;
|
|
49
|
+
}): (args: I extends ObjectType<any> ? I["infer"] : void) => Promise<O extends Parsed<unknown> ? O["infer"] : void>;
|
|
40
50
|
}
|
|
41
51
|
export {};
|
|
42
52
|
//# sourceMappingURL=SQLite.d.ts.map
|
package/lib/private/SQLite.js
CHANGED
|
@@ -134,6 +134,9 @@ export default class SQLite {
|
|
|
134
134
|
get #db() {
|
|
135
135
|
return this.#client ??= this.#factory();
|
|
136
136
|
}
|
|
137
|
+
get client() {
|
|
138
|
+
return this.#db;
|
|
139
|
+
}
|
|
137
140
|
#sql(query) {
|
|
138
141
|
return this.#db.prepare(query);
|
|
139
142
|
}
|
|
@@ -216,7 +219,7 @@ export default class SQLite {
|
|
|
216
219
|
const value = where[field];
|
|
217
220
|
const datatype = types[field];
|
|
218
221
|
const q = sql.quote(field);
|
|
219
|
-
const quoted = alias ? `${alias}.${q}` : q;
|
|
222
|
+
const quoted = is.defined(alias) ? `${alias}.${q}` : q;
|
|
220
223
|
if (value === null) {
|
|
221
224
|
parts.push(`${quoted} IS NULL`);
|
|
222
225
|
continue;
|
|
@@ -245,6 +248,12 @@ export default class SQLite {
|
|
|
245
248
|
case "$before":
|
|
246
249
|
parts.push(cmp_expr(quoted, bound_key, op, datatype));
|
|
247
250
|
break;
|
|
251
|
+
case "$in": {
|
|
252
|
+
const arr = value.$in;
|
|
253
|
+
const placeholders = arr.map((_, i) => `${BIND_BY}${sql.bindKey(field, `in${i}`)}`);
|
|
254
|
+
parts.push(`${quoted} IN (${placeholders.join(", ")})`);
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
248
257
|
default:
|
|
249
258
|
throw E.operator_unknown(field, op);
|
|
250
259
|
}
|
|
@@ -278,6 +287,14 @@ export default class SQLite {
|
|
|
278
287
|
case "$ne":
|
|
279
288
|
filtered[bound_key] = op_value;
|
|
280
289
|
break;
|
|
290
|
+
case "$in": {
|
|
291
|
+
const arr = op_value;
|
|
292
|
+
for (let i = 0; i < arr.length; i++) {
|
|
293
|
+
const bound_key = sql.bindKey(field, `in${i}`);
|
|
294
|
+
filtered[bound_key] = arr[i];
|
|
295
|
+
}
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
281
298
|
default:
|
|
282
299
|
throw E.operator_unknown(field, op);
|
|
283
300
|
}
|
|
@@ -512,8 +529,9 @@ export default class SQLite {
|
|
|
512
529
|
const WHERE = this.#where(as.types, args.where);
|
|
513
530
|
const ORDER_BY = sql.orderBy(as.types, args.sort);
|
|
514
531
|
const LIMIT = sql.limit(args.limit);
|
|
532
|
+
const OFFSET = args.offset !== undefined ? ` OFFSET ${args.offset}` : "";
|
|
515
533
|
const table = sql.quote(as.table);
|
|
516
|
-
return `SELECT ${SELECT} FROM ${table} ${WHERE}${ORDER_BY}${LIMIT}`;
|
|
534
|
+
return `SELECT ${SELECT} FROM ${table} ${WHERE}${ORDER_BY}${LIMIT}${OFFSET}`;
|
|
517
535
|
}
|
|
518
536
|
async #read_joined(as, args) {
|
|
519
537
|
if (as.pk === null)
|
|
@@ -563,5 +581,33 @@ export default class SQLite {
|
|
|
563
581
|
close() {
|
|
564
582
|
this.#db.close();
|
|
565
583
|
}
|
|
584
|
+
sql(options) {
|
|
585
|
+
if (is.defined(options.input)) {
|
|
586
|
+
const placeholders = new Set([...options.query.matchAll(/:(\w+)/g)].map(m => m[1]));
|
|
587
|
+
const input_keys = new Set(Object.keys(options.input.properties));
|
|
588
|
+
for (const key of input_keys) {
|
|
589
|
+
if (!placeholders.has(key))
|
|
590
|
+
throw E.sql_placeholder_missing(key);
|
|
591
|
+
}
|
|
592
|
+
for (const key of placeholders) {
|
|
593
|
+
if (!input_keys.has(key))
|
|
594
|
+
throw E.sql_input_missing(key);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return async (args) => {
|
|
598
|
+
const input = is.defined(options.input)
|
|
599
|
+
? options.input.parse(args)
|
|
600
|
+
: undefined;
|
|
601
|
+
const query = options.query.replace(/:(\w+)/g, (_, name) => `$${name}`);
|
|
602
|
+
const binds = is.defined(input)
|
|
603
|
+
? await bind(Object.fromEntries(Object.entries(options.input.properties)
|
|
604
|
+
.map(([k, v]) => [k, v.datatype])), input)
|
|
605
|
+
: {};
|
|
606
|
+
const rows = this.#sql(query).all(binds);
|
|
607
|
+
return (is.defined(options.output)
|
|
608
|
+
? options.output.parse(rows)
|
|
609
|
+
: undefined);
|
|
610
|
+
};
|
|
611
|
+
}
|
|
566
612
|
}
|
|
567
613
|
//# sourceMappingURL=SQLite.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primate/sqlite",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "SQLite databases for Primate",
|
|
5
5
|
"homepage": "https://primate.run/docs/database/sqlite",
|
|
6
6
|
"bugs": "https://github.com/primate-run/primate/issues",
|
|
@@ -17,17 +17,17 @@
|
|
|
17
17
|
"!/**/*.spec.*"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@rcompat/assert": "^0.
|
|
21
|
-
"@rcompat/is": "^0.
|
|
22
|
-
"@rcompat/sqlite": "^0.
|
|
23
|
-
"@primate/core": "^0.
|
|
20
|
+
"@rcompat/assert": "^0.13.0",
|
|
21
|
+
"@rcompat/is": "^0.11.0",
|
|
22
|
+
"@rcompat/sqlite": "^0.16.0",
|
|
23
|
+
"@primate/core": "^0.7.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@rcompat/type": "^0.
|
|
27
|
-
"pema": "^0.
|
|
26
|
+
"@rcompat/type": "^0.17.0",
|
|
27
|
+
"pema": "^0.7.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"primate": "^0.
|
|
30
|
+
"primate": "^0.38.0"
|
|
31
31
|
},
|
|
32
32
|
"imports": {
|
|
33
33
|
"#*": {
|