@vibeorm/migrate 2.0.0-alpha.6 → 2.0.0-alpha.8
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/ddl/render.d.ts.map +1 -1
- package/dist/execute.d.ts +26 -1
- package/dist/execute.d.ts.map +1 -1
- package/dist/index.js +50 -19
- package/dist/index.js.map +6 -6
- package/dist/runner.d.ts +48 -22
- package/dist/runner.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/ddl/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/ddl/render.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,EAAE,CAAC,EAAE,QAAQ,CAAC;CACf,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/ddl/render.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,EAAE,CAAC,EAAE,QAAQ,CAAC;CACf,GAAG,MAAM,EAAE,CAsBX"}
|
package/dist/execute.d.ts
CHANGED
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
* `usesSelfManagedTransactions` detects them. Plain statements in a
|
|
11
11
|
* self-managed script auto-commit individually (documented sqlite
|
|
12
12
|
* limitation: a mixed script is not atomic as a whole; each rebuild block
|
|
13
|
-
* is).
|
|
13
|
+
* is). Because of that, the migration runner records per-statement progress
|
|
14
|
+
* for these scripts and resumes with `selfManagedResumeStart`, which rewinds
|
|
15
|
+
* INTO the enclosing block so the session-scoped `PRAGMA foreign_keys=OFF`
|
|
16
|
+
* is re-issued before the block replays.
|
|
14
17
|
* - `PRAGMA foreign_key_check` RETURNS VIOLATION ROWS instead of failing —
|
|
15
18
|
* `executeStatement` runs it row-returning (`values: []`, the adapter-sqlite
|
|
16
19
|
* contract for reads) and throws VIBE_MIGRATION when any come back.
|
|
@@ -21,6 +24,28 @@ import type { SqlExecutor } from "./types.ts";
|
|
|
21
24
|
export declare function usesSelfManagedTransactions(params: {
|
|
22
25
|
sql: readonly string[];
|
|
23
26
|
}): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Where a resume of a self-managed sqlite script must actually restart.
|
|
29
|
+
*
|
|
30
|
+
* A recorded statement_index can point INSIDE a rebuild block: the progress
|
|
31
|
+
* UPDATE issued after `PRAGMA foreign_keys=OFF;` auto-commits (no transaction
|
|
32
|
+
* is open yet), while every UPDATE after the block's `BEGIN;` is rolled back
|
|
33
|
+
* with the crash — so the persisted index lands on the block's `BEGIN;`, one
|
|
34
|
+
* past a pragma that is SESSION-scoped and gone in the new session. Resuming
|
|
35
|
+
* there would run the rebuild — `DROP TABLE` of a possibly-referenced parent
|
|
36
|
+
* included — with foreign keys ON.
|
|
37
|
+
*
|
|
38
|
+
* This rewinds `start` to the nearest preceding `PRAGMA foreign_keys=OFF` that
|
|
39
|
+
* is not already closed by a `PRAGMA foreign_keys=ON`. Replaying from a
|
|
40
|
+
* block's start is safe: the block is transactional (nothing of it survived a
|
|
41
|
+
* crash) and re-running a COMPLETED block is the idempotence the recipe
|
|
42
|
+
* already relies on. Scripts with no marker before `start` are returned
|
|
43
|
+
* unchanged.
|
|
44
|
+
*/
|
|
45
|
+
export declare function selfManagedResumeStart(params: {
|
|
46
|
+
sql: readonly string[];
|
|
47
|
+
start: number;
|
|
48
|
+
}): number;
|
|
24
49
|
/**
|
|
25
50
|
* Execute one migration statement. On sqlite, `PRAGMA foreign_key_check` is
|
|
26
51
|
* executed row-returning and its violations become a VIBE_MIGRATION error.
|
package/dist/execute.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAU9C,2EAA2E;AAC3E,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG,OAAO,CAEvF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAST;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,QAAQ,EAAE,WAAW,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhB;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,WAAW,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhG"}
|
package/dist/index.js
CHANGED
|
@@ -1771,6 +1771,8 @@ function columnDefSql3(params) {
|
|
|
1771
1771
|
});
|
|
1772
1772
|
}
|
|
1773
1773
|
let def = `${name} ${mysqlColumnTypeSql({ field, enums })}`;
|
|
1774
|
+
if (field.collation !== undefined)
|
|
1775
|
+
def += ` COLLATE ${field.collation}`;
|
|
1774
1776
|
if (!field.isOptional)
|
|
1775
1777
|
def += " NOT NULL";
|
|
1776
1778
|
if (autoincrement)
|
|
@@ -1957,10 +1959,22 @@ function artifactCreateSql(params) {
|
|
|
1957
1959
|
// packages/migrate/src/execute.ts
|
|
1958
1960
|
import { VibeError as VibeError8 } from "@vibeorm/schema";
|
|
1959
1961
|
var SELF_MANAGED_MARKER = "PRAGMA foreign_keys=OFF";
|
|
1962
|
+
var SELF_MANAGED_RESTORE_MARKER = "PRAGMA foreign_keys=ON";
|
|
1960
1963
|
var FK_CHECK_PREFIX = "PRAGMA foreign_key_check";
|
|
1961
1964
|
function usesSelfManagedTransactions(params) {
|
|
1962
1965
|
return params.sql.some((statement) => statement.startsWith(SELF_MANAGED_MARKER));
|
|
1963
1966
|
}
|
|
1967
|
+
function selfManagedResumeStart(params) {
|
|
1968
|
+
const { sql, start } = params;
|
|
1969
|
+
for (let index = start - 1;index >= 0; index -= 1) {
|
|
1970
|
+
const statement = sql[index];
|
|
1971
|
+
if (statement.startsWith(SELF_MANAGED_RESTORE_MARKER))
|
|
1972
|
+
return start;
|
|
1973
|
+
if (statement.startsWith(SELF_MANAGED_MARKER))
|
|
1974
|
+
return index;
|
|
1975
|
+
}
|
|
1976
|
+
return start;
|
|
1977
|
+
}
|
|
1964
1978
|
async function executeStatement(params) {
|
|
1965
1979
|
const { executor, statement, dialect } = params;
|
|
1966
1980
|
if (dialect === "sqlite" && statement.startsWith(FK_CHECK_PREFIX)) {
|
|
@@ -2057,10 +2071,9 @@ function generateMigration(params) {
|
|
|
2057
2071
|
async function applyMigrations(params) {
|
|
2058
2072
|
const { executor, migrations } = params;
|
|
2059
2073
|
const dialect = params.dialect ?? "postgres";
|
|
2060
|
-
const transactional = DIALECT_CAPABILITIES[dialect].transactionalDdl;
|
|
2061
|
-
await ensureMigrationsTable({ executor, dialect });
|
|
2062
2074
|
await acquireLock({ executor, dialect });
|
|
2063
2075
|
try {
|
|
2076
|
+
await ensureMigrationsTable({ executor, dialect });
|
|
2064
2077
|
const recorded = await recordedRows({ executor, dialect });
|
|
2065
2078
|
const applied = [];
|
|
2066
2079
|
const skipped = [];
|
|
@@ -2074,8 +2087,7 @@ async function applyMigrations(params) {
|
|
|
2074
2087
|
meta: { migration: migration.name, statementIndex: stored.statementIndex }
|
|
2075
2088
|
});
|
|
2076
2089
|
}
|
|
2077
|
-
|
|
2078
|
-
if (complete) {
|
|
2090
|
+
if (isCompleteRecord({ dialect, migration, stored })) {
|
|
2079
2091
|
assertChecksumMatches({ migration, stored: stored.checksum });
|
|
2080
2092
|
skipped.push(migration.name);
|
|
2081
2093
|
continue;
|
|
@@ -2091,10 +2103,10 @@ async function applyMigrations(params) {
|
|
|
2091
2103
|
applied.push(migration.name);
|
|
2092
2104
|
continue;
|
|
2093
2105
|
}
|
|
2094
|
-
if (
|
|
2095
|
-
await runTransactional({ executor, dialect, migration });
|
|
2096
|
-
} else {
|
|
2106
|
+
if (usesStatementBookkeeping({ dialect, sql: migration.sql })) {
|
|
2097
2107
|
await runNonTransactional({ executor, dialect, migration, start: 0, insertRecord: true });
|
|
2108
|
+
} else {
|
|
2109
|
+
await runTransactional({ executor, dialect, migration });
|
|
2098
2110
|
}
|
|
2099
2111
|
applied.push(migration.name);
|
|
2100
2112
|
}
|
|
@@ -2106,7 +2118,6 @@ async function applyMigrations(params) {
|
|
|
2106
2118
|
async function migrationStatus(params) {
|
|
2107
2119
|
const { executor, migrations } = params;
|
|
2108
2120
|
const dialect = params.dialect ?? "postgres";
|
|
2109
|
-
const transactional = DIALECT_CAPABILITIES[dialect].transactionalDdl;
|
|
2110
2121
|
await ensureMigrationsTable({ executor, dialect });
|
|
2111
2122
|
const recorded = await recordedRows({ executor, dialect });
|
|
2112
2123
|
const applied = [];
|
|
@@ -2131,8 +2142,7 @@ async function migrationStatus(params) {
|
|
|
2131
2142
|
mismatched.push(migration.name);
|
|
2132
2143
|
continue;
|
|
2133
2144
|
}
|
|
2134
|
-
|
|
2135
|
-
if (complete)
|
|
2145
|
+
if (isCompleteRecord({ dialect, migration, stored }))
|
|
2136
2146
|
applied.push(migration.name);
|
|
2137
2147
|
else
|
|
2138
2148
|
pending.push(migration.name);
|
|
@@ -2157,7 +2167,6 @@ async function resolveMigration(params) {
|
|
|
2157
2167
|
async function rollbackMigration(params) {
|
|
2158
2168
|
const { executor, migration } = params;
|
|
2159
2169
|
const dialect = params.dialect ?? "postgres";
|
|
2160
|
-
const transactional = DIALECT_CAPABILITIES[dialect].transactionalDdl;
|
|
2161
2170
|
const downSql = migration.downSql;
|
|
2162
2171
|
if (downSql === undefined) {
|
|
2163
2172
|
throw new VibeError9({
|
|
@@ -2166,9 +2175,9 @@ async function rollbackMigration(params) {
|
|
|
2166
2175
|
meta: { migration: migration.name }
|
|
2167
2176
|
});
|
|
2168
2177
|
}
|
|
2169
|
-
await ensureMigrationsTable({ executor, dialect });
|
|
2170
2178
|
await acquireLock({ executor, dialect });
|
|
2171
2179
|
try {
|
|
2180
|
+
await ensureMigrationsTable({ executor, dialect });
|
|
2172
2181
|
const recorded = await recordedRows({ executor, dialect });
|
|
2173
2182
|
const stored = recorded.get(migration.name);
|
|
2174
2183
|
if (stored === undefined) {
|
|
@@ -2181,7 +2190,7 @@ async function rollbackMigration(params) {
|
|
|
2181
2190
|
const resumingDown = stored.statementIndex < 0;
|
|
2182
2191
|
assertChecksumMatches({ migration, stored: stored.checksum });
|
|
2183
2192
|
if (!resumingDown) {
|
|
2184
|
-
const partialUp = !
|
|
2193
|
+
const partialUp = !isCompleteRecord({ dialect, migration, stored });
|
|
2185
2194
|
if (partialUp) {
|
|
2186
2195
|
throw new VibeError9({
|
|
2187
2196
|
code: "VIBE_MIGRATION",
|
|
@@ -2190,11 +2199,11 @@ async function rollbackMigration(params) {
|
|
|
2190
2199
|
});
|
|
2191
2200
|
}
|
|
2192
2201
|
}
|
|
2193
|
-
if (
|
|
2194
|
-
await runTransactionalDown({ executor, dialect, migration, downSql });
|
|
2195
|
-
} else {
|
|
2202
|
+
if (usesStatementBookkeeping({ dialect, sql: downSql })) {
|
|
2196
2203
|
const start = resumingDown ? -stored.statementIndex - 1 : 0;
|
|
2197
2204
|
await runNonTransactionalDown({ executor, dialect, migration, downSql, start });
|
|
2205
|
+
} else {
|
|
2206
|
+
await runTransactionalDown({ executor, dialect, migration, downSql });
|
|
2198
2207
|
}
|
|
2199
2208
|
} finally {
|
|
2200
2209
|
await releaseLock({ executor, dialect });
|
|
@@ -2233,8 +2242,10 @@ async function runTransactionalDown(params) {
|
|
|
2233
2242
|
}
|
|
2234
2243
|
}
|
|
2235
2244
|
async function runNonTransactionalDown(params) {
|
|
2236
|
-
const { executor, dialect, migration, downSql
|
|
2245
|
+
const { executor, dialect, migration, downSql } = params;
|
|
2237
2246
|
const table = q4(dialect, MIGRATIONS_TABLE_NAME);
|
|
2247
|
+
const selfManaged = dialect === "sqlite" && usesSelfManagedTransactions({ sql: downSql });
|
|
2248
|
+
const start = selfManaged ? selfManagedResumeStart({ sql: downSql, start: params.start }) : params.start;
|
|
2238
2249
|
const recordProgress = async (completed) => {
|
|
2239
2250
|
await executor({
|
|
2240
2251
|
text: `UPDATE ${table} SET ${q4(dialect, "statement_index")} = ${ph(dialect, 1)}, ${q4(dialect, "error")} = NULL WHERE ${q4(dialect, "name")} = ${ph(dialect, 2)}`,
|
|
@@ -2247,6 +2258,8 @@ async function runNonTransactionalDown(params) {
|
|
|
2247
2258
|
try {
|
|
2248
2259
|
await executeStatement({ executor, statement: downSql[index], dialect });
|
|
2249
2260
|
} catch (error) {
|
|
2261
|
+
if (selfManaged)
|
|
2262
|
+
await cleanupSelfManagedFailure({ executor });
|
|
2250
2263
|
try {
|
|
2251
2264
|
await executor({
|
|
2252
2265
|
text: `UPDATE ${table} SET ${q4(dialect, "error")} = ${ph(dialect, 1)} WHERE ${q4(dialect, "name")} = ${ph(dialect, 2)}`,
|
|
@@ -2302,8 +2315,10 @@ async function runTransactional(params) {
|
|
|
2302
2315
|
}
|
|
2303
2316
|
}
|
|
2304
2317
|
async function runNonTransactional(params) {
|
|
2305
|
-
const { executor, dialect, migration,
|
|
2318
|
+
const { executor, dialect, migration, insertRecord } = params;
|
|
2306
2319
|
const table = q4(dialect, MIGRATIONS_TABLE_NAME);
|
|
2320
|
+
const selfManaged = dialect === "sqlite" && usesSelfManagedTransactions({ sql: migration.sql });
|
|
2321
|
+
const start = selfManaged ? selfManagedResumeStart({ sql: migration.sql, start: params.start }) : params.start;
|
|
2307
2322
|
if (insertRecord) {
|
|
2308
2323
|
await executor({
|
|
2309
2324
|
text: `INSERT INTO ${table} (${q4(dialect, "name")}, ${q4(dialect, "checksum")}, ${q4(dialect, "statement_index")}) VALUES (${ph(dialect, 1)}, ${ph(dialect, 2)}, 0)`,
|
|
@@ -2314,6 +2329,8 @@ async function runNonTransactional(params) {
|
|
|
2314
2329
|
try {
|
|
2315
2330
|
await executeStatement({ executor, statement: migration.sql[index], dialect });
|
|
2316
2331
|
} catch (error) {
|
|
2332
|
+
if (selfManaged)
|
|
2333
|
+
await cleanupSelfManagedFailure({ executor });
|
|
2317
2334
|
try {
|
|
2318
2335
|
await executor({
|
|
2319
2336
|
text: `UPDATE ${table} SET ${q4(dialect, "error")} = ${ph(dialect, 1)} WHERE ${q4(dialect, "name")} = ${ph(dialect, 2)}`,
|
|
@@ -2364,6 +2381,20 @@ async function releaseLock(params) {
|
|
|
2364
2381
|
}
|
|
2365
2382
|
} catch {}
|
|
2366
2383
|
}
|
|
2384
|
+
function usesStatementBookkeeping(params) {
|
|
2385
|
+
const { dialect, sql } = params;
|
|
2386
|
+
if (!DIALECT_CAPABILITIES[dialect].transactionalDdl)
|
|
2387
|
+
return true;
|
|
2388
|
+
return dialect === "sqlite" && usesSelfManagedTransactions({ sql });
|
|
2389
|
+
}
|
|
2390
|
+
function isCompleteRecord(params) {
|
|
2391
|
+
const { dialect, migration, stored } = params;
|
|
2392
|
+
if (stored.checksum === "")
|
|
2393
|
+
return true;
|
|
2394
|
+
if (!usesStatementBookkeeping({ dialect, sql: migration.sql }))
|
|
2395
|
+
return true;
|
|
2396
|
+
return stored.statementIndex >= migration.sql.length;
|
|
2397
|
+
}
|
|
2367
2398
|
async function recordedRows(params) {
|
|
2368
2399
|
const { executor, dialect } = params;
|
|
2369
2400
|
const rows = await executor({
|
|
@@ -4057,4 +4088,4 @@ export {
|
|
|
4057
4088
|
MIGRATIONS_TABLE_NAME
|
|
4058
4089
|
};
|
|
4059
4090
|
|
|
4060
|
-
//# debugId=
|
|
4091
|
+
//# debugId=70C1B35231C75DF864756E2164756E21
|