From 26b23948ecdd1455244b320e85252560314ca727 Mon Sep 17 00:00:00 2001 From: Bulat Kurbanov Date: Fri, 16 Jan 2026 10:39:51 +0100 Subject: [PATCH] Run SQLx migrations on startup --- Cargo.toml | 2 +- .../20240101000001_create_user_settings.sql | 12 +++++++ .../20240101000002_create_languages.sql | 9 +++++ .../20240101000003_create_user_activity.sql | 22 +++++++++++++ .../20240101000004_create_users_languages.sql | 33 +++++++++++++++++++ ...00005_create_chat_donate_notifications.sql | 9 +++++ src/db.rs | 15 +++++++-- 7 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 migrations/20240101000001_create_user_settings.sql create mode 100644 migrations/20240101000002_create_languages.sql create mode 100644 migrations/20240101000003_create_user_activity.sql create mode 100644 migrations/20240101000004_create_users_languages.sql create mode 100644 migrations/20240101000005_create_chat_donate_notifications.sql diff --git a/Cargo.toml b/Cargo.toml index b95f12c..9181020 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,4 +34,4 @@ tracing-subscriber = { version = "0.3.19", features = ["env-filter"]} sentry-tracing = "0.42.0" tower-http = { version = "0.6.2", features = ["trace"] } -sqlx = { version = "0.8.3", features = ["runtime-tokio", "postgres", "macros", "chrono"] } +sqlx = { version = "0.8.3", features = ["runtime-tokio", "postgres", "macros", "chrono", "migrate"] } diff --git a/migrations/20240101000001_create_user_settings.sql b/migrations/20240101000001_create_user_settings.sql new file mode 100644 index 0000000..275e6e6 --- /dev/null +++ b/migrations/20240101000001_create_user_settings.sql @@ -0,0 +1,12 @@ +-- Create user_settings table +CREATE TABLE IF NOT EXISTS user_settings ( + id SERIAL PRIMARY KEY, + user_id BIGINT NOT NULL UNIQUE, + last_name VARCHAR(64) NOT NULL, + first_name VARCHAR(64) NOT NULL, + username VARCHAR(32) NOT NULL, + source VARCHAR(32) NOT NULL +); + +-- Create unique index on user_id (if not exists from UNIQUE constraint) +CREATE UNIQUE INDEX IF NOT EXISTS user_settings_user_id_key ON user_settings(user_id); diff --git a/migrations/20240101000002_create_languages.sql b/migrations/20240101000002_create_languages.sql new file mode 100644 index 0000000..13d214c --- /dev/null +++ b/migrations/20240101000002_create_languages.sql @@ -0,0 +1,9 @@ +-- Create languages table +CREATE TABLE IF NOT EXISTS languages ( + id SERIAL PRIMARY KEY, + label VARCHAR(16) NOT NULL, + code VARCHAR(4) NOT NULL UNIQUE +); + +-- Create unique index on code (if not exists from UNIQUE constraint) +CREATE UNIQUE INDEX IF NOT EXISTS languages_code_key ON languages(code); diff --git a/migrations/20240101000003_create_user_activity.sql b/migrations/20240101000003_create_user_activity.sql new file mode 100644 index 0000000..e204280 --- /dev/null +++ b/migrations/20240101000003_create_user_activity.sql @@ -0,0 +1,22 @@ +-- Create user_activity table +CREATE TABLE IF NOT EXISTS user_activity ( + id SERIAL PRIMARY KEY, + "user" INTEGER NOT NULL UNIQUE, + updated TIMESTAMP WITHOUT TIME ZONE NOT NULL +); + +-- Create unique index on user (if not exists from UNIQUE constraint) +CREATE UNIQUE INDEX IF NOT EXISTS user_activity_user_key ON user_activity("user"); + +-- Add foreign key constraint if it doesn't exist +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conname = 'fk_user_activity_user_settings_id_user' + ) THEN + ALTER TABLE user_activity + ADD CONSTRAINT fk_user_activity_user_settings_id_user + FOREIGN KEY ("user") REFERENCES user_settings(id); + END IF; +END $$; diff --git a/migrations/20240101000004_create_users_languages.sql b/migrations/20240101000004_create_users_languages.sql new file mode 100644 index 0000000..75e536a --- /dev/null +++ b/migrations/20240101000004_create_users_languages.sql @@ -0,0 +1,33 @@ +-- Create users_languages table +CREATE TABLE IF NOT EXISTS users_languages ( + id SERIAL PRIMARY KEY, + language INTEGER NOT NULL, + "user" INTEGER NOT NULL +); + +-- Add foreign key constraints if they don't exist +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conname = 'fk_users_languages_languages_language_id' + ) THEN + ALTER TABLE users_languages + ADD CONSTRAINT fk_users_languages_languages_language_id + FOREIGN KEY (language) REFERENCES languages(id) + ON UPDATE CASCADE ON DELETE CASCADE; + END IF; +END $$; + +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_constraint + WHERE conname = 'fk_users_languages_user_settings_user_id' + ) THEN + ALTER TABLE users_languages + ADD CONSTRAINT fk_users_languages_user_settings_user_id + FOREIGN KEY ("user") REFERENCES user_settings(id) + ON UPDATE CASCADE ON DELETE CASCADE; + END IF; +END $$; diff --git a/migrations/20240101000005_create_chat_donate_notifications.sql b/migrations/20240101000005_create_chat_donate_notifications.sql new file mode 100644 index 0000000..7535355 --- /dev/null +++ b/migrations/20240101000005_create_chat_donate_notifications.sql @@ -0,0 +1,9 @@ +-- Create chat_donate_notifications table +CREATE TABLE IF NOT EXISTS chat_donate_notifications ( + id BIGSERIAL PRIMARY KEY, + chat_id BIGINT NOT NULL UNIQUE, + sended TIMESTAMP WITHOUT TIME ZONE NOT NULL +); + +-- Create unique index on chat_id (if not exists from UNIQUE constraint) +CREATE UNIQUE INDEX IF NOT EXISTS chat_donate_notifications_chat_id_key ON chat_donate_notifications(chat_id); diff --git a/src/db.rs b/src/db.rs index d66431c..157d0c0 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,6 +1,7 @@ use crate::config::CONFIG; use sqlx::{postgres::PgPoolOptions, PgPool}; +use tracing::info; pub async fn get_postgres_pool() -> PgPool { let database_url: String = format!( @@ -12,10 +13,20 @@ pub async fn get_postgres_pool() -> PgPool { CONFIG.postgres_db ); - PgPoolOptions::new() + let pool = PgPoolOptions::new() .max_connections(10) .acquire_timeout(std::time::Duration::from_secs(300)) .connect(&database_url) .await - .unwrap() + .unwrap(); + + // Run migrations + info!("Running database migrations..."); + sqlx::migrate!("./migrations") + .run(&pool) + .await + .expect("Failed to run migrations"); + info!("Database migrations completed successfully"); + + pool }