Unified · Split
| @@ -1343,16 +1343,16 @@ export const migrateLocalV1ToV2IfNeeded = async ( · 1342 unmodified lines | |||
| 1343 | 1343 | ||
| 1344 | if (!fs.existsSync(options.sqlitePath)) return { migrated: false, warnings: [] }; | 1344 | if (!fs.existsSync(options.sqlitePath)) return { migrated: false, warnings: [] }; |
| 1345 | 1345 | ||
| 1346 | // Fast steady-state probe: migrated v2 databases short-circuit on their ledger | 1346 | // The caller holds the data-dir ownership lock, so this process is the sole |
| 1347 | // stamp without copying the whole DB. The caller holds the data-dir ownership | 1347 | // writer and recovery already ran above. A single probe decides the outcome: |
| 1348 | // lock, so this process is the sole writer; any ambiguous shape decision | 1348 | // already-migrated databases short-circuit on their ledger stamp, and only an |
| 1349 | // happens below. | 1349 | // actual v1 database falls through to the heavy copy/stage/flip path below. |
| 1350 | let probe: Client | null = await openLocalLibsql(options.sqlitePath); | 1350 | const probe: Client = await openLocalLibsql(options.sqlitePath); |
| 1351 | try { | 1351 | try { |
| 1352 | if (await hasV1GateStamp(probe)) return { migrated: false, warnings: [] }; | 1352 | if (await hasV1GateStamp(probe)) return { migrated: false, warnings: [] }; |
| 1353 | if (!(await isLocalV1Database(probe))) return { migrated: false, warnings: [] }; | ||
| 1353 | } finally { | 1354 | } finally { |
| 1354 | probe.close(); | 1355 | probe.close(); |
| 1355 | probe = null; | ||
| 1356 | } | 1356 | } |
| 1357 | 1357 | ||
| 1358 | let normalizedSourcePath: string | null = null; | 1358 | let normalizedSourcePath: string | null = null; |
| @@ -1364,18 +1364,6 @@ export const migrateLocalV1ToV2IfNeeded = async ( · 5 unmodified lines | |||
| 1364 | let flipStarted = false; | 1364 | let flipStarted = false; |
| 1365 | 1365 | ||
| 1366 | try { | 1366 | try { |
| 1367 | await recoverV1V2Migration(options.sqlitePath); | ||
| 1368 | if (!fs.existsSync(options.sqlitePath)) return { migrated: false, warnings: [] }; | ||
| 1369 | |||
| 1370 | probe = await openLocalLibsql(options.sqlitePath); | ||
| 1371 | try { | ||
| 1372 | if (await hasV1GateStamp(probe)) return { migrated: false, warnings: [] }; | ||
| 1373 | if (!(await isLocalV1Database(probe))) return { migrated: false, warnings: [] }; | ||
| 1374 | } finally { | ||
| 1375 | probe.close(); | ||
| 1376 | probe = null; | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | const nonce = randomBytes(4).toString("hex"); | 1367 | const nonce = randomBytes(4).toString("hex"); |
| 1380 | normalizedSourcePath = normalizedSourcePathFor(options.sqlitePath, nonce); | 1368 | normalizedSourcePath = normalizedSourcePathFor(options.sqlitePath, nonce); |
| 1381 | stagingPath = stagingPathFor(options.sqlitePath, nonce); | 1369 | stagingPath = stagingPathFor(options.sqlitePath, nonce); |