chore(database): condensate all migrations into one

This commit is contained in:
Rodrigo Verdiani 2026-03-17 19:42:17 -03:00
parent 9f1437f056
commit 3ecd38ef2c
21 changed files with 163 additions and 245 deletions

View File

@ -0,0 +1,163 @@
CREATE TABLE IF NOT EXISTS languages
(
id SERIAL PRIMARY KEY,
code VARCHAR(12) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL
);
INSERT INTO languages (code, name)
VALUES ('en-US', 'English'),
('es', 'Spanish'),
('ja-JP', 'Japanese'),
('pt-BR', 'Portuguese (Brazil)')
ON CONFLICT DO NOTHING;
CREATE TABLE images
(
id UUID NOT NULL PRIMARY KEY,
file_key VARCHAR NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE mangas
(
id BIGSERIAL NOT NULL PRIMARY KEY,
ani_list_id BIGINT UNIQUE,
mal_id BIGINT UNIQUE,
title VARCHAR,
status VARCHAR,
synopsis VARCHAR,
cover_image_id UUID REFERENCES images (id),
score DOUBLE PRECISION,
published_from TIMESTAMPTZ,
published_to TIMESTAMPTZ,
chapter_count INT DEFAULT 0,
follow BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE content_providers
(
id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR NOT NULL,
active BOOLEAN NOT NULL DEFAULT TRUE,
supports_chapter_fetch BOOLEAN NOT NULL DEFAULT TRUE,
manual_import BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE manga_content_provider
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_id BIGINT NOT NULL REFERENCES mangas (id) ON DELETE CASCADE,
content_provider_id BIGINT NOT NULL REFERENCES content_providers (id) ON DELETE CASCADE,
manga_title VARCHAR NOT NULL,
url VARCHAR NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (manga_id, content_provider_id)
);
CREATE TABLE manga_chapters
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_content_provider_id BIGINT NOT NULL REFERENCES manga_content_provider (id) ON DELETE CASCADE,
title VARCHAR NOT NULL,
url VARCHAR NOT NULL,
chapter_number INTEGER,
language_id BIGINT REFERENCES languages (id),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE manga_chapter_images
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_chapter_id BIGINT NOT NULL REFERENCES manga_chapters (id) ON DELETE CASCADE,
image_id UUID REFERENCES images (id) ON DELETE CASCADE,
position INT NOT NULL,
downloaded BOOLEAN DEFAULT FALSE,
read BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE manga_import_reviews
(
id BIGSERIAL NOT NULL PRIMARY KEY,
content_provider_id BIGINT NOT NULL REFERENCES content_providers (id) ON DELETE CASCADE,
title VARCHAR NOT NULL,
url VARCHAR NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE authors
(
id BIGSERIAL NOT NULL PRIMARY KEY,
mal_id BIGINT UNIQUE,
name VARCHAR,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE manga_author
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_id BIGINT REFERENCES mangas (id),
author_id BIGINT REFERENCES authors (id),
UNIQUE (manga_id, author_id)
);
CREATE TABLE genres
(
id BIGSERIAL NOT NULL PRIMARY KEY,
mal_id BIGINT UNIQUE,
name VARCHAR
);
CREATE TABLE manga_genre
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_id BIGINT REFERENCES mangas (id),
genre_id BIGINT REFERENCES genres (id),
UNIQUE (manga_id, genre_id)
);
CREATE TABLE users
(
id SERIAL PRIMARY KEY,
email VARCHAR NOT NULL UNIQUE,
name VARCHAR NOT NULL,
password VARCHAR NOT NULL,
role VARCHAR
);
CREATE TABLE user_favorite_mangas
(
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
manga_id BIGINT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, manga_id)
);
CREATE TABLE manga_alternative_titles
(
id BIGSERIAL PRIMARY KEY,
manga_id BIGINT REFERENCES mangas (id),
title VARCHAR NOT NULL
);
CREATE INDEX idx_manga_alternative_titles_manga_id ON manga_alternative_titles (manga_id);
CREATE INDEX idx_manga_alternative_titles_title ON manga_alternative_titles (title);
CREATE TABLE user_manga_follow
(
id BIGSERIAL NOT NULL PRIMARY KEY,
user_id BIGINT REFERENCES users (id),
manga_id BIGINT REFERENCES mangas (id)
);

View File

@ -1,7 +0,0 @@
CREATE TABLE images
(
id UUID NOT NULL PRIMARY KEY,
file_key VARCHAR NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

View File

@ -1,11 +0,0 @@
CREATE TABLE mangas
(
id BIGSERIAL NOT NULL PRIMARY KEY,
mal_id BIGINT UNIQUE,
title VARCHAR,
alternative_titles TEXT[],
status VARCHAR,
synopsis VARCHAR,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

View File

@ -1,21 +0,0 @@
CREATE TABLE providers
(
id BIGSERIAL NOT NULL PRIMARY KEY,
name VARCHAR NOT NULL,
status VARCHAR NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE manga_provider
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_id BIGINT NOT NULL REFERENCES mangas (id) ON DELETE CASCADE,
provider_id BIGINT NOT NULL REFERENCES providers (id) ON DELETE CASCADE,
manga_title VARCHAR NOT NULL,
url VARCHAR NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (manga_id, provider_id)
)

View File

@ -1,20 +0,0 @@
CREATE TABLE manga_chapters
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_provider_id BIGINT NOT NULL REFERENCES manga_provider (id) ON DELETE CASCADE,
title VARCHAR NOT NULL,
url VARCHAR NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE manga_chapter_images
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_chapter_id BIGINT NOT NULL REFERENCES manga_chapters (id) ON DELETE CASCADE,
image_id UUID REFERENCES images (id) ON DELETE CASCADE,
position INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
)

View File

@ -1,8 +0,0 @@
CREATE TABLE manga_import_reviews
(
id BIGSERIAL NOT NULL PRIMARY KEY,
provider_id BIGINT NOT NULL REFERENCES providers (id) ON DELETE CASCADE,
title VARCHAR NOT NULL,
url VARCHAR NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

View File

@ -1,5 +0,0 @@
ALTER TABLE mangas
ADD COLUMN cover_image_id UUID REFERENCES images (id),
ADD COLUMN score DOUBLE PRECISION,
ADD COLUMN published_from TIMESTAMPTZ,
ADD COLUMN published_to TIMESTAMPTZ;

View File

@ -1,31 +0,0 @@
CREATE TABLE authors
(
id BIGSERIAL NOT NULL PRIMARY KEY,
mal_id BIGINT UNIQUE,
name VARCHAR,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE manga_author
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_id BIGINT REFERENCES mangas (id),
author_id BIGINT REFERENCES authors (id),
UNIQUE (manga_id, author_id)
);
CREATE TABLE genres
(
id BIGSERIAL NOT NULL PRIMARY KEY,
mal_id BIGINT UNIQUE,
name VARCHAR
);
CREATE TABLE manga_genre
(
id BIGSERIAL NOT NULL PRIMARY KEY,
manga_id BIGINT REFERENCES mangas (id),
genre_id BIGINT REFERENCES genres (id),
UNIQUE (manga_id, genre_id)
);

View File

@ -1 +0,0 @@
ALTER TABLE manga_chapters ADD COLUMN downloaded BOOLEAN DEFAULT FALSE;

View File

@ -1 +0,0 @@
ALTER TABLE manga_chapters ADD COLUMN read BOOLEAN DEFAULT FALSE;

View File

@ -1,7 +0,0 @@
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR NOT NULL UNIQUE,
name VARCHAR NOT NULL,
password VARCHAR NOT NULL,
role VARCHAR
);

View File

@ -1,8 +0,0 @@
CREATE TABLE user_favorite_mangas
(
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
manga_id BIGINT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (user_id, manga_id)
);

View File

@ -1,2 +0,0 @@
ALTER TABLE mangas
ADD COLUMN chapter_count INT DEFAULT 0;

View File

@ -1,3 +0,0 @@
ALTER TABLE manga_chapters
ADD COLUMN language VARCHAR(10) DEFAULT 'pt-br',
ADD COLUMN chapter_number INTEGER;

View File

@ -1,18 +0,0 @@
CREATE TABLE manga_alternative_titles
(
id BIGSERIAL PRIMARY KEY,
manga_id BIGINT REFERENCES mangas (id),
title VARCHAR NOT NULL
);
INSERT INTO manga_alternative_titles (manga_id, title)
SELECT id as manga_id,
unnest(alternative_titles) as title
FROM mangas
WHERE alternative_titles IS NOT NULL;
CREATE INDEX idx_manga_alternative_titles_manga_id ON manga_alternative_titles (manga_id);
CREATE INDEX idx_manga_alternative_titles_title ON manga_alternative_titles (title);
ALTER TABLE mangas DROP COLUMN alternative_titles;

View File

@ -1,2 +0,0 @@
ALTER TABLE providers
ADD COLUMN supports_chapter_fetch BOOLEAN NOT NULL DEFAULT true;

View File

@ -1,9 +0,0 @@
ALTER TABLE mangas
ADD COLUMN follow BOOLEAN NOT NULL DEFAULT FALSE;
CREATE TABLE user_manga_follow
(
id BIGSERIAL NOT NULL PRIMARY KEY,
user_id BIGINT REFERENCES users (id),
manga_id BIGINT REFERENCES mangas (id)
);

View File

@ -1,44 +0,0 @@
DO
$$
DECLARE
_target_provider_name TEXT := 'Manga Livre';
_target_provider_id BIGINT;
_deleted_chapters_count INTEGER;
_deleted_manga_providers_count INTEGER;
BEGIN
SELECT id
INTO _target_provider_id
FROM providers
WHERE name = _target_provider_name;
IF _target_provider_id IS NULL THEN
RAISE NOTICE 'Provider with name "%" not found.', _target_provider_name;
RETURN;
END IF;
UPDATE providers SET status = 'INACTIVE' WHERE id = _target_provider_id;
-- Delete non-downloaded manga chapters associated with the target provider
DELETE
FROM manga_chapters mc
USING manga_provider mp
WHERE mc.manga_provider_id = mp.id
AND mp.provider_id = _target_provider_id
AND mc.downloaded = FALSE;
GET DIAGNOSTICS _deleted_chapters_count = ROW_COUNT;
RAISE NOTICE 'Deleted % non-downloaded chapters for provider ID %.', _deleted_chapters_count, _target_provider_id;
-- Delete MangaProvider records ONLY if NO chapters
DELETE
FROM manga_provider mp
WHERE mp.provider_id = _target_provider_id
AND NOT EXISTS (SELECT 1
FROM manga_chapters mc
WHERE mc.manga_provider_id = mp.id);
GET DIAGNOSTICS _deleted_manga_providers_count = ROW_COUNT;
RAISE NOTICE 'Deleted % manga_provider entries', _deleted_manga_providers_count;
END
$$;

View File

@ -1,6 +0,0 @@
ALTER TABLE providers
ADD COLUMN manual_import BOOLEAN DEFAULT FALSE;
UPDATE providers
SET manual_import = TRUE
WHERE name IN ('MangaDex', 'Bato');

View File

@ -1,40 +0,0 @@
CREATE TABLE IF NOT EXISTS languages
(
id SERIAL PRIMARY KEY,
code VARCHAR(12) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL
);
INSERT INTO languages (code, name)
VALUES ('en-US', 'English'),
('es', 'Spanish'),
('ja-JP', 'Japanese'),
('pt-BR', 'Portuguese (Brazil)')
ON CONFLICT DO NOTHING;
ALTER TABLE manga_chapters
ADD COLUMN IF NOT EXISTS language_id BIGINT REFERENCES languages (id);
UPDATE manga_chapters
SET language = NULL;
UPDATE manga_chapters mc
SET language_id = (SELECT id FROM languages WHERE code = 'pt-BR')
FROM manga_provider mp
JOIN providers p ON mp.provider_id = p.id
WHERE mc.manga_provider_id = mp.id
AND mc.language IS NULL
AND p.name ILIKE ANY
(ARRAY ['Manga Livre Blog', 'Pink Rosa Scan', 'Manga Livre.to', 'Manga Livre', 'MangaDex', 'Bato', 'Taimu']);
UPDATE manga_chapters mc
SET language_id = (SELECT id FROM languages WHERE code = 'en-US')
FROM manga_provider mp
JOIN providers p ON mp.provider_id = p.id
WHERE mc.manga_provider_id = mp.id
AND mc.language IS NULL
AND p.name ILIKE ANY
(ARRAY ['Manual Import']);
ALTER TABLE manga_chapters
DROP COLUMN IF EXISTS language;

View File

@ -1 +0,0 @@
ALTER TABLE mangas ADD COLUMN ani_list_id BIGINT;