diff --git a/migrations.py b/migrations.py index 93c27a9..a2f8e61 100644 --- a/migrations.py +++ b/migrations.py @@ -2,10 +2,12 @@ async def m001_initial(db): """ Tasks table (NIP-52 kind 31922 cache) and completions table (kind 31925 cache). The (pubkey, d_tag) pair is the parameterized-replaceable key. + Uses IF NOT EXISTS throughout so a partial first-run leaves the + migration safely re-runnable. """ await db.execute( f""" - CREATE TABLE tasks.tasks ( + CREATE TABLE IF NOT EXISTS tasks.tasks ( id TEXT PRIMARY KEY, wallet TEXT NOT NULL, pubkey TEXT NOT NULL, @@ -26,14 +28,17 @@ async def m001_initial(db): ); """ ) + # Schema prefix goes on the INDEX NAME (not the target table) in sqlite + # when the schema is an ATTACHed database — `CREATE INDEX schema.idx`, + # not `CREATE INDEX idx ON schema.tbl`. await db.execute( - "CREATE UNIQUE INDEX tasks_pubkey_dtag_idx " - "ON tasks.tasks (pubkey, d_tag)" + "CREATE UNIQUE INDEX IF NOT EXISTS tasks.tasks_pubkey_dtag_idx " + "ON tasks (pubkey, d_tag)" ) await db.execute( f""" - CREATE TABLE tasks.completions ( + CREATE TABLE IF NOT EXISTS tasks.completions ( id TEXT PRIMARY KEY, task_address TEXT NOT NULL, pubkey TEXT NOT NULL, @@ -46,16 +51,13 @@ async def m001_initial(db): ); """ ) - # occurrence is NULL for one-shot tasks; the (task_address, pubkey, - # occurrence) tuple identifies "the latest claim by this user for this - # specific occurrence". await db.execute( - "CREATE INDEX tasks_completions_address_idx " - "ON tasks.completions (task_address)" + "CREATE INDEX IF NOT EXISTS tasks.tasks_completions_address_idx " + "ON completions (task_address)" ) await db.execute( - "CREATE INDEX tasks_completions_pubkey_idx " - "ON tasks.completions (pubkey)" + "CREATE INDEX IF NOT EXISTS tasks.tasks_completions_pubkey_idx " + "ON completions (pubkey)" )