fix: always apply database schema on startup

Previously, the application only applied the schema if auth.users table
didn't exist. This caused issues when upgrading - new schema elements
(like storage.trash_items view) weren't created on existing databases.

Now the schema is applied on every startup. Since schema.sql uses
'IF NOT EXISTS' and 'CREATE OR REPLACE', it's safe to run repeatedly.
This commit is contained in:
George Wu
2026-02-18 17:56:06 -08:00
parent 4168e259a5
commit d782d8469c
+10 -30
View File
@@ -1,6 +1,6 @@
use crate::common::config::AppConfig; use crate::common::config::AppConfig;
use anyhow::Result; use anyhow::Result;
use sqlx::{PgPool, Row, postgres::PgPoolOptions}; use sqlx::{PgPool, postgres::PgPoolOptions};
use std::time::Duration; use std::time::Duration;
pub async fn create_database_pool(config: &AppConfig) -> Result<PgPool> { pub async fn create_database_pool(config: &AppConfig) -> Result<PgPool> {
@@ -37,25 +37,16 @@ pub async fn create_database_pool(config: &AppConfig) -> Result<PgPool> {
Ok(_) => { Ok(_) => {
tracing::info!("PostgreSQL connection established successfully"); tracing::info!("PostgreSQL connection established successfully");
if !tables_exist(&pool).await { // Always apply schema - it's idempotent (uses IF NOT EXISTS and CREATE OR REPLACE)
tracing::warn!("Database tables do not exist. Auto-applying schema..."); tracing::info!("Applying database schema...");
if let Err(e) = apply_schema(&pool).await { if let Err(e) = apply_schema(&pool).await {
return Err(anyhow::anyhow!( return Err(anyhow::anyhow!(
"Database schema could not be applied: {}. \ "Database schema could not be applied: {}. \
Run manually: psql -f db/schema.sql", Run manually: psql -f db/schema.sql",
e e
)); ));
}
// Verify tables were actually created
if !tables_exist(&pool).await {
return Err(anyhow::anyhow!(
"Database schema was applied but tables still missing. \
Check db/schema.sql for errors."
));
}
tracing::info!("Database schema applied and verified successfully");
} }
tracing::info!("Database schema applied successfully");
return Ok(pool); return Ok(pool);
} }
@@ -91,17 +82,6 @@ pub async fn create_database_pool(config: &AppConfig) -> Result<PgPool> {
)) ))
} }
/// Check whether the core auth tables exist in the database.
async fn tables_exist(pool: &PgPool) -> bool {
sqlx::query(
"SELECT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'auth' AND tablename = 'users')",
)
.fetch_one(pool)
.await
.map(|row| row.get::<bool, _>(0))
.unwrap_or(false)
}
/// Apply the embedded schema.sql to the database. /// Apply the embedded schema.sql to the database.
/// First tries `raw_sql` (simple query protocol). If that fails, falls back /// First tries `raw_sql` (simple query protocol). If that fails, falls back
/// to splitting the SQL into individual statements and executing them one by one. /// to splitting the SQL into individual statements and executing them one by one.