docs: add README for db-customization scripts

Documents which SQL script to run for new deployments vs existing 0.11.6
database upgrades, ordering prerequisites, and what changed in the MUC
storage layout between 0.11.6 and 13.0.6.

Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
This commit is contained in:
2026-07-15 17:58:02 +02:00
parent 8392402301
commit ea043d759c
+80
View File
@@ -0,0 +1,80 @@
# db-customization
PostgreSQL schema, rules, triggers and migration scripts for the VNCtalk
Prosody 13.0.6 database. Applied out-of-band (manually or via a job), **not**
by the Prosody container itself.
## Files
| File | Idempotent | Purpose |
|------|------------|---------|
| `prosody-13-new-deployment.sql` | Yes | **All-in-one script for new/fresh deployments.** Creates every derived table, rule, view, trigger and index adapted to the 13.0.6 storage layout. Replaces the two legacy 0.11.6 scripts entirely. |
| `prosody-queries-noowner.sql` | No | Legacy 0.11.6 table + rule definitions (original non-idempotent form). Used only on databases that were set up under 0.11.6 and have not yet been migrated. |
| `prosody-trigger-noowner.sql` | No | Legacy 0.11.6 trigger definitions (original non-idempotent form). Companion to `prosody-queries-noowner.sql`. |
| `prosody-13-rules-triggers.sql` | Yes | **Incremental upgrade script for existing 0.11.6 databases.** Recreates only the rules, views and trigger functions that changed with the 13.0.6 MUC storage layout (affiliations stored one row per bare JID; `_affiliations` / `_occupants` keys gone). Does not touch the many objects that are unaffected. |
| `prosody-13-migration-once.sql` | Yes (but intended once) | **One-time data migration for existing 0.11.6 databases.** Backfills `room_nick_jid_map`, `group_owners` and `recent_history_table` from the new per-affiliation rows, and drops obsolete objects (`room_nicknames` view, `update_room_nick_jid_map` rule). Run after the legacy scripts and `prosody-13-rules-triggers.sql` have been applied. |
## Prerequisites
All scripts require the Prosody storage tables `prosody` and `prosodyarchive`
to already exist. These are created by `mod_storage_sql` when Prosody first
starts against the database. Therefore:
1. Point Prosody 13.0.6 at the database and start it once so the tables are
created.
2. Run the appropriate script(s) below.
Every 13.0 script begins with a guard that aborts (`\set ON_ERROR_STOP on` +
`RAISE EXCEPTION`) if the tables are missing.
## Which script to run when
### New deployment (empty database)
```
psql -f prosody-13-new-deployment.sql
```
That is the only script needed. It creates everything: tables, rules, views,
triggers, indexes — all idempotent and adapted to 13.0.6.
### Existing 0.11.6 database being upgraded to 13.0.6
Run **all three** in this order:
```
psql -f prosody-13-rules-triggers.sql # 1. Replace changed rules/views/triggers
psql -f prosody-13-migration-once.sql # 2. Backfill derived tables from new layout
```
The legacy scripts (`prosody-queries-noowner.sql`, `prosody-trigger-noowner.sql`)
must have already been applied to the database under 0.11.6 — they created the
derived tables and the majority of rules/triggers that are unaffected by the
storage change. `prosody-13-rules-triggers.sql` only overwrites the objects that
changed; `prosody-13-migration-once.sql` reconciles the data.
If the legacy scripts were never applied (unlikely for an existing 0.11.6
database), run them first, then the two 13.0 scripts above.
### Re-running / drift correction
All 13.0 scripts are safe to re-run (idempotent). The legacy scripts are **not**
idempotent and must not be re-run on a database that already has the objects.
## What changed between 0.11.6 and 13.0.6
Under 0.11.6, MUC affiliations were stored as a single JSON blob in one row
(`key='_affiliations'`, value = JSON object of JID → affiliation). Under 13.0.6,
each affiliation is a separate row (`key=<bare-jid>`, `value=<affiliation>`).
The `_occupants` key (used for live occupant/nickname tracking) no longer exists
in the DB.
This affected:
- `room_membership` view — rewritten to read per-row affiliations instead of
`jsonb_object_keys`.
- `room_nicknames` view — dropped (depended on `_occupants`).
- `update_room_nick_jid_map` rule — dropped; replaced by a trigger on the
`_data` row that rebuilds `room_nick_jid_map` from affiliations.
- `update_group_owners` rule — replaced by a trigger (the old rule conflicted
with the `upsert_group_owners` INSTEAD rule).