@nicia-ai/typegraph 0.38.0 → 0.40.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/dist/backend/drizzle/indexes.cjs +8 -10
- package/dist/backend/drizzle/indexes.d.cts +2 -2
- package/dist/backend/drizzle/indexes.d.ts +2 -2
- package/dist/backend/drizzle/indexes.js +4 -6
- package/dist/backend/index.cjs +60 -39
- package/dist/backend/index.d.cts +60 -1
- package/dist/backend/index.d.ts +60 -1
- package/dist/backend/index.js +12 -3
- package/dist/backend/postgres/index.cjs +25 -27
- package/dist/backend/postgres/index.d.cts +6 -6
- package/dist/backend/postgres/index.d.ts +6 -6
- package/dist/backend/postgres/index.js +12 -14
- package/dist/backend/postgres/pglite-store.cjs +26 -27
- package/dist/backend/postgres/pglite-store.cjs.map +1 -1
- package/dist/backend/postgres/pglite-store.d.cts +6 -5
- package/dist/backend/postgres/pglite-store.d.ts +6 -5
- package/dist/backend/postgres/pglite-store.js +22 -23
- package/dist/backend/postgres/pglite-store.js.map +1 -1
- package/dist/backend/postgres/pglite.cjs +14 -16
- package/dist/backend/postgres/pglite.d.cts +3 -3
- package/dist/backend/postgres/pglite.d.ts +3 -3
- package/dist/backend/postgres/pglite.js +13 -15
- package/dist/backend/sqlite/index.cjs +26 -28
- package/dist/backend/sqlite/index.d.cts +6 -6
- package/dist/backend/sqlite/index.d.ts +6 -6
- package/dist/backend/sqlite/index.js +10 -12
- package/dist/backend/sqlite/libsql.cjs +16 -18
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +3 -3
- package/dist/backend/sqlite/libsql.d.ts +3 -3
- package/dist/backend/sqlite/libsql.js +15 -17
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local-store.cjs +27 -28
- package/dist/backend/sqlite/local-store.cjs.map +1 -1
- package/dist/backend/sqlite/local-store.d.cts +6 -5
- package/dist/backend/sqlite/local-store.d.ts +6 -5
- package/dist/backend/sqlite/local-store.js +23 -24
- package/dist/backend/sqlite/local-store.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +15 -17
- package/dist/backend/sqlite/local.d.cts +3 -3
- package/dist/backend/sqlite/local.d.ts +3 -3
- package/dist/backend/sqlite/local.js +13 -15
- package/dist/{chunk-U4JDJKPD.js → chunk-2I3DNNBU.js} +4 -4
- package/dist/{chunk-U4JDJKPD.js.map → chunk-2I3DNNBU.js.map} +1 -1
- package/dist/{chunk-NPWACFQJ.cjs → chunk-2J5NMMVR.cjs} +43 -43
- package/dist/{chunk-NPWACFQJ.cjs.map → chunk-2J5NMMVR.cjs.map} +1 -1
- package/dist/{chunk-NU23DUSJ.cjs → chunk-2X73QTIC.cjs} +12 -13
- package/dist/chunk-2X73QTIC.cjs.map +1 -0
- package/dist/{chunk-A2FGSWMQ.js → chunk-3BL3JFHL.js} +202 -52
- package/dist/chunk-3BL3JFHL.js.map +1 -0
- package/dist/chunk-3SHAUJRB.js +79 -0
- package/dist/chunk-3SHAUJRB.js.map +1 -0
- package/dist/{chunk-UPXDVI3T.js → chunk-53BSOG3O.js} +8 -7
- package/dist/chunk-53BSOG3O.js.map +1 -0
- package/dist/chunk-5J4VNCUD.js +856 -0
- package/dist/chunk-5J4VNCUD.js.map +1 -0
- package/dist/chunk-5YBDB7UG.cjs +12 -0
- package/dist/{chunk-FMNUSGZ4.cjs.map → chunk-5YBDB7UG.cjs.map} +1 -1
- package/dist/{chunk-6XDBRDZE.js → chunk-6N7QBIWN.js} +7 -3
- package/dist/chunk-6N7QBIWN.js.map +1 -0
- package/dist/{chunk-EZH7FNUS.js → chunk-6QP4QXBR.js} +3 -3
- package/dist/{chunk-EZH7FNUS.js.map → chunk-6QP4QXBR.js.map} +1 -1
- package/dist/{chunk-E6TXEISH.cjs → chunk-7UTUKH4E.cjs} +4 -4
- package/dist/{chunk-E6TXEISH.cjs.map → chunk-7UTUKH4E.cjs.map} +1 -1
- package/dist/chunk-7WLEQIHA.cjs +605 -0
- package/dist/chunk-7WLEQIHA.cjs.map +1 -0
- package/dist/{chunk-BQITNFQJ.js → chunk-AQVDAKXH.js} +3 -3
- package/dist/{chunk-BQITNFQJ.js.map → chunk-AQVDAKXH.js.map} +1 -1
- package/dist/{chunk-X6CNEA32.js → chunk-BUZWMDNL.js} +5 -5
- package/dist/{chunk-X6CNEA32.js.map → chunk-BUZWMDNL.js.map} +1 -1
- package/dist/{chunk-7M3NACL3.cjs → chunk-CKFBZ4LV.cjs} +4 -4
- package/dist/{chunk-7M3NACL3.cjs.map → chunk-CKFBZ4LV.cjs.map} +1 -1
- package/dist/{chunk-VBH7ZXSZ.js → chunk-CU3LPYNB.js} +5 -5
- package/dist/{chunk-VBH7ZXSZ.js.map → chunk-CU3LPYNB.js.map} +1 -1
- package/dist/{chunk-YJDSPA5E.js → chunk-EFZ4S22A.js} +11 -10
- package/dist/chunk-EFZ4S22A.js.map +1 -0
- package/dist/chunk-ELA3V6UN.js +601 -0
- package/dist/chunk-ELA3V6UN.js.map +1 -0
- package/dist/{chunk-2SL7OGPR.cjs → chunk-H6I36MGT.cjs} +1037 -887
- package/dist/chunk-H6I36MGT.cjs.map +1 -0
- package/dist/chunk-HAQVISUF.cjs +1098 -0
- package/dist/chunk-HAQVISUF.cjs.map +1 -0
- package/dist/{chunk-O5H62ZWJ.cjs → chunk-HP6LWBLB.cjs} +14 -2
- package/dist/chunk-HP6LWBLB.cjs.map +1 -0
- package/dist/{chunk-BKAKAVRW.cjs → chunk-HQRZEYYB.cjs} +44 -44
- package/dist/{chunk-BKAKAVRW.cjs.map → chunk-HQRZEYYB.cjs.map} +1 -1
- package/dist/{chunk-XD6X7O5R.js → chunk-I5CRUPKO.js} +9 -10
- package/dist/{chunk-XD6X7O5R.js.map → chunk-I5CRUPKO.js.map} +1 -1
- package/dist/{chunk-RQPRCEIO.js → chunk-JHK6NPFV.js} +218 -306
- package/dist/chunk-JHK6NPFV.js.map +1 -0
- package/dist/chunk-JZYMOHHM.cjs +226 -0
- package/dist/chunk-JZYMOHHM.cjs.map +1 -0
- package/dist/{chunk-CQC6VBAF.cjs → chunk-K4FB2RMO.cjs} +10 -10
- package/dist/{chunk-CQC6VBAF.cjs.map → chunk-K4FB2RMO.cjs.map} +1 -1
- package/dist/{chunk-ERZ4QPQX.js → chunk-K6CD6W5J.js} +5 -5
- package/dist/{chunk-ERZ4QPQX.js.map → chunk-K6CD6W5J.js.map} +1 -1
- package/dist/{chunk-LZ3TVJY4.cjs → chunk-KHNKYSGP.cjs} +34 -34
- package/dist/{chunk-LZ3TVJY4.cjs.map → chunk-KHNKYSGP.cjs.map} +1 -1
- package/dist/{chunk-CWX77JB4.cjs → chunk-KLR77R5A.cjs} +13 -13
- package/dist/{chunk-CWX77JB4.cjs.map → chunk-KLR77R5A.cjs.map} +1 -1
- package/dist/{chunk-AOL64O4Z.js → chunk-L3DDZUZP.js} +3 -3
- package/dist/{chunk-AOL64O4Z.js.map → chunk-L3DDZUZP.js.map} +1 -1
- package/dist/{chunk-PZHC5GCD.js → chunk-L5ET7FYQ.js} +3 -3
- package/dist/{chunk-PZHC5GCD.js.map → chunk-L5ET7FYQ.js.map} +1 -1
- package/dist/{chunk-B63IFHXR.cjs → chunk-LFFVD5ZR.cjs} +41 -41
- package/dist/{chunk-B63IFHXR.cjs.map → chunk-LFFVD5ZR.cjs.map} +1 -1
- package/dist/chunk-LL5D5T5W.cjs +157 -0
- package/dist/chunk-LL5D5T5W.cjs.map +1 -0
- package/dist/{chunk-GUUWKPTK.cjs → chunk-LLE25NRD.cjs} +7 -7
- package/dist/{chunk-GUUWKPTK.cjs.map → chunk-LLE25NRD.cjs.map} +1 -1
- package/dist/chunk-LLHMAHG4.cjs +886 -0
- package/dist/chunk-LLHMAHG4.cjs.map +1 -0
- package/dist/{chunk-ZHX4KEM7.cjs → chunk-M2RPZS7J.cjs} +10 -10
- package/dist/{chunk-ZHX4KEM7.cjs.map → chunk-M2RPZS7J.cjs.map} +1 -1
- package/dist/chunk-MNURF4RF.cjs +85 -0
- package/dist/chunk-MNURF4RF.cjs.map +1 -0
- package/dist/chunk-QOHTVDHU.js +144 -0
- package/dist/chunk-QOHTVDHU.js.map +1 -0
- package/dist/{chunk-7VLCN3JB.cjs → chunk-QXKVUJLI.cjs} +113 -112
- package/dist/chunk-QXKVUJLI.cjs.map +1 -0
- package/dist/{chunk-GNPGGLAE.cjs → chunk-QYDUCWD2.cjs} +4 -4
- package/dist/{chunk-GNPGGLAE.cjs.map → chunk-QYDUCWD2.cjs.map} +1 -1
- package/dist/{chunk-TE5ZA4VX.js → chunk-QZYGZVUI.js} +45 -41
- package/dist/chunk-QZYGZVUI.js.map +1 -0
- package/dist/{chunk-YLINFV7Z.cjs → chunk-SAMJLDGG.cjs} +114 -110
- package/dist/chunk-SAMJLDGG.cjs.map +1 -0
- package/dist/{chunk-DOVMTPKE.cjs → chunk-SE422RES.cjs} +27 -27
- package/dist/{chunk-DOVMTPKE.cjs.map → chunk-SE422RES.cjs.map} +1 -1
- package/dist/{chunk-NWYCOFEZ.cjs → chunk-UCHW2MGP.cjs} +332 -433
- package/dist/chunk-UCHW2MGP.cjs.map +1 -0
- package/dist/{chunk-XFY73JWD.cjs → chunk-UDS5DZNY.cjs} +498 -1098
- package/dist/chunk-UDS5DZNY.cjs.map +1 -0
- package/dist/{chunk-KFLXWVUJ.js → chunk-UUIBACKJ.js} +14 -3
- package/dist/chunk-UUIBACKJ.js.map +1 -0
- package/dist/{chunk-VDYA2HMS.js → chunk-VWEFXG73.js} +3 -3
- package/dist/{chunk-VDYA2HMS.js.map → chunk-VWEFXG73.js.map} +1 -1
- package/dist/{chunk-G32AO634.js → chunk-W66YCXWT.js} +464 -1048
- package/dist/chunk-W66YCXWT.js.map +1 -0
- package/dist/{chunk-E6YZRKMM.js → chunk-XMEYZYGE.js} +6 -6
- package/dist/{chunk-E6YZRKMM.js.map → chunk-XMEYZYGE.js.map} +1 -1
- package/dist/{chunk-G3CSQLLT.js → chunk-Y5UC3IXF.js} +461 -6
- package/dist/chunk-Y5UC3IXF.js.map +1 -0
- package/dist/{chunk-SDHV2MWU.js → chunk-YGX4PMG6.js} +5 -5
- package/dist/{chunk-SDHV2MWU.js.map → chunk-YGX4PMG6.js.map} +1 -1
- package/dist/{chunk-KCLZHYPU.cjs → chunk-YIX3BEBR.cjs} +86 -85
- package/dist/chunk-YIX3BEBR.cjs.map +1 -0
- package/dist/{chunk-X6RDQ5NB.cjs → chunk-YX3H63VV.cjs} +8 -2
- package/dist/chunk-YX3H63VV.cjs.map +1 -0
- package/dist/chunk-YYLMXERH.js +211 -0
- package/dist/chunk-YYLMXERH.js.map +1 -0
- package/dist/{chunk-6G5CQ6JX.js → chunk-ZE7E46IZ.js} +5 -5
- package/dist/{chunk-6G5CQ6JX.js.map → chunk-ZE7E46IZ.js.map} +1 -1
- package/dist/{chunk-Z2PPIVOO.js → chunk-ZVME6OSV.js} +5 -5
- package/dist/{chunk-Z2PPIVOO.js.map → chunk-ZVME6OSV.js.map} +1 -1
- package/dist/core/index.cjs +15 -3
- package/dist/core/index.d.cts +4 -3
- package/dist/core/index.d.ts +4 -3
- package/dist/core/index.js +2 -2
- package/dist/{ddl-Dx3Z0_WC.d.ts → ddl-BLEzHw6j.d.ts} +3 -3
- package/dist/{ddl-J6sDyABg.d.cts → ddl-KnCdF_le.d.cts} +3 -3
- package/dist/{define-graph-CzEvA_8F.d.cts → define-graph-Cv3CFwKm.d.cts} +1 -1
- package/dist/{define-graph-DRo9xpYN.d.ts → define-graph-DQnj3fNH.d.ts} +1 -1
- package/dist/graph-merge/index.cjs +40 -43
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +15 -9
- package/dist/graph-merge/index.d.ts +15 -9
- package/dist/graph-merge/index.js +19 -22
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/index.cjs +143 -119
- package/dist/index.d.cts +12 -10
- package/dist/index.d.ts +12 -10
- package/dist/index.js +23 -23
- package/dist/indexes/index.cjs +12 -14
- package/dist/indexes/index.d.cts +5 -5
- package/dist/indexes/index.d.ts +5 -5
- package/dist/indexes/index.js +5 -7
- package/dist/interchange/index.cjs +29 -30
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +6 -5
- package/dist/interchange/index.d.ts +6 -5
- package/dist/interchange/index.js +10 -11
- package/dist/interchange/index.js.map +1 -1
- package/dist/{manager-CASfhmzV.d.ts → manager-DjE6Mhag.d.ts} +2 -2
- package/dist/{manager-nCEJiYBb.d.cts → manager-mqee5MVB.d.cts} +2 -2
- package/dist/{postgres-DMgIKQU-.d.cts → postgres-Bm4DyFQU.d.cts} +100 -49
- package/dist/{postgres-Cl1ZAN1G.d.ts → postgres-DtaVALOZ.d.ts} +100 -49
- package/dist/profiler/index.d.cts +8 -7
- package/dist/profiler/index.d.ts +8 -7
- package/dist/provenance/index.cjs +20 -20
- package/dist/provenance/index.d.cts +6 -5
- package/dist/provenance/index.d.ts +6 -5
- package/dist/provenance/index.js +7 -7
- package/dist/schema/index.cjs +26 -28
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +5 -5
- package/dist/schema/index.d.ts +5 -5
- package/dist/schema/index.js +7 -9
- package/dist/schema/index.js.map +1 -1
- package/dist/{temporal-DqtOEo_B.d.ts → searchable-BxlJQVFw.d.cts} +3 -58
- package/dist/{temporal-BC_NQV5Y.d.cts → searchable-ChJ29MCd.d.ts} +3 -58
- package/dist/{sqlite-BDkW39aa.d.cts → sqlite-DT6tTHOG.d.cts} +124 -97
- package/dist/{sqlite-CYfhvESj.d.ts → sqlite-m9Izphk_.d.ts} +124 -97
- package/dist/{store-view-BoHqdHjB.d.cts → store-view-C-buB8Q8.d.cts} +46 -31
- package/dist/{store-view-Ctq-3OHy.d.ts → store-view-CagdeyNn.d.ts} +46 -31
- package/dist/temporal-CyFsSPe8.d.ts +73 -0
- package/dist/temporal-Dn_JADWY.d.cts +73 -0
- package/dist/{types-CUevi_D1.d.ts → types-CYdXzZef.d.ts} +1 -1
- package/dist/{types-COq3-vMC.d.cts → types-CqSfMRW3.d.cts} +1 -1
- package/dist/{where-C92TXCzT.d.cts → where-C3-HRgUq.d.cts} +1 -1
- package/dist/{where-BdE_cYtx.d.ts → where-sQL4u5h-.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-2SL7OGPR.cjs.map +0 -1
- package/dist/chunk-6XDBRDZE.js.map +0 -1
- package/dist/chunk-7VLCN3JB.cjs.map +0 -1
- package/dist/chunk-A2FGSWMQ.js.map +0 -1
- package/dist/chunk-DDCIXXOO.js +0 -9
- package/dist/chunk-DDCIXXOO.js.map +0 -1
- package/dist/chunk-DDCYVIVV.cjs +0 -44
- package/dist/chunk-DDCYVIVV.cjs.map +0 -1
- package/dist/chunk-EOJFGECD.cjs +0 -284
- package/dist/chunk-EOJFGECD.cjs.map +0 -1
- package/dist/chunk-FMNUSGZ4.cjs +0 -12
- package/dist/chunk-G32AO634.js.map +0 -1
- package/dist/chunk-G3CSQLLT.js.map +0 -1
- package/dist/chunk-I6FX7AAG.js +0 -39
- package/dist/chunk-I6FX7AAG.js.map +0 -1
- package/dist/chunk-J6IJARLG.js +0 -94
- package/dist/chunk-J6IJARLG.js.map +0 -1
- package/dist/chunk-KCLZHYPU.cjs.map +0 -1
- package/dist/chunk-KFLXWVUJ.js.map +0 -1
- package/dist/chunk-MTNEGGM2.js +0 -273
- package/dist/chunk-MTNEGGM2.js.map +0 -1
- package/dist/chunk-NU23DUSJ.cjs.map +0 -1
- package/dist/chunk-NWYCOFEZ.cjs.map +0 -1
- package/dist/chunk-O5H62ZWJ.cjs.map +0 -1
- package/dist/chunk-RQPRCEIO.js.map +0 -1
- package/dist/chunk-SVUKGWSN.cjs +0 -102
- package/dist/chunk-SVUKGWSN.cjs.map +0 -1
- package/dist/chunk-TE5ZA4VX.js.map +0 -1
- package/dist/chunk-UH2USOMG.cjs +0 -627
- package/dist/chunk-UH2USOMG.cjs.map +0 -1
- package/dist/chunk-UPXDVI3T.js.map +0 -1
- package/dist/chunk-X6RDQ5NB.cjs.map +0 -1
- package/dist/chunk-XFY73JWD.cjs.map +0 -1
- package/dist/chunk-Y7M44XEK.js +0 -462
- package/dist/chunk-Y7M44XEK.js.map +0 -1
- package/dist/chunk-YJDSPA5E.js.map +0 -1
- package/dist/chunk-YLINFV7Z.cjs.map +0 -1
- package/dist/chunk-Z5QHVL5U.cjs +0 -12
- package/dist/chunk-Z5QHVL5U.cjs.map +0 -1
- package/dist/chunk-ZKZAIX42.cjs +0 -479
- package/dist/chunk-ZKZAIX42.cjs.map +0 -1
- package/dist/{index-CrFL_ENI.d.cts → types-C5pZeKTl.d.cts} +1 -1
- package/dist/{index-Bq7vSPHy.d.ts → types-D8szWDUo.d.ts} +1 -1
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
import { createSqliteTables, sqliteContributions, createPostgresTables, postgresContributions } from './chunk-5J4VNCUD.js';
|
|
2
|
+
import { createSqlSchema } from './chunk-YYLMXERH.js';
|
|
3
|
+
import { asRecordedInstant, createRecordedInstant, RECORDED_MAX_REVISION } from './chunk-QOHTVDHU.js';
|
|
4
|
+
import { canonicalizeDatabaseTimestamp } from './chunk-3SHAUJRB.js';
|
|
5
|
+
import { shortHash } from './chunk-Y5UC3IXF.js';
|
|
6
|
+
import { asCompiledRowsSql, sql, asCompiledStatementSql } from './chunk-6N7QBIWN.js';
|
|
7
|
+
import { ConfigurationError, ValidationError } from './chunk-DPNA466P.js';
|
|
8
|
+
|
|
9
|
+
// src/backend/migrate-recorded-time.ts
|
|
10
|
+
var LEGACY_RECORDED_MAX = "9999-12-31T23:59:59.999Z";
|
|
11
|
+
var MIGRATION_SUFFIX = "legacy_recorded_anchors";
|
|
12
|
+
var RECORDED_NODE_COLUMNS = [
|
|
13
|
+
"history_id",
|
|
14
|
+
"graph_id",
|
|
15
|
+
"kind",
|
|
16
|
+
"id",
|
|
17
|
+
"props",
|
|
18
|
+
"version",
|
|
19
|
+
"valid_from",
|
|
20
|
+
"valid_to",
|
|
21
|
+
"created_at",
|
|
22
|
+
"updated_at",
|
|
23
|
+
"deleted_at",
|
|
24
|
+
"recorded_from",
|
|
25
|
+
"recorded_to",
|
|
26
|
+
"op",
|
|
27
|
+
"schema_version",
|
|
28
|
+
"tx_id",
|
|
29
|
+
"meta"
|
|
30
|
+
];
|
|
31
|
+
var RECORDED_EDGE_COLUMNS = [
|
|
32
|
+
"history_id",
|
|
33
|
+
"graph_id",
|
|
34
|
+
"id",
|
|
35
|
+
"kind",
|
|
36
|
+
"from_kind",
|
|
37
|
+
"from_id",
|
|
38
|
+
"to_kind",
|
|
39
|
+
"to_id",
|
|
40
|
+
"props",
|
|
41
|
+
"valid_from",
|
|
42
|
+
"valid_to",
|
|
43
|
+
"created_at",
|
|
44
|
+
"updated_at",
|
|
45
|
+
"deleted_at",
|
|
46
|
+
"recorded_from",
|
|
47
|
+
"recorded_to",
|
|
48
|
+
"op",
|
|
49
|
+
"schema_version",
|
|
50
|
+
"tx_id",
|
|
51
|
+
"meta"
|
|
52
|
+
];
|
|
53
|
+
function resolvedTableNames(backend, override) {
|
|
54
|
+
return createSqlSchema(override ?? backend.tableNames ?? {}).tables;
|
|
55
|
+
}
|
|
56
|
+
function shortenedIdentifier(value) {
|
|
57
|
+
if (value.length <= 63) return value;
|
|
58
|
+
return `${value.slice(0, 50)}_${shortHash(value)}`;
|
|
59
|
+
}
|
|
60
|
+
function mappingTableName(tables, override) {
|
|
61
|
+
const candidate = override ?? `${tables.recordedClock}_${MIGRATION_SUFFIX}`;
|
|
62
|
+
return createSqlSchema({
|
|
63
|
+
recordedClock: shortenedIdentifier(candidate)
|
|
64
|
+
}).tables.recordedClock;
|
|
65
|
+
}
|
|
66
|
+
function temporaryTableName(tableName, role) {
|
|
67
|
+
return shortenedIdentifier(`__tg_${role}_${shortHash(tableName)}`);
|
|
68
|
+
}
|
|
69
|
+
function requireStatements(target) {
|
|
70
|
+
if (target.executeStatement === void 0) {
|
|
71
|
+
throw new ConfigurationError(
|
|
72
|
+
"Recorded-time migration requires executeStatement support.",
|
|
73
|
+
{ dialect: target.dialect },
|
|
74
|
+
{ suggestion: "Use a built-in SQLite or PostgreSQL backend." }
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return target.executeStatement;
|
|
78
|
+
}
|
|
79
|
+
async function executeStatement(target, statement) {
|
|
80
|
+
await requireStatements(target)(asCompiledStatementSql(statement));
|
|
81
|
+
}
|
|
82
|
+
async function executeDdl(target, ddl) {
|
|
83
|
+
await executeStatement(target, sql.raw(ddl));
|
|
84
|
+
}
|
|
85
|
+
function canonicalLegacyInstant(value) {
|
|
86
|
+
const canonical = canonicalizeDatabaseTimestamp(value);
|
|
87
|
+
if (canonical === void 0) {
|
|
88
|
+
throw new ConfigurationError(
|
|
89
|
+
"Legacy recorded-time relation contained an invalid timestamp.",
|
|
90
|
+
{ value }
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return canonical;
|
|
94
|
+
}
|
|
95
|
+
function safeRevision(value) {
|
|
96
|
+
const revision = typeof value === "bigint" ? Number(value) : typeof value === "string" && /^\d+$/.test(value) ? Number(value) : value;
|
|
97
|
+
if (typeof revision !== "number" || !Number.isSafeInteger(revision) || revision < 1 || revision >= RECORDED_MAX_REVISION) {
|
|
98
|
+
throw new ConfigurationError(
|
|
99
|
+
"Recorded anchor mapping contained an invalid revision.",
|
|
100
|
+
{ value }
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return revision;
|
|
104
|
+
}
|
|
105
|
+
async function columnNames(target, tableName) {
|
|
106
|
+
const rows = target.dialect === "sqlite" ? await target.execute(
|
|
107
|
+
asCompiledRowsSql(sql`PRAGMA table_info(${sql.identifier(tableName)})`)
|
|
108
|
+
) : await target.execute(
|
|
109
|
+
asCompiledRowsSql(sql`
|
|
110
|
+
SELECT column_name AS name
|
|
111
|
+
FROM information_schema.columns
|
|
112
|
+
WHERE table_schema = current_schema()
|
|
113
|
+
AND table_name = ${tableName}
|
|
114
|
+
`)
|
|
115
|
+
);
|
|
116
|
+
return new Set(
|
|
117
|
+
rows.flatMap((row) => typeof row.name === "string" ? [row.name] : [])
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
async function readLegacyInstants(target, tables) {
|
|
121
|
+
const rows = await target.execute(
|
|
122
|
+
asCompiledRowsSql(sql`
|
|
123
|
+
SELECT graph_id, recorded_from AS recorded_at
|
|
124
|
+
FROM ${sql.identifier(tables.recordedNodes)}
|
|
125
|
+
UNION
|
|
126
|
+
SELECT graph_id, recorded_to AS recorded_at
|
|
127
|
+
FROM ${sql.identifier(tables.recordedNodes)}
|
|
128
|
+
WHERE recorded_to <> ${LEGACY_RECORDED_MAX}
|
|
129
|
+
UNION
|
|
130
|
+
SELECT graph_id, recorded_from AS recorded_at
|
|
131
|
+
FROM ${sql.identifier(tables.recordedEdges)}
|
|
132
|
+
UNION
|
|
133
|
+
SELECT graph_id, recorded_to AS recorded_at
|
|
134
|
+
FROM ${sql.identifier(tables.recordedEdges)}
|
|
135
|
+
WHERE recorded_to <> ${LEGACY_RECORDED_MAX}
|
|
136
|
+
UNION
|
|
137
|
+
SELECT graph_id, recorded_at
|
|
138
|
+
FROM ${sql.identifier(tables.recordedClock)}
|
|
139
|
+
`)
|
|
140
|
+
);
|
|
141
|
+
const instants = rows.map((row) => {
|
|
142
|
+
if (typeof row.graph_id !== "string") {
|
|
143
|
+
throw new ConfigurationError(
|
|
144
|
+
"Legacy recorded-time relation contained an invalid graph id.",
|
|
145
|
+
{ graphId: row.graph_id }
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
graphId: row.graph_id,
|
|
150
|
+
recordedAt: canonicalLegacyInstant(row.recorded_at)
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
instants.sort((left, right) => {
|
|
154
|
+
if (left.graphId < right.graphId) return -1;
|
|
155
|
+
if (left.graphId > right.graphId) return 1;
|
|
156
|
+
if (left.recordedAt < right.recordedAt) return -1;
|
|
157
|
+
if (left.recordedAt > right.recordedAt) return 1;
|
|
158
|
+
return 0;
|
|
159
|
+
});
|
|
160
|
+
const mapping = [];
|
|
161
|
+
let graphId;
|
|
162
|
+
let revision = 0;
|
|
163
|
+
let previousInstant;
|
|
164
|
+
for (const instant of instants) {
|
|
165
|
+
if (instant.graphId !== graphId) {
|
|
166
|
+
graphId = instant.graphId;
|
|
167
|
+
revision = 0;
|
|
168
|
+
previousInstant = void 0;
|
|
169
|
+
}
|
|
170
|
+
if (instant.recordedAt === previousInstant) continue;
|
|
171
|
+
revision += 1;
|
|
172
|
+
mapping.push({
|
|
173
|
+
graphId: instant.graphId,
|
|
174
|
+
legacyRecordedAt: instant.recordedAt,
|
|
175
|
+
recordedAt: instant.recordedAt,
|
|
176
|
+
revision
|
|
177
|
+
});
|
|
178
|
+
previousInstant = instant.recordedAt;
|
|
179
|
+
}
|
|
180
|
+
return mapping;
|
|
181
|
+
}
|
|
182
|
+
function migrationMapDdl(dialect, table) {
|
|
183
|
+
const revisionType = dialect === "postgres" ? "BIGINT" : "INTEGER";
|
|
184
|
+
const recordedAtType = dialect === "postgres" ? "TIMESTAMPTZ" : "TEXT";
|
|
185
|
+
return `CREATE TABLE IF NOT EXISTS "${table}" (
|
|
186
|
+
graph_id TEXT NOT NULL,
|
|
187
|
+
legacy_recorded_at TEXT NOT NULL,
|
|
188
|
+
revision ${revisionType} NOT NULL,
|
|
189
|
+
recorded_at ${recordedAtType} NOT NULL,
|
|
190
|
+
PRIMARY KEY (graph_id, legacy_recorded_at)
|
|
191
|
+
);`;
|
|
192
|
+
}
|
|
193
|
+
async function writeMappingRows(target, tableName, rows) {
|
|
194
|
+
await executeStatement(target, sql`DELETE FROM ${sql.identifier(tableName)}`);
|
|
195
|
+
const rowsPerStatement = Math.max(
|
|
196
|
+
1,
|
|
197
|
+
Math.floor((target.capabilities.maxBindParameters ?? 900) / 4)
|
|
198
|
+
);
|
|
199
|
+
for (let start = 0; start < rows.length; start += rowsPerStatement) {
|
|
200
|
+
const values = rows.slice(start, start + rowsPerStatement).map(
|
|
201
|
+
(row) => sql`(${row.graphId}, ${row.legacyRecordedAt}, ${row.revision}, ${row.recordedAt})`
|
|
202
|
+
);
|
|
203
|
+
await executeStatement(
|
|
204
|
+
target,
|
|
205
|
+
sql`
|
|
206
|
+
INSERT INTO ${sql.identifier(tableName)}
|
|
207
|
+
(graph_id, legacy_recorded_at, revision, recorded_at)
|
|
208
|
+
VALUES ${sql.join(values, sql`, `)}
|
|
209
|
+
`
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function tableDdl(dialect, tables, temporary) {
|
|
214
|
+
if (dialect === "sqlite") {
|
|
215
|
+
const temporaryTables2 = createSqliteTables(temporary);
|
|
216
|
+
const finalTables2 = createSqliteTables(tables);
|
|
217
|
+
const temporaryContributions = sqliteContributions(temporaryTables2);
|
|
218
|
+
const finalContributions = sqliteContributions(finalTables2);
|
|
219
|
+
return ddlForRecordedTables(temporaryContributions, finalContributions);
|
|
220
|
+
}
|
|
221
|
+
const temporaryTables = createPostgresTables(temporary);
|
|
222
|
+
const finalTables = createPostgresTables(tables);
|
|
223
|
+
return ddlForRecordedTables(
|
|
224
|
+
postgresContributions(temporaryTables),
|
|
225
|
+
postgresContributions(finalTables)
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
function ddlForRecordedTables(temporary, final) {
|
|
229
|
+
function statements(logicalName) {
|
|
230
|
+
const temporaryDdl = temporary.find(
|
|
231
|
+
(entry) => entry.logicalName === logicalName
|
|
232
|
+
)?.createDdl;
|
|
233
|
+
const finalDdl = final.find(
|
|
234
|
+
(entry) => entry.logicalName === logicalName
|
|
235
|
+
)?.createDdl;
|
|
236
|
+
if (temporaryDdl === void 0 || finalDdl === void 0) {
|
|
237
|
+
throw new ConfigurationError(
|
|
238
|
+
`Could not generate migration DDL for ${logicalName}.`
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
const createTable = temporaryDdl[0];
|
|
242
|
+
if (createTable === void 0) {
|
|
243
|
+
throw new ConfigurationError(
|
|
244
|
+
`Could not generate migration table DDL for ${logicalName}.`
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
return [createTable, ...finalDdl.slice(1)];
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
clock: statements("recordedClock"),
|
|
251
|
+
edges: statements("recordedEdges"),
|
|
252
|
+
nodes: statements("recordedNodes")
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function migratedColumn(column, legacyAlias) {
|
|
256
|
+
if (column === "recorded_from") return sql`from_map.revision`;
|
|
257
|
+
if (column === "recorded_to") {
|
|
258
|
+
return sql`
|
|
259
|
+
CASE
|
|
260
|
+
WHEN ${sql.raw(legacyAlias)}.recorded_to = ${LEGACY_RECORDED_MAX}
|
|
261
|
+
THEN ${RECORDED_MAX_REVISION}
|
|
262
|
+
ELSE to_map.revision
|
|
263
|
+
END
|
|
264
|
+
`;
|
|
265
|
+
}
|
|
266
|
+
return sql`${sql.raw(legacyAlias)}.${sql.identifier(column)}`;
|
|
267
|
+
}
|
|
268
|
+
function mappingMatch(dialect, mappingAlias, legacyColumn) {
|
|
269
|
+
const mapping = sql.raw(mappingAlias);
|
|
270
|
+
const legacy = sql.raw(`legacy.${legacyColumn}`);
|
|
271
|
+
return dialect === "postgres" ? sql`${mapping}.recorded_at = ${legacy}` : sql`${mapping}.legacy_recorded_at = ${legacy}`;
|
|
272
|
+
}
|
|
273
|
+
function missingMappingCount(value, legacyTable) {
|
|
274
|
+
const count = Number(value);
|
|
275
|
+
if (!Number.isSafeInteger(count) || count < 0) {
|
|
276
|
+
throw new ConfigurationError(
|
|
277
|
+
"Recorded-time migration returned an invalid integrity-check count.",
|
|
278
|
+
{ legacyTable, value }
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
return count;
|
|
282
|
+
}
|
|
283
|
+
async function assertRecordedRelationMappings(target, options) {
|
|
284
|
+
const fromMatch = mappingMatch(target.dialect, "from_map", "recorded_from");
|
|
285
|
+
const toMatch = mappingMatch(target.dialect, "to_map", "recorded_to");
|
|
286
|
+
const rows = await target.execute(
|
|
287
|
+
asCompiledRowsSql(sql`
|
|
288
|
+
SELECT COUNT(*) AS missing
|
|
289
|
+
FROM ${sql.identifier(options.legacyTable)} AS legacy
|
|
290
|
+
LEFT JOIN ${sql.identifier(options.mappingTable)} AS from_map
|
|
291
|
+
ON from_map.graph_id = legacy.graph_id AND ${fromMatch}
|
|
292
|
+
LEFT JOIN ${sql.identifier(options.mappingTable)} AS to_map
|
|
293
|
+
ON to_map.graph_id = legacy.graph_id AND ${toMatch}
|
|
294
|
+
WHERE from_map.revision IS NULL
|
|
295
|
+
OR (
|
|
296
|
+
legacy.recorded_to <> ${LEGACY_RECORDED_MAX}
|
|
297
|
+
AND to_map.revision IS NULL
|
|
298
|
+
)
|
|
299
|
+
`)
|
|
300
|
+
);
|
|
301
|
+
const missing = missingMappingCount(rows[0]?.missing, options.legacyTable);
|
|
302
|
+
if (missing === 0) return;
|
|
303
|
+
throw new ConfigurationError(
|
|
304
|
+
"Legacy recorded-time boundaries could not be mapped exactly.",
|
|
305
|
+
{ legacyTable: options.legacyTable, missingRows: missing },
|
|
306
|
+
{
|
|
307
|
+
suggestion: "Ensure every legacy boundary is a valid millisecond-precision timestamp produced by the preview recorded clock before retrying the offline migration."
|
|
308
|
+
}
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
async function assertRecordedClockMappings(target, options) {
|
|
312
|
+
const match = mappingMatch(target.dialect, "anchor_map", "recorded_at");
|
|
313
|
+
const rows = await target.execute(
|
|
314
|
+
asCompiledRowsSql(sql`
|
|
315
|
+
SELECT COUNT(*) AS missing
|
|
316
|
+
FROM ${sql.identifier(options.legacyTable)} AS legacy
|
|
317
|
+
LEFT JOIN ${sql.identifier(options.mappingTable)} AS anchor_map
|
|
318
|
+
ON anchor_map.graph_id = legacy.graph_id AND ${match}
|
|
319
|
+
WHERE anchor_map.revision IS NULL
|
|
320
|
+
`)
|
|
321
|
+
);
|
|
322
|
+
const missing = missingMappingCount(rows[0]?.missing, options.legacyTable);
|
|
323
|
+
if (missing === 0) return;
|
|
324
|
+
throw new ConfigurationError(
|
|
325
|
+
"Legacy recorded clock values could not be mapped exactly.",
|
|
326
|
+
{ legacyTable: options.legacyTable, missingRows: missing },
|
|
327
|
+
{
|
|
328
|
+
suggestion: "Ensure every legacy clock value is a valid millisecond-precision timestamp produced by the preview recorded clock before retrying the offline migration."
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
async function copyRecordedRelation(target, options) {
|
|
333
|
+
const columnList = options.columns.map((column) => sql.identifier(column));
|
|
334
|
+
const values = options.columns.map(
|
|
335
|
+
(column) => migratedColumn(column, "legacy")
|
|
336
|
+
);
|
|
337
|
+
await assertRecordedRelationMappings(target, options);
|
|
338
|
+
const fromMatch = mappingMatch(target.dialect, "from_map", "recorded_from");
|
|
339
|
+
const toMatch = mappingMatch(target.dialect, "to_map", "recorded_to");
|
|
340
|
+
await executeStatement(
|
|
341
|
+
target,
|
|
342
|
+
sql`
|
|
343
|
+
INSERT INTO ${sql.identifier(options.temporaryTable)}
|
|
344
|
+
(${sql.join(columnList, sql`, `)})
|
|
345
|
+
SELECT ${sql.join(values, sql`, `)}
|
|
346
|
+
FROM ${sql.identifier(options.legacyTable)} AS legacy
|
|
347
|
+
-- LEFT JOIN is deliberate: a missing mapping reaches the NOT NULL
|
|
348
|
+
-- revision columns and fails loud instead of silently dropping history.
|
|
349
|
+
LEFT JOIN ${sql.identifier(options.mappingTable)} AS from_map
|
|
350
|
+
ON from_map.graph_id = legacy.graph_id AND ${fromMatch}
|
|
351
|
+
LEFT JOIN ${sql.identifier(options.mappingTable)} AS to_map
|
|
352
|
+
ON to_map.graph_id = legacy.graph_id AND ${toMatch}
|
|
353
|
+
`
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
async function copyRecordedClock(target, options) {
|
|
357
|
+
await assertRecordedClockMappings(target, options);
|
|
358
|
+
const match = mappingMatch(target.dialect, "anchor_map", "recorded_at");
|
|
359
|
+
await executeStatement(
|
|
360
|
+
target,
|
|
361
|
+
sql`
|
|
362
|
+
INSERT INTO ${sql.identifier(options.temporaryTable)}
|
|
363
|
+
(graph_id, revision, recorded_at)
|
|
364
|
+
SELECT legacy.graph_id, anchor_map.revision, legacy.recorded_at
|
|
365
|
+
FROM ${sql.identifier(options.legacyTable)} AS legacy
|
|
366
|
+
-- Preserve fail-loud behavior if the preflight invariant changes later.
|
|
367
|
+
LEFT JOIN ${sql.identifier(options.mappingTable)} AS anchor_map
|
|
368
|
+
ON anchor_map.graph_id = legacy.graph_id AND ${match}
|
|
369
|
+
`
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
async function replaceLegacyTables(target, tables, mappingTable) {
|
|
373
|
+
const temporary = {
|
|
374
|
+
recordedNodes: temporaryTableName(tables.recordedNodes, "rn"),
|
|
375
|
+
recordedEdges: temporaryTableName(tables.recordedEdges, "re"),
|
|
376
|
+
recordedClock: temporaryTableName(tables.recordedClock, "rc")
|
|
377
|
+
};
|
|
378
|
+
const ddl = tableDdl(target.dialect, tables, temporary);
|
|
379
|
+
for (const table of Object.values(temporary)) {
|
|
380
|
+
await executeStatement(
|
|
381
|
+
target,
|
|
382
|
+
sql`DROP TABLE IF EXISTS ${sql.identifier(table)}`
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
await executeDdl(target, requireCreateTable(ddl.nodes));
|
|
386
|
+
await executeDdl(target, requireCreateTable(ddl.edges));
|
|
387
|
+
await executeDdl(target, requireCreateTable(ddl.clock));
|
|
388
|
+
await copyRecordedRelation(target, {
|
|
389
|
+
columns: RECORDED_NODE_COLUMNS,
|
|
390
|
+
legacyTable: tables.recordedNodes,
|
|
391
|
+
mappingTable,
|
|
392
|
+
temporaryTable: temporary.recordedNodes
|
|
393
|
+
});
|
|
394
|
+
await copyRecordedRelation(target, {
|
|
395
|
+
columns: RECORDED_EDGE_COLUMNS,
|
|
396
|
+
legacyTable: tables.recordedEdges,
|
|
397
|
+
mappingTable,
|
|
398
|
+
temporaryTable: temporary.recordedEdges
|
|
399
|
+
});
|
|
400
|
+
await copyRecordedClock(target, {
|
|
401
|
+
legacyTable: tables.recordedClock,
|
|
402
|
+
mappingTable,
|
|
403
|
+
temporaryTable: temporary.recordedClock
|
|
404
|
+
});
|
|
405
|
+
await executeStatement(
|
|
406
|
+
target,
|
|
407
|
+
sql`DROP TABLE ${sql.identifier(tables.recordedNodes)}`
|
|
408
|
+
);
|
|
409
|
+
await executeStatement(
|
|
410
|
+
target,
|
|
411
|
+
sql`DROP TABLE ${sql.identifier(tables.recordedEdges)}`
|
|
412
|
+
);
|
|
413
|
+
await executeStatement(
|
|
414
|
+
target,
|
|
415
|
+
sql`DROP TABLE ${sql.identifier(tables.recordedClock)}`
|
|
416
|
+
);
|
|
417
|
+
await renameTable(target, temporary.recordedNodes, tables.recordedNodes);
|
|
418
|
+
await renameTable(target, temporary.recordedEdges, tables.recordedEdges);
|
|
419
|
+
await renameTable(target, temporary.recordedClock, tables.recordedClock);
|
|
420
|
+
await renamePrimaryKeyConstraint(
|
|
421
|
+
target,
|
|
422
|
+
temporary.recordedNodes,
|
|
423
|
+
tables.recordedNodes
|
|
424
|
+
);
|
|
425
|
+
await renamePrimaryKeyConstraint(
|
|
426
|
+
target,
|
|
427
|
+
temporary.recordedEdges,
|
|
428
|
+
tables.recordedEdges
|
|
429
|
+
);
|
|
430
|
+
await renamePrimaryKeyConstraint(
|
|
431
|
+
target,
|
|
432
|
+
temporary.recordedClock,
|
|
433
|
+
tables.recordedClock
|
|
434
|
+
);
|
|
435
|
+
for (const statement of [
|
|
436
|
+
...ddl.nodes.slice(1),
|
|
437
|
+
...ddl.edges.slice(1),
|
|
438
|
+
...ddl.clock.slice(1)
|
|
439
|
+
]) {
|
|
440
|
+
await executeDdl(target, statement);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
async function renamePrimaryKeyConstraint(target, temporaryTable, finalTable) {
|
|
444
|
+
if (target.dialect !== "postgres") return;
|
|
445
|
+
await executeStatement(
|
|
446
|
+
target,
|
|
447
|
+
sql`
|
|
448
|
+
ALTER TABLE ${sql.identifier(finalTable)}
|
|
449
|
+
RENAME CONSTRAINT ${sql.identifier(`${temporaryTable}_pkey`)}
|
|
450
|
+
TO ${sql.identifier(shortenedIdentifier(`${finalTable}_pkey`))}
|
|
451
|
+
`
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
function requireCreateTable(statements) {
|
|
455
|
+
const statement = statements[0];
|
|
456
|
+
if (statement === void 0) {
|
|
457
|
+
throw new ConfigurationError("Recorded migration table DDL was empty.");
|
|
458
|
+
}
|
|
459
|
+
return statement;
|
|
460
|
+
}
|
|
461
|
+
async function renameTable(target, from, to) {
|
|
462
|
+
try {
|
|
463
|
+
await executeStatement(
|
|
464
|
+
target,
|
|
465
|
+
sql`ALTER TABLE ${sql.identifier(from)} RENAME TO ${sql.identifier(to)}`
|
|
466
|
+
);
|
|
467
|
+
} catch (error) {
|
|
468
|
+
throw new ConfigurationError(
|
|
469
|
+
"Could not rename a migrated recorded-time table.",
|
|
470
|
+
{ from, to },
|
|
471
|
+
{ cause: error }
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
async function migrateLegacyRecordedTime(options) {
|
|
476
|
+
const tables = resolvedTableNames(options.backend, options.tableNames);
|
|
477
|
+
const mapTable = mappingTableName(tables, options.mappingTableName);
|
|
478
|
+
return options.backend.transaction(async (target) => {
|
|
479
|
+
const clockColumns = await columnNames(target, tables.recordedClock);
|
|
480
|
+
if (clockColumns.size === 0) {
|
|
481
|
+
return {
|
|
482
|
+
migrated: false,
|
|
483
|
+
graphs: 0,
|
|
484
|
+
anchors: 0,
|
|
485
|
+
mappingTableName: mapTable
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
if (clockColumns.has("revision")) {
|
|
489
|
+
const mapColumns = await columnNames(target, mapTable);
|
|
490
|
+
if (mapColumns.size === 0) {
|
|
491
|
+
return {
|
|
492
|
+
migrated: false,
|
|
493
|
+
graphs: 0,
|
|
494
|
+
anchors: 0,
|
|
495
|
+
mappingTableName: mapTable
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
const rows = await target.execute(
|
|
499
|
+
asCompiledRowsSql(sql`
|
|
500
|
+
SELECT COUNT(*) AS anchors, COUNT(DISTINCT graph_id) AS graphs
|
|
501
|
+
FROM ${sql.identifier(mapTable)}
|
|
502
|
+
`)
|
|
503
|
+
);
|
|
504
|
+
const anchors = Number(rows[0]?.anchors ?? 0);
|
|
505
|
+
const graphs = Number(rows[0]?.graphs ?? 0);
|
|
506
|
+
return {
|
|
507
|
+
migrated: false,
|
|
508
|
+
graphs: Number.isSafeInteger(graphs) ? graphs : 0,
|
|
509
|
+
anchors: Number.isSafeInteger(anchors) ? anchors : 0,
|
|
510
|
+
mappingTableName: mapTable
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
const nodeColumns = await columnNames(target, tables.recordedNodes);
|
|
514
|
+
const edgeColumns = await columnNames(target, tables.recordedEdges);
|
|
515
|
+
if (!nodeColumns.has("recorded_from") || !edgeColumns.has("recorded_from")) {
|
|
516
|
+
throw new ConfigurationError(
|
|
517
|
+
"Legacy recorded-time schema is incomplete.",
|
|
518
|
+
{ tables }
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
await executeDdl(target, migrationMapDdl(target.dialect, mapTable));
|
|
522
|
+
const mapping = await readLegacyInstants(target, tables);
|
|
523
|
+
await writeMappingRows(target, mapTable, mapping);
|
|
524
|
+
await replaceLegacyTables(target, tables, mapTable);
|
|
525
|
+
return {
|
|
526
|
+
migrated: true,
|
|
527
|
+
graphs: new Set(mapping.map((row) => row.graphId)).size,
|
|
528
|
+
anchors: mapping.length,
|
|
529
|
+
mappingTableName: mapTable
|
|
530
|
+
};
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
async function migrateRecordedAnchor(options) {
|
|
534
|
+
try {
|
|
535
|
+
return asRecordedInstant(options.anchor);
|
|
536
|
+
} catch (error) {
|
|
537
|
+
if (!(error instanceof ValidationError)) throw error;
|
|
538
|
+
}
|
|
539
|
+
const legacyRecordedAt = canonicalLegacyInstant(options.anchor);
|
|
540
|
+
const tables = resolvedTableNames(options.backend, options.tableNames);
|
|
541
|
+
const mapTable = mappingTableName(tables, options.mappingTableName);
|
|
542
|
+
const rows = await options.backend.execute(
|
|
543
|
+
asCompiledRowsSql(sql`
|
|
544
|
+
SELECT revision, recorded_at
|
|
545
|
+
FROM ${sql.identifier(mapTable)}
|
|
546
|
+
WHERE graph_id = ${options.graphId}
|
|
547
|
+
AND legacy_recorded_at = ${legacyRecordedAt}
|
|
548
|
+
`)
|
|
549
|
+
);
|
|
550
|
+
const row = rows[0];
|
|
551
|
+
if (row === void 0) {
|
|
552
|
+
throw new ConfigurationError(
|
|
553
|
+
"No migrated recorded anchor matches this graph and legacy timestamp.",
|
|
554
|
+
{ anchor: options.anchor, graphId: options.graphId },
|
|
555
|
+
{
|
|
556
|
+
suggestion: "Run migrateLegacyRecordedTime() before deleting its mapping rows, and pass the graph that produced the checkpoint."
|
|
557
|
+
}
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
return createRecordedInstant(
|
|
561
|
+
safeRevision(row.revision),
|
|
562
|
+
canonicalLegacyInstant(row.recorded_at)
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
async function deleteLegacyRecordedAnchorMap(options) {
|
|
566
|
+
if (options.backend.executeStatement === void 0) {
|
|
567
|
+
throw new ConfigurationError(
|
|
568
|
+
"Deleting a recorded anchor migration map requires executeStatement support.",
|
|
569
|
+
{ dialect: options.backend.dialect }
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
const tables = resolvedTableNames(options.backend, options.tableNames);
|
|
573
|
+
const mapTable = mappingTableName(tables, options.mappingTableName);
|
|
574
|
+
await options.backend.transaction(async (target) => {
|
|
575
|
+
await executeStatement(
|
|
576
|
+
target,
|
|
577
|
+
sql`
|
|
578
|
+
DELETE FROM ${sql.identifier(mapTable)}
|
|
579
|
+
WHERE graph_id = ${options.graphId}
|
|
580
|
+
`
|
|
581
|
+
);
|
|
582
|
+
if (options.dropWhenEmpty !== true) return;
|
|
583
|
+
const rows = await target.execute(
|
|
584
|
+
asCompiledRowsSql(sql`
|
|
585
|
+
SELECT COUNT(*) AS anchors, COUNT(DISTINCT graph_id) AS graphs
|
|
586
|
+
FROM ${sql.identifier(mapTable)}
|
|
587
|
+
`)
|
|
588
|
+
);
|
|
589
|
+
const remaining = missingMappingCount(rows[0]?.anchors, mapTable);
|
|
590
|
+
if (remaining === 0) {
|
|
591
|
+
await executeStatement(
|
|
592
|
+
target,
|
|
593
|
+
sql`DROP TABLE ${sql.identifier(mapTable)}`
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
export { deleteLegacyRecordedAnchorMap, migrateLegacyRecordedTime, migrateRecordedAnchor };
|
|
600
|
+
//# sourceMappingURL=chunk-ELA3V6UN.js.map
|
|
601
|
+
//# sourceMappingURL=chunk-ELA3V6UN.js.map
|