@delali/sirannon-db 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backup-scheduler/index.d.ts +15 -1
- package/dist/backup-scheduler/index.mjs +2 -2
- package/dist/baseline-D93hcIEE.d.ts +17 -0
- package/dist/{change-tracker-DKRVUC3l.d.ts → change-tracker-DDmXB754.d.ts} +56 -8
- package/dist/{chunk-5NOIGN5Y.mjs → chunk-2QLXDHAP.mjs} +1 -1
- package/dist/{chunk-LNY2VVHE.mjs → chunk-7C36BCSN.mjs} +1 -1
- package/dist/{chunk-NVQS53NT.mjs → chunk-7FQRQH5Z.mjs} +53 -64
- package/dist/{chunk-D7LAYTKN.mjs → chunk-7R4ER4FB.mjs} +1 -1
- package/dist/{chunk-FHWTZFI4.mjs → chunk-BQFQ65OL.mjs} +1 -1
- package/dist/{chunk-O7SLN3GI.mjs → chunk-BTTFW4Z4.mjs} +1 -1
- package/dist/{chunk-H6PIVVDN.mjs → chunk-CCZK6LCB.mjs} +38 -25
- package/dist/{chunk-JZGINXTN.mjs → chunk-HCCGEIZ2.mjs} +2 -2
- package/dist/{chunk-67M7KAH6.mjs → chunk-IWGIYDMZ.mjs} +1 -1
- package/dist/{chunk-LFZ37BSX.mjs → chunk-OUSWVNWT.mjs} +1 -1
- package/dist/{chunk-HR5CWTLC.mjs → chunk-P2VJYRVY.mjs} +60 -7
- package/dist/{chunk-UC3SCMIN.mjs → chunk-PBRXXISQ.mjs} +3 -0
- package/dist/{chunk-JU64Y7HM.mjs → chunk-SBL6GN43.mjs} +1 -1
- package/dist/{chunk-EBJXPQQO.mjs → chunk-UPKKSUPA.mjs} +2 -2
- package/dist/{chunk-TJF5GZSV.mjs → chunk-VOSJBZ6Q.mjs} +1 -1
- package/dist/{chunk-PIKHN33N.mjs → chunk-VOYGMAU7.mjs} +9 -1
- package/dist/{chunk-H237TXZW.mjs → chunk-WJ67DTD6.mjs} +48 -6
- package/dist/{chunk-OQVZBEBY.mjs → chunk-XF2HH5E6.mjs} +4 -61
- package/dist/client/index.d.ts +211 -12
- package/dist/client/index.mjs +155 -67
- package/dist/client/topology.d.ts +55 -7
- package/dist/client/topology.mjs +20 -1
- package/dist/{client-base-CLWmH5Ln.d.ts → client-base-CmZO0v3m.d.ts} +133 -24
- package/dist/codegen/cli.mjs +3 -3
- package/dist/codegen/index.d.ts +92 -2
- package/dist/codegen/index.mjs +3 -3
- package/dist/core/index.d.ts +177 -15
- package/dist/core/index.mjs +2481 -2226
- package/dist/core/writer-worker.mjs +3 -3
- package/dist/database-B5Qv1-cU.d.ts +380 -0
- package/dist/driver/better-sqlite3.d.ts +18 -1
- package/dist/driver/better-sqlite3.mjs +5 -5
- package/dist/driver/bun.d.ts +28 -0
- package/dist/driver/expo.d.ts +17 -0
- package/dist/driver/node.d.ts +18 -1
- package/dist/driver/node.mjs +5 -5
- package/dist/driver/wa-sqlite.d.ts +18 -1
- package/dist/{errors-Bw5MdNCu.d.ts → errors-Dei4GdBb.d.ts} +80 -7
- package/dist/file-migrations/index.d.ts +54 -2
- package/dist/file-migrations/index.mjs +3 -3
- package/dist/{operation-registry-9DcvxcE5.d.ts → operation-registry-hlbhqu7q.d.ts} +50 -1
- package/dist/{primary-wins-DPAm2AKG.d.ts → primary-wins-B0np8JS3.d.ts} +25 -1
- package/dist/protocol-rqANt-9Q.d.ts +152 -0
- package/dist/query-types-DL3LtPvY.d.ts +95 -0
- package/dist/react/index.d.ts +58 -3
- package/dist/replication/coordinator/etcd.d.ts +63 -3
- package/dist/replication/coordinator/etcd.mjs +82 -46
- package/dist/replication/index.d.ts +329 -95
- package/dist/replication/index.mjs +256 -141
- package/dist/server/index.d.ts +230 -12
- package/dist/server/index.mjs +63 -50
- package/dist/{server-options-1JHu8pid.d.ts → server-options-Dab_Jvd_.d.ts} +96 -12
- package/dist/sirannon-CMhiJa5Y.d.ts +111 -0
- package/dist/transport/grpc.d.ts +93 -9
- package/dist/transport/grpc.mjs +63 -20
- package/dist/transport/memory.d.ts +50 -20
- package/dist/transport/memory.mjs +25 -0
- package/dist/{types-CL6piSnD.d.ts → types-BCejqzNA.d.ts} +20 -0
- package/dist/types-CMBcFPhb.d.ts +336 -0
- package/dist/types-CjhxcjhA.d.ts +123 -0
- package/dist/types-DyrCiWuc.d.ts +499 -0
- package/dist/types-rVZKnKN-.d.ts +591 -0
- package/package.json +7 -1
- package/dist/baseline-Br77Fnhb.d.ts +0 -6
- package/dist/database-BY0L5Q2n.d.ts +0 -172
- package/dist/protocol-6KrSq2Hy.d.ts +0 -66
- package/dist/sirannon-DaQSyhbJ.d.ts +0 -36
- package/dist/types-B7gmEsZW.d.ts +0 -221
- package/dist/types-BsVabqSI.d.ts +0 -139
- package/dist/types-C_D8IhpO.d.ts +0 -60
- package/dist/types-zhnRXrsb.d.ts +0 -384
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BackupManager, BackupScheduler } from './chunk-
|
|
1
|
+
import { BackupManager, BackupScheduler } from './chunk-VOYGMAU7.mjs';
|
|
2
2
|
import { WORKER_CANCELLED_CODE, deserializeError } from './chunk-4ISB7XMA.mjs';
|
|
3
|
-
import { SirannonError } from './chunk-
|
|
3
|
+
import { SirannonError } from './chunk-PBRXXISQ.mjs';
|
|
4
4
|
import { Worker } from 'worker_threads';
|
|
5
5
|
import { existsSync } from 'fs';
|
|
6
6
|
import { resolve, dirname, join, sep } from 'path';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { tokenizeSql, readSelectItems, findClauses } from './chunk-
|
|
1
|
+
import { tokenizeSql, readSelectItems, findClauses } from './chunk-SBL6GN43.mjs';
|
|
2
2
|
import { operationRegistryDigest } from './chunk-TUD5CJ76.mjs';
|
|
3
3
|
import { mkdirSync, writeFileSync } from 'fs';
|
|
4
4
|
import { resolve, dirname } from 'path';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BackupError } from './chunk-
|
|
1
|
+
import { BackupError } from './chunk-PBRXXISQ.mjs';
|
|
2
2
|
import { existsSync, mkdirSync, rmSync, readdirSync, lstatSync } from 'fs';
|
|
3
3
|
import { resolve, dirname, join } from 'path';
|
|
4
4
|
|
|
@@ -383,6 +383,14 @@ var BackupScheduler = class {
|
|
|
383
383
|
constructor(manager) {
|
|
384
384
|
this.manager = manager ?? new BackupManager();
|
|
385
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* Starts repeating backups and returns a function that stops them.
|
|
388
|
+
*
|
|
389
|
+
* @param conn - Connection to the database being copied.
|
|
390
|
+
* @param options - Cron expression, destination directory, retention, time zone, and failure callback.
|
|
391
|
+
* @param runExclusive - Runs each copy with the database's writer held so that no write commits mid-copy.
|
|
392
|
+
* @returns A function that stops the schedule.
|
|
393
|
+
*/
|
|
386
394
|
schedule(conn, options, runExclusive = runDirect) {
|
|
387
395
|
const { cron: cronExpr, destDir, maxFiles = DEFAULT_MAX_FILES, onError, timezone } = options;
|
|
388
396
|
let cron;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/client/types.ts
|
|
2
2
|
var RemoteError = class extends Error {
|
|
3
|
+
/** Machine-readable code the server sent with the error. */
|
|
3
4
|
code;
|
|
4
5
|
constructor(code, message) {
|
|
5
6
|
super(message);
|
|
@@ -15,6 +16,7 @@ var RemoteLiveQuery = class _RemoteLiveQuery {
|
|
|
15
16
|
listeners = /* @__PURE__ */ new Set();
|
|
16
17
|
subscription = null;
|
|
17
18
|
closed = false;
|
|
19
|
+
/** @internal */
|
|
18
20
|
static async open(subscribe) {
|
|
19
21
|
const query = new _RemoteLiveQuery();
|
|
20
22
|
try {
|
|
@@ -30,15 +32,27 @@ var RemoteLiveQuery = class _RemoteLiveQuery {
|
|
|
30
32
|
}
|
|
31
33
|
return query;
|
|
32
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns the rows the query holds right now.
|
|
37
|
+
*/
|
|
33
38
|
getState() {
|
|
34
39
|
return this.state;
|
|
35
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Calls back on each update and returns a function that stops the listener.
|
|
43
|
+
*
|
|
44
|
+
* @param listener - Receives each update.
|
|
45
|
+
* @returns A function that removes the listener.
|
|
46
|
+
*/
|
|
36
47
|
subscribe(listener) {
|
|
37
48
|
this.listeners.add(listener);
|
|
38
49
|
return () => {
|
|
39
50
|
this.listeners.delete(listener);
|
|
40
51
|
};
|
|
41
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Ends the query and releases its subscription.
|
|
55
|
+
*/
|
|
42
56
|
async close() {
|
|
43
57
|
if (this.closed) return;
|
|
44
58
|
this.closed = true;
|
|
@@ -168,7 +182,7 @@ var RemoteDatabase = class {
|
|
|
168
182
|
* Execute multiple statements as a single atomic transaction.
|
|
169
183
|
* Returns an array of results, one per statement.
|
|
170
184
|
*
|
|
171
|
-
* The whole list
|
|
185
|
+
* The whole list is sent in one request and commits or rolls back as a
|
|
172
186
|
* unit, so the client is never in the loop between statements.
|
|
173
187
|
*/
|
|
174
188
|
async transaction(statements) {
|
|
@@ -192,10 +206,10 @@ var RemoteDatabase = class {
|
|
|
192
206
|
* for you and paying the one fsyncing WAL checkpoint once, after the final
|
|
193
207
|
* batch. The configured durability is restored after every batch, so an
|
|
194
208
|
* import that stops partway never leaves the writer at the relaxed level.
|
|
195
|
-
* Prefer this over {@link load} for anything larger than a single request:
|
|
196
|
-
* it
|
|
209
|
+
* Prefer this over {@link RemoteDatabase.load} for anything larger than a single request:
|
|
210
|
+
* it finalises the load itself, so there is no checkpoint flag to forget.
|
|
197
211
|
*
|
|
198
|
-
* Accepts a synchronous or asynchronous iterable of parameter sets
|
|
212
|
+
* Accepts a synchronous or asynchronous iterable of parameter sets so that rows
|
|
199
213
|
* can stream from a file or the network without being held in memory at
|
|
200
214
|
* once. Returns the total rows loaded and changes applied.
|
|
201
215
|
*
|
|
@@ -249,8 +263,8 @@ var RemoteDatabase = class {
|
|
|
249
263
|
/**
|
|
250
264
|
* Load one batch of rows through the same statement with writer durability
|
|
251
265
|
* relaxed for the duration, then restored before this resolves. This is the
|
|
252
|
-
* low-level primitive; prefer {@link loadAll} for a dataset that spans more
|
|
253
|
-
* than one request, since it
|
|
266
|
+
* low-level primitive; prefer {@link RemoteDatabase.loadAll} for a dataset that spans more
|
|
267
|
+
* than one request, since it finalises the load itself rather than relying on
|
|
254
268
|
* a `checkpoint` flag.
|
|
255
269
|
*
|
|
256
270
|
* Returns the total rows loaded and changes applied. When splitting a dataset
|
|
@@ -276,6 +290,11 @@ var RemoteDatabase = class {
|
|
|
276
290
|
* // Later:
|
|
277
291
|
* sub.unsubscribe()
|
|
278
292
|
* ```
|
|
293
|
+
*
|
|
294
|
+
* Begins a change subscription on a watched table.
|
|
295
|
+
*
|
|
296
|
+
* @param table - Name of the watched table.
|
|
297
|
+
* @returns A builder you narrow with a filter and then subscribe to.
|
|
279
298
|
*/
|
|
280
299
|
on(table) {
|
|
281
300
|
return new RemoteSubscriptionBuilderImpl(table, this.transport);
|
|
@@ -581,6 +600,7 @@ function isMissingEndpoint(err) {
|
|
|
581
600
|
|
|
582
601
|
// src/client/transport/http.ts
|
|
583
602
|
var HttpTransport = class {
|
|
603
|
+
/** @internal */
|
|
584
604
|
carriesReadConcern = true;
|
|
585
605
|
baseUrl;
|
|
586
606
|
headers;
|
|
@@ -592,6 +612,7 @@ var HttpTransport = class {
|
|
|
592
612
|
...headers
|
|
593
613
|
};
|
|
594
614
|
}
|
|
615
|
+
/** Sends a read and returns its rows. */
|
|
595
616
|
async query(sql, params, readConcern) {
|
|
596
617
|
const response = await this.post("/query", {
|
|
597
618
|
sql,
|
|
@@ -600,14 +621,17 @@ var HttpTransport = class {
|
|
|
600
621
|
});
|
|
601
622
|
return { rows: decodeTaggedValues(response.rows ?? []) };
|
|
602
623
|
}
|
|
624
|
+
/** Sends one write. */
|
|
603
625
|
async execute(sql, params) {
|
|
604
626
|
return this.post("/execute", { sql, params: encodeTaggedValues(params) });
|
|
605
627
|
}
|
|
628
|
+
/** Sends several statements the server runs in one transaction. */
|
|
606
629
|
async transaction(statements) {
|
|
607
630
|
return this.post("/transaction", {
|
|
608
631
|
statements: statements.map((stmt) => ({ sql: stmt.sql, params: encodeTaggedValues(stmt.params) }))
|
|
609
632
|
});
|
|
610
633
|
}
|
|
634
|
+
/** Sends one statement over many parameter sets, which the server runs in one transaction. */
|
|
611
635
|
async batch(sql, paramsBatch, writeConcern) {
|
|
612
636
|
return this.post("/batch", {
|
|
613
637
|
sql,
|
|
@@ -615,6 +639,7 @@ var HttpTransport = class {
|
|
|
615
639
|
writeConcern
|
|
616
640
|
});
|
|
617
641
|
}
|
|
642
|
+
/** Sends a bulk load, which the server runs at relaxed durability. */
|
|
618
643
|
async load(sql, paramsBatch, durability, checkpoint) {
|
|
619
644
|
return this.post("/load", {
|
|
620
645
|
sql,
|
|
@@ -623,6 +648,7 @@ var HttpTransport = class {
|
|
|
623
648
|
checkpoint
|
|
624
649
|
});
|
|
625
650
|
}
|
|
651
|
+
/** Runs a registered read by name and returns its rows. */
|
|
626
652
|
async queryNamed(name, args, readConcern) {
|
|
627
653
|
const response = await this.post(`/query/${encodeURIComponent(name)}`, {
|
|
628
654
|
args: encodeTaggedValues(args),
|
|
@@ -630,24 +656,28 @@ var HttpTransport = class {
|
|
|
630
656
|
});
|
|
631
657
|
return { rows: decodeTaggedValues(response.rows ?? []) };
|
|
632
658
|
}
|
|
659
|
+
/** Runs a registered write by name. */
|
|
633
660
|
async executeNamed(name, args, writeConcern) {
|
|
634
661
|
return this.post(`/execute/${encodeURIComponent(name)}`, {
|
|
635
662
|
args: encodeTaggedValues(args),
|
|
636
663
|
writeConcern
|
|
637
664
|
});
|
|
638
665
|
}
|
|
666
|
+
/** Opens a live query on a registered read and delivers its updates to the handlers. */
|
|
639
667
|
async liveSubscribe() {
|
|
640
668
|
throw new RemoteError(
|
|
641
669
|
"TRANSPORT_ERROR",
|
|
642
670
|
'Live queries require WebSocket transport. Create the client with { transport: "websocket" } to use them.'
|
|
643
671
|
);
|
|
644
672
|
}
|
|
673
|
+
/** Opens a change subscription on a watched table. */
|
|
645
674
|
async subscribe(_table, _filter, _callback) {
|
|
646
675
|
throw new RemoteError(
|
|
647
676
|
"TRANSPORT_ERROR",
|
|
648
677
|
'Subscriptions require WebSocket transport. Create the client with { transport: "websocket" } to use real-time subscriptions.'
|
|
649
678
|
);
|
|
650
679
|
}
|
|
680
|
+
/** Closes the transport and every subscription running on it. */
|
|
651
681
|
close() {
|
|
652
682
|
this.closed = true;
|
|
653
683
|
}
|
|
@@ -1061,6 +1091,7 @@ var PendingRequests = class {
|
|
|
1061
1091
|
// src/client/transport/ws.ts
|
|
1062
1092
|
var DEFAULT_REQUEST_TIMEOUT = 3e4;
|
|
1063
1093
|
var WebSocketTransport = class {
|
|
1094
|
+
/** @internal */
|
|
1064
1095
|
carriesReadConcern = true;
|
|
1065
1096
|
ws = null;
|
|
1066
1097
|
url;
|
|
@@ -1090,6 +1121,7 @@ var WebSocketTransport = class {
|
|
|
1090
1121
|
this.headers = options?.headers;
|
|
1091
1122
|
this.pending = new PendingRequests(this.requestTimeout);
|
|
1092
1123
|
}
|
|
1124
|
+
/** Sends a read and returns its rows. */
|
|
1093
1125
|
async query(sql, params, readConcern) {
|
|
1094
1126
|
await this.ensureConnected();
|
|
1095
1127
|
const id = this.nextId();
|
|
@@ -1102,6 +1134,7 @@ var WebSocketTransport = class {
|
|
|
1102
1134
|
});
|
|
1103
1135
|
return { rows: decodeTaggedValues(response.rows ?? []) };
|
|
1104
1136
|
}
|
|
1137
|
+
/** Sends one write. */
|
|
1105
1138
|
async execute(sql, params) {
|
|
1106
1139
|
await this.ensureConnected();
|
|
1107
1140
|
const id = this.nextId();
|
|
@@ -1112,6 +1145,7 @@ var WebSocketTransport = class {
|
|
|
1112
1145
|
params: encodeTaggedValues(params)
|
|
1113
1146
|
});
|
|
1114
1147
|
}
|
|
1148
|
+
/** Sends several statements the server runs in one transaction. */
|
|
1115
1149
|
async transaction(statements) {
|
|
1116
1150
|
await this.ensureConnected();
|
|
1117
1151
|
const id = this.nextId();
|
|
@@ -1124,6 +1158,7 @@ var WebSocketTransport = class {
|
|
|
1124
1158
|
}))
|
|
1125
1159
|
});
|
|
1126
1160
|
}
|
|
1161
|
+
/** Sends one statement over many parameter sets, which the server runs in one transaction. */
|
|
1127
1162
|
async batch(sql, paramsBatch, writeConcern) {
|
|
1128
1163
|
await this.ensureConnected();
|
|
1129
1164
|
const id = this.nextId();
|
|
@@ -1135,6 +1170,7 @@ var WebSocketTransport = class {
|
|
|
1135
1170
|
...writeConcern ? { writeConcern } : {}
|
|
1136
1171
|
});
|
|
1137
1172
|
}
|
|
1173
|
+
/** Sends a bulk load, which the server runs at relaxed durability. */
|
|
1138
1174
|
async load(sql, paramsBatch, durability, checkpoint) {
|
|
1139
1175
|
await this.ensureConnected();
|
|
1140
1176
|
const id = this.nextId();
|
|
@@ -1147,6 +1183,7 @@ var WebSocketTransport = class {
|
|
|
1147
1183
|
...checkpoint !== void 0 ? { checkpoint } : {}
|
|
1148
1184
|
});
|
|
1149
1185
|
}
|
|
1186
|
+
/** Runs a registered read by name and returns its rows. */
|
|
1150
1187
|
async queryNamed(name, args, readConcern) {
|
|
1151
1188
|
await this.ensureConnected();
|
|
1152
1189
|
const id = this.nextId();
|
|
@@ -1159,6 +1196,7 @@ var WebSocketTransport = class {
|
|
|
1159
1196
|
});
|
|
1160
1197
|
return { rows: decodeTaggedValues(response.rows ?? []) };
|
|
1161
1198
|
}
|
|
1199
|
+
/** Runs a registered write by name. */
|
|
1162
1200
|
async executeNamed(name, args, writeConcern) {
|
|
1163
1201
|
await this.ensureConnected();
|
|
1164
1202
|
const id = this.nextId();
|
|
@@ -1170,10 +1208,12 @@ var WebSocketTransport = class {
|
|
|
1170
1208
|
...writeConcern ? { writeConcern } : {}
|
|
1171
1209
|
});
|
|
1172
1210
|
}
|
|
1211
|
+
/** Opens a live query on a registered read and delivers its updates to the handlers. */
|
|
1173
1212
|
async liveSubscribe(name, args, handlers, registryDigest) {
|
|
1174
1213
|
await this.ensureConnected();
|
|
1175
1214
|
return this.liveQueries.open(this.nextId(), name, args, handlers, registryDigest);
|
|
1176
1215
|
}
|
|
1216
|
+
/** Opens a change subscription on a watched table. */
|
|
1177
1217
|
async subscribe(table, filter, callback, options) {
|
|
1178
1218
|
await this.ensureConnected();
|
|
1179
1219
|
const id = this.nextId();
|
|
@@ -1221,11 +1261,13 @@ var WebSocketTransport = class {
|
|
|
1221
1261
|
this.ws.send(JSON.stringify({ type: "unsubscribe", id }));
|
|
1222
1262
|
}
|
|
1223
1263
|
}
|
|
1264
|
+
/** @internal */
|
|
1224
1265
|
async ack(deviceId, seq) {
|
|
1225
1266
|
await this.ensureConnected();
|
|
1226
1267
|
const id = this.nextId();
|
|
1227
1268
|
return this.request({ type: "ack", id, deviceId, seq: seq.toString() });
|
|
1228
1269
|
}
|
|
1270
|
+
/** Closes the transport and every subscription running on it. */
|
|
1229
1271
|
close() {
|
|
1230
1272
|
this.closed = true;
|
|
1231
1273
|
this.cancelReconnect();
|
|
@@ -1,70 +1,13 @@
|
|
|
1
|
-
import { IDENTIFIER_RE, selectCountTableRows,
|
|
2
|
-
import { ReplicationError } from './chunk-
|
|
3
|
-
import { INTERNAL_TABLE_PREFIX } from './chunk-
|
|
1
|
+
import { IDENTIFIER_RE, selectCountTableRows, canonicaliseForChecksum, selectUserSchemaObjects, validateDdlSafety, selectUserTableNames, referencedTables } from './chunk-7FQRQH5Z.mjs';
|
|
2
|
+
import { ReplicationError } from './chunk-2QLXDHAP.mjs';
|
|
3
|
+
import { INTERNAL_TABLE_PREFIX } from './chunk-7R4ER4FB.mjs';
|
|
4
4
|
import { createHash } from 'crypto';
|
|
5
5
|
|
|
6
6
|
var DumpOps = class {
|
|
7
|
-
constructor(conn,
|
|
7
|
+
constructor(conn, pkResolver) {
|
|
8
8
|
this.conn = conn;
|
|
9
|
-
this.localNodeId = localNodeId;
|
|
10
|
-
this.hlc = hlc;
|
|
11
9
|
this.pkResolver = pkResolver;
|
|
12
10
|
}
|
|
13
|
-
async *dumpTable(table, batchSize) {
|
|
14
|
-
if (!IDENTIFIER_RE.test(table)) {
|
|
15
|
-
throw new ReplicationError(`Invalid table name: ${table}`);
|
|
16
|
-
}
|
|
17
|
-
const total = await selectCountTableRows(this.conn, table);
|
|
18
|
-
if (total === 0) return;
|
|
19
|
-
const pkColumns = await this.pkResolver.forTable(table);
|
|
20
|
-
let offset = 0;
|
|
21
|
-
let batchNum = 0;
|
|
22
|
-
const needsRowid = pkColumns.length === 1 && pkColumns[0] === "rowid";
|
|
23
|
-
while (offset < total) {
|
|
24
|
-
const selectSql = needsRowid ? `SELECT rowid, * FROM "${table}" LIMIT ? OFFSET ?` : `SELECT * FROM "${table}" LIMIT ? OFFSET ?`;
|
|
25
|
-
const selectStmt = await this.conn.prepare(selectSql);
|
|
26
|
-
const rows = await selectStmt.all(batchSize, offset);
|
|
27
|
-
if (rows.length === 0) break;
|
|
28
|
-
const changes = [];
|
|
29
|
-
const hlcValue = this.hlc.now();
|
|
30
|
-
for (const row of rows) {
|
|
31
|
-
const primaryKey = {};
|
|
32
|
-
for (const col of pkColumns) {
|
|
33
|
-
if (col in row) {
|
|
34
|
-
primaryKey[col] = row[col];
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const rowId = pkColumns.map((col) => String(row[col] ?? "")).join("-");
|
|
38
|
-
changes.push({
|
|
39
|
-
table,
|
|
40
|
-
operation: "insert",
|
|
41
|
-
rowId,
|
|
42
|
-
primaryKey,
|
|
43
|
-
hlc: hlcValue,
|
|
44
|
-
txId: `dump-${table}-${batchNum}`,
|
|
45
|
-
nodeId: this.localNodeId,
|
|
46
|
-
newData: row,
|
|
47
|
-
oldData: null
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
const checksum = computeChecksum(changes);
|
|
51
|
-
const dumpEpoch = BigInt(Date.now()) * 1000000n;
|
|
52
|
-
const fromSeq = dumpEpoch + BigInt(offset);
|
|
53
|
-
const toSeq = dumpEpoch + BigInt(offset + rows.length - 1);
|
|
54
|
-
const dumpNodeId = `dump-${this.localNodeId}`;
|
|
55
|
-
yield {
|
|
56
|
-
sourceNodeId: dumpNodeId,
|
|
57
|
-
batchId: `dump-${table}-${batchNum}`,
|
|
58
|
-
fromSeq,
|
|
59
|
-
toSeq,
|
|
60
|
-
hlcRange: { min: hlcValue, max: hlcValue },
|
|
61
|
-
changes,
|
|
62
|
-
checksum
|
|
63
|
-
};
|
|
64
|
-
offset += rows.length;
|
|
65
|
-
batchNum += 1;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
11
|
dumpTableOnConnection(conn, table, batchSize, startAfter) {
|
|
69
12
|
return dumpTablePages(conn, this.pkResolver, table, batchSize, startAfter);
|
|
70
13
|
}
|