@prisma-next/target-sqlite 0.5.0-dev.6 → 0.5.0-dev.61

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.
Files changed (134) hide show
  1. package/dist/codec-ids-B1-OiN8Q.mjs +14 -0
  2. package/dist/codec-ids-B1-OiN8Q.mjs.map +1 -0
  3. package/dist/codec-ids-DyLO2Rfx.d.mts +13 -0
  4. package/dist/codec-ids-DyLO2Rfx.d.mts.map +1 -0
  5. package/dist/codec-ids.d.mts +2 -0
  6. package/dist/codec-ids.mjs +3 -0
  7. package/dist/codec-types-Bbzv7qCW.d.mts +24 -0
  8. package/dist/codec-types-Bbzv7qCW.d.mts.map +1 -0
  9. package/dist/codec-types.d.mts +4 -0
  10. package/dist/codec-types.mjs +3 -0
  11. package/dist/codecs-BqDitp2X.d.mts +127 -0
  12. package/dist/codecs-BqDitp2X.d.mts.map +1 -0
  13. package/dist/codecs-CDcidsHL.mjs +221 -0
  14. package/dist/codecs-CDcidsHL.mjs.map +1 -0
  15. package/dist/codecs.d.mts +3 -0
  16. package/dist/codecs.mjs +14 -0
  17. package/dist/codecs.mjs.map +1 -0
  18. package/dist/control.d.mts +4 -3
  19. package/dist/control.d.mts.map +1 -1
  20. package/dist/control.mjs +343 -1
  21. package/dist/control.mjs.map +1 -1
  22. package/dist/default-normalizer-R-sQXAYt.mjs +69 -0
  23. package/dist/default-normalizer-R-sQXAYt.mjs.map +1 -0
  24. package/dist/default-normalizer.d.mts +8 -0
  25. package/dist/default-normalizer.d.mts.map +1 -0
  26. package/dist/default-normalizer.mjs +3 -0
  27. package/dist/descriptor-meta-BA2YAFQq.mjs +24 -0
  28. package/dist/descriptor-meta-BA2YAFQq.mjs.map +1 -0
  29. package/dist/migration.d.mts +76 -0
  30. package/dist/migration.d.mts.map +1 -0
  31. package/dist/migration.mjs +38 -0
  32. package/dist/migration.mjs.map +1 -0
  33. package/dist/native-type-normalizer-BMovohPm.mjs +14 -0
  34. package/dist/native-type-normalizer-BMovohPm.mjs.map +1 -0
  35. package/dist/native-type-normalizer.d.mts +11 -0
  36. package/dist/native-type-normalizer.d.mts.map +1 -0
  37. package/dist/native-type-normalizer.mjs +3 -0
  38. package/dist/op-factory-call-BUVV-W9F.mjs +252 -0
  39. package/dist/op-factory-call-BUVV-W9F.mjs.map +1 -0
  40. package/dist/op-factory-call-dUIOao68.d.mts +134 -0
  41. package/dist/op-factory-call-dUIOao68.d.mts.map +1 -0
  42. package/dist/op-factory-call.d.mts +3 -0
  43. package/dist/op-factory-call.mjs +3 -0
  44. package/dist/pack.d.mts +37 -1
  45. package/dist/pack.d.mts.map +1 -1
  46. package/dist/pack.mjs +1 -1
  47. package/dist/planner-CuchCrpN.mjs +522 -0
  48. package/dist/planner-CuchCrpN.mjs.map +1 -0
  49. package/dist/planner-produced-sqlite-migration-BfIIUtxe.d.mts +24 -0
  50. package/dist/planner-produced-sqlite-migration-BfIIUtxe.d.mts.map +1 -0
  51. package/dist/planner-produced-sqlite-migration-C3AAaQoW.mjs +107 -0
  52. package/dist/planner-produced-sqlite-migration-C3AAaQoW.mjs.map +1 -0
  53. package/dist/planner-produced-sqlite-migration.d.mts +5 -0
  54. package/dist/planner-produced-sqlite-migration.mjs +3 -0
  55. package/dist/planner-target-details-BQIWQlBu.mjs +16 -0
  56. package/dist/planner-target-details-BQIWQlBu.mjs.map +1 -0
  57. package/dist/planner-target-details-CtWRvse0.d.mts +12 -0
  58. package/dist/planner-target-details-CtWRvse0.d.mts.map +1 -0
  59. package/dist/planner-target-details.d.mts +2 -0
  60. package/dist/planner-target-details.mjs +3 -0
  61. package/dist/planner.d.mts +56 -0
  62. package/dist/planner.d.mts.map +1 -0
  63. package/dist/planner.mjs +3 -0
  64. package/dist/render-ops-CXOv7SRC.mjs +8 -0
  65. package/dist/render-ops-CXOv7SRC.mjs.map +1 -0
  66. package/dist/render-ops.d.mts +11 -0
  67. package/dist/render-ops.d.mts.map +1 -0
  68. package/dist/render-ops.mjs +3 -0
  69. package/dist/runtime.d.mts.map +1 -1
  70. package/dist/runtime.mjs +2 -4
  71. package/dist/runtime.mjs.map +1 -1
  72. package/dist/shared-D_1fFqLf.d.mts +69 -0
  73. package/dist/shared-D_1fFqLf.d.mts.map +1 -0
  74. package/dist/sql-utils-D3SMPFDD.mjs +33 -0
  75. package/dist/sql-utils-D3SMPFDD.mjs.map +1 -0
  76. package/dist/sql-utils.d.mts +22 -0
  77. package/dist/sql-utils.d.mts.map +1 -0
  78. package/dist/sql-utils.mjs +3 -0
  79. package/dist/sqlite-migration-BeR1cikr.d.mts +18 -0
  80. package/dist/sqlite-migration-BeR1cikr.d.mts.map +1 -0
  81. package/dist/sqlite-migration-CnLhIrJF.mjs +17 -0
  82. package/dist/sqlite-migration-CnLhIrJF.mjs.map +1 -0
  83. package/dist/statement-builders-B3OGOp7n.mjs +148 -0
  84. package/dist/statement-builders-B3OGOp7n.mjs.map +1 -0
  85. package/dist/statement-builders.d.mts +48 -0
  86. package/dist/statement-builders.d.mts.map +1 -0
  87. package/dist/statement-builders.mjs +3 -0
  88. package/dist/tables-sKIg_lWE.mjs +408 -0
  89. package/dist/tables-sKIg_lWE.mjs.map +1 -0
  90. package/package.json +29 -7
  91. package/src/core/authoring.ts +9 -0
  92. package/src/core/codec-helpers.ts +11 -0
  93. package/src/core/codec-ids.ts +13 -0
  94. package/src/core/codecs.ts +337 -0
  95. package/src/core/control-target.ts +54 -11
  96. package/src/core/default-normalizer.ts +92 -0
  97. package/src/core/descriptor-meta.ts +5 -1
  98. package/src/core/migrations/issue-planner.ts +586 -0
  99. package/src/core/migrations/op-factory-call.ts +332 -0
  100. package/src/core/migrations/operations/columns.ts +62 -0
  101. package/src/core/migrations/operations/data-transform.ts +51 -0
  102. package/src/core/migrations/operations/indexes.ts +52 -0
  103. package/src/core/migrations/operations/shared.ts +120 -0
  104. package/src/core/migrations/operations/tables.ts +388 -0
  105. package/src/core/migrations/planner-ddl-builders.ts +142 -0
  106. package/src/core/migrations/planner-produced-sqlite-migration.ts +56 -0
  107. package/src/core/migrations/planner-strategies.ts +231 -0
  108. package/src/core/migrations/planner-target-details.ts +33 -0
  109. package/src/core/migrations/planner.ts +149 -0
  110. package/src/core/migrations/render-ops.ts +9 -0
  111. package/src/core/migrations/render-typescript.ts +91 -0
  112. package/src/core/migrations/runner.ts +593 -0
  113. package/src/core/migrations/sqlite-migration.ts +13 -0
  114. package/src/core/migrations/statement-builders.ts +190 -0
  115. package/src/core/native-type-normalizer.ts +9 -0
  116. package/src/core/registry.ts +11 -0
  117. package/src/core/runtime-target.ts +1 -3
  118. package/src/core/sql-utils.ts +47 -0
  119. package/src/exports/codec-ids.ts +13 -0
  120. package/src/exports/codec-types.ts +43 -0
  121. package/src/exports/codecs.ts +20 -0
  122. package/src/exports/control.ts +1 -0
  123. package/src/exports/default-normalizer.ts +1 -0
  124. package/src/exports/migration.ts +23 -0
  125. package/src/exports/native-type-normalizer.ts +1 -0
  126. package/src/exports/op-factory-call.ts +11 -0
  127. package/src/exports/planner-produced-sqlite-migration.ts +4 -0
  128. package/src/exports/planner-target-details.ts +2 -0
  129. package/src/exports/planner.ts +2 -0
  130. package/src/exports/render-ops.ts +1 -0
  131. package/src/exports/sql-utils.ts +1 -0
  132. package/src/exports/statement-builders.ts +11 -0
  133. package/dist/descriptor-meta-DbuuziYA.mjs +0 -14
  134. package/dist/descriptor-meta-DbuuziYA.mjs.map +0 -1
@@ -0,0 +1,148 @@
1
+ //#region src/core/migrations/statement-builders.ts
2
+ const MARKER_TABLE_NAME = "_prisma_marker";
3
+ const LEDGER_TABLE_NAME = "_prisma_ledger";
4
+ /**
5
+ * Control tables the runner creates/manages. The planner must not drop these
6
+ * when reconciling "extra" tables against the contract.
7
+ */
8
+ const CONTROL_TABLE_NAMES = new Set([MARKER_TABLE_NAME, LEDGER_TABLE_NAME]);
9
+ const ensureMarkerTableStatement = {
10
+ sql: `CREATE TABLE IF NOT EXISTS _prisma_marker (
11
+ id INTEGER PRIMARY KEY CHECK (id = 1),
12
+ core_hash TEXT NOT NULL,
13
+ profile_hash TEXT NOT NULL,
14
+ contract_json TEXT,
15
+ canonical_version INTEGER,
16
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
17
+ app_tag TEXT,
18
+ meta TEXT NOT NULL DEFAULT '{}',
19
+ invariants TEXT NOT NULL DEFAULT '[]'
20
+ )`,
21
+ params: []
22
+ };
23
+ const ensureLedgerTableStatement = {
24
+ sql: `CREATE TABLE IF NOT EXISTS _prisma_ledger (
25
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
26
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
27
+ origin_core_hash TEXT,
28
+ origin_profile_hash TEXT,
29
+ destination_core_hash TEXT NOT NULL,
30
+ destination_profile_hash TEXT,
31
+ contract_json_before TEXT,
32
+ contract_json_after TEXT,
33
+ operations TEXT NOT NULL
34
+ )`,
35
+ params: []
36
+ };
37
+ function readMarkerStatement() {
38
+ return {
39
+ sql: `SELECT
40
+ core_hash,
41
+ profile_hash,
42
+ contract_json,
43
+ canonical_version,
44
+ updated_at,
45
+ app_tag,
46
+ meta,
47
+ invariants
48
+ FROM _prisma_marker
49
+ WHERE id = ?`,
50
+ params: [1]
51
+ };
52
+ }
53
+ function buildWriteMarkerStatements(input) {
54
+ return {
55
+ insert: {
56
+ sql: `INSERT INTO _prisma_marker (
57
+ id,
58
+ core_hash,
59
+ profile_hash,
60
+ contract_json,
61
+ canonical_version,
62
+ updated_at,
63
+ app_tag,
64
+ meta,
65
+ invariants
66
+ ) VALUES (
67
+ ?,
68
+ ?,
69
+ ?,
70
+ ?,
71
+ ?,
72
+ datetime('now'),
73
+ ?,
74
+ ?,
75
+ ?
76
+ )`,
77
+ params: [
78
+ 1,
79
+ input.storageHash,
80
+ input.profileHash,
81
+ jsonParam(input.contractJson),
82
+ input.canonicalVersion ?? null,
83
+ input.appTag ?? null,
84
+ jsonParam(input.meta ?? {}),
85
+ jsonParam(input.invariants)
86
+ ]
87
+ },
88
+ update: {
89
+ sql: `UPDATE _prisma_marker SET
90
+ core_hash = ?,
91
+ profile_hash = ?,
92
+ contract_json = ?,
93
+ canonical_version = ?,
94
+ updated_at = datetime('now'),
95
+ app_tag = ?,
96
+ meta = ?,
97
+ invariants = ?
98
+ WHERE id = ?`,
99
+ params: [
100
+ input.storageHash,
101
+ input.profileHash,
102
+ jsonParam(input.contractJson),
103
+ input.canonicalVersion ?? null,
104
+ input.appTag ?? null,
105
+ jsonParam(input.meta ?? {}),
106
+ jsonParam(input.invariants),
107
+ 1
108
+ ]
109
+ }
110
+ };
111
+ }
112
+ function buildLedgerInsertStatement(input) {
113
+ return {
114
+ sql: `INSERT INTO _prisma_ledger (
115
+ origin_core_hash,
116
+ origin_profile_hash,
117
+ destination_core_hash,
118
+ destination_profile_hash,
119
+ contract_json_before,
120
+ contract_json_after,
121
+ operations
122
+ ) VALUES (
123
+ ?,
124
+ ?,
125
+ ?,
126
+ ?,
127
+ ?,
128
+ ?,
129
+ ?
130
+ )`,
131
+ params: [
132
+ input.originStorageHash ?? null,
133
+ input.originProfileHash ?? null,
134
+ input.destinationStorageHash,
135
+ input.destinationProfileHash ?? null,
136
+ jsonParam(input.contractJsonBefore),
137
+ jsonParam(input.contractJsonAfter),
138
+ jsonParam(input.operations)
139
+ ]
140
+ };
141
+ }
142
+ function jsonParam(value) {
143
+ return JSON.stringify(value ?? null);
144
+ }
145
+
146
+ //#endregion
147
+ export { buildWriteMarkerStatements as a, readMarkerStatement as c, buildLedgerInsertStatement as i, LEDGER_TABLE_NAME as n, ensureLedgerTableStatement as o, MARKER_TABLE_NAME as r, ensureMarkerTableStatement as s, CONTROL_TABLE_NAMES as t };
148
+ //# sourceMappingURL=statement-builders-B3OGOp7n.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statement-builders-B3OGOp7n.mjs","names":["CONTROL_TABLE_NAMES: ReadonlySet<string>","ensureMarkerTableStatement: SqlStatement","ensureLedgerTableStatement: SqlStatement"],"sources":["../src/core/migrations/statement-builders.ts"],"sourcesContent":["export interface SqlStatement {\n readonly sql: string;\n readonly params: readonly unknown[];\n}\n\nexport const MARKER_TABLE_NAME = '_prisma_marker';\nexport const LEDGER_TABLE_NAME = '_prisma_ledger';\n\n/**\n * Control tables the runner creates/manages. The planner must not drop these\n * when reconciling \"extra\" tables against the contract.\n */\nexport const CONTROL_TABLE_NAMES: ReadonlySet<string> = new Set([\n MARKER_TABLE_NAME,\n LEDGER_TABLE_NAME,\n]);\n\nexport const ensureMarkerTableStatement: SqlStatement = {\n sql: `CREATE TABLE IF NOT EXISTS _prisma_marker (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n core_hash TEXT NOT NULL,\n profile_hash TEXT NOT NULL,\n contract_json TEXT,\n canonical_version INTEGER,\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n app_tag TEXT,\n meta TEXT NOT NULL DEFAULT '{}',\n invariants TEXT NOT NULL DEFAULT '[]'\n )`,\n params: [],\n};\n\nexport const ensureLedgerTableStatement: SqlStatement = {\n sql: `CREATE TABLE IF NOT EXISTS _prisma_ledger (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n origin_core_hash TEXT,\n origin_profile_hash TEXT,\n destination_core_hash TEXT NOT NULL,\n destination_profile_hash TEXT,\n contract_json_before TEXT,\n contract_json_after TEXT,\n operations TEXT NOT NULL\n )`,\n params: [],\n};\n\nexport function readMarkerStatement(): SqlStatement {\n return {\n sql: `SELECT\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n FROM _prisma_marker\n WHERE id = ?`,\n params: [1],\n };\n}\n\nexport interface WriteMarkerInput {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly contractJson?: unknown;\n readonly canonicalVersion?: number | null;\n readonly appTag?: string | null;\n readonly meta?: Record<string, unknown>;\n /**\n * Invariants to write into `marker.invariants`. Stored as a JSON-encoded\n * TEXT array — SQLite has no native array type. The runner is responsible\n * for merging with the existing column (no SQL-side merge here, unlike\n * Postgres) before passing them in: BEGIN EXCLUSIVE on the migration\n * transaction makes the read-then-merge-then-write sequence safe.\n */\n readonly invariants: readonly string[];\n}\n\nexport function buildWriteMarkerStatements(input: WriteMarkerInput): {\n readonly insert: SqlStatement;\n readonly update: SqlStatement;\n} {\n const params: readonly unknown[] = [\n 1,\n input.storageHash,\n input.profileHash,\n jsonParam(input.contractJson),\n input.canonicalVersion ?? null,\n input.appTag ?? null,\n jsonParam(input.meta ?? {}),\n jsonParam(input.invariants),\n ];\n\n return {\n insert: {\n sql: `INSERT INTO _prisma_marker (\n id,\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n ) VALUES (\n ?,\n ?,\n ?,\n ?,\n ?,\n datetime('now'),\n ?,\n ?,\n ?\n )`,\n params,\n },\n update: {\n sql: `UPDATE _prisma_marker SET\n core_hash = ?,\n profile_hash = ?,\n contract_json = ?,\n canonical_version = ?,\n updated_at = datetime('now'),\n app_tag = ?,\n meta = ?,\n invariants = ?\n WHERE id = ?`,\n params: [\n input.storageHash,\n input.profileHash,\n jsonParam(input.contractJson),\n input.canonicalVersion ?? null,\n input.appTag ?? null,\n jsonParam(input.meta ?? {}),\n jsonParam(input.invariants),\n 1,\n ],\n },\n };\n}\n\nexport interface LedgerInsertInput {\n readonly originStorageHash?: string | null;\n readonly originProfileHash?: string | null;\n readonly destinationStorageHash: string;\n readonly destinationProfileHash?: string | null;\n readonly contractJsonBefore?: unknown;\n readonly contractJsonAfter?: unknown;\n readonly operations: unknown;\n}\n\nexport function buildLedgerInsertStatement(input: LedgerInsertInput): SqlStatement {\n return {\n sql: `INSERT INTO _prisma_ledger (\n origin_core_hash,\n origin_profile_hash,\n destination_core_hash,\n destination_profile_hash,\n contract_json_before,\n contract_json_after,\n operations\n ) VALUES (\n ?,\n ?,\n ?,\n ?,\n ?,\n ?,\n ?\n )`,\n params: [\n input.originStorageHash ?? null,\n input.originProfileHash ?? null,\n input.destinationStorageHash,\n input.destinationProfileHash ?? null,\n jsonParam(input.contractJsonBefore),\n jsonParam(input.contractJsonAfter),\n jsonParam(input.operations),\n ],\n };\n}\n\nfunction jsonParam(value: unknown): string {\n return JSON.stringify(value ?? null);\n}\n"],"mappings":";AAKA,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;;;;;AAMjC,MAAaA,sBAA2C,IAAI,IAAI,CAC9D,mBACA,kBACD,CAAC;AAEF,MAAaC,6BAA2C;CACtD,KAAK;;;;;;;;;;;CAWL,QAAQ,EAAE;CACX;AAED,MAAaC,6BAA2C;CACtD,KAAK;;;;;;;;;;;CAWL,QAAQ,EAAE;CACX;AAED,SAAgB,sBAAoC;AAClD,QAAO;EACL,KAAK;;;;;;;;;;;EAWL,QAAQ,CAAC,EAAE;EACZ;;AAoBH,SAAgB,2BAA2B,OAGzC;AAYA,QAAO;EACL,QAAQ;GACN,KAAK;;;;;;;;;;;;;;;;;;;;;GAqBL,QAlC+B;IACjC;IACA,MAAM;IACN,MAAM;IACN,UAAU,MAAM,aAAa;IAC7B,MAAM,oBAAoB;IAC1B,MAAM,UAAU;IAChB,UAAU,MAAM,QAAQ,EAAE,CAAC;IAC3B,UAAU,MAAM,WAAW;IAC5B;GA0BE;EACD,QAAQ;GACN,KAAK;;;;;;;;;;GAUL,QAAQ;IACN,MAAM;IACN,MAAM;IACN,UAAU,MAAM,aAAa;IAC7B,MAAM,oBAAoB;IAC1B,MAAM,UAAU;IAChB,UAAU,MAAM,QAAQ,EAAE,CAAC;IAC3B,UAAU,MAAM,WAAW;IAC3B;IACD;GACF;EACF;;AAaH,SAAgB,2BAA2B,OAAwC;AACjF,QAAO;EACL,KAAK;;;;;;;;;;;;;;;;;EAiBL,QAAQ;GACN,MAAM,qBAAqB;GAC3B,MAAM,qBAAqB;GAC3B,MAAM;GACN,MAAM,0BAA0B;GAChC,UAAU,MAAM,mBAAmB;GACnC,UAAU,MAAM,kBAAkB;GAClC,UAAU,MAAM,WAAW;GAC5B;EACF;;AAGH,SAAS,UAAU,OAAwB;AACzC,QAAO,KAAK,UAAU,SAAS,KAAK"}
@@ -0,0 +1,48 @@
1
+ //#region src/core/migrations/statement-builders.d.ts
2
+ interface SqlStatement {
3
+ readonly sql: string;
4
+ readonly params: readonly unknown[];
5
+ }
6
+ declare const MARKER_TABLE_NAME = "_prisma_marker";
7
+ declare const LEDGER_TABLE_NAME = "_prisma_ledger";
8
+ /**
9
+ * Control tables the runner creates/manages. The planner must not drop these
10
+ * when reconciling "extra" tables against the contract.
11
+ */
12
+ declare const CONTROL_TABLE_NAMES: ReadonlySet<string>;
13
+ declare const ensureMarkerTableStatement: SqlStatement;
14
+ declare const ensureLedgerTableStatement: SqlStatement;
15
+ declare function readMarkerStatement(): SqlStatement;
16
+ interface WriteMarkerInput {
17
+ readonly storageHash: string;
18
+ readonly profileHash: string;
19
+ readonly contractJson?: unknown;
20
+ readonly canonicalVersion?: number | null;
21
+ readonly appTag?: string | null;
22
+ readonly meta?: Record<string, unknown>;
23
+ /**
24
+ * Invariants to write into `marker.invariants`. Stored as a JSON-encoded
25
+ * TEXT array — SQLite has no native array type. The runner is responsible
26
+ * for merging with the existing column (no SQL-side merge here, unlike
27
+ * Postgres) before passing them in: BEGIN EXCLUSIVE on the migration
28
+ * transaction makes the read-then-merge-then-write sequence safe.
29
+ */
30
+ readonly invariants: readonly string[];
31
+ }
32
+ declare function buildWriteMarkerStatements(input: WriteMarkerInput): {
33
+ readonly insert: SqlStatement;
34
+ readonly update: SqlStatement;
35
+ };
36
+ interface LedgerInsertInput {
37
+ readonly originStorageHash?: string | null;
38
+ readonly originProfileHash?: string | null;
39
+ readonly destinationStorageHash: string;
40
+ readonly destinationProfileHash?: string | null;
41
+ readonly contractJsonBefore?: unknown;
42
+ readonly contractJsonAfter?: unknown;
43
+ readonly operations: unknown;
44
+ }
45
+ declare function buildLedgerInsertStatement(input: LedgerInsertInput): SqlStatement;
46
+ //#endregion
47
+ export { CONTROL_TABLE_NAMES, LEDGER_TABLE_NAME, MARKER_TABLE_NAME, type SqlStatement, buildLedgerInsertStatement, buildWriteMarkerStatements, ensureLedgerTableStatement, ensureMarkerTableStatement, readMarkerStatement };
48
+ //# sourceMappingURL=statement-builders.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statement-builders.d.mts","names":[],"sources":["../src/core/migrations/statement-builders.ts"],"sourcesContent":[],"mappings":";UAAiB,YAAA;EAAA,SAAA,GAAA,EAAA,MAAY;EAKhB,SAAA,MAAA,EAAA,SAAiB,OAAA,EAAA;AAC9B;AAMa,cAPA,iBAAA,GAOqB,gBAAW;AAKhC,cAXA,iBAAA,GAwBZ,gBAbwC;AAezC;AAeA;AAiBA;AAiBA;AAAkD,cArErC,mBAqEqC,EArEhB,WAqEgB,CAAA,MAAA,CAAA;AAC/B,cAjEN,0BAiEM,EAjEsB,YAiEtB;AACA,cAnDN,0BAmDM,EAnDsB,YAmDtB;AAAY,iBApCf,mBAAA,CAAA,CAoCe,EApCQ,YAoCR;AA+Dd,UAlFA,gBAAA,CAkFiB;EAUlB,SAAA,WAAA,EAAA,MAAA;;;;;kBAtFE;;;;;;;;;;iBAWF,0BAAA,QAAkC;mBAC/B;mBACA;;UA+DF,iBAAA;;;;;;;;;iBAUD,0BAAA,QAAkC,oBAAoB"}
@@ -0,0 +1,3 @@
1
+ import { a as buildWriteMarkerStatements, c as readMarkerStatement, i as buildLedgerInsertStatement, n as LEDGER_TABLE_NAME, o as ensureLedgerTableStatement, r as MARKER_TABLE_NAME, s as ensureMarkerTableStatement, t as CONTROL_TABLE_NAMES } from "./statement-builders-B3OGOp7n.mjs";
2
+
3
+ export { CONTROL_TABLE_NAMES, LEDGER_TABLE_NAME, MARKER_TABLE_NAME, buildLedgerInsertStatement, buildWriteMarkerStatements, ensureLedgerTableStatement, ensureMarkerTableStatement, readMarkerStatement };
@@ -0,0 +1,408 @@
1
+ import { n as stripOuterParens } from "./default-normalizer-R-sQXAYt.mjs";
2
+ import { n as escapeLiteral, r as quoteIdentifier } from "./sql-utils-D3SMPFDD.mjs";
3
+ import { t as buildTargetDetails } from "./planner-target-details-BQIWQlBu.mjs";
4
+
5
+ //#region src/core/migrations/operations/shared.ts
6
+ function step(description, sql) {
7
+ return {
8
+ description,
9
+ sql
10
+ };
11
+ }
12
+ const REFERENTIAL_ACTION_SQL = {
13
+ noAction: "NO ACTION",
14
+ restrict: "RESTRICT",
15
+ cascade: "CASCADE",
16
+ setNull: "SET NULL",
17
+ setDefault: "SET DEFAULT"
18
+ };
19
+ /**
20
+ * Renders a single column's inline DDL fragment within a `CREATE TABLE`
21
+ * statement. Honours the `inlineAutoincrementPrimaryKey` flag — SQLite
22
+ * treats `INTEGER PRIMARY KEY AUTOINCREMENT` as a special form that aliases
23
+ * `rowid`, and the column must not carry a `DEFAULT` or repeat `NOT NULL`.
24
+ */
25
+ function renderColumnDefinition(column) {
26
+ const parts = [quoteIdentifier(column.name), column.typeSql];
27
+ if (column.inlineAutoincrementPrimaryKey) parts.push("PRIMARY KEY AUTOINCREMENT");
28
+ else {
29
+ if (column.defaultSql) parts.push(column.defaultSql);
30
+ if (!column.nullable) parts.push("NOT NULL");
31
+ }
32
+ return parts.join(" ");
33
+ }
34
+ /**
35
+ * Renders an inline FOREIGN KEY constraint clause for a `CREATE TABLE`
36
+ * body. Returns the empty string when `constraint` is false (the FK is
37
+ * tracked at the contract level for index-creation purposes only and must
38
+ * not produce DDL).
39
+ */
40
+ function renderForeignKeyClause(fk) {
41
+ if (!fk.constraint) return "";
42
+ let sql = `${fk.name ? `CONSTRAINT ${quoteIdentifier(fk.name)} ` : ""}FOREIGN KEY (${fk.columns.map(quoteIdentifier).join(", ")}) REFERENCES ${quoteIdentifier(fk.references.table)} (${fk.references.columns.map(quoteIdentifier).join(", ")})`;
43
+ if (fk.onDelete !== void 0) sql += ` ON DELETE ${REFERENTIAL_ACTION_SQL[fk.onDelete]}`;
44
+ if (fk.onUpdate !== void 0) sql += ` ON UPDATE ${REFERENTIAL_ACTION_SQL[fk.onUpdate]}`;
45
+ return sql;
46
+ }
47
+
48
+ //#endregion
49
+ //#region src/core/migrations/operations/columns.ts
50
+ function addColumn(tableName, column) {
51
+ const addSql = [
52
+ `ALTER TABLE ${quoteIdentifier(tableName)}`,
53
+ `ADD COLUMN ${quoteIdentifier(column.name)} ${column.typeSql}`,
54
+ column.defaultSql,
55
+ column.nullable ? "" : "NOT NULL"
56
+ ].filter(Boolean).join(" ");
57
+ return {
58
+ id: `column.${tableName}.${column.name}`,
59
+ label: `Add column ${column.name} on ${tableName}`,
60
+ summary: `Adds column ${column.name} on ${tableName}`,
61
+ operationClass: "additive",
62
+ target: {
63
+ id: "sqlite",
64
+ details: buildTargetDetails("column", column.name, tableName)
65
+ },
66
+ precheck: [step(`ensure column "${column.name}" is missing`, `SELECT COUNT(*) = 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(column.name)}'`)],
67
+ execute: [step(`add column "${column.name}"`, addSql)],
68
+ postcheck: [step(`verify column "${column.name}" exists`, `SELECT COUNT(*) > 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(column.name)}'`)]
69
+ };
70
+ }
71
+ function dropColumn(tableName, columnName) {
72
+ return {
73
+ id: `dropColumn.${tableName}.${columnName}`,
74
+ label: `Drop column ${columnName} on ${tableName}`,
75
+ summary: `Drops column ${columnName} on ${tableName} which is not in the contract`,
76
+ operationClass: "destructive",
77
+ target: {
78
+ id: "sqlite",
79
+ details: buildTargetDetails("column", columnName, tableName)
80
+ },
81
+ precheck: [step(`ensure column "${columnName}" exists on "${tableName}"`, `SELECT COUNT(*) > 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(columnName)}'`)],
82
+ execute: [step(`drop column "${columnName}" from "${tableName}"`, `ALTER TABLE ${quoteIdentifier(tableName)} DROP COLUMN ${quoteIdentifier(columnName)}`)],
83
+ postcheck: [step(`verify column "${columnName}" is gone from "${tableName}"`, `SELECT COUNT(*) = 0 FROM pragma_table_info('${escapeLiteral(tableName)}') WHERE name = '${escapeLiteral(columnName)}'`)]
84
+ };
85
+ }
86
+
87
+ //#endregion
88
+ //#region src/core/migrations/planner-ddl-builders.ts
89
+ const SAFE_NATIVE_TYPE_PATTERN = /^[a-zA-Z][a-zA-Z0-9_ ]*$/;
90
+ function assertSafeNativeType(nativeType) {
91
+ if (!SAFE_NATIVE_TYPE_PATTERN.test(nativeType)) throw new Error(`Unsafe native type name in contract: "${nativeType}". Native type names must match /^[a-zA-Z][a-zA-Z0-9_ ]*\$/`);
92
+ }
93
+ function assertSafeDefaultExpression(expression) {
94
+ if (expression.includes(";") || /--|\/\*|\bSELECT\b/i.test(expression)) throw new Error(`Unsafe default expression in contract: "${expression}". Default expressions must not contain semicolons, SQL comment tokens, or subqueries.`);
95
+ }
96
+ /**
97
+ * Renders the column's DDL type token (e.g. `"INTEGER"`, `"TEXT"`).
98
+ * Resolves `typeRef` against `storageTypes` and validates the resulting
99
+ * native type against a safe-identifier pattern.
100
+ */
101
+ function buildColumnTypeSql(column, storageTypes = {}) {
102
+ const resolved = resolveColumnTypeMetadata(column, storageTypes);
103
+ assertSafeNativeType(resolved.nativeType);
104
+ return resolved.nativeType.toUpperCase();
105
+ }
106
+ /**
107
+ * Renders the column's `DEFAULT …` clause. Returns the empty string when
108
+ * there is no default, and also when the default is `autoincrement()` —
109
+ * SQLite encodes that as `INTEGER PRIMARY KEY AUTOINCREMENT` inline on the
110
+ * column definition, not as a separate DEFAULT.
111
+ */
112
+ function buildColumnDefaultSql(columnDefault) {
113
+ if (!columnDefault) return "";
114
+ switch (columnDefault.kind) {
115
+ case "literal": return `DEFAULT ${renderDefaultLiteral(columnDefault.value)}`;
116
+ case "function":
117
+ if (columnDefault.expression === "autoincrement()") return "";
118
+ if (columnDefault.expression === "now()") return "DEFAULT (datetime('now'))";
119
+ assertSafeDefaultExpression(columnDefault.expression);
120
+ return `DEFAULT (${columnDefault.expression})`;
121
+ }
122
+ }
123
+ function renderDefaultLiteral(value) {
124
+ if (value instanceof Date) return `'${escapeLiteral(value.toISOString())}'`;
125
+ if (typeof value === "string") return `'${escapeLiteral(value)}'`;
126
+ if (typeof value === "number" || typeof value === "bigint") return String(value);
127
+ if (typeof value === "boolean") return value ? "1" : "0";
128
+ if (value === null) return "NULL";
129
+ return `'${escapeLiteral(JSON.stringify(value))}'`;
130
+ }
131
+ function buildCreateIndexSql(tableName, indexName, columns, unique = false) {
132
+ return `CREATE ${unique ? "UNIQUE " : ""}INDEX ${quoteIdentifier(indexName)} ON ${quoteIdentifier(tableName)} (${columns.map(quoteIdentifier).join(", ")})`;
133
+ }
134
+ function buildDropIndexSql(indexName) {
135
+ return `DROP INDEX IF EXISTS ${quoteIdentifier(indexName)}`;
136
+ }
137
+ /**
138
+ * True when the column is rendered inline as `INTEGER PRIMARY KEY
139
+ * AUTOINCREMENT`. Requires the column's default to be `autoincrement()` and
140
+ * the column to be the sole member of the table's primary key — anything
141
+ * else falls back to a separate PRIMARY KEY constraint with a default
142
+ * AUTOINCREMENT semantics expressed elsewhere.
143
+ */
144
+ function isInlineAutoincrementPrimaryKey(table, columnName) {
145
+ if (table.primaryKey?.columns.length !== 1) return false;
146
+ if (table.primaryKey.columns[0] !== columnName) return false;
147
+ const column = table.columns[columnName];
148
+ return column?.default?.kind === "function" && column.default.expression === "autoincrement()";
149
+ }
150
+ function resolveColumnTypeMetadata(column, storageTypes) {
151
+ if (!column.typeRef) return column;
152
+ const referencedType = storageTypes[column.typeRef];
153
+ if (!referencedType) throw new Error(`Storage type "${column.typeRef}" referenced by column is not defined in storage.types.`);
154
+ return {
155
+ codecId: referencedType.codecId,
156
+ nativeType: referencedType.nativeType,
157
+ typeParams: referencedType.typeParams
158
+ };
159
+ }
160
+
161
+ //#endregion
162
+ //#region src/core/migrations/operations/indexes.ts
163
+ function createIndex(tableName, indexName, columns) {
164
+ return {
165
+ id: `index.${tableName}.${indexName}`,
166
+ label: `Create index ${indexName} on ${tableName}`,
167
+ summary: `Creates index ${indexName} on ${tableName}`,
168
+ operationClass: "additive",
169
+ target: {
170
+ id: "sqlite",
171
+ details: buildTargetDetails("index", indexName, tableName)
172
+ },
173
+ precheck: [step(`ensure index "${indexName}" is missing`, `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`)],
174
+ execute: [step(`create index "${indexName}"`, buildCreateIndexSql(tableName, indexName, columns))],
175
+ postcheck: [step(`verify index "${indexName}" exists`, `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`)]
176
+ };
177
+ }
178
+ function dropIndex(tableName, indexName) {
179
+ return {
180
+ id: `dropIndex.${tableName}.${indexName}`,
181
+ label: `Drop index ${indexName} on ${tableName}`,
182
+ summary: `Drops index ${indexName} on ${tableName} which is not in the contract`,
183
+ operationClass: "destructive",
184
+ target: {
185
+ id: "sqlite",
186
+ details: buildTargetDetails("index", indexName, tableName)
187
+ },
188
+ precheck: [step(`ensure index "${indexName}" exists`, `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`)],
189
+ execute: [step(`drop index "${indexName}"`, buildDropIndexSql(indexName))],
190
+ postcheck: [step(`verify index "${indexName}" is gone`, `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'index' AND name = '${escapeLiteral(indexName)}'`)]
191
+ };
192
+ }
193
+
194
+ //#endregion
195
+ //#region src/core/migrations/operations/tables.ts
196
+ /**
197
+ * Renders the body of a `CREATE TABLE <name> ( … )` statement from a flat
198
+ * `SqliteTableSpec`. SQLite's `INTEGER PRIMARY KEY AUTOINCREMENT` form is
199
+ * inline on the column; the table-level PRIMARY KEY clause is emitted only
200
+ * when no column carries `inlineAutoincrementPrimaryKey`.
201
+ */
202
+ function renderCreateTableSql(tableName, spec) {
203
+ const columnDefs = spec.columns.map(renderColumnDefinition);
204
+ const constraintDefs = [];
205
+ const hasInlinePk = spec.columns.some((c) => c.inlineAutoincrementPrimaryKey);
206
+ if (spec.primaryKey && !hasInlinePk) constraintDefs.push(`PRIMARY KEY (${spec.primaryKey.columns.map(quoteIdentifier).join(", ")})`);
207
+ for (const u of spec.uniques ?? []) {
208
+ const name = u.name ? `CONSTRAINT ${quoteIdentifier(u.name)} ` : "";
209
+ constraintDefs.push(`${name}UNIQUE (${u.columns.map(quoteIdentifier).join(", ")})`);
210
+ }
211
+ for (const fk of spec.foreignKeys ?? []) {
212
+ const clause = renderForeignKeyClause(fk);
213
+ if (clause) constraintDefs.push(clause);
214
+ }
215
+ const allDefs = [...columnDefs, ...constraintDefs];
216
+ return `CREATE TABLE ${quoteIdentifier(tableName)} (\n ${allDefs.join(",\n ")}\n)`;
217
+ }
218
+ function createTable(tableName, spec) {
219
+ return {
220
+ id: `table.${tableName}`,
221
+ label: `Create table ${tableName}`,
222
+ summary: `Creates table ${tableName} with required columns`,
223
+ operationClass: "additive",
224
+ target: {
225
+ id: "sqlite",
226
+ details: buildTargetDetails("table", tableName)
227
+ },
228
+ precheck: [step(`ensure table "${tableName}" does not exist`, `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`)],
229
+ execute: [step(`create table "${tableName}"`, renderCreateTableSql(tableName, spec))],
230
+ postcheck: [step(`verify table "${tableName}" exists`, `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`)]
231
+ };
232
+ }
233
+ function dropTable(tableName) {
234
+ return {
235
+ id: `dropTable.${tableName}`,
236
+ label: `Drop table ${tableName}`,
237
+ summary: `Drops table ${tableName} which is not in the contract`,
238
+ operationClass: "destructive",
239
+ target: {
240
+ id: "sqlite",
241
+ details: buildTargetDetails("table", tableName)
242
+ },
243
+ precheck: [step(`ensure table "${tableName}" exists`, `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`)],
244
+ execute: [step(`drop table "${tableName}"`, `DROP TABLE ${quoteIdentifier(tableName)}`)],
245
+ postcheck: [step(`verify table "${tableName}" is gone`, `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`)]
246
+ };
247
+ }
248
+ function recreateTable(args) {
249
+ const { tableName, contractTable, schemaColumnNames, indexes, summary, postchecks, operationClass } = args;
250
+ const tempName = `_prisma_new_${tableName}`;
251
+ const liveSet = new Set(schemaColumnNames);
252
+ const sharedColumns = contractTable.columns.filter((c) => liveSet.has(c.name)).map((c) => c.name);
253
+ const columnList = sharedColumns.map(quoteIdentifier).join(", ");
254
+ const indexStatements = indexes.map((idx) => ({
255
+ description: `recreate index "${idx.name}" on "${tableName}"`,
256
+ sql: buildCreateIndexSql(tableName, idx.name, idx.columns)
257
+ }));
258
+ const copyStep = sharedColumns.length > 0 ? [step(`copy data from "${tableName}" to "${tempName}"`, `INSERT INTO ${quoteIdentifier(tempName)} (${columnList}) SELECT ${columnList} FROM ${quoteIdentifier(tableName)}`)] : [];
259
+ return {
260
+ id: `recreateTable.${tableName}`,
261
+ label: `Recreate table ${tableName}`,
262
+ summary,
263
+ operationClass,
264
+ target: {
265
+ id: "sqlite",
266
+ details: buildTargetDetails("table", tableName)
267
+ },
268
+ precheck: [step(`ensure table "${tableName}" exists`, `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`), step(`ensure temp table "${tempName}" does not exist`, `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tempName)}'`)],
269
+ execute: [
270
+ step(`create new table "${tempName}" with desired schema`, renderCreateTableSql(tempName, contractTable)),
271
+ ...copyStep,
272
+ step(`drop old table "${tableName}"`, `DROP TABLE ${quoteIdentifier(tableName)}`),
273
+ step(`rename "${tempName}" to "${tableName}"`, `ALTER TABLE ${quoteIdentifier(tempName)} RENAME TO ${quoteIdentifier(tableName)}`),
274
+ ...indexStatements
275
+ ],
276
+ postcheck: [
277
+ step(`verify table "${tableName}" exists`, `SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tableName)}'`),
278
+ step(`verify temp table "${tempName}" is gone`, `SELECT COUNT(*) = 0 FROM sqlite_master WHERE type = 'table' AND name = '${escapeLiteral(tempName)}'`),
279
+ ...postchecks
280
+ ]
281
+ };
282
+ }
283
+ /**
284
+ * Build a one-line summary of a recreate-table operation from the schema
285
+ * issues that triggered it. Lives next to `recreateTable` so the planner
286
+ * (which has the issues) can produce the same description the factory
287
+ * used to build inline. Keeping the formatting target-side keeps
288
+ * `RecreateTableCall` issue-free at the IR layer.
289
+ */
290
+ function buildRecreateSummary(tableName, issues) {
291
+ return `Recreates table ${tableName} to apply schema changes: ${issues.map((i) => i.message).join("; ")}`;
292
+ }
293
+ const COLUMN_LEVEL_ISSUE_KINDS = new Set([
294
+ "nullability_mismatch",
295
+ "default_mismatch",
296
+ "default_missing",
297
+ "extra_default",
298
+ "type_mismatch"
299
+ ]);
300
+ const PK_ISSUE_KINDS = new Set(["primary_key_mismatch", "extra_primary_key"]);
301
+ const UNIQUE_ISSUE_KINDS = new Set(["unique_constraint_mismatch", "extra_unique_constraint"]);
302
+ const FK_ISSUE_KINDS = new Set(["foreign_key_mismatch", "extra_foreign_key"]);
303
+ /**
304
+ * Returns the columns the contract expects as the table's primary key. Picks
305
+ * up SQLite's inline `INTEGER PRIMARY KEY AUTOINCREMENT` form when no
306
+ * explicit `primaryKey` clause is set on the spec.
307
+ */
308
+ function expectedPrimaryKeyColumns(spec) {
309
+ if (spec.primaryKey) return spec.primaryKey.columns;
310
+ const inlinePk = spec.columns.find((c) => c.inlineAutoincrementPrimaryKey);
311
+ return inlinePk ? [inlinePk.name] : [];
312
+ }
313
+ function quoteSqlList(values) {
314
+ return values.map((v) => `'${escapeLiteral(v)}'`).join(", ");
315
+ }
316
+ /**
317
+ * Per-issue postchecks verifying the recreated table's shape against the
318
+ * contract spec. Column-level issues (`nullability_mismatch`,
319
+ * `default_mismatch`, …) emit one targeted check each; constraint-level
320
+ * issues (`primary_key_mismatch`, `unique_constraint_mismatch`,
321
+ * `foreign_key_mismatch`, plus their `extra_*` siblings) emit one
322
+ * `pragma_*`-driven check per declared constraint in the contract spec, so
323
+ * a recreated table with the right columns but the wrong PK / unique / FK
324
+ * shape fails the postcheck instead of passing silently. Exported so the
325
+ * planner can pre-build the list at construction time and
326
+ * `RecreateTableCall` doesn't have to carry `SchemaIssue` objects through
327
+ * to render time.
328
+ */
329
+ function buildRecreatePostchecks(tableName, issues, spec) {
330
+ const checks = [];
331
+ const t = escapeLiteral(tableName);
332
+ const byName = new Map(spec.columns.map((c) => [c.name, c]));
333
+ for (const issue of issues) {
334
+ if (issue.kind === "enum_values_changed") continue;
335
+ if (!COLUMN_LEVEL_ISSUE_KINDS.has(issue.kind)) continue;
336
+ if (!issue.column) continue;
337
+ const c = escapeLiteral(issue.column);
338
+ if (issue.kind === "nullability_mismatch") {
339
+ let wantNotNull;
340
+ if (issue.expected === "false") wantNotNull = true;
341
+ else if (issue.expected === "true") wantNotNull = false;
342
+ if (wantNotNull !== void 0) checks.push({
343
+ description: `verify "${issue.column}" nullability on "${tableName}"`,
344
+ sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND "notnull" = ${wantNotNull ? 1 : 0}`
345
+ });
346
+ }
347
+ if (issue.kind === "default_mismatch" || issue.kind === "default_missing") {
348
+ const colSpec = byName.get(issue.column);
349
+ const expectedRaw = colSpec?.defaultSql.startsWith("DEFAULT ") ? stripOuterParens(colSpec.defaultSql.slice(8)) : null;
350
+ if (expectedRaw) checks.push({
351
+ description: `verify "${issue.column}" default on "${tableName}"`,
352
+ sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND dflt_value = '${escapeLiteral(expectedRaw)}'`
353
+ });
354
+ }
355
+ if (issue.kind === "type_mismatch") {
356
+ const colSpec = byName.get(issue.column);
357
+ if (colSpec) checks.push({
358
+ description: `verify "${issue.column}" type on "${tableName}"`,
359
+ sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND LOWER(type) = '${escapeLiteral(colSpec.typeSql.toLowerCase())}'`
360
+ });
361
+ }
362
+ if (issue.kind === "extra_default") checks.push({
363
+ description: `verify "${issue.column}" has no default on "${tableName}"`,
364
+ sql: `SELECT COUNT(*) > 0 FROM pragma_table_info('${t}') WHERE name = '${c}' AND dflt_value IS NULL`
365
+ });
366
+ }
367
+ const hasPkIssue = issues.some((i) => PK_ISSUE_KINDS.has(i.kind));
368
+ const hasUniqueIssue = issues.some((i) => UNIQUE_ISSUE_KINDS.has(i.kind));
369
+ const hasFkIssue = issues.some((i) => FK_ISSUE_KINDS.has(i.kind));
370
+ if (hasPkIssue) {
371
+ const pkColumns = expectedPrimaryKeyColumns(spec);
372
+ const colCount = pkColumns.length;
373
+ if (colCount === 0) checks.push({
374
+ description: `verify "${tableName}" has no primary key`,
375
+ sql: `SELECT (SELECT COUNT(*) FROM pragma_table_info('${t}') WHERE pk > 0) = 0`
376
+ });
377
+ else checks.push({
378
+ description: `verify primary key on "${tableName}"`,
379
+ sql: `SELECT (SELECT COUNT(*) FROM pragma_table_info('${t}') WHERE pk > 0) = ${colCount} AND (SELECT COUNT(*) FROM pragma_table_info('${t}') WHERE pk > 0 AND name IN (${quoteSqlList(pkColumns)})) = ${colCount}`
380
+ });
381
+ }
382
+ if (hasUniqueIssue) for (const u of spec.uniques ?? []) {
383
+ const colCount = u.columns.length;
384
+ const description = u.name ? `verify unique constraint "${u.name}" on "${tableName}"` : `verify unique constraint (${u.columns.join(", ")}) on "${tableName}"`;
385
+ checks.push({
386
+ description,
387
+ sql: `SELECT EXISTS (SELECT 1 FROM pragma_index_list('${t}') l WHERE l."unique" = 1 AND (SELECT COUNT(*) FROM pragma_index_info(l.name)) = ${colCount} AND (SELECT COUNT(*) FROM pragma_index_info(l.name) WHERE name IN (${quoteSqlList(u.columns)})) = ${colCount})`
388
+ });
389
+ }
390
+ if (hasFkIssue) for (const fk of spec.foreignKeys ?? []) {
391
+ const refTable = escapeLiteral(fk.references.table);
392
+ const colCount = fk.columns.length;
393
+ const tuples = fk.columns.map((from, i) => {
394
+ const to = fk.references.columns[i] ?? from;
395
+ return `('${escapeLiteral(from)}', '${escapeLiteral(to)}')`;
396
+ }).join(", ");
397
+ const description = `verify foreign key (${fk.columns.join(", ")}) → ${fk.references.table}(${fk.references.columns.join(", ")}) on "${tableName}"`;
398
+ checks.push({
399
+ description,
400
+ sql: `SELECT EXISTS (SELECT 1 FROM pragma_foreign_key_list('${t}') f WHERE f."table" = '${refTable}' GROUP BY f.id HAVING COUNT(*) = ${colCount} AND SUM(CASE WHEN (f."from", f."to") IN (${tuples}) THEN 1 ELSE 0 END) = ${colCount})`
401
+ });
402
+ }
403
+ return checks;
404
+ }
405
+
406
+ //#endregion
407
+ export { recreateTable as a, buildColumnDefaultSql as c, renderDefaultLiteral as d, addColumn as f, dropTable as i, buildColumnTypeSql as l, step as m, buildRecreateSummary as n, createIndex as o, dropColumn as p, createTable as r, dropIndex as s, buildRecreatePostchecks as t, isInlineAutoincrementPrimaryKey as u };
408
+ //# sourceMappingURL=tables-sKIg_lWE.mjs.map