Database
Rejoice provides optional SQLite support via sqlx.
Quick Setup
rejoice init my-app --with-db
This creates an AppState with a connection pool, .env with DATABASE_URL, and an empty .db file.
Manual Setup
Enable the feature in Cargo.toml:
[dependencies]
rejoice = { version = "0.12.0", features = ["sqlite"] }
Create .env:
DATABASE_URL=sqlite:./my-app.db
Configure your app:
use std::time::Duration;
use rejoice::{App, db::{Pool, PoolConfig, Sqlite, create_pool}};
rejoice::routes!(AppState);
#[derive(Clone)]
pub struct AppState {
pub db: Pool<Sqlite>,
}
#[tokio::main]
async fn main() {
let pool = create_pool(PoolConfig {
db_url: rejoice::env!("DATABASE_URL").to_string(),
max_connections: 5,
acquire_timeout: Duration::from_secs(3),
idle_timeout: Duration::from_secs(60),
max_lifetime: Duration::from_secs(1800),
}).await;
let state = AppState { db: pool };
let app = App::with_state(8080, create_router(), state);
app.run().await;
}
Queries
use rejoice::{Req, Res, html, db::{query, query_as, query_scalar, FromRow}};
#[derive(FromRow)]
struct User { id: i32, name: String }
pub async fn get(state: AppState, req: Req, res: Res) -> Res {
// Typed query
let users: Vec<User> = query_as("SELECT id, name FROM users")
.fetch_all(&state.db)
.await
.unwrap();
// With parameters
let user: Option<User> = query_as("SELECT * FROM users WHERE id = ?")
.bind(123)
.fetch_optional(&state.db)
.await
.unwrap();
// Scalar query (for COUNT, MAX, single values)
let count: i32 = query_scalar("SELECT COUNT(*) FROM users")
.fetch_one(&state.db)
.await
.unwrap();
// Insert/update/delete
query("INSERT INTO users (name) VALUES (?)")
.bind("Alice")
.execute(&state.db)
.await
.unwrap();
res.html(html! { /* ... */ })
}
Migrations
Rejoice provides a convenient CLI for managing database migrations.
Creating Migrations
rejoice migrate add create_users_table
This creates two files in migrations/:
<timestamp>_create_users_table.up.sql- SQL to apply the migration<timestamp>_create_users_table.down.sql- SQL to revert the migration
Running Migrations
# Apply all pending migrations
rejoice migrate up
# Revert the last migration
rejoice migrate revert
# Check migration status
rejoice migrate status
Example Migration
migrations/20250117000000_create_users_table.up.sql:
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
migrations/20250117000000_create_users_table.down.sql:
DROP TABLE users;
For complete sqlx documentation, see docs.rs/sqlx.