Files
MikrotikManager/backend/src/db/sqlite-import-control-writes.ts
T

36 lines
2.3 KiB
TypeScript

import type { Pool } from "pg"
import { withPartitionWrite, PartitionWriteError, isPartitionWriteOutcomeUnknown } from "../services/partition-write-transaction.js"
/** Uses the same
* admission already used by import batches, on the marker's actual backend. */
export async function writeSqliteImportMarker(pool: Pool, sqlitePath: string, sqliteSha256: string, reportJson: string): Promise<void> {
await withPartitionWrite(async ({ client }) => {
await client.query(`UPDATE data_migration
SET sqlite_imported_at = now(), sqlite_path = $1, sqlite_sha256 = $2, report_json = $3::jsonb
WHERE id = 1`, [sqlitePath, sqliteSha256, reportJson])
}, { connect: () => pool.connect() })
}
/** Missing serial metadata is the explicit supported compatibility no-op.
* Never catch arbitrary SQL errors or unknown COMMIT outcomes. setval itself
* is NONTRANSACTIONAL: a later rollback/ACK loss cannot undo its visible value. */
export async function resetSqliteImportSequence(pool: Pool, table: string): Promise<"sequence-absent" | "sequence-set"> {
if (typeof table !== "string" || !/^[a-z_][a-z0-9_]{0,62}$/.test(table)) throw Error("Fixed importer relation identifier required")
let sequenceMutationSent = false
try { return await withPartitionWrite(async ({ client }) => {
const rows = (await client.query<{ sequence_oid: string | null }>("SELECT pg_catalog.pg_get_serial_sequence($1,'id')::pg_catalog.regclass::pg_catalog.oid::text AS sequence_oid", ["public." + table])).rows
if (rows.length !== 1) throw Error("Importer identity metadata unavailable")
if (rows[0].sequence_oid === null) return "sequence-absent" as const
if (!/^[1-9][0-9]{0,9}$/.test(rows[0].sequence_oid)) throw Error("Importer sequence identity unavailable")
sequenceMutationSent = true
await client.query(`SELECT pg_catalog.setval($1::pg_catalog.oid::pg_catalog.regclass,
GREATEST(COALESCE((SELECT MAX(id) FROM "public"."${table}"),1),1),true)`, [rows[0].sequence_oid])
return "sequence-set" as const
}, { connect: () => pool.connect() }) }
catch (error) {
// The surrounding SQL transaction may be known rolled back, while setval
// was already visible. Never feed that case into known-failure/retry lanes.
if (sequenceMutationSent && !isPartitionWriteOutcomeUnknown(error)) throw new PartitionWriteError(true)
throw error
}
}