v0.2.15
RustBox CI / rustbox (push) Canceled after 0s

This commit is contained in:
Mateusz Gruszczyński committed 2026-11-02 23:13:21 +01:00
1 parent fb9eab87eb
commit d91212d24c
40 files changed
+585 -380

No files matched your search

+11 -26
View File
@@ -1,6 +1,6 @@
# Database schemas and migrations
RustBox 0.2.15 keeps SQL, blob storage and search as independent concerns:
RustBox keeps SQL, blob storage and search as independent concerns.
```text
database_backend = sqlite | mysql | pgsql
@@ -9,41 +9,26 @@ storage.backend = filesystem | s3
search.backend = disabled | local_tantivy | opensearch
```
When `session_backend = "database"`, sessions live in the selected SQL database. `session_backend = "redis"` moves only session persistence to Redis/Redis Sentinel.
## Layout
```text
migrations/
├── sqlite/
│ ├── schema.sql
│ ├── V047__blob_keys_and_search_outbox.sql
│ ├── V048__folder_counter_generation.sql
│ ├── V049__blob_delete_outbox.sql
│ └── V050__compact_rows_and_signature_mode.sql
├── mysql/
│ ├── schema.sql
│ ├── V047__blob_keys_and_search_outbox.sql
│ ├── V048__folder_counter_generation.sql
│ ├── V049__blob_delete_outbox.sql
│ └── V050__compact_rows_and_signature_mode.sql
└── pgsql/
├── schema.sql
├── V047__blob_keys_and_search_outbox.sql
├── V048__folder_counter_generation.sql
├── V049__blob_delete_outbox.sql
└── V050__compact_rows_and_signature_mode.sql
├── sqlite/schema.sql
├── mysql/schema.sql
└── pgsql/schema.sql
```
Each `schema.sql` is the current complete schema for fresh installations. The historical compatibility baseline remains **V046**. RustBox 0.2.1 adds **V047**, which adds attachment SHA-256 metadata and the durable search outbox used by external indexing. RustBox 0.2.8 adds **V048**, which adds the monotonic `folders.counter_generation` used to reject stale IMAP counter writes even when the numeric counts temporarily return to an earlier value. RustBox 0.2.13 adds **V049**, the durable `blob_delete_outbox` used to retry physical object deletion after metadata is removed. RustBox 0.2.14 adds **V050**, which stores the default-on compact wide-row preference and each identity's signature insertion mode (`silent` or `visible`).
Each `schema.sql` is the complete V050 schema for fresh installations. Migrations V047-V049 have been consolidated into the **V049 compatibility baseline** and their standalone files are intentionally removed. V050 remains the single runtime migration. Because RustBox 0.2.15 has not been released yet, V050 includes `mail_preferences.compact_wide_rows`, `identities.signature_insert_mode`, `display_preferences.adaptive_email_colors` and `mail_preferences.message_loading_mode`.
Account data is isolated inside the selected physical database with a deterministic, collision-checked table prefix derived from the account hash. The `{{p}}` marker in tenant SQL is replaced by RustBox at provisioning/migration time. Sessions are global and therefore are not prefixed.
`mail_preferences.message_loading_mode` defaults to `pagination`; `messages_per_page` defaults to 300. Supported modes are `pagination`, `progressive` and `all`.
Databases older than **V049** are no longer migrated directly by this build. Upgrade them to schema V049 first; this build then applies V050. **V051** is the next migration number after this snapshot.
Account data is isolated inside the selected physical database with a deterministic, collision-checked table prefix derived from the account hash. The `{{p}}` marker in tenant SQL is replaced by RustBox at provisioning time. Sessions are global and therefore are not prefixed.
## Runtime migrations
Every schema-changing release must add the same logical migration for all supported SQL engines and register it in `src/db/pool.rs`. Do not update only `schema.sql`: fresh installs use the baseline while existing installations use the numbered migration path.
RustBox 0.2.14 adds runtime migration **V050** on SQLite, MySQL and PostgreSQL. **V051** is the next migration number.
V050 is the only runtime migration in this unreleased snapshot. Future schema-changing releases must add the same logical migration for SQLite, MySQL and PostgreSQL and register it in `src/db/pool.rs`.
Redis and Redis Sentinel do not use SQL migrations.
@@ -1,18 +0,0 @@
ALTER TABLE {{p}}draft_attachments ADD COLUMN checksum_sha256 VARCHAR(64) NULL;
CREATE TABLE {{p}}search_outbox (
id VARCHAR(64) PRIMARY KEY,
generation VARCHAR(64) NOT NULL,
event_type VARCHAR(16) NOT NULL,
message_uid BIGINT NOT NULL,
folder TEXT NOT NULL,
payload LONGTEXT NULL,
attempts BIGINT NOT NULL DEFAULT 0,
available_at BIGINT NOT NULL DEFAULT 0,
claimed_until BIGINT NOT NULL DEFAULT 0,
dead_letter BIGINT NOT NULL DEFAULT 0,
last_error TEXT NULL,
created_at BIGINT NOT NULL,
updated_at BIGINT NOT NULL,
INDEX idx_search_outbox_ready (dead_letter, available_at, claimed_until, updated_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -1 +0,0 @@
ALTER TABLE {{p}}folders ADD COLUMN counter_generation BIGINT NOT NULL DEFAULT 0;
@@ -1,11 +0,0 @@
CREATE TABLE {{p}}blob_delete_outbox (
id VARCHAR(64) PRIMARY KEY,
storage_key TEXT NOT NULL,
attempts BIGINT NOT NULL DEFAULT 0,
available_at BIGINT NOT NULL DEFAULT 0,
claimed_until BIGINT NOT NULL DEFAULT 0,
last_error TEXT NULL,
created_at BIGINT NOT NULL,
updated_at BIGINT NOT NULL,
INDEX idx_blob_delete_outbox_ready (available_at, claimed_until, updated_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -1,3 +1,9 @@
ALTER TABLE {{p}}display_preferences
ADD COLUMN adaptive_email_colors BIGINT NOT NULL DEFAULT 0;
ALTER TABLE {{p}}mail_preferences
ADD COLUMN message_loading_mode TEXT NOT NULL DEFAULT 'pagination';
ALTER TABLE {{p}}mail_preferences
ADD COLUMN compact_wide_rows BIGINT NOT NULL DEFAULT 1;
+5 -3
View File
@@ -1,13 +1,13 @@
-- RustBox 0.2.0 MySQL schema.
-- One physical database contains global sessions plus isolated per-account tables.
-- Application tables are materialized by replacing {{p}} with a collision-checked prefix.
-- Squashed compatibility baseline: V046. Current runtime schema: V050.
-- Squashed compatibility baseline: V049. Current schema: V050.
-- RUSTBOX:GLOBAL-BEGIN
CREATE TABLE IF NOT EXISTS rustbox_accounts (
user_hash VARCHAR(128) PRIMARY KEY,
table_prefix VARCHAR(64) NOT NULL UNIQUE,
schema_version BIGINT NOT NULL DEFAULT 46,
schema_version BIGINT NOT NULL DEFAULT 50,
created_at VARCHAR(64) NOT NULL DEFAULT (CAST(CURRENT_TIMESTAMP AS CHAR)),
updated_at VARCHAR(64) NOT NULL DEFAULT (CAST(CURRENT_TIMESTAMP AS CHAR))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -176,7 +176,8 @@ CREATE TABLE {{p}}display_preferences (
forward_mode TEXT NOT NULL DEFAULT ('inline'),
spellcheck_enabled BIGINT NOT NULL DEFAULT 1,
interface_skin TEXT NOT NULL DEFAULT ('rustbox'),
preset_scale_unlocked BIGINT NOT NULL DEFAULT 0
preset_scale_unlocked BIGINT NOT NULL DEFAULT 0,
adaptive_email_colors BIGINT NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE {{p}}draft_attachments (
@@ -296,6 +297,7 @@ CREATE TABLE {{p}}known_addresses (
CREATE TABLE {{p}}mail_preferences (
id BIGINT PRIMARY KEY,
messages_per_page BIGINT NOT NULL DEFAULT 300,
message_loading_mode TEXT NOT NULL DEFAULT 'pagination',
mark_read_delay_ms BIGINT NOT NULL DEFAULT 0,
remote_images TEXT NOT NULL DEFAULT ('ask'),
preferred_body TEXT NOT NULL DEFAULT ('auto'),
@@ -1,20 +0,0 @@
ALTER TABLE {{p}}draft_attachments ADD COLUMN checksum_sha256 TEXT;
CREATE TABLE {{p}}search_outbox (
id TEXT PRIMARY KEY,
generation TEXT NOT NULL,
event_type TEXT NOT NULL,
message_uid BIGINT NOT NULL,
folder TEXT NOT NULL,
payload TEXT,
attempts BIGINT NOT NULL DEFAULT 0,
available_at BIGINT NOT NULL DEFAULT 0,
claimed_until BIGINT NOT NULL DEFAULT 0,
dead_letter BIGINT NOT NULL DEFAULT 0,
last_error TEXT,
created_at BIGINT NOT NULL,
updated_at BIGINT NOT NULL
);
CREATE INDEX {{p}}idx_search_outbox_ready
ON {{p}}search_outbox(dead_letter, available_at, claimed_until, updated_at);
@@ -1 +0,0 @@
ALTER TABLE {{p}}folders ADD COLUMN counter_generation BIGINT NOT NULL DEFAULT 0;
@@ -1,13 +0,0 @@
CREATE TABLE {{p}}blob_delete_outbox (
id TEXT PRIMARY KEY,
storage_key TEXT NOT NULL,
attempts BIGINT NOT NULL DEFAULT 0,
available_at BIGINT NOT NULL DEFAULT 0,
claimed_until BIGINT NOT NULL DEFAULT 0,
last_error TEXT,
created_at BIGINT NOT NULL,
updated_at BIGINT NOT NULL
);
CREATE INDEX {{p}}idx_blob_delete_outbox_ready
ON {{p}}blob_delete_outbox(available_at, claimed_until, updated_at);
@@ -1,3 +1,9 @@
ALTER TABLE {{p}}display_preferences
ADD COLUMN adaptive_email_colors BIGINT NOT NULL DEFAULT 0;
ALTER TABLE {{p}}mail_preferences
ADD COLUMN message_loading_mode TEXT NOT NULL DEFAULT 'pagination';
ALTER TABLE {{p}}mail_preferences
ADD COLUMN compact_wide_rows BIGINT NOT NULL DEFAULT 1;
+5 -3
View File
@@ -1,13 +1,13 @@
-- RustBox 0.2.0 PostgreSQL schema.
-- One physical database contains global sessions plus isolated per-account tables.
-- Application tables are materialized by replacing {{p}} with a collision-checked prefix.
-- Squashed compatibility baseline: V046. Current runtime schema: V050.
-- Squashed compatibility baseline: V049. Current schema: V050.
-- RUSTBOX:GLOBAL-BEGIN
CREATE TABLE IF NOT EXISTS rustbox_accounts (
user_hash VARCHAR(128) PRIMARY KEY,
table_prefix VARCHAR(64) NOT NULL UNIQUE,
schema_version BIGINT NOT NULL DEFAULT 46,
schema_version BIGINT NOT NULL DEFAULT 50,
created_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP::text),
updated_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP::text)
);
@@ -176,7 +176,8 @@ CREATE TABLE {{p}}display_preferences (
forward_mode TEXT NOT NULL DEFAULT 'inline',
spellcheck_enabled BIGINT NOT NULL DEFAULT 1,
interface_skin TEXT NOT NULL DEFAULT 'rustbox',
preset_scale_unlocked BIGINT NOT NULL DEFAULT 0
preset_scale_unlocked BIGINT NOT NULL DEFAULT 0,
adaptive_email_colors BIGINT NOT NULL DEFAULT 0
);
CREATE TABLE {{p}}draft_attachments (
@@ -298,6 +299,7 @@ CREATE TABLE {{p}}known_addresses (
CREATE TABLE {{p}}mail_preferences (
id BIGINT PRIMARY KEY,
messages_per_page BIGINT NOT NULL DEFAULT 300,
message_loading_mode TEXT NOT NULL DEFAULT 'pagination',
mark_read_delay_ms BIGINT NOT NULL DEFAULT 0,
remote_images TEXT NOT NULL DEFAULT 'ask',
preferred_body TEXT NOT NULL DEFAULT 'auto',
@@ -1,20 +0,0 @@
ALTER TABLE {{p}}draft_attachments ADD COLUMN checksum_sha256 TEXT;
CREATE TABLE {{p}}search_outbox (
id TEXT PRIMARY KEY,
generation TEXT NOT NULL,
event_type TEXT NOT NULL,
message_uid INTEGER NOT NULL,
folder TEXT NOT NULL,
payload TEXT,
attempts INTEGER NOT NULL DEFAULT 0,
available_at INTEGER NOT NULL DEFAULT 0,
claimed_until INTEGER NOT NULL DEFAULT 0,
dead_letter INTEGER NOT NULL DEFAULT 0,
last_error TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE INDEX {{p}}idx_search_outbox_ready
ON {{p}}search_outbox(dead_letter, available_at, claimed_until, updated_at);
@@ -1 +0,0 @@
ALTER TABLE {{p}}folders ADD COLUMN counter_generation INTEGER NOT NULL DEFAULT 0;
@@ -1,13 +0,0 @@
CREATE TABLE {{p}}blob_delete_outbox (
id TEXT PRIMARY KEY,
storage_key TEXT NOT NULL,
attempts INTEGER NOT NULL DEFAULT 0,
available_at INTEGER NOT NULL DEFAULT 0,
claimed_until INTEGER NOT NULL DEFAULT 0,
last_error TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
CREATE INDEX {{p}}idx_blob_delete_outbox_ready
ON {{p}}blob_delete_outbox(available_at, claimed_until, updated_at);
@@ -1,3 +1,9 @@
ALTER TABLE {{p}}display_preferences
ADD COLUMN adaptive_email_colors INTEGER NOT NULL DEFAULT 0;
ALTER TABLE {{p}}mail_preferences
ADD COLUMN message_loading_mode TEXT NOT NULL DEFAULT 'pagination';
ALTER TABLE {{p}}mail_preferences
ADD COLUMN compact_wide_rows INTEGER NOT NULL DEFAULT 1;
+4 -3
View File
@@ -1,13 +1,13 @@
-- RustBox 0.2.0 SQLite schema.
-- One physical database contains global sessions plus isolated per-account tables.
-- Application tables are materialized from the tenant section by replacing {{p}}.
-- Squashed compatibility baseline: V046. Current runtime schema: V050.
-- Squashed compatibility baseline: V049. Current schema: V050.
-- RUSTBOX:GLOBAL-BEGIN
CREATE TABLE IF NOT EXISTS rustbox_accounts (
user_hash TEXT PRIMARY KEY NOT NULL,
table_prefix TEXT NOT NULL UNIQUE,
schema_version INTEGER NOT NULL DEFAULT 46,
schema_version INTEGER NOT NULL DEFAULT 50,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
@@ -122,7 +122,7 @@ CREATE TABLE {{p}}display_preferences (
theme TEXT NOT NULL DEFAULT 'system',
language TEXT NOT NULL DEFAULT 'en',
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
compose_format TEXT NOT NULL DEFAULT 'html', deep_index BOOLEAN NOT NULL DEFAULT 0, animation_mode TEXT NULL, preview_pane TEXT NOT NULL DEFAULT 'right', ui_scale TEXT NOT NULL DEFAULT 'normal', color_preset TEXT NOT NULL DEFAULT 'sage', accent_color TEXT NOT NULL DEFAULT '#6f9c86', font_family TEXT NOT NULL DEFAULT 'system', font_size INTEGER NOT NULL DEFAULT 13, row_height INTEGER NOT NULL DEFAULT 58, folder_pane_width INTEGER NOT NULL DEFAULT 228, message_pane_width INTEGER NOT NULL DEFAULT 420, border_radius INTEGER NOT NULL DEFAULT 4, contrast TEXT NOT NULL DEFAULT 'normal', show_avatars INTEGER NOT NULL DEFAULT 1, show_attachment_icons INTEGER NOT NULL DEFAULT 1, show_flags INTEGER NOT NULL DEFAULT 1, reduce_motion INTEGER NOT NULL DEFAULT 0, date_format TEXT NOT NULL DEFAULT 'locale', time_format TEXT NOT NULL DEFAULT 'locale', background_color TEXT NOT NULL DEFAULT '#121513', panel_color TEXT NOT NULL DEFAULT '#181c19', text_color TEXT NOT NULL DEFAULT '#edf0ec', compose_autosave_ms INTEGER NOT NULL DEFAULT 3000, default_priority TEXT NOT NULL DEFAULT 'normal', request_mdn_default INTEGER NOT NULL DEFAULT 0, attachment_reminder INTEGER NOT NULL DEFAULT 1, icon_size INTEGER NOT NULL DEFAULT 18, toolbar_density TEXT NOT NULL DEFAULT 'normal', sidebar_item_height INTEGER NOT NULL DEFAULT 29, reader_max_width INTEGER NOT NULL DEFAULT 0, composer_width INTEGER NOT NULL DEFAULT 900, selection_color TEXT NOT NULL DEFAULT '#28352e', unread_font_weight INTEGER NOT NULL DEFAULT 730, unread_badge_style TEXT NOT NULL DEFAULT 'dot', compact_headers INTEGER NOT NULL DEFAULT 0, show_borders INTEGER NOT NULL DEFAULT 1, scrollbar_density TEXT NOT NULL DEFAULT 'thin', monochrome INTEGER NOT NULL DEFAULT 0, folder_background TEXT NOT NULL DEFAULT '', message_background TEXT NOT NULL DEFAULT '', reader_background TEXT NOT NULL DEFAULT '', compose_font_family TEXT NOT NULL DEFAULT 'system', reply_position TEXT NOT NULL DEFAULT 'above', quote_style TEXT NOT NULL DEFAULT 'standard', forward_mode TEXT NOT NULL DEFAULT 'inline', spellcheck_enabled INTEGER NOT NULL DEFAULT 1, interface_skin TEXT NOT NULL DEFAULT 'rustbox', preset_scale_unlocked INTEGER NOT NULL DEFAULT 0);
compose_format TEXT NOT NULL DEFAULT 'html', deep_index BOOLEAN NOT NULL DEFAULT 0, animation_mode TEXT NULL, preview_pane TEXT NOT NULL DEFAULT 'right', ui_scale TEXT NOT NULL DEFAULT 'normal', color_preset TEXT NOT NULL DEFAULT 'sage', accent_color TEXT NOT NULL DEFAULT '#6f9c86', font_family TEXT NOT NULL DEFAULT 'system', font_size INTEGER NOT NULL DEFAULT 13, row_height INTEGER NOT NULL DEFAULT 58, folder_pane_width INTEGER NOT NULL DEFAULT 228, message_pane_width INTEGER NOT NULL DEFAULT 420, border_radius INTEGER NOT NULL DEFAULT 4, contrast TEXT NOT NULL DEFAULT 'normal', show_avatars INTEGER NOT NULL DEFAULT 1, show_attachment_icons INTEGER NOT NULL DEFAULT 1, show_flags INTEGER NOT NULL DEFAULT 1, reduce_motion INTEGER NOT NULL DEFAULT 0, date_format TEXT NOT NULL DEFAULT 'locale', time_format TEXT NOT NULL DEFAULT 'locale', background_color TEXT NOT NULL DEFAULT '#121513', panel_color TEXT NOT NULL DEFAULT '#181c19', text_color TEXT NOT NULL DEFAULT '#edf0ec', compose_autosave_ms INTEGER NOT NULL DEFAULT 3000, default_priority TEXT NOT NULL DEFAULT 'normal', request_mdn_default INTEGER NOT NULL DEFAULT 0, attachment_reminder INTEGER NOT NULL DEFAULT 1, icon_size INTEGER NOT NULL DEFAULT 18, toolbar_density TEXT NOT NULL DEFAULT 'normal', sidebar_item_height INTEGER NOT NULL DEFAULT 29, reader_max_width INTEGER NOT NULL DEFAULT 0, composer_width INTEGER NOT NULL DEFAULT 900, selection_color TEXT NOT NULL DEFAULT '#28352e', unread_font_weight INTEGER NOT NULL DEFAULT 730, unread_badge_style TEXT NOT NULL DEFAULT 'dot', compact_headers INTEGER NOT NULL DEFAULT 0, show_borders INTEGER NOT NULL DEFAULT 1, scrollbar_density TEXT NOT NULL DEFAULT 'thin', monochrome INTEGER NOT NULL DEFAULT 0, folder_background TEXT NOT NULL DEFAULT '', message_background TEXT NOT NULL DEFAULT '', reader_background TEXT NOT NULL DEFAULT '', compose_font_family TEXT NOT NULL DEFAULT 'system', reply_position TEXT NOT NULL DEFAULT 'above', quote_style TEXT NOT NULL DEFAULT 'standard', forward_mode TEXT NOT NULL DEFAULT 'inline', spellcheck_enabled INTEGER NOT NULL DEFAULT 1, interface_skin TEXT NOT NULL DEFAULT 'rustbox', preset_scale_unlocked INTEGER NOT NULL DEFAULT 0, adaptive_email_colors INTEGER NOT NULL DEFAULT 0);
CREATE TABLE {{p}}draft_attachments (
id TEXT PRIMARY KEY,
@@ -221,6 +221,7 @@ CREATE TABLE {{p}}known_addresses (
CREATE TABLE {{p}}mail_preferences (
id INTEGER PRIMARY KEY CHECK (id = 1),
messages_per_page INTEGER NOT NULL DEFAULT 300,
message_loading_mode TEXT NOT NULL DEFAULT 'pagination',
mark_read_delay_ms INTEGER NOT NULL DEFAULT 0,
remote_images TEXT NOT NULL DEFAULT 'ask',
preferred_body TEXT NOT NULL DEFAULT 'auto',