mirror of
https://github.com/flibusta-apps/book_library_server.git
synced 2026-03-02 22:55:21 +01:00
Add DB migrations and run them on startup
Enable sqlx "migrate" feature and add SQL migrations to create the database schema: pg_trgm extension, sources, genres, authors, sequences, books, junction tables, annotations, and supporting indexes
This commit is contained in:
@@ -42,4 +42,4 @@ rand = "0.9.0"
|
||||
|
||||
chrono = { version = "0.4.40", features = ["serde"] }
|
||||
|
||||
sqlx = { version = "0.8.3", features = ["runtime-tokio", "postgres", "macros", "chrono", "json"] }
|
||||
sqlx = { version = "0.8.3", features = ["runtime-tokio", "postgres", "macros", "chrono", "json", "migrate"] }
|
||||
|
||||
2
migrations/20260116092202_create_extensions.sql
Normal file
2
migrations/20260116092202_create_extensions.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
-- Create pg_trgm extension for trigram-based text search
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
5
migrations/20260116092203_create_sources_table.sql
Normal file
5
migrations/20260116092203_create_sources_table.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
-- Create sources table
|
||||
CREATE TABLE IF NOT EXISTS sources (
|
||||
id SMALLSERIAL PRIMARY KEY,
|
||||
name VARCHAR(32) NOT NULL UNIQUE
|
||||
);
|
||||
11
migrations/20260116092204_create_genres_table.sql
Normal file
11
migrations/20260116092204_create_genres_table.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- Create genres table
|
||||
CREATE TABLE IF NOT EXISTS genres (
|
||||
id SERIAL PRIMARY KEY,
|
||||
source SMALLINT NOT NULL,
|
||||
remote_id INTEGER NOT NULL,
|
||||
code VARCHAR(45) NOT NULL,
|
||||
description VARCHAR(99) NOT NULL,
|
||||
meta VARCHAR(45) NOT NULL,
|
||||
CONSTRAINT uc_genres_source_remote_id UNIQUE (source, remote_id),
|
||||
CONSTRAINT fk_genres_sources_id_source FOREIGN KEY (source) REFERENCES sources(id)
|
||||
);
|
||||
15
migrations/20260116092205_create_authors_table.sql
Normal file
15
migrations/20260116092205_create_authors_table.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- Create authors table
|
||||
CREATE TABLE IF NOT EXISTS authors (
|
||||
id SERIAL PRIMARY KEY,
|
||||
source SMALLINT NOT NULL,
|
||||
remote_id INTEGER NOT NULL,
|
||||
first_name VARCHAR(256) NOT NULL,
|
||||
last_name VARCHAR(256) NOT NULL,
|
||||
middle_name VARCHAR(256),
|
||||
CONSTRAINT uc_authors_source_remote_id UNIQUE (source, remote_id),
|
||||
CONSTRAINT fk_authors_sources_id_source FOREIGN KEY (source) REFERENCES sources(id)
|
||||
);
|
||||
|
||||
-- Create trigram indexes for author search
|
||||
CREATE INDEX IF NOT EXISTS tgrm_authors_lf ON authors USING gin ((last_name || ' ' || first_name) gin_trgm_ops);
|
||||
CREATE INDEX IF NOT EXISTS tgrm_authors_lfm ON authors USING gin ((last_name || ' ' || first_name || ' ' || middle_name) gin_trgm_ops);
|
||||
9
migrations/20260116092206_create_sequences_table.sql
Normal file
9
migrations/20260116092206_create_sequences_table.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- Create sequences table
|
||||
CREATE TABLE IF NOT EXISTS sequences (
|
||||
id SERIAL PRIMARY KEY,
|
||||
source SMALLINT NOT NULL,
|
||||
remote_id INTEGER NOT NULL,
|
||||
name VARCHAR(256) NOT NULL,
|
||||
CONSTRAINT uc_sequences_source_remote_id UNIQUE (source, remote_id),
|
||||
CONSTRAINT fk_sequences_sources_id_source FOREIGN KEY (source) REFERENCES sources(id)
|
||||
);
|
||||
20
migrations/20260116092207_create_books_table.sql
Normal file
20
migrations/20260116092207_create_books_table.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- Create books table
|
||||
CREATE TABLE IF NOT EXISTS books (
|
||||
id SERIAL PRIMARY KEY,
|
||||
source SMALLINT NOT NULL,
|
||||
remote_id INTEGER NOT NULL,
|
||||
title VARCHAR(256) NOT NULL,
|
||||
lang VARCHAR(3) NOT NULL,
|
||||
file_type VARCHAR(4) NOT NULL,
|
||||
uploaded DATE NOT NULL,
|
||||
is_deleted BOOLEAN NOT NULL DEFAULT false,
|
||||
pages INTEGER,
|
||||
year SMALLINT NOT NULL DEFAULT 0,
|
||||
CONSTRAINT uc_books_source_remote_id UNIQUE (source, remote_id),
|
||||
CONSTRAINT fk_books_sources_id_source FOREIGN KEY (source) REFERENCES sources(id)
|
||||
);
|
||||
|
||||
-- Create indexes for books
|
||||
CREATE INDEX IF NOT EXISTS idx_id_asc__not_is_deleted ON books (id) WHERE NOT is_deleted;
|
||||
CREATE INDEX IF NOT EXISTS idx_id_asc__uploaded__not_is_deleted ON books (id, uploaded) WHERE NOT is_deleted;
|
||||
CREATE INDEX IF NOT EXISTS idx_uploaded__id_asc__not_is_deleted ON books (uploaded, id) WHERE NOT is_deleted;
|
||||
13
migrations/20260116092208_create_book_authors_table.sql
Normal file
13
migrations/20260116092208_create_book_authors_table.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- Create book_authors junction table
|
||||
CREATE TABLE IF NOT EXISTS book_authors (
|
||||
id SERIAL PRIMARY KEY,
|
||||
author INTEGER NOT NULL,
|
||||
book INTEGER NOT NULL,
|
||||
CONSTRAINT uc_book_authors_book_author UNIQUE (book, author),
|
||||
CONSTRAINT fk_book_authors_authors_author_id FOREIGN KEY (author) REFERENCES authors(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT fk_book_authors_books_book_id FOREIGN KEY (book) REFERENCES books(id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Create indexes for book_authors
|
||||
CREATE INDEX IF NOT EXISTS book_authors_author ON book_authors (author);
|
||||
CREATE INDEX IF NOT EXISTS book_authors_book ON book_authors (book);
|
||||
13
migrations/20260116092209_create_book_genres_table.sql
Normal file
13
migrations/20260116092209_create_book_genres_table.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- Create book_genres junction table
|
||||
CREATE TABLE IF NOT EXISTS book_genres (
|
||||
id SERIAL PRIMARY KEY,
|
||||
genre INTEGER NOT NULL,
|
||||
book INTEGER NOT NULL,
|
||||
CONSTRAINT uc_book_genres_book_genre UNIQUE (book, genre),
|
||||
CONSTRAINT fk_book_genres_genres_genre_id FOREIGN KEY (genre) REFERENCES genres(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT fk_book_genres_books_book_id FOREIGN KEY (book) REFERENCES books(id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Create indexes for book_genres
|
||||
CREATE INDEX IF NOT EXISTS book_genres_genre ON book_genres (genre);
|
||||
CREATE INDEX IF NOT EXISTS book_genres_book ON book_genres (book);
|
||||
14
migrations/20260116092210_create_book_sequences_table.sql
Normal file
14
migrations/20260116092210_create_book_sequences_table.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
-- Create book_sequences junction table
|
||||
CREATE TABLE IF NOT EXISTS book_sequences (
|
||||
id SERIAL PRIMARY KEY,
|
||||
position SMALLINT NOT NULL,
|
||||
sequence INTEGER NOT NULL,
|
||||
book INTEGER NOT NULL,
|
||||
CONSTRAINT uc_book_sequences_book_sequence UNIQUE (book, sequence),
|
||||
CONSTRAINT fk_book_sequences_sequences_sequence_id FOREIGN KEY (sequence) REFERENCES sequences(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT fk_book_sequences_books_book_id FOREIGN KEY (book) REFERENCES books(id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Create indexes for book_sequences
|
||||
CREATE INDEX IF NOT EXISTS book_sequences_sequence ON book_sequences (sequence);
|
||||
CREATE INDEX IF NOT EXISTS book_sequences_book ON book_sequences (book);
|
||||
14
migrations/20260116092211_create_translations_table.sql
Normal file
14
migrations/20260116092211_create_translations_table.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
-- Create translations junction table
|
||||
CREATE TABLE IF NOT EXISTS translations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
position SMALLINT NOT NULL,
|
||||
author INTEGER NOT NULL,
|
||||
book INTEGER NOT NULL,
|
||||
CONSTRAINT uc_translations_book_author UNIQUE (book, author),
|
||||
CONSTRAINT fk_translations_authors_author_id FOREIGN KEY (author) REFERENCES authors(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT fk_translations_books_book_id FOREIGN KEY (book) REFERENCES books(id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Create indexes for translations
|
||||
CREATE INDEX IF NOT EXISTS translations_author ON translations (author);
|
||||
CREATE INDEX IF NOT EXISTS translations_book ON translations (book);
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Create author_annotations table
|
||||
CREATE TABLE IF NOT EXISTS author_annotations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
author INTEGER NOT NULL UNIQUE,
|
||||
title VARCHAR(256) NOT NULL,
|
||||
text TEXT NOT NULL,
|
||||
file VARCHAR(256),
|
||||
CONSTRAINT fk_author_annotations_authors_id_author FOREIGN KEY (author) REFERENCES authors(id)
|
||||
);
|
||||
|
||||
-- Create index for author_annotations
|
||||
CREATE INDEX IF NOT EXISTS author_annotation_author_id ON author_annotations (author);
|
||||
12
migrations/20260116092213_create_book_annotations_table.sql
Normal file
12
migrations/20260116092213_create_book_annotations_table.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
-- Create book_annotations table
|
||||
CREATE TABLE IF NOT EXISTS book_annotations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
book INTEGER NOT NULL UNIQUE,
|
||||
title VARCHAR(256) NOT NULL,
|
||||
text TEXT NOT NULL,
|
||||
file VARCHAR(256),
|
||||
CONSTRAINT fk_book_annotations_books_id_book FOREIGN KEY (book) REFERENCES books(id)
|
||||
);
|
||||
|
||||
-- Create index for book_annotations
|
||||
CREATE INDEX IF NOT EXISTS book_annotation_book_id ON book_annotations (book);
|
||||
12
src/db.rs
12
src/db.rs
@@ -12,10 +12,18 @@ 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
|
||||
sqlx::migrate!("./migrations")
|
||||
.run(&pool)
|
||||
.await
|
||||
.expect("Failed to run migrations");
|
||||
|
||||
pool
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user