@voltro/sql-sqlite 0.70.0 → 0.71.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/CHANGELOG.md +1289 -111
- package/dist/index.d.ts +4 -0
- package/dist/index.js +54 -41
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Context } from 'effect';
|
|
|
7
7
|
import { DataStore } from '@voltro/database';
|
|
8
8
|
import { Effect } from 'effect';
|
|
9
9
|
import { EventEmitter } from 'node:events';
|
|
10
|
+
import { InsertIgnoreResult } from '@voltro/database';
|
|
10
11
|
import { Layer } from 'effect';
|
|
11
12
|
import { ManagedRuntime } from 'effect';
|
|
12
13
|
import { Predicate } from '@voltro/database';
|
|
@@ -166,6 +167,9 @@ export declare class SqliteStore implements DataStore {
|
|
|
166
167
|
insertIgnore(table: string, row: Row, options: {
|
|
167
168
|
conflictColumns: ReadonlyArray<string>;
|
|
168
169
|
}): Promise<Row>;
|
|
170
|
+
insertIgnoreWithOutcome(table: string, row: Row, options: {
|
|
171
|
+
conflictColumns: ReadonlyArray<string>;
|
|
172
|
+
}): Promise<InsertIgnoreResult>;
|
|
169
173
|
/* Excluded from this release type: emitChange */
|
|
170
174
|
/* Excluded from this release type: getInternalExecuteQuery */
|
|
171
175
|
/* Excluded from this release type: getInternalExecuteInsert */
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SqliteClient as e } from "@effect/sql-sqlite-node";
|
|
2
2
|
import { Config as t, Context as n, Effect as r, Layer as i, ManagedRuntime as a, Option as o } from "effect";
|
|
3
|
-
import { EagerCardinalityError as s, SQLITE_TRANSIENT_CODES as c, attachEagerLoads as l, attributionFields as u, bulkInsertLimitsFor as d, causeBranches as f, chunkRowsForInsert as p, coercePredicateForSqlite as m, compileEagerJson as h, compileJsonPatch as g, compilePredicate as _, compileRawFragment as v, compileSelect as y, decodeRowsFromSchema as b, encodeRowForSchema as x, externalChangeEvent as
|
|
3
|
+
import { EagerCardinalityError as s, SQLITE_TRANSIENT_CODES as c, attachEagerLoads as l, attributionFields as u, bulkInsertLimitsFor as d, causeBranches as f, chunkRowsForInsert as p, coercePredicateForSqlite as m, compileEagerJson as h, compileJsonPatch as g, compilePredicate as _, compileRawFragment as v, compileSelect as y, decodeRowsFromSchema as b, encodeRowForSchema as x, externalChangeEvent as S, hasEagerLoads as C, isTableReactive as w, jsonPatchAssignments as ee, makeEagerFallbackReporter as T, observeDbOp as E, qualifyTable as D, quoteIdent as O, raiseChangeListenerCeiling as k, recordsTable as A, requireTable as j, rowKeyColumns as M, runStoreTransaction as N, runWriteRecorders as te, stampGeneratedId as P, stampGeneratedIds as F, upsertUpdatePatch as I, upsertUpdateValues as L, withCapturedAttribution as R } from "@voltro/database";
|
|
4
4
|
import { EventEmitter as z } from "node:events";
|
|
5
5
|
import { createLogger as B } from "@voltro/logger";
|
|
6
6
|
import { SqlClient as V, TransactionConnection as H } from "@effect/sql/SqlClient";
|
|
@@ -66,23 +66,23 @@ var U = (r) => e.layerConfig({
|
|
|
66
66
|
}
|
|
67
67
|
async executeInsert(e, t, n, i, a) {
|
|
68
68
|
t = P(e, t);
|
|
69
|
-
let o = this.sql, s = o`INSERT INTO ${o(this.nsT(e))} ${o.insert($(t, e))} RETURNING *`, c = n ? r.provideService(s, H, n) : s, l =
|
|
70
|
-
if (!
|
|
69
|
+
let o = this.sql, s = o`INSERT INTO ${o(this.nsT(e))} ${o.insert($(t, e))} RETURNING *`, c = n ? r.provideService(s, H, n) : s, l = await this.runtime.runPromise(c), u = b(l, e, "sqlite")[0];
|
|
70
|
+
if (!u) throw Error(`SqliteStore.insert: no row returned for table '${e}'`);
|
|
71
71
|
return await this.routeEvent({
|
|
72
72
|
table: e,
|
|
73
73
|
op: "insert",
|
|
74
74
|
old: null,
|
|
75
|
-
new:
|
|
76
|
-
}, i, n, a),
|
|
75
|
+
new: u
|
|
76
|
+
}, i, n, a), u;
|
|
77
77
|
}
|
|
78
78
|
async executeUpdate(e, t, n, i, a, o) {
|
|
79
|
-
let s = this.sql, c = s`UPDATE ${s(this.nsT(e))} SET ${s.update($(n, e))} WHERE ${s.and(M(t).map(([e, t]) => s`${s(e)} = ${t}`))} RETURNING *`, l = i ? r.provideService(c, H, i) : c, u =
|
|
80
|
-
return
|
|
79
|
+
let s = this.sql, c = s`UPDATE ${s(this.nsT(e))} SET ${s.update($(n, e))} WHERE ${s.and(M(t).map(([e, t]) => s`${s(e)} = ${t}`))} RETURNING *`, l = i ? r.provideService(c, H, i) : c, u = await this.runtime.runPromise(l), d = b(u, e, "sqlite")[0];
|
|
80
|
+
return d ? (await this.routeEvent({
|
|
81
81
|
table: e,
|
|
82
82
|
op: "update",
|
|
83
83
|
old: null,
|
|
84
|
-
new:
|
|
85
|
-
}, a, i, o),
|
|
84
|
+
new: d
|
|
85
|
+
}, a, i, o), d) : null;
|
|
86
86
|
}
|
|
87
87
|
async executeInsertMany(e, t, n, i, a) {
|
|
88
88
|
if (t = F(e, t), t.length === 0) return [];
|
|
@@ -95,29 +95,30 @@ var U = (r) => e.layerConfig({
|
|
|
95
95
|
for (let t of c) e.push(...await this.runtime.runPromise(r.provideService(l(t), H, n)));
|
|
96
96
|
u = e;
|
|
97
97
|
} else u = await this.runtime.runPromise(o.withTransaction(r.map(r.forEach(c, l, { concurrency: 1 }), (e) => e.flat())));
|
|
98
|
-
|
|
98
|
+
let f = b(u, e, "sqlite");
|
|
99
|
+
for (let t of f) await this.routeEvent({
|
|
99
100
|
table: e,
|
|
100
101
|
op: "insert",
|
|
101
102
|
old: null,
|
|
102
103
|
new: t
|
|
103
104
|
}, i, n, a);
|
|
104
|
-
return
|
|
105
|
+
return f;
|
|
105
106
|
}
|
|
106
107
|
async executePatchJson(e, t, n, i, a, o, s, c) {
|
|
107
|
-
let l = this.sql, u = $(
|
|
108
|
-
return
|
|
108
|
+
let l = this.sql, u = $(ee(t, n, c), e), d = l.csv([g(l, "sqlite", n, i, l`${l(this.nsT(e))}.${l(n.split(".")[0])}`), ...Object.entries(u).map(([e, t]) => l`${l(e)} = ${t}`)]), f = l`UPDATE ${l(this.nsT(e))} SET ${d} WHERE ${l.and(M(t).map(([e, t]) => l`${l(e)} = ${t}`))} RETURNING *`, p = a ? r.provideService(f, H, a) : f, m = await this.runtime.runPromise(p), h = b(m, e, "sqlite")[0];
|
|
109
|
+
return h ? (await this.routeEvent({
|
|
109
110
|
table: e,
|
|
110
111
|
op: "update",
|
|
111
112
|
old: null,
|
|
112
|
-
new:
|
|
113
|
-
}, o, a, s),
|
|
113
|
+
new: h
|
|
114
|
+
}, o, a, s), h) : null;
|
|
114
115
|
}
|
|
115
116
|
async executeDelete(e, t, n, i, a) {
|
|
116
|
-
let o = this.sql, s = o`DELETE FROM ${o(this.nsT(e))} WHERE ${o.and(M(t).map(([e, t]) => o`${o(e)} = ${t}`))} RETURNING *`, c = n ? r.provideService(s, H, n) : s, l =
|
|
117
|
-
return
|
|
117
|
+
let o = this.sql, s = o`DELETE FROM ${o(this.nsT(e))} WHERE ${o.and(M(t).map(([e, t]) => o`${o(e)} = ${t}`))} RETURNING *`, c = n ? r.provideService(s, H, n) : s, l = await this.runtime.runPromise(c), u = b(l, e, "sqlite")[0];
|
|
118
|
+
return u ? (await this.routeEvent({
|
|
118
119
|
table: e,
|
|
119
120
|
op: "delete",
|
|
120
|
-
old:
|
|
121
|
+
old: u,
|
|
121
122
|
new: null
|
|
122
123
|
}, i, n, a), !0) : !1;
|
|
123
124
|
}
|
|
@@ -133,7 +134,7 @@ var U = (r) => e.layerConfig({
|
|
|
133
134
|
e = {
|
|
134
135
|
...u(r),
|
|
135
136
|
...e
|
|
136
|
-
}, A(e.table) && await
|
|
137
|
+
}, A(e.table) && await te({
|
|
137
138
|
append: (e, t) => this.appendInTxn(e, t, n),
|
|
138
139
|
maxOf: (e, t, r) => this.maxInTxn(e, t, r, n)
|
|
139
140
|
}, {
|
|
@@ -143,41 +144,47 @@ var U = (r) => e.layerConfig({
|
|
|
143
144
|
prev: e.old,
|
|
144
145
|
traceId: e.traceId,
|
|
145
146
|
subjectId: e.subjectId
|
|
146
|
-
}),
|
|
147
|
+
}), w(e.table) && (t === null ? this.emitter.emit("change", e) : t.push(e));
|
|
147
148
|
}
|
|
148
149
|
async executeUpsert(e, t, n, i, a, o) {
|
|
149
150
|
let s = L(n);
|
|
150
151
|
if (t = P(e, t), typeof n.update == "function") {
|
|
151
152
|
let r = await this.findByConflict(e, t, n.conflictColumns, i);
|
|
152
|
-
return r ? await this.executeUpdate(e, r.id, I(t, r, n), i, a) ?? r : this.executeInsert(e, t, i, a);
|
|
153
|
+
return r ? await this.executeUpdate(e, r.id, I(t, r, n), i, a, o) ?? r : this.executeInsert(e, t, i, a, o);
|
|
153
154
|
}
|
|
154
|
-
let c = this.sql, l = n.conflictColumns.map((e) => c`${c(e)}`), u = Object.keys(t).filter((e) => t[e] !== void 0), d = n.update === void 0 ? u.filter((e) => e !== "id" && !n.conflictColumns.includes(e)) : n.update, f = $(s, e), p = [...d.filter((e) => !Object.hasOwn(s, e)).map((e) => c`${c(e)} = excluded.${c(e)}`), ...Object.entries(f).map(([e, t]) => c`${c(e)} = ${t}`)], m = p.length > 0 ? c.csv(p) : c`${c(n.conflictColumns[0])} = excluded.${c(n.conflictColumns[0])}`, h = c`INSERT INTO ${c(this.nsT(e))} ${c.insert($(t, e))} ON CONFLICT (${c.csv(l)}) DO UPDATE SET ${m} RETURNING *`, g = i ? r.provideService(h, H, i) : h, _ =
|
|
155
|
-
if (!
|
|
156
|
-
let
|
|
155
|
+
let c = this.sql, l = n.conflictColumns.map((e) => c`${c(e)}`), u = Object.keys(t).filter((e) => t[e] !== void 0), d = n.update === void 0 ? u.filter((e) => e !== "id" && !n.conflictColumns.includes(e)) : n.update, f = $(s, e), p = [...d.filter((e) => !Object.hasOwn(s, e)).map((e) => c`${c(e)} = excluded.${c(e)}`), ...Object.entries(f).map(([e, t]) => c`${c(e)} = ${t}`)], m = p.length > 0 ? c.csv(p) : c`${c(n.conflictColumns[0])} = excluded.${c(n.conflictColumns[0])}`, h = c`INSERT INTO ${c(this.nsT(e))} ${c.insert($(t, e))} ON CONFLICT (${c.csv(l)}) DO UPDATE SET ${m} RETURNING *`, g = i ? r.provideService(h, H, i) : h, _ = await this.runtime.runPromise(g), v = b(_, e, "sqlite")[0];
|
|
156
|
+
if (!v) throw Error(`SqliteStore.upsert: no row returned for table '${e}'`);
|
|
157
|
+
let y = t.id !== void 0 && t.id === v.id ? "insert" : "update";
|
|
157
158
|
return await this.routeEvent({
|
|
158
159
|
table: e,
|
|
159
|
-
op:
|
|
160
|
+
op: y,
|
|
160
161
|
old: null,
|
|
161
|
-
new:
|
|
162
|
-
}, a, i, o),
|
|
162
|
+
new: v
|
|
163
|
+
}, a, i, o), v;
|
|
163
164
|
}
|
|
164
165
|
async executeInsertIgnore(e, t, n, i, a, o) {
|
|
165
166
|
t = P(e, t);
|
|
166
|
-
let s = this.sql, c = n.conflictColumns.map((e) => s`${s(e)}`), l = s`INSERT INTO ${s(this.nsT(e))} ${s.insert($(t, e))} ON CONFLICT (${s.csv(c)}) DO NOTHING RETURNING *`, u = i ? r.provideService(l, H, i) : l, d =
|
|
167
|
-
if (
|
|
167
|
+
let s = this.sql, c = n.conflictColumns.map((e) => s`${s(e)}`), l = s`INSERT INTO ${s(this.nsT(e))} ${s.insert($(t, e))} ON CONFLICT (${s.csv(c)}) DO NOTHING RETURNING *`, u = i ? r.provideService(l, H, i) : l, d = await this.runtime.runPromise(u), f = b(d, e, "sqlite")[0];
|
|
168
|
+
if (f) return await this.routeEvent({
|
|
168
169
|
table: e,
|
|
169
170
|
op: "insert",
|
|
170
171
|
old: null,
|
|
171
|
-
new:
|
|
172
|
-
}, a, i, o),
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
new: f
|
|
173
|
+
}, a, i, o), {
|
|
174
|
+
row: f,
|
|
175
|
+
outcome: "inserted"
|
|
176
|
+
};
|
|
177
|
+
let p = await this.findByConflict(e, t, n.conflictColumns, i);
|
|
178
|
+
if (!p) throw Error(`SqliteStore.insertIgnore: conflict fired but no existing row found in '${e}'`);
|
|
179
|
+
return {
|
|
180
|
+
row: p,
|
|
181
|
+
outcome: "ignored"
|
|
182
|
+
};
|
|
176
183
|
}
|
|
177
184
|
async findByConflict(e, t, n, i) {
|
|
178
185
|
if (n.length === 0) return;
|
|
179
|
-
let a = this.sql, o = n.map((e) => a`${a(e)} = ${t[e]}`), s = a`SELECT * FROM ${a(this.nsT(e))} WHERE ${a.and(o)} LIMIT 1`, c = i ? r.provideService(s, H, i) : s;
|
|
180
|
-
return (
|
|
186
|
+
let a = this.sql, o = n.map((e) => a`${a(e)} = ${t[e]}`), s = a`SELECT * FROM ${a(this.nsT(e))} WHERE ${a.and(o)} LIMIT 1`, c = i ? r.provideService(s, H, i) : s, l = await this.runtime.runPromise(c);
|
|
187
|
+
return b(l, e, "sqlite")[0];
|
|
181
188
|
}
|
|
182
189
|
query(e) {
|
|
183
190
|
return this.runWithEager(e, null);
|
|
@@ -190,7 +197,7 @@ var U = (r) => e.layerConfig({
|
|
|
190
197
|
return E(this.systemName, "raw", () => this.runtime.runPromise(i));
|
|
191
198
|
}
|
|
192
199
|
async runWithEager(e, t) {
|
|
193
|
-
if (!
|
|
200
|
+
if (!C(e)) return this.executeQuery(e, t);
|
|
194
201
|
let n = this.namespace === null ? h(e, this.sql, "sqlite") : null;
|
|
195
202
|
if (n !== null) try {
|
|
196
203
|
let e = t ? r.provideService(n.fragment, H, t) : n.fragment, i = await E(this.systemName, "select", () => this.runtime.runPromise(e));
|
|
@@ -250,7 +257,7 @@ var U = (r) => e.layerConfig({
|
|
|
250
257
|
}
|
|
251
258
|
async executeUpdateMany(e, t, n, i, a, o) {
|
|
252
259
|
let s = this.sql, c = _(Q(n.where), s, this.namespace), l = s`UPDATE ${s(this.nsT(e))} SET ${s.update($(t, e))} WHERE ${c} RETURNING *`, u = i ? r.provideService(l, H, i) : l, d = await E(this.systemName, "update", () => this.runtime.runPromise(u));
|
|
253
|
-
for (let t of d) await this.routeEvent({
|
|
260
|
+
for (let t of b(d, e, "sqlite")) await this.routeEvent({
|
|
254
261
|
table: e,
|
|
255
262
|
op: "update",
|
|
256
263
|
old: null,
|
|
@@ -260,7 +267,7 @@ var U = (r) => e.layerConfig({
|
|
|
260
267
|
}
|
|
261
268
|
async executeDeleteMany(e, t, n, i, a) {
|
|
262
269
|
let o = this.sql, s = _(Q(t.where), o, this.namespace), c = o`DELETE FROM ${o(this.nsT(e))} WHERE ${s} RETURNING *`, l = n ? r.provideService(c, H, n) : c, u = await E(this.systemName, "delete", () => this.runtime.runPromise(l));
|
|
263
|
-
for (let t of u) await this.routeEvent({
|
|
270
|
+
for (let t of b(u, e, "sqlite")) await this.routeEvent({
|
|
264
271
|
table: e,
|
|
265
272
|
op: "delete",
|
|
266
273
|
old: t,
|
|
@@ -272,6 +279,9 @@ var U = (r) => e.layerConfig({
|
|
|
272
279
|
return this.localWrite("upsert", e, (r, i, a) => this.executeUpsert(e, t, n, i, a, r));
|
|
273
280
|
}
|
|
274
281
|
insertIgnore(e, t, n) {
|
|
282
|
+
return this.insertIgnoreWithOutcome(e, t, n).then((e) => e.row);
|
|
283
|
+
}
|
|
284
|
+
insertIgnoreWithOutcome(e, t, n) {
|
|
275
285
|
return this.localWrite("upsert", e, (r, i, a) => this.executeInsertIgnore(e, t, n, i, a, r));
|
|
276
286
|
}
|
|
277
287
|
emitChange(e) {
|
|
@@ -332,7 +342,7 @@ var U = (r) => e.layerConfig({
|
|
|
332
342
|
async transactional(e) {
|
|
333
343
|
this.inflightTxns++;
|
|
334
344
|
try {
|
|
335
|
-
return await
|
|
345
|
+
return await N({
|
|
336
346
|
...this.txnSpec("SqliteStore.transactional"),
|
|
337
347
|
work: e,
|
|
338
348
|
makeView: (e, t) => new ae(this, e, t)
|
|
@@ -364,7 +374,7 @@ var U = (r) => e.layerConfig({
|
|
|
364
374
|
};
|
|
365
375
|
}
|
|
366
376
|
injectExternalChange(e) {
|
|
367
|
-
|
|
377
|
+
w(e.table) && this.emitter.emit("change", S(e));
|
|
368
378
|
}
|
|
369
379
|
run(e) {
|
|
370
380
|
return this.runtime.runPromise(e);
|
|
@@ -426,6 +436,9 @@ var U = (r) => e.layerConfig({
|
|
|
426
436
|
return this.parent.getInternalExecuteUpsert()(e, t, n, this.txn, this.events, this.attr);
|
|
427
437
|
}
|
|
428
438
|
insertIgnore(e, t, n) {
|
|
439
|
+
return this.insertIgnoreWithOutcome(e, t, n).then((e) => e.row);
|
|
440
|
+
}
|
|
441
|
+
insertIgnoreWithOutcome(e, t, n) {
|
|
429
442
|
return this.parent.getInternalExecuteInsertIgnore()(e, t, n, this.txn, this.events, this.attr);
|
|
430
443
|
}
|
|
431
444
|
transactional(e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/sql-sqlite",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.71.0",
|
|
4
4
|
"description": "SQLite dialect adapter for Voltro's cross-dialect DataStore (single-process; in-process change events).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@effect/sql": "^0.52.1",
|
|
37
37
|
"@effect/sql-sqlite-node": "^0.53.0",
|
|
38
|
-
"@voltro/database": "0.
|
|
39
|
-
"@voltro/logger": "0.
|
|
38
|
+
"@voltro/database": "0.71.0",
|
|
39
|
+
"@voltro/logger": "0.71.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"effect": "^3.22.1"
|