add kilo plan add support Posgrest

This commit is contained in:
duong.doan1 2026-04-07 11:33:10 +07:00
parent 7e0d680bdf
commit 69b6b2bf93
2 changed files with 173 additions and 0 deletions

View file

@ -0,0 +1,170 @@
# Kế hoạch chuyển đổi Komga từ SQLite sang PostgreSQL
## Mục tiêu
Thêm hỗ trợ PostgreSQL cho Komga, cho phép người dùng lựa chọn database engine (SQLite hoặc PostgreSQL) thông qua cấu hình. Vẫn giữ backward compatibility với SQLite (mặc định).
## Hiện trạng
- Dự án hiện chỉ hỗ trợ SQLite.
- Cấu hình database trong `KomgaProperties.Database` chỉ có thuộc tính `file` (đường dẫn file SQLite).
- DataSource sử dụng `SqliteUdfDataSource` với các UDF và collation đặc thù.
- JOOQ dialect cố định `SQLDialect.SQLITE`.
- Flyway migration chỉ có thư mục `sqlite`.
- Code DAO sử dụng nhiều `collate(SqliteUdfDataSource.COLLATION_UNICODE_3)``udfStripAccents()`.
- Build Gradle cấu hình jooq generation chỉ cho SQLite.
## Phạm vi thay đổi
1. **Cấu hình database động**: Thêm thuộc tính `type` (sqlite/postgresql) và các thuộc tính kết nối.
2. **DataSourcesConfiguration**: Tạo DataSource tương ứng với database type.
3. **Abstract UDF/Collation**: Tạo interface cung cấp UDF và collation phù hợp với dialect.
4. **Flyway migration cho PostgreSQL**: Tạo thư mục migration PostgreSQL, chuyển đổi toàn bộ migration hiện tại.
5. **JOOQ configuration động**: Dialect và code generation cho cả hai database.
6. **Cập nhật code DAO**: Sử dụng abstract UDF/collation.
7. **Cập nhật build.gradle.kts**: Thêm dependency PostgreSQL, mở rộng jooq configuration.
8. **Testing**: Đảm bảo hoạt động với cả hai database.
## Sprint 1: Cơ sở hạ tầng và cấu hình (Tuần 1)
### 1.1. Thêm dependency PostgreSQL
- Thêm runtime dependency `org.postgresql:postgresql` vào `build.gradle.kts`.
- Thêm `jooqGenerator` dependency tương ứng.
- Giữ SQLite làm mặc định.
### 1.2. Mở rộng KomgaProperties.Database
- Thêm enum `DatabaseType { SQLITE, POSTGRESQL }`.
- Thêm thuộc tính `type: DatabaseType = SQLITE`.
- Thêm thuộc tính `url`, `username`, `password`, `driverClassName` (optional).
- Giữ thuộc tính `file` cho SQLite (backward compatibility).
- Xử lý logic: nếu `file` được cung cấp và `type` không set, mặc định là SQLite; nếu `url` chứa `jdbc:postgresql://` thì type là PostgreSQL.
### 1.3. Cập nhật DataSourcesConfiguration
- Tách `buildDataSource` thành hai phiên bản: `buildSqliteDataSource``buildPostgresDataSource`.
- Chọn phiên bản dựa trên `database.type`.
- Với PostgreSQL: sử dụng `DataSourceBuilder` với driver PostgreSQL, không có pragmas/journal mode.
- Với SQLite: giữ nguyên logic hiện tại.
- Tạo bean DataSource tương ứng.
### 1.4. Tạo abstract UDF/Collation provider
- Tạo interface `DatabaseDialectProvider` với các method: `collationUnicode3()`, `regexpFunction()`, `stripAccentsFunction()`.
- Tạo implementation cho SQLite (`SqliteDialectProvider`) và PostgreSQL (`PostgresDialectProvider`).
- PostgreSQL: sử dụng extension `unaccent` cho strip accents, collation ICU cho unicode collation, toán tử `~*` cho regexp.
- Đăng ký bean tương ứng với database type.
### 1.5. Cập nhật KomgaJooqConfiguration
- Inject `KomgaProperties` để lấy `database.type`.
- Set dialect động: `SQLDialect.SQLITE` hoặc `SQLDialect.POSTGRES`.
- Cập nhật `createDslContext` để sử dụng dialect phù hợp.
### 1.6. Cập nhật cấu hình Flyway
- `spring.flyway.locations` hiện dùng `{vendor}` sẽ tự động chọn thư mục `postgresql` khi dialect là PostgreSQL.
- Đảm bảo Flyway detect đúng vendor.
### Deliverables Sprint 1
- Dependency PostgreSQL được thêm.
- Cấu hình database type hoạt động.
- DataSources tạo đúng với PostgreSQL.
- Abstract dialect provider.
- JOOQ dialect động.
- Các unit test cơ bản cho cấu hình.
## Sprint 2: Migration database và JOOQ generation (Tuần 2)
### 2.1. Tạo thư mục migration PostgreSQL
- Tạo `src/flyway/resources/db/migration/postgresql/`.
- Tạo `src/flyway/kotlin/db/migration/postgresql/`.
- Chuyển đổi toàn bộ migration SQLite sang PostgreSQL.
### 2.2. Chuyển đổi migration scripts
- Chuyển đổi kiểu dữ liệu:
- `boolean``boolean`
- `datetime``timestamptz` (hoặc `timestamp`)
- `int8``bigint`
- `varchar``text` hoặc `varchar(n)`
- `blob``bytea`
- Điều chỉnh syntax: `CREATE INDEX IF NOT EXISTS``CREATE INDEX IF NOT EXISTS` (PostgreSQL 9.5+ hỗ trợ).
- Các ràng buộc khóa ngoại: `FOREIGN KEY (...) REFERENCES ...` giữ nguyên.
- Các migration Kotlin: đảm bảo SQL tương thích cả hai dialect (có thể dùng Flyway's `@DatabaseType` hoặc tách riêng).
### 2.3. Cập nhật build.gradle.kts cho JOOQ generation
- Thêm jooq configuration cho PostgreSQL:
- Driver: `org.postgresql.Driver`
- URL: kết nối đến PostgreSQL test instance (có thể dùng Testcontainers).
- Database: `org.jooq.meta.postgres.PostgresDatabase`
- Tạo task `generateJooqPostgres` riêng.
- Có thể generate code vào package riêng: `org.gotson.komga.jooq.main.postgres`.
### 2.4. Cập nhật code generation workflow
- Hiện tại jooq generation dựa trên SQLite schema được tạo bởi Flyway migration.
- Với PostgreSQL, cần chạy migration PostgreSQL trên test database rồi generate.
- Có thể sử dụng Testcontainers PostgreSQL trong quá trình build.
### 2.5. Cập nhật tasks database
- Tasks database hiện cũng dùng SQLite. Có thể giữ nguyên SQLite (đơn giản) hoặc hỗ trợ PostgreSQL.
- Quyết định: giữ SQLite cho tasks (không cần scale), nhưng cấu hình cho phép chung nếu muốn.
### Deliverables Sprint 2
- Toàn bộ migration PostgreSQL.
- JOOQ generation thành công cho PostgreSQL.
- Tasks database được xử lý phù hợp.
- Có thể khởi động ứng dụng với PostgreSQL (chưa có UDF/collation).
## Sprint 3: Cập nhật code DAO và testing (Tuần 3)
### 3.1. Thay thế sử dụng UDF/collation trong DAO
- Cập nhật file Utils.kt: `Field<String>.udfStripAccents()` sử dụng `DatabaseDialectProvider`.
- Cập nhật các file DAO: thay `collate(SqliteUdfDataSource.COLLATION_UNICODE_3)` bằng `collate(dialectProvider.collationUnicode3())`.
- Cập nhật SeriesSearchHelper, BookSearchHelper, ReferentialDao, SeriesDtoDao, BookDtoDao, SeriesCollectionDao, ReadListDao.
### 3.2. Xử lý REGEXP trong queries
- Tìm tất cả chỗ sử dụng `DSL.field("{0} REGEXP {1}", ...)` và thay bằng `dialectProvider.regexpFunction()`.
- Đảm bảo regexp syntax tương thích (PostgreSQL sử dụng `~*`).
### 3.3. Cập nhật SqliteUdfDataSource
- Đổi tên thành `DialectAwareDataSource` hoặc giữ nguyên nhưng tách logic PostgreSQL.
- Hoặc tạo `PostgresUdfDataSource` riêng.
### 3.4. Testing
- Tạo integration tests với Testcontainers PostgreSQL.
- Test tất cả các chức năng chính với cả hai database.
- Đảm bảo migration PostgreSQL chạy đúng.
- Test UDF/collation hoạt động tương đương.
### 3.5. Documentation
- Cập nhật tài liệu cấu hình database.
- Hướng dẫn chuyển đổi từ SQLite sang PostgreSQL (migration tool có thể cần thiết).
### 3.6. Migration tool cho dữ liệu hiện có
- Có thể phát triển tool export/import hoặc sử dụng pgloader.
- Không nằm trong phạm vi chính nhưng cần xem xét.
### Deliverables Sprint 3
- Code DAO hoạt động với cả hai database.
- Integration tests pass.
- Documentation cập nhật.
- Ứng dụng có thể chạy với PostgreSQL đầy đủ chức năng.
## Rủi ro và phụ thuộc
1. **Hiệu năng**: PostgreSQL có thể khác SQLite, cần tuning.
2. **UDF/collation**: Đảm bảo chức năng tương đương.
3. **Migration phức tạp**: Số lượng migration lớn (91 files), cần chuyển đổi cẩn thận.
4. **Testing**: Cần thiết lập CI với cả hai database.
## Các file chính cần sửa đổi
1. `komga/build.gradle.kts`
2. `komga/src/main/resources/application.yml`
3. `komga/src/main/kotlin/org/gotson/komga/infrastructure/configuration/KomgaProperties.kt`
4. `komga/src/main/kotlin/org/gotson/komga/infrastructure/datasource/DataSourcesConfiguration.kt`
5. `komga/src/main/kotlin/org/gotson/komga/infrastructure/datasource/SqliteUdfDataSource.kt`
6. `komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/KomgaJooqConfiguration.kt`
7. `komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/Utils.kt`
8. Các file DAO (SeriesDtoDao, ReferentialDao, ...)
9. Tạo thư mục `src/flyway/resources/db/migration/postgresql/`
10. Tạo `src/flyway/kotlin/db/migration/postgresql/`
## Ước lượng công sức
- Sprint 1: 40 giờ
- Sprint 2: 60 giờ (do migration nhiều)
- Sprint 3: 50 giờ
- Tổng: ~150 giờ
## Kết quả mong đợi
Komga hỗ trợ cả SQLite và PostgreSQL, người dùng có thể lựa chọn database phù hợp với nhu cầu scale.

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"snyk.advanced.autoSelectOrganization": true
}