What Database Technologies Are Used by Meetily? SQLite and SQLx Explained
Meetily stores all persistent data in an embedded SQLite database and interacts with it exclusively through the async Rust ORM sqlx, keeping every meeting record local and offline.
Zackriya-Solutions/meetily is a privacy-first meeting assistant that keeps all data on the user's machine. The database technologies used by Meetily center on a lightweight pairing of SQLite for file-based storage and SQLx for type-safe async queries.
The Core Database Technologies Behind Meetily
SQLite: The Local Relational Engine
Meetily persists every meeting, transcript, summary, and setting into a single SQLite file named meeting_minutes.sqlite. Because SQLite is a serverless, file-based database engine, Meetily never contacts an external database server. The entire data layer lives inside the user's application-data directory, making the app fully offline-first.
SQLx: Compile-Time Checked Async ORM
All database interactions flow through sqlx version 0.8 with the features runtime-tokio, sqlite, and chrono enabled. According to the frontend/src-tauri/Cargo.toml manifest, this setup provides async connection pooling via SqlitePool, compile-time-checked queries, and built-in migration support. The DatabaseManager type in the source code wraps these capabilities into a reusable interface.
Initializing the Database on App Startup
When the Tauri application launches, initialize_database_on_startup in frontend/src-tauri/src/database/setup.rs decides whether this is the user's first run or a normal startup. If it is not the first launch, the function creates a DatabaseManager and injects it into the shared application state.
// src/database/setup.rs
pub async fn initialize_database_on_startup(app: &AppHandle) -> Result<(), String> {
// Detect first launch → emit event or initialise immediately
let is_first_launch = DatabaseManager::is_first_launch(app).await?;
if is_first_launch {
// First‑run path – UI can show onboarding
} else {
// Normal start – create manager and inject into shared state
let db_manager = DatabaseManager::new_from_app_handle(app)
.await
.map_err(|e| format!("Failed to init DB: {}", e))?;
app.manage(AppState { db_manager });
}
Ok(())
}
This pattern ensures that the SQLite file is ready before any UI component attempts to query data.
Creating the SQLite File and Running Migrations
The DatabaseManager::new function in frontend/src-tauri/src/database/manager.rs handles the physical database file. It creates the parent directory if needed, copies an existing database or creates a new one with Sqlite::create_database, connects a SqlitePool, and then applies migrations.
// src/database/manager.rs
pub async fn new(tauri_db_path: &str, backend_db_path: &str) -> Result<Self> {
// Ensure parent directory exists
if let Some(parent) = Path::new(tauri_db_path).parent() {
fs::create_dir_all(parent)?;
}
// Create or copy the DB file
if !Path::new(tauri_db_path).exists() {
if Path::new(backend_db_path).exists() {
fs::copy(backend_db_path, tauri_db_path)?;
} else {
Sqlite::create_database(tauri_db_path).await?;
}
}
// Build a connection pool and run migrations
let pool = SqlitePool::connect(tauri_db_path).await?;
sqlx::migrate!("./migrations").run(&pool).await?;
Ok(DatabaseManager { pool })
}
Migrations live in frontend/src-tauri/migrations and are referenced by the macro sqlx::migrate!("./migrations"). This guarantees that schema changes stay up-to-date across releases.
Querying Meeting Data with SQLx
Actual CRUD operations are performed in modules like frontend/src-tauri/src/database/commands.rs. The following simplified example shows how Meetily fetches every meeting record using sqlx::query_as and maps rows to a MeetingModel struct.
// src/database/commands.rs (simplified)
pub async fn get_all_meetings(db: &DatabaseManager) -> Result<Vec<MeetingModel>> {
sqlx::query_as::<_, MeetingModel>("SELECT * FROM meeting")
.fetch_all(db.pool())
.await
}
The MeetingModel type is defined in frontend/src-tauri/src/database/models.rs alongside other #[derive(sqlx::FromRow)] structs such as Transcript and SummaryProcess. Repository-specific logic is further organized under frontend/src-tauri/src/database/repositories/.
Key Source Files in Meetily's Database Layer
frontend/src-tauri/Cargo.toml— Declares thesqlxdependency with thesqlitefeature.frontend/src-tauri/src/database/mod.rs— Re-exports the database submodules for the rest of the application.frontend/src-tauri/src/database/manager.rs— Contains theDatabaseManagerstruct that manages theSqlitePooland migrations.frontend/src-tauri/src/database/setup.rs— Boots the database on startup and detects first-launch scenarios.frontend/src-tauri/src/database/models.rs— Definessqlx::FromRowstructs that map SQLite tables to Rust types.frontend/src-tauri/src/database/commands.rs— Provides high-level async functions for CRUD operations.frontend/src-tauri/src/database/repositories/*— Implements the repository pattern for entities like meetings and transcripts.frontend/src-tauri/migrations/— Holds SQL migration scripts applied automatically at runtime.
Summary
- Meetily relies on an embedded SQLite database stored in a local
meeting_minutes.sqlitefile. - The SQLx async ORM handles all queries, pooling, and migrations via
SqlitePool. - The
DatabaseManagertype inmanager.rscreates the database file, establishes the pool, and runssqlx::migrate!on startup. - All meeting data stays on the user's machine because Meetily never connects to an external database server.
Frequently Asked Questions
Does Meetily use PostgreSQL or MySQL?
No. Meetily uses only SQLite as implemented in the project source code. The sqlx crate is compiled with the sqlite feature alone, and the application is intentionally designed to remain offline-first without external database servers.
Where is the Meetily database file stored on disk?
The SQLite file is named meeting_minutes.sqlite and resides in the user's application-data directory. The exact path is determined at runtime by the DatabaseManager and passed as tauri_db_path in frontend/src-tauri/src/database/manager.rs.
How does Meetily handle database schema changes?
Schema changes are managed through versioned SQL migration scripts stored in frontend/src-tauri/migrations. The DatabaseManager automatically executes sqlx::migrate!("./migrations").run(&pool) whenever the application starts, ensuring the schema is current.
What Rust crate does Meetily use for database access?
Meetily uses sqlx version 0.8 with the runtime-tokio, sqlite, and chrono features. This crate provides the SqlitePool, compile-time query checking, and migration runner that power the entire data layer.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →