5.2 KiB
Executable File
5.2 KiB
Executable File
Phase 2 — Database Layer
Persistent storage using PostgreSQL via pgx. Migrations run on startup. sqlc generates type-safe query code.
Reference schema modeled after Suwayomi-Server:
/Users/achmad/Documents/Belajar/Web/Suwayomi-Server/server/src/main/kotlin/suwayomi/tachidesk/manga/model/table/- Migrations:
/Users/achmad/Documents/Belajar/Web/Suwayomi-Server/server/src/main/kotlin/suwayomi/tachidesk/server/database/migration/
2.1 Schema Migration — internal/db/migrations/000001_init.up.sql
sourcestableid BIGINT PRIMARY KEYname VARCHAR(128) NOT NULLlang VARCHAR(32) NOT NULLis_nsfw BOOLEAN NOT NULL DEFAULT FALSE
mangatableid SERIAL PRIMARY KEYsource_id BIGINT NOT NULL REFERENCES sources(id)url VARCHAR(2048) NOT NULLtitle VARCHAR(512) NOT NULLinitialized BOOLEAN NOT NULL DEFAULT FALSEartist TEXT,author TEXT,description TEXT,genre TEXTstatus INTEGER NOT NULL DEFAULT 0thumbnail_url VARCHAR(2048)thumbnail_last_fetched BIGINT NOT NULL DEFAULT 0in_library BOOLEAN NOT NULL DEFAULT FALSEin_library_at BIGINT NOT NULL DEFAULT 0real_url VARCHAR(2048)last_fetched_at BIGINT NOT NULL DEFAULT 0chapters_last_fetched_at BIGINT NOT NULL DEFAULT 0update_strategy VARCHAR(64) NOT NULL DEFAULT 'ALWAYS_UPDATE'UNIQUE (source_id, url)
chapterstableid SERIAL PRIMARY KEYmanga_id INTEGER NOT NULL REFERENCES manga(id) ON DELETE CASCADEurl VARCHAR(2048) NOT NULLname VARCHAR(512) NOT NULLdate_upload BIGINT NOT NULL DEFAULT 0chapter_number REAL NOT NULL DEFAULT -1scanlator VARCHAR(256)source_order INTEGER NOT NULLis_read BOOLEAN NOT NULL DEFAULT FALSEis_bookmarked BOOLEAN NOT NULL DEFAULT FALSElast_page_read INTEGER NOT NULL DEFAULT 0last_read_at BIGINT NOT NULL DEFAULT 0fetched_at BIGINT NOT NULL DEFAULT 0real_url VARCHAR(2048)is_downloaded BOOLEAN NOT NULL DEFAULT FALSEpage_count INTEGER NOT NULL DEFAULT -1UNIQUE (manga_id, url)
pagestableid SERIAL PRIMARY KEYchapter_id INTEGER NOT NULL REFERENCES chapters(id) ON DELETE CASCADE"index" INTEGER NOT NULLurl VARCHAR(2048) NOT NULLimage_url TEXTUNIQUE (chapter_id, "index")— added for upsert support
source_metatablesource_id BIGINT NOT NULL REFERENCES sources(id)key VARCHAR(256) NOT NULLvalue TEXT NOT NULLPRIMARY KEY (source_id, key)
- Indexes
CREATE INDEX ON manga (source_id)CREATE INDEX ON manga (last_fetched_at)CREATE INDEX ON chapters (manga_id)CREATE INDEX ON pages (chapter_id)
2.2 DB Initialization — internal/db/db.go
pgxpool.Poolinit fromDATABASE_URLenv var- Configurable
MaxConnsviaDB_MAX_CONNS(default 10) - Configurable
MinConnsviaDB_MIN_CONNS(default 2) - Connection health check on startup (
pool.Ping)
- Configurable
- Migration runner using
golang-migrate/migrate- Source:
iofs(embed migration SQL files with//go:embed) - Driver:
pgx5(DSN scheme rewritten frompostgres://→pgx5://) - Run
migrate.Up()on startup; log version before/after - Non-fatal on "no change" (
migrate.ErrNoChange)
- Source:
Queriesstruct wrapping sqlc-generated query clientsClose()method to drain pool on shutdown
2.3 SQL Queries — internal/db/queries/
Generated by sqlc generate (config: sqlc.yaml, sql_package: pgx/v5).
manga.sql
UpsertMangaGetMangaBySourceURLGetMangaByIDListMangaBySourceUpdateMangaDetailsUpdateMangaFetchedAtUpdateChaptersFetchedAt
chapter.sql
UpsertChapterGetChapterByIDListChaptersByMangaUpdateChapterFetchedAt
page.sql
UpsertPageListPagesByChapterUpdatePageImageURL
source.sql
UpsertSourceListSourcesGetSourceByIDGetSourceMetaSetSourceMeta
2.4 sqlc Configuration — sqlc.yaml
version: "2"- engine:
postgresql - schema path:
internal/db/migrations/ - queries path:
internal/db/queries/*.sql - output package:
internal/db/queries sql_package: "pgx/v5"— required for pgxpool compatibilityemit_json_tags: trueemit_db_tags: trueemit_pointers_for_null_types: true
2.5 Data Flow & Cache Logic
TTL env vars implemented in internal/config/config.go. Cache check logic and ?refresh=true bypass live in the Phase 5 API handler using these values.
MANGA_LIST_TTL_SECONDSenv var (default 600)MANGA_DETAIL_TTL_SECONDSenv var (default 3600)CHAPTER_LIST_TTL_SECONDSenv var (default 600)
Checklist: Phase 2 Done When
sqlc generatecompletes without errors; generated files compilego build ./...succeeds