diff --git a/src/migrations/00_encoding_contract.lua b/src/migrations/00_encoding_contract.lua new file mode 100644 index 0000000..8d02023 --- /dev/null +++ b/src/migrations/00_encoding_contract.lua @@ -0,0 +1,26 @@ +-- The engine stores text; a Postgres database that is not UTF8 rejects every +-- non-ASCII byte at write time, poisoning whole commit batches long after +-- install. The contract is asserted first and loudly: a misprovisioned +-- database refuses to migrate. SQLite stores byte sequences verbatim. + +return require("migration").define(function() + migration("database encoding is UTF8", function() + database("postgres", function() + up(function(db) + local rows = db:query( + "SELECT pg_encoding_to_char(encoding) AS enc FROM pg_database WHERE datname = current_database()") + local enc = type(rows) == "table" and rows[1] and tostring(rows[1].enc) or "unknown" + if enc ~= "UTF8" then + error("database encoding is " .. enc .. "; dataflow requires UTF8 — " .. + "recreate the database with ENCODING 'UTF8' (TEMPLATE template0) before installing") + end + end) + down(function(_db) end) + end) + + database("sqlite", function() + up(function(_db) end) + down(function(_db) end) + end) + end) +end) diff --git a/src/migrations/_index.yaml b/src/migrations/_index.yaml index 4bc19d4..1fc6aed 100644 --- a/src/migrations/_index.yaml +++ b/src/migrations/_index.yaml @@ -2,6 +2,21 @@ version: "1.0" namespace: userspace.dataflow.migrations entries: + # userspace.dataflow.migrations:00_encoding_contract + - name: 00_encoding_contract + kind: function.lua + meta: + type: migration + tags: [dataflows, encoding, contract] + description: The database encoding contract — Postgres must be UTF8 + depends_on: [ns:wippy.migration] + target_db: app:db + timestamp: "2025-01-01T00:00:00Z" + source: file://00_encoding_contract.lua + imports: + migration: wippy.migration:migration + method: migrate + # userspace.dataflow.migrations:01_create_dataflows_table - name: 01_create_dataflows_table kind: function.lua