Overview
pwr-bot uses SQLite as its database with SQLx for type-safe, compile-time verified SQL queries. All schema changes are managed through migrations.Database Schema
Feeds
Stores feed metadata for subscriptions.platform_id+source_id- Unique identifier across platformsitems_id- Used to fetch latest items from the platformtags- Comma-separated tags for categorization
Feed Items
Stores the history of feed updates.Subscribers
Represents entities that can subscribe to feeds.dm- Direct message to a user (target_id = user_id)guild- Guild channel (target_id = guild_id)
Feed Subscriptions
Junction table for many-to-many relationship between feeds and subscribers.Voice Sessions
Tracks user voice channel activity.migrations/20260105094744_add_voice_sessions.up.sql
Key features:
is_active- Tracks currently active sessions for crash recoveryleave_time- Updated when user leaves or bot shuts down gracefully- Unique constraint prevents duplicate session records
Server Settings
Stores per-guild configuration.migrations/20251229162924_add_server_settings.up.sql
Settings format:
Bot Meta
Internal metadata for the bot.migrations/20260220074756_add_bot_meta.up.sql
Usage: Store bot startup time, version info, and crash recovery data.
SQLx Usage
Type-Safe Queries
SQLx provides compile-time verification of SQL queries:Query Macros
The codebase uses theimpl_table! macro to generate CRUD operations:
Location: src/repository/table.rs:130-247
select_all()- Get all recordsselect(id)- Get by IDinsert(model)- Insert new recordupdate(model)- Update existing recorddelete(id)- Delete by IDreplace(model)- Insert or replace
Custom Queries
Complex queries are implemented as table methods:src/repository/table.rs:564-596
Parameter Binding
TheBindParam trait handles SQLite type conversions:
src/repository/table.rs:56-128
Creating Migrations
Generate Migration
Use SQLx CLI to create a new migration:migrations/<timestamp>_add_feed_tags.up.sql- Apply changesmigrations/<timestamp>_add_feed_tags.down.sql- Revert changes
Writing Migrations
Write DOWN migration
Define how to revert the changes:
SQLite has limited ALTER TABLE support. You may need to recreate tables.
Migration Best Practices
Make migrations reversible
Make migrations reversible
Always write proper DOWN migrations. This allows rollback if issues occur in production.
Use transactions
Use transactions
Wrap complex migrations in transactions:
Preserve data
Preserve data
When modifying tables, preserve existing data:
Add indexes for queries
Add indexes for queries
Create indexes for frequently queried columns:
Complex Migration Example
The server settings migration demonstrates data transformation: Migration:migrations/20251229162924_add_server_settings.up.sql
Running Migrations
Manual Execution
Automatic on Startup
The bot runs migrations automatically: Location:src/main.rs:94-96
Offline Mode
SQLx supports offline compilation using prepared query metadata:Prepare Queries
CI/CD Usage
In CI environments, set:Entity Models
Database entities use Rust structs with SQLx derives:src/entity/
Advanced Queries
Leaderboard Query
Calculates total voice time including active sessions:src/repository/table.rs:696-745
Features:
- Calculates duration for closed sessions
- Uses current time for active sessions
- Supports time range filtering
- Pagination support
Partner Leaderboard
Finds overlapping voice sessions between users: Location:src/repository/table.rs:776-830
Database Maintenance
Vacuum
SQLite benefits from periodic vacuuming:Backup
Create database backups:Troubleshooting
Migration failed
Migration failed
Check migration SQL syntax and rollback:Fix the migration file and re-run.
Compile-time query errors
Compile-time query errors
Regenerate offline query metadata:
Database locked
Database locked
SQLite uses file-based locking. Ensure:
- Only one bot instance is running
- No other process has the database file open
- Check file permissions