@voltro/database 0.85.0 → 0.87.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.
Files changed (173) hide show
  1. package/CHANGELOG.md +5987 -0
  2. package/THIRD-PARTY-NOTICES.md +5 -257
  3. package/dist/actorSnapshot.js +24 -0
  4. package/dist/arrayCodec.js +32 -0
  5. package/dist/branchExecute.js +92 -0
  6. package/dist/branching.js +106 -0
  7. package/dist/bulkInsertLimits.js +25 -0
  8. package/dist/cdcOffsetsTables.js +19 -0
  9. package/dist/changeEvent.js +41 -0
  10. package/dist/changeIdentity.js +65 -0
  11. package/dist/changeListenerCeiling.js +6 -0
  12. package/dist/columnReference.js +17 -0
  13. package/dist/columns.js +326 -0
  14. package/dist/committedChanges.js +12 -0
  15. package/dist/connectionIdentity.js +36 -0
  16. package/dist/coreTables.js +16 -0
  17. package/dist/coreTablesRegistry.js +10 -0
  18. package/dist/dataTransfers.js +23 -0
  19. package/dist/dbCause.js +222 -0
  20. package/dist/dbMetrics.js +65 -0
  21. package/dist/decimalComparison.js +27 -0
  22. package/dist/derivedRowId.js +5 -0
  23. package/dist/dialect.js +13 -0
  24. package/dist/enumRenames.js +14 -0
  25. package/dist/expiresMixin.js +10 -0
  26. package/dist/fieldEncryption.js +121 -0
  27. package/dist/frameworkTables.js +143 -0
  28. package/dist/ginIndex.js +10 -0
  29. package/dist/hybridSearch.js +32 -0
  30. package/dist/idGenerator.js +57 -0
  31. package/dist/identifierLimits.js +32 -0
  32. package/dist/index.d.ts +166 -22
  33. package/dist/index.js +82 -2183
  34. package/dist/indexAudit.js +61 -0
  35. package/dist/indexStorage.js +58 -0
  36. package/dist/joinCompiler.js +160 -0
  37. package/dist/jsonEagerCompiler.js +436 -0
  38. package/dist/jsonPatch.js +78 -0
  39. package/dist/jsonPatchAssignments.js +13 -0
  40. package/dist/jsonPath.js +31 -0
  41. package/dist/localFirstMixin.js +12 -0
  42. package/dist/migrate.js +644 -0
  43. package/dist/migration.js +18 -0
  44. package/dist/migrations/appliedAtValue.js +8 -0
  45. package/dist/migrations/applier.js +1100 -0
  46. package/dist/migrations/boot.js +196 -0
  47. package/dist/migrations/branchRehearsal.js +122 -0
  48. package/dist/migrations/columnEquivalence.js +85 -0
  49. package/dist/migrations/ddlError.js +63 -0
  50. package/dist/migrations/ddlStatements.js +9 -0
  51. package/dist/migrations/declaredSchema.js +162 -0
  52. package/dist/migrations/deployLedger.js +19 -0
  53. package/dist/migrations/fileBased.js +57 -0
  54. package/dist/migrations/fileContext.js +482 -0
  55. package/dist/migrations/fileDiscovery.js +332 -0
  56. package/dist/migrations/fileSkipProbes.js +117 -0
  57. package/dist/migrations/fingerprint.js +46 -0
  58. package/dist/migrations/fkCycles.js +13 -0
  59. package/dist/migrations/frameworkLiveTables.js +25 -0
  60. package/dist/migrations/idempotentDdl.js +37 -0
  61. package/dist/migrations/indexPredicate.js +50 -0
  62. package/dist/migrations/introspect.js +801 -0
  63. package/dist/migrations/ledgerRows.js +4 -0
  64. package/dist/migrations/lock.js +91 -0
  65. package/dist/migrations/migrationTableExists.js +9 -0
  66. package/dist/migrations/mssqlColumnDependencies.js +76 -0
  67. package/dist/migrations/mysqlEngine.js +11 -0
  68. package/dist/migrations/namespaceCharset.js +51 -0
  69. package/dist/migrations/planner.js +785 -0
  70. package/dist/migrations/postgresEnumCheck.js +22 -0
  71. package/dist/migrations/reactiveTriggerDrift.js +58 -0
  72. package/dist/migrations/reactiveTriggerName.js +7 -0
  73. package/dist/migrations/renameMssqlCheck.js +21 -0
  74. package/dist/migrations/restoreSnapshots.js +206 -0
  75. package/dist/migrations/resumeLedger.js +86 -0
  76. package/dist/migrations/rollingDeploy.js +106 -0
  77. package/dist/migrations/schemaOwner.js +46 -0
  78. package/dist/migrations/schemaOwnerTable.js +4 -0
  79. package/dist/migrations/softDropSnapshot.js +20 -0
  80. package/dist/migrations/sqlLimit.js +8 -0
  81. package/dist/migrations/sqliteCatalogName.js +13 -0
  82. package/dist/migrations/sqliteConstraintIdentity.js +97 -0
  83. package/dist/migrations/sqliteDecimalBoot.js +22 -0
  84. package/dist/migrations/sqliteDecimalPublication.js +257 -0
  85. package/dist/migrations/sqliteDecimalReview.js +30 -0
  86. package/dist/migrations/sqliteDecimalReviewStore.js +188 -0
  87. package/dist/migrations/sqliteDecimalReviewWitness.js +38 -0
  88. package/dist/migrations/sqliteDecimalSource.js +69 -0
  89. package/dist/migrations/sqliteDecimalStage.js +135 -0
  90. package/dist/migrations/sqliteForeignKeys.js +38 -0
  91. package/dist/migrations/sqliteMigrationBatch.js +37 -0
  92. package/dist/migrations/sqliteRetainedSource.js +106 -0
  93. package/dist/migrations/sqliteRowIdentity.js +63 -0
  94. package/dist/migrations/sqliteSchemaEpoch.js +12 -0
  95. package/dist/migrations/sqliteSnapshotGuard.js +10 -0
  96. package/dist/migrations/sqliteTableContents.js +34 -0
  97. package/dist/migrations/sqliteTableCopy.js +25 -0
  98. package/dist/migrations/sqliteTableSchema.js +19 -0
  99. package/dist/migrations/sqliteWitnessProtection.js +8 -0
  100. package/dist/migrations/squash.js +81 -0
  101. package/dist/migrations/storeCharset.js +66 -0
  102. package/dist/migrations/transactionCause.js +10 -0
  103. package/dist/migrations/undeclaredCharset.js +40 -0
  104. package/dist/migrations/uniqueActiveLowering.js +39 -0
  105. package/dist/mixins.js +22 -0
  106. package/dist/mssqlDecimalDistinct.js +51 -0
  107. package/dist/mssqlJsonValueCheck.js +42 -0
  108. package/dist/mssqlTextStorage.js +9 -0
  109. package/dist/namespace.js +21 -0
  110. package/dist/{wire-CG2j7J3f.js → optimisticVersion.js} +2 -2
  111. package/dist/pendingAttribution.js +79 -0
  112. package/dist/pluginRef.js +17 -0
  113. package/dist/predicate.js +273 -0
  114. package/dist/predicateCoercion.js +13 -0
  115. package/dist/projectedColumn.js +37 -0
  116. package/dist/queryBuilder.js +388 -0
  117. package/dist/rawSql.js +8 -0
  118. package/dist/relations.js +69 -0
  119. package/dist/relationsRegistry.js +38 -0
  120. package/dist/replaceInProgress.js +53 -0
  121. package/dist/requiredColumns.js +26 -0
  122. package/dist/residency.js +52 -0
  123. package/dist/retention.js +62 -0
  124. package/dist/rowDecoder.js +173 -0
  125. package/dist/rowKey.js +8 -0
  126. package/dist/rowSchema.js +31 -0
  127. package/dist/scopeKey.js +8 -0
  128. package/dist/seed.js +33 -0
  129. package/dist/snowflake.js +26 -0
  130. package/dist/sql.d.ts +2792 -3773
  131. package/dist/sql.js +42 -6905
  132. package/dist/sqlCompiler.js +360 -0
  133. package/dist/sqlError.js +8 -0
  134. package/dist/sqlMutation.js +55 -0
  135. package/dist/sqlPoolCapacity.js +12 -0
  136. package/dist/sqliteDecimal.js +22 -0
  137. package/dist/sqliteDecimalAggregateSql.js +61 -0
  138. package/dist/sqliteDecimalColumnSql.js +108 -0
  139. package/dist/sqliteDecimalConversion.js +15 -0
  140. package/dist/sqliteDecimalCte.js +154 -0
  141. package/dist/sqliteDecimalEncodeSql.js +32 -0
  142. package/dist/sqliteDecimalOutputs.js +74 -0
  143. package/dist/sqliteDecimalPredicate.js +66 -0
  144. package/dist/sqliteDecimalQuery.js +183 -0
  145. package/dist/sqliteDecimalQueryPlan.js +37 -0
  146. package/dist/sqliteDecimalResultSql.js +44 -0
  147. package/dist/sqliteDecimalRowQuery.js +63 -0
  148. package/dist/sqliteDecimalSetQuery.js +50 -0
  149. package/dist/sqliteDecimalSource.js +63 -0
  150. package/dist/sqliteDecimalStorage.js +29 -0
  151. package/dist/sqliteDecimalSubquery.js +19 -0
  152. package/dist/sqliteDecimalWindowQuery.js +196 -0
  153. package/dist/sqliteValueCoercion.js +4 -0
  154. package/dist/stampId.js +21 -0
  155. package/dist/storeErrors.js +9 -0
  156. package/dist/storeRefusal.js +20 -0
  157. package/dist/stream.js +36 -0
  158. package/dist/subjectGraph.js +175 -0
  159. package/dist/table.js +394 -0
  160. package/dist/tableRegistry.js +16 -0
  161. package/dist/tenantSelection.js +27 -0
  162. package/dist/transactionOutcome.js +100 -0
  163. package/dist/transientContention.js +36 -0
  164. package/dist/typeId.js +51 -0
  165. package/dist/typedStore.js +16 -0
  166. package/dist/upsertUpdate.js +20 -0
  167. package/dist/vectorEmbedding.js +31 -0
  168. package/dist/view.js +39 -0
  169. package/dist/wire.js +6 -2
  170. package/dist/writeAttribution.js +16 -0
  171. package/dist/writeRecorder.js +38 -0
  172. package/package.json +3 -4
  173. package/dist/replaceInProgress-DC88Pdiy.js +0 -3735
@@ -0,0 +1,4 @@
1
+ //#region src/migrations/ledgerRows.ts
2
+ var e = (e) => e.literal("(source = 'file' AND id NOT LIKE 'plan!_%' ESCAPE '!')"), t = (e) => e.literal("(source IS NULL OR source <> 'file' OR id LIKE 'plan!_%' ESCAPE '!')");
3
+ //#endregion
4
+ export { t as describesSchema, e as isFileMigrationRow };
@@ -0,0 +1,91 @@
1
+ import { sqlPoolCapacity as e } from "../sqlPoolCapacity.js";
2
+ import { Effect as t, Exit as n, Fiber as r, Scope as i } from "effect";
3
+ //#region src/migrations/lock.ts
4
+ var a = (e, t) => e.executeUnprepared(t, [], void 0), o = 6322741009312437n, s = (e) => {
5
+ let t = e?.trim();
6
+ return t === void 0 || t === "" || t === "public" ? void 0 : t;
7
+ }, c = (e) => e?.schema === void 0 ? s(process.env.DB_SCHEMA) : s(e.schema), l = 14695981039346656037n, u = 1099511628211n, d = 18446744073709551615n, f = (e) => {
8
+ let t = l;
9
+ for (let n of new TextEncoder().encode(e)) t ^= BigInt(n), t = t * u & d;
10
+ return t;
11
+ }, p = (e) => {
12
+ let t = s(e);
13
+ return t === void 0 ? o : f(`voltro_migration_lock:${t}`) & 9223372036854775807n;
14
+ }, m = (e) => {
15
+ let t = `voltro_migration_${o.toString(36)}`, n = s(e);
16
+ if (n === void 0) return t;
17
+ let r = `${t}_${n}`;
18
+ return /^[A-Za-z0-9_]+$/.test(n) && r.length <= 64 ? r : `${t}_h${(f(`voltro_migration_lock:${n}`) & d).toString(16)}`;
19
+ }, h = 250, g = () => {
20
+ let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
21
+ return Number.isFinite(e) && e > 0 ? e : 3e4;
22
+ }, _ = (e, n) => t.map(a(e, `SELECT (EXTRACT(EPOCH FROM (clock_timestamp() - a.state_change)) * 1000)::float8 AS silent
23
+ FROM pg_catalog.pg_locks l JOIN pg_catalog.pg_stat_activity a ON a.pid = l.pid
24
+ WHERE l.locktype = 'advisory' AND l.granted AND l.objsubid = 1
25
+ AND l.classid::bigint = ((${n.toString()}::bigint >> 32) & 4294967295)
26
+ AND l.objid::bigint = (${n.toString()}::bigint & 4294967295)
27
+ LIMIT 1`), (e) => {
28
+ let t = e[0]?.silent;
29
+ return t == null ? void 0 : Number(t);
30
+ }), v = () => Math.max(250, Math.min(5e3, Math.floor(g() / 4))), y = (e, n) => t.gen(function* () {
31
+ let r = g(), i = Date.now(), o = 0;
32
+ for (;;) {
33
+ if ((yield* a(e, `SELECT pg_try_advisory_lock(${n.toString()}::bigint) AS got`))[0]?.got) return;
34
+ let s = yield* _(e, n), c = s !== void 0 && s < r, l = Date.now() - i;
35
+ c && l - o >= r && (o = l, yield* t.logInfo(`migration lock: waiting for another migration in progress (${Math.round(l / 1e3)}s so far; its session was active ${Math.round(s / 1e3)}s ago)`).pipe(t.annotateLogs({ scope: "voltro:migrate" }))), !c && l >= r && (yield* t.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock: its holder has been silent for ${Math.round(r / 1e3)}s. A migration still running would have kept its lock session active, so this is most likely a prior boot that crashed while holding it. (A crashed process's session-level advisory lock is released once its DB connection closes; if this persists, find + terminate the holder via pg_stat_activity, or raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS.)`))), yield* t.sleep(`${h} millis`);
36
+ }
37
+ }), b = (e, n) => t.asVoid(a(e, `SELECT pg_advisory_unlock(${n.toString()}::bigint)`)), x = (e, n) => t.map(a(e, `SELECT p.TIME AS silent FROM information_schema.PROCESSLIST p WHERE p.ID = IS_USED_LOCK('${n}')`), (e) => {
38
+ let t = e[0]?.silent;
39
+ return t == null ? void 0 : Number(t) * 1e3;
40
+ }), S = (e, n) => t.gen(function* () {
41
+ let r = g(), i = Date.now(), o = 0;
42
+ for (;;) {
43
+ if ((yield* a(e, `SELECT GET_LOCK('${n}', 1) AS got`))[0]?.got === 1) return;
44
+ let s = yield* x(e, n), c = s !== void 0 && s - 1e3 < r, l = Date.now() - i;
45
+ c && l - o >= r && (o = l, yield* t.logInfo(`migration lock: waiting for another migration in progress (${Math.round(l / 1e3)}s so far)`).pipe(t.annotateLogs({ scope: "voltro:migrate" }))), !c && l >= r && (yield* t.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${n}' within ${Math.round(r / 1e3)}s (another migration is in progress and has been silent that long, or a prior one left it held). Raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS if a migration legitimately goes quiet for longer.`)));
46
+ }
47
+ }), C = (e, n) => t.asVoid(a(e, `SELECT RELEASE_LOCK('${n}')`)), w = 3e4, T = (e, n) => t.gen(function* () {
48
+ let r = yield* a(e, `
49
+ DECLARE @res int;
50
+ EXEC @res = sp_getapplock @Resource = '${n}', @LockMode = 'Exclusive',
51
+ @LockOwner = 'Session', @LockTimeout = ${String(w)};
52
+ SELECT @res AS res`);
53
+ (r[0]?.res ?? -999) < 0 && (yield* t.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${n}' (sp_getapplock returned ${r[0]?.res ?? "no row"}; another migration is in progress).`)));
54
+ }), E = (e, n) => t.asVoid(a(e, `EXEC sp_releaseapplock @Resource = '${n}', @LockOwner = 'Session'`)), D = t.void, O = (o, s) => t.gen(function* () {
55
+ let l = c(s), u = m(l), d = p(l);
56
+ if (!o.onDialectOrElse({
57
+ mysql: () => !0,
58
+ mssql: () => !0,
59
+ sqlite: () => !1,
60
+ orElse: () => !0
61
+ })) return {
62
+ release: D,
63
+ connection: void 0
64
+ };
65
+ let f = e(o);
66
+ if (f !== void 0 && f < 2) return yield* t.die(/* @__PURE__ */ Error(`migrate needs at least 2 connections, pool has ${f}: one holds the migration lock and another runs the statements. Configure maxConnections >= 2 for the migrating process.`));
67
+ let h = yield* i.make(), g = yield* t.provideService(o.reserve, i.Scope, h), _ = i.close(h, n.void);
68
+ yield* o.onDialectOrElse({
69
+ mysql: () => S(g, u),
70
+ mssql: () => T(g, u),
71
+ sqlite: () => D,
72
+ orElse: () => y(g, d)
73
+ }).pipe(t.onExit((e) => n.isSuccess(e) ? t.void : _));
74
+ let x = t.uninterruptible(t.ignore(a(g, "SELECT 1"))).pipe(t.delay(`${v()} millis`), t.forever, t.interruptible, t.forkIn(h)), w = yield* o.onDialectOrElse({
75
+ mysql: () => x,
76
+ mssql: () => t.succeed(void 0),
77
+ sqlite: () => t.succeed(void 0),
78
+ orElse: () => x
79
+ }), O = w === void 0 ? t.void : r.interrupt(w);
80
+ return {
81
+ release: o.onDialectOrElse({
82
+ mysql: () => C(g, u),
83
+ mssql: () => E(g, u),
84
+ sqlite: () => D,
85
+ orElse: () => b(g, d)
86
+ }).pipe((e) => t.andThen(O, e), t.ensuring(_)),
87
+ connection: g
88
+ };
89
+ }), k = "a migration needs 2 connections: one holds the migration lock for the whole apply, the other runs the statements. The pool could not hand out the second one — raise its size (DB_MAX_CONNECTIONS / PG_MAX_CONNECTIONS, or the driver's own `maxConnections`) to at least 2 for the migrating process; behind a pooler (PgBouncer, Supavisor) point the migration at the database directly (DB_DIRECT_URL / DB_MIGRATE_URL).", A = (e) => /acquire connection/i.test(String(e?.message ?? e)), j = (e, n, r) => t.acquireUseRelease(O(e, r), () => n.pipe(t.tapError((e) => A(e) ? t.logError(`migrate: ${k}`).pipe(t.annotateLogs({ scope: "voltro:migrate" })) : t.void)), (e) => e.release.pipe(t.orDie));
90
+ //#endregion
91
+ export { k as MIGRATION_NEEDS_TWO_CONNECTIONS, o as VOLTRO_MIGRATION_LOCK_KEY, O as acquireMigrationLock, f as fnv1a64, p as migrationLockKeyForSchema, m as migrationLockNameForSchema, c as resolveMigrationLockSchema, j as withMigrationLock };
@@ -0,0 +1,9 @@
1
+ import { dialectOf as e } from "./resumeLedger.js";
2
+ import { Effect as t } from "effect";
3
+ //#region src/migrations/migrationTableExists.ts
4
+ var n = (n, r) => {
5
+ let i = e(n);
6
+ return (i === "sqlite" ? n`SELECT COUNT(*) AS n FROM sqlite_master WHERE type = 'table' AND name = ${r}` : i === "mysql" ? n`SELECT COUNT(*) AS n FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ${r}` : i === "mssql" ? n`SELECT COUNT(*) AS n FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = ${r}` : n`SELECT COUNT(*) AS n FROM information_schema.tables WHERE table_schema = current_schema() AND table_name = ${r}`).pipe(t.map((e) => Number(e[0]?.n ?? 0) > 0));
7
+ };
8
+ //#endregion
9
+ export { n as migrationTableExists };
@@ -0,0 +1,76 @@
1
+ import { quoteIdent as e } from "../dialect.js";
2
+ import { sqlError as t } from "../sqlError.js";
3
+ import { Effect as n } from "effect";
4
+ //#region src/migrations/mssqlColumnDependencies.ts
5
+ var r = (t) => e(t, "mssql"), i = (e, i, a, o) => n.gen(function* () {
6
+ let s = yield* e`
7
+ SELECT 'foreign key' AS kind FROM sys.foreign_key_columns f
8
+ JOIN sys.columns c ON c.object_id = f.parent_object_id AND c.column_id = f.parent_column_id
9
+ WHERE c.object_id = OBJECT_ID(${i}) AND c.name = ${a}
10
+ UNION ALL
11
+ SELECT 'referencing foreign key' FROM sys.foreign_key_columns f
12
+ JOIN sys.columns c ON c.object_id = f.referenced_object_id AND c.column_id = f.referenced_column_id
13
+ WHERE c.object_id = OBJECT_ID(${i}) AND c.name = ${a}
14
+ UNION ALL
15
+ SELECT 'schema-bound expression' FROM sys.sql_expression_dependencies dep
16
+ JOIN sys.columns c ON c.object_id = dep.referenced_id AND c.column_id = dep.referenced_minor_id
17
+ WHERE c.object_id = OBJECT_ID(${i}) AND c.name = ${a} AND dep.is_schema_bound_reference = 1
18
+ AND dep.referencing_class <> 7
19
+ AND NOT EXISTS (SELECT 1 FROM sys.check_constraints ck WHERE ck.object_id = dep.referencing_id)
20
+ UNION ALL
21
+ SELECT 'user-created statistics' FROM sys.stats s
22
+ JOIN sys.stats_columns sc ON sc.object_id = s.object_id AND sc.stats_id = s.stats_id
23
+ JOIN sys.columns c ON c.object_id = sc.object_id AND c.column_id = sc.column_id
24
+ WHERE c.object_id = OBJECT_ID(${i}) AND c.name = ${a} AND s.user_created = 1
25
+ AND NOT EXISTS (SELECT 1 FROM sys.indexes i WHERE i.object_id = s.object_id AND i.index_id = s.stats_id)
26
+ `, c = yield* e`
27
+ SELECT dc.name, dc.definition FROM sys.default_constraints dc
28
+ JOIN sys.columns c ON c.object_id = dc.parent_object_id AND c.column_id = dc.parent_column_id
29
+ WHERE c.object_id = OBJECT_ID(${i}) AND c.name = ${a}
30
+ `, l = yield* e`
31
+ SELECT ck.name, ck.definition, ck.is_disabled AS disabled, ck.is_not_trusted AS untrusted,
32
+ ck.is_not_for_replication AS notForReplication
33
+ FROM sys.check_constraints ck WHERE ck.parent_object_id = OBJECT_ID(${i}) AND (
34
+ ck.parent_column_id = (SELECT c.column_id FROM sys.columns c WHERE c.object_id = ck.parent_object_id AND c.name = ${a})
35
+ OR EXISTS (SELECT 1 FROM sys.sql_expression_dependencies dep
36
+ JOIN sys.columns c ON c.object_id = dep.referenced_id AND c.column_id = dep.referenced_minor_id
37
+ WHERE dep.referencing_id = ck.object_id AND c.object_id = ck.parent_object_id AND c.name = ${a})
38
+ ) ORDER BY ck.name
39
+ `, u = yield* e`SELECT CASE WHEN COL_LENGTH('sys.indexes', 'optimize_for_sequential_key') IS NULL THEN 0 ELSE 1 END AS present`, d = yield* e`
40
+ SELECT i.index_id AS id, i.name, i.type, i.is_unique AS [unique], i.is_primary_key AS [primary],
41
+ i.is_unique_constraint AS [constraint], i.is_disabled AS disabled, i.filter_definition AS [filter],
42
+ i.fill_factor AS [fillFactor], i.is_padded AS padded, i.ignore_dup_key AS ignoreDuplicate,
43
+ i.allow_row_locks AS rowLocks, i.allow_page_locks AS pageLocks, s.no_recompute AS noRecompute,
44
+ ds.name AS dataSpace, ds.type AS dataSpaceType, ${e.literal(u[0].present ? "i.optimize_for_sequential_key" : "CAST(0 AS bit)")} AS sequential
45
+ FROM sys.indexes i JOIN sys.data_spaces ds ON ds.data_space_id = i.data_space_id
46
+ JOIN sys.stats s ON s.object_id = i.object_id AND s.stats_id = i.index_id
47
+ WHERE i.object_id = OBJECT_ID(${i}) AND (i.has_filter = 1 OR EXISTS (
48
+ SELECT 1 FROM sys.index_columns ic JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
49
+ WHERE ic.object_id = i.object_id AND ic.index_id = i.index_id AND c.name = ${a}
50
+ )) ORDER BY i.type, i.index_id
51
+ `, f = yield* e`
52
+ SELECT ic.index_id AS indexId, c.name, ic.key_ordinal AS ordinal,
53
+ ic.is_included_column AS included, ic.is_descending_key AS descending
54
+ FROM sys.index_columns ic JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
55
+ WHERE ic.object_id = OBJECT_ID(${i}) ORDER BY ic.index_id, ic.key_ordinal, ic.index_column_id
56
+ `, p = yield* e`
57
+ SELECT DISTINCT p.index_id AS indexId FROM sys.partitions p
58
+ WHERE p.object_id = OBJECT_ID(${i}) AND p.data_compression <> 0
59
+ `, m = d.find((e) => ![1, 2].includes(e.type) || e.dataSpaceType !== "FG" || p.some((t) => t.indexId === e.id) || e.type === 1 && e.disabled);
60
+ if (s.length > 0 || m !== void 0) return yield* n.fail(t(`Cannot retype ${i}.${a} while ${s[0]?.kind ?? `unsupported index ${m.name}`} depends on it. No dependencies were removed; use a reviewed file migration that restores the dependent definitions.`));
61
+ let h = d.flatMap((e) => {
62
+ let t = f.filter((t) => t.indexId === e.id), n = t.filter((e) => e.ordinal > 0).sort((e, t) => e.ordinal - t.ordinal).map((e) => `${r(e.name)} ${e.descending ? "DESC" : "ASC"}`).join(", "), a = t.filter((e) => e.included).map((e) => r(e.name)).join(", "), o = e.type === 1 ? "CLUSTERED" : "NONCLUSTERED", s = `PAD_INDEX = ${e.padded ? "ON" : "OFF"}, ` + (e.fillFactor > 0 ? `FILLFACTOR = ${e.fillFactor}, ` : "") + `IGNORE_DUP_KEY = ${e.ignoreDuplicate ? "ON" : "OFF"}, STATISTICS_NORECOMPUTE = ${e.noRecompute ? "ON" : "OFF"}, ALLOW_ROW_LOCKS = ${e.rowLocks ? "ON" : "OFF"}, ALLOW_PAGE_LOCKS = ${e.pageLocks ? "ON" : "OFF"}` + (u[0].present ? `, OPTIMIZE_FOR_SEQUENTIAL_KEY = ${e.sequential ? "ON" : "OFF"}` : "");
63
+ return [e.primary || e.constraint ? `ALTER TABLE ${r(i)} ADD CONSTRAINT ${r(e.name)} ${e.primary ? "PRIMARY KEY" : "UNIQUE"} ${o} (${n}) WITH (${s}) ON ${r(e.dataSpace)}` : `CREATE ${e.unique ? "UNIQUE " : ""}${o} INDEX ${r(e.name)} ON ${r(i)} (${n})` + (a ? ` INCLUDE (${a})` : "") + (e.filter ? ` WHERE ${e.filter}` : "") + ` WITH (${s}) ON ${r(e.dataSpace)}`, ...e.disabled ? [`ALTER INDEX ${r(e.name)} ON ${r(i)} DISABLE`] : []];
64
+ }), g = [
65
+ ...c.map((e) => `ALTER TABLE ${r(i)} DROP CONSTRAINT ${r(e.name)}`),
66
+ ...l.map((e) => `ALTER TABLE ${r(i)} DROP CONSTRAINT ${r(e.name)}`),
67
+ ...[...d].reverse().map((e) => e.primary || e.constraint ? `ALTER TABLE ${r(i)} DROP CONSTRAINT ${r(e.name)}` : `DROP INDEX ${r(e.name)} ON ${r(i)}`),
68
+ o,
69
+ ...c.map((e) => `ALTER TABLE ${r(i)} ADD CONSTRAINT ${r(e.name)} DEFAULT ${e.definition} FOR ${r(a)}`),
70
+ ...l.flatMap((e) => [`ALTER TABLE ${r(i)} WITH ${e.untrusted ? "NOCHECK" : "CHECK"} ADD CONSTRAINT ${r(e.name)} CHECK ${e.notForReplication ? "NOT FOR REPLICATION " : ""}${e.definition}`, ...e.disabled ? [`ALTER TABLE ${r(i)} NOCHECK CONSTRAINT ${r(e.name)}`] : []]),
71
+ ...h
72
+ ];
73
+ yield* n.forEach(g, (t) => e.unsafe(t), { discard: !0 });
74
+ });
75
+ //#endregion
76
+ export { i as alterColumnWithDependenciesMssql };
@@ -0,0 +1,11 @@
1
+ import { Effect as e } from "effect";
2
+ //#region src/migrations/mysqlEngine.ts
3
+ var t = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", n = /* @__PURE__ */ new WeakMap(), r = (t) => e.suspend(() => {
4
+ let r = n.get(t);
5
+ return r === void 0 ? i(t).pipe(e.tap((r) => e.sync(() => n.set(t, r)))) : e.succeed(r);
6
+ }), i = (n) => n.unsafe("SELECT VERSION() AS v").pipe(e.map((e) => {
7
+ let n = e[0]?.v;
8
+ return typeof n == "string" ? t(n) : "mysql";
9
+ }), e.catch(() => e.succeed("mysql")));
10
+ //#endregion
11
+ export { t as engineFromVersion, r as resolveMysqlEngine };
@@ -0,0 +1,51 @@
1
+ import { storeCharsetFindings as e } from "./storeCharset.js";
2
+ import { Effect as t } from "effect";
3
+ import { SqlClient as n } from "effect/sql";
4
+ //#region src/migrations/namespaceCharset.ts
5
+ var r = "tenant_", i = (e) => e.map((e) => Object.fromEntries(Object.entries(e).map(([e, t]) => [e.toLowerCase(), t]))), a = async (a, o) => a(t.gen(function* () {
6
+ let a = yield* n.SqlClient, s = i(yield* a`
7
+ SELECT schema_name FROM information_schema.schemata
8
+ WHERE schema_name LIKE ${`${r}%`} ORDER BY schema_name`), c = [];
9
+ for (let { schema_name: n } of s) {
10
+ let r = i(yield* a`
11
+ SELECT table_name, column_name, data_type, character_set_name
12
+ FROM information_schema.columns
13
+ WHERE table_schema = ${n}
14
+ ORDER BY table_name, ordinal_position`), s = i(yield* a`
15
+ SELECT cc.table_name AS table_name, cc.check_clause AS check_clause
16
+ FROM information_schema.check_constraints cc
17
+ WHERE cc.constraint_schema = ${n}`.pipe(t.orElseSucceed(() => []))), l = /* @__PURE__ */ new Set();
18
+ for (let e of s) {
19
+ let t = /json_valid\(`?([^`)]+)`?\)/i.exec(e.check_clause);
20
+ t && l.add(`${e.table_name}.${t[1]}`);
21
+ }
22
+ let u = /* @__PURE__ */ new Map();
23
+ for (let e of r) {
24
+ let t = e.data_type.toLowerCase() === "json" || l.has(`${e.table_name}.${e.column_name}`), n = {
25
+ name: e.column_name,
26
+ type: t ? "json" : e.character_set_name === null ? "integer" : "text",
27
+ nullable: !0,
28
+ unique: !1,
29
+ hasDefault: !1,
30
+ ...!t && e.character_set_name !== null ? { charset: e.character_set_name } : {}
31
+ }, r = u.get(e.table_name) ?? [];
32
+ r.push(n), u.set(e.table_name, r);
33
+ }
34
+ let d = { tables: [...u].map(([e, t]) => ({
35
+ name: e,
36
+ columns: t,
37
+ indexes: []
38
+ })) }, f = e({
39
+ live: d,
40
+ dialect: o.dialect ?? "mysql",
41
+ charset: o.charset
42
+ });
43
+ f.length > 0 && c.push({
44
+ namespace: n,
45
+ findings: f
46
+ });
47
+ }
48
+ return c;
49
+ }));
50
+ //#endregion
51
+ export { a as tenantNamespaceCharsetFindings };