refactor: move fork-only migrations to migrations_fork.py
`migrations.py` now matches upstream v1.3.0 exactly. Every aio-only schema delta (the old m007-m011: user_id, status, nostr_event_id + created_at, settings table, location + categories) moves into a single `m001_aio_event_schema` function in `migrations_fork.py`, tracked under `events_fork` in `dbversions` by the loader added in aiolabs/lnbits@ae997181. Idempotency guards on every ADD COLUMN / CREATE TABLE let the squashed migration no-op cleanly on dev DBs that already ran the old m007-m011 — schema lands identical from either path. Why now: aiolabs/lnbits#8. We're about to rebase events onto upstream v1.6.1 which adds its own m007_add_allow_fiat. With this move done first, migrations.py stays a fast-forward on rebase and our fork-only schema lives in a separate file that never collides. Requires aiolabs/lnbits @ ae997181 or later for the extension_fork loader. Running on an upstream lnbits without the loader patch will NOT apply the fork schema — but the aiolabs deploy fleet already pulls from aiolabs/lnbits, so this is the only host we ship to. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2ba791821b
commit
02f3511e86
2 changed files with 110 additions and 85 deletions
|
|
@ -162,96 +162,16 @@ async def m005_add_image_banner(db):
|
||||||
await db.execute("ALTER TABLE events.events ADD COLUMN banner TEXT;")
|
await db.execute("ALTER TABLE events.events ADD COLUMN banner TEXT;")
|
||||||
|
|
||||||
|
|
||||||
async def _alter_add_column_safe(db, sql: str) -> None:
|
|
||||||
"""ALTER TABLE ADD COLUMN that swallows duplicate-column errors.
|
|
||||||
|
|
||||||
Earlier aiolabs/events forks added some of these columns under different
|
|
||||||
migration names (e.g. our former m007). Skipping the error keeps the
|
|
||||||
migration log monotonic for both fresh installs and pre-rebase upgrades.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
await db.execute(sql)
|
|
||||||
except Exception as exc:
|
|
||||||
msg = str(exc).lower()
|
|
||||||
if "duplicate column" in msg or "already exists" in msg:
|
|
||||||
return
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
async def m006_add_extra_fields(db):
|
async def m006_add_extra_fields(db):
|
||||||
"""
|
"""
|
||||||
Add a canceled and 'extra' column to events and ticket tables
|
Add a canceled and 'extra' column to events and ticket tables
|
||||||
to support promo codes and ticket metadata.
|
to support promo codes and ticket metadata.
|
||||||
"""
|
"""
|
||||||
await _alter_add_column_safe(
|
# Add canceled and 'extra' columns to events table
|
||||||
db,
|
|
||||||
"ALTER TABLE events.events ADD COLUMN canceled BOOLEAN NOT NULL DEFAULT FALSE",
|
|
||||||
)
|
|
||||||
await _alter_add_column_safe(db, "ALTER TABLE events.events ADD COLUMN extra TEXT")
|
|
||||||
await _alter_add_column_safe(db, "ALTER TABLE events.ticket ADD COLUMN extra TEXT")
|
|
||||||
|
|
||||||
|
|
||||||
async def m007_add_user_id_support(db):
|
|
||||||
"""
|
|
||||||
Add user_id column to ticket table so a ticket can reference an LNbits
|
|
||||||
user id instead of (name, email). Application logic enforces that exactly
|
|
||||||
one identifier scheme is used per ticket.
|
|
||||||
"""
|
|
||||||
await _alter_add_column_safe(
|
|
||||||
db, "ALTER TABLE events.ticket ADD COLUMN user_id TEXT"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def m008_add_event_status(db):
|
|
||||||
"""
|
|
||||||
Add status column to events table for the proposal/approval workflow.
|
|
||||||
Values: 'proposed', 'approved', 'rejected'. Existing rows default to
|
|
||||||
'approved' so they stay visible after upgrade.
|
|
||||||
"""
|
|
||||||
await _alter_add_column_safe(
|
|
||||||
db,
|
|
||||||
"ALTER TABLE events.events ADD COLUMN status TEXT NOT NULL DEFAULT 'approved'",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def m009_add_nostr_columns(db):
|
|
||||||
"""
|
|
||||||
Track the most recent NIP-52 calendar event we published for this event
|
|
||||||
(used for replaceable updates and NIP-09 deletes).
|
|
||||||
"""
|
|
||||||
await _alter_add_column_safe(
|
|
||||||
db, "ALTER TABLE events.events ADD COLUMN nostr_event_id TEXT"
|
|
||||||
)
|
|
||||||
await _alter_add_column_safe(
|
|
||||||
db, "ALTER TABLE events.events ADD COLUMN nostr_event_created_at INTEGER"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def m010_add_events_settings(db):
|
|
||||||
"""
|
|
||||||
Create the extension settings singleton row used by the admin UI to
|
|
||||||
toggle e.g. auto_approve.
|
|
||||||
"""
|
|
||||||
await db.execute("""
|
|
||||||
CREATE TABLE IF NOT EXISTS events.settings (
|
|
||||||
id INTEGER PRIMARY KEY DEFAULT 1,
|
|
||||||
auto_approve BOOLEAN NOT NULL DEFAULT FALSE
|
|
||||||
)
|
|
||||||
""")
|
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"INSERT INTO events.settings (id, auto_approve) "
|
"ALTER TABLE events.events ADD COLUMN canceled BOOLEAN NOT NULL DEFAULT FALSE;"
|
||||||
"SELECT 1, FALSE WHERE NOT EXISTS "
|
|
||||||
"(SELECT 1 FROM events.settings WHERE id = 1)"
|
|
||||||
)
|
)
|
||||||
|
await db.execute("ALTER TABLE events.events ADD COLUMN extra TEXT;")
|
||||||
|
|
||||||
|
# Add 'extra' column to ticket table
|
||||||
async def m011_add_location_and_categories(db):
|
await db.execute("ALTER TABLE events.ticket ADD COLUMN extra TEXT;")
|
||||||
"""
|
|
||||||
Add NIP-52 calendar metadata (location and a JSON-encoded category list).
|
|
||||||
"""
|
|
||||||
await _alter_add_column_safe(
|
|
||||||
db, "ALTER TABLE events.events ADD COLUMN location TEXT"
|
|
||||||
)
|
|
||||||
await _alter_add_column_safe(
|
|
||||||
db, "ALTER TABLE events.events ADD COLUMN categories TEXT"
|
|
||||||
)
|
|
||||||
|
|
|
||||||
105
migrations_fork.py
Normal file
105
migrations_fork.py
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
"""
|
||||||
|
Fork-specific database migrations for the aiolabs events extension.
|
||||||
|
|
||||||
|
These migrations are tracked separately under `events_fork` in the
|
||||||
|
`dbversions` table (loaded by `lnbits/core/helpers.py:migrate_extension_database`),
|
||||||
|
so they do not collide with upstream's `m{NNN}_*` numbering in
|
||||||
|
`migrations.py`. Keeping the upstream-tracked file untouched means
|
||||||
|
`git pull upstream` stays rebase-clean for schema changes.
|
||||||
|
|
||||||
|
Conventions:
|
||||||
|
- Sequential numbering starting from m001.
|
||||||
|
- Each migration is `async def m{NNN}_<description>(db)`.
|
||||||
|
- DDL must be idempotent: a fresh install runs every migration; an
|
||||||
|
install that previously ran the OLD versions of these as
|
||||||
|
`m007-m011` in `migrations.py` has the columns/tables already.
|
||||||
|
Use `_alter_add_column_safe` / `_create_table_safe` so re-runs are
|
||||||
|
no-ops instead of crashes.
|
||||||
|
|
||||||
|
History compressed into m001 (was m007-m011 in migrations.py pre-v1.6
|
||||||
|
rebase):
|
||||||
|
- m007 add_user_id_support (ticket.user_id column)
|
||||||
|
- m008 add_event_status (events.status column)
|
||||||
|
- m009 add_nostr_columns (events.nostr_event_id + created_at)
|
||||||
|
- m010 add_events_settings (events.settings singleton table)
|
||||||
|
- m011 add_location_and_categories (events.location + categories)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
async def _alter_add_column_safe(db, sql: str) -> None:
|
||||||
|
"""ALTER TABLE ADD COLUMN that swallows duplicate-column errors.
|
||||||
|
|
||||||
|
Re-running the squashed migration on a database that already has
|
||||||
|
these columns (from the pre-squash `m007-m011` in migrations.py)
|
||||||
|
must be a silent no-op. Same swallow we used in the old migrations.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
await db.execute(sql)
|
||||||
|
except Exception as exc:
|
||||||
|
msg = str(exc).lower()
|
||||||
|
if "duplicate column" in msg or "already exists" in msg:
|
||||||
|
return
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
async def m001_aio_event_schema(db):
|
||||||
|
"""
|
||||||
|
Apply every aiolabs schema delta on top of upstream events v1.3.0.
|
||||||
|
|
||||||
|
This is the squashed equivalent of the pre-v1.6 sequence
|
||||||
|
m007 → m011. Order matters for the settings table seed insert
|
||||||
|
but the individual column adds are independent and idempotent.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# --- ticket.user_id ----------------------------------------------
|
||||||
|
# Lets a ticket reference an LNbits user id instead of (name, email).
|
||||||
|
# Application logic enforces that exactly one identifier scheme is
|
||||||
|
# used per ticket.
|
||||||
|
await _alter_add_column_safe(
|
||||||
|
db, "ALTER TABLE events.ticket ADD COLUMN user_id TEXT"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- events.status -----------------------------------------------
|
||||||
|
# Proposal / approval workflow. Existing rows default to 'approved'
|
||||||
|
# so they stay visible after upgrade.
|
||||||
|
await _alter_add_column_safe(
|
||||||
|
db,
|
||||||
|
"ALTER TABLE events.events ADD COLUMN status TEXT NOT NULL DEFAULT 'approved'",
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- events.nostr_event_id, nostr_event_created_at ---------------
|
||||||
|
# Track the most recent NIP-52 calendar event we published, so
|
||||||
|
# subsequent edits can issue replaceable updates and NIP-09 deletes
|
||||||
|
# against the right addressable coordinate.
|
||||||
|
await _alter_add_column_safe(
|
||||||
|
db, "ALTER TABLE events.events ADD COLUMN nostr_event_id TEXT"
|
||||||
|
)
|
||||||
|
await _alter_add_column_safe(
|
||||||
|
db, "ALTER TABLE events.events ADD COLUMN nostr_event_created_at INTEGER"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- events.settings ---------------------------------------------
|
||||||
|
# Singleton settings row used by the admin UI to toggle e.g.
|
||||||
|
# auto_approve. CREATE TABLE IF NOT EXISTS + a guarded seed keeps
|
||||||
|
# this idempotent.
|
||||||
|
await db.execute("""
|
||||||
|
CREATE TABLE IF NOT EXISTS events.settings (
|
||||||
|
id INTEGER PRIMARY KEY DEFAULT 1,
|
||||||
|
auto_approve BOOLEAN NOT NULL DEFAULT FALSE
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
await db.execute(
|
||||||
|
"INSERT INTO events.settings (id, auto_approve) "
|
||||||
|
"SELECT 1, FALSE WHERE NOT EXISTS "
|
||||||
|
"(SELECT 1 FROM events.settings WHERE id = 1)"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- events.location, events.categories --------------------------
|
||||||
|
# NIP-52 calendar metadata. `categories` carries a JSON-encoded
|
||||||
|
# list of hashtags (the NIP-52 `t` tags).
|
||||||
|
await _alter_add_column_safe(
|
||||||
|
db, "ALTER TABLE events.events ADD COLUMN location TEXT"
|
||||||
|
)
|
||||||
|
await _alter_add_column_safe(
|
||||||
|
db, "ALTER TABLE events.events ADD COLUMN categories TEXT"
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue