Skip to content

Fix library/category count mismatch from duplicate category-manga rows - #2247

Open
Seanstoppable wants to merge 1 commit into
Suwayomi:masterfrom
Seanstoppable:seanstoppable-fix-library-count-mismatch
Open

Fix library/category count mismatch from duplicate category-manga rows#2247
Seanstoppable wants to merge 1 commit into
Suwayomi:masterfrom
Seanstoppable:seanstoppable-fix-library-count-mismatch

Conversation

@Seanstoppable

Copy link
Copy Markdown
Contributor

Why

Library/category counts didn't match the number of manga actually selectable in that category, worsening as manga were moved between categories. CategoryMangaTable (the manga<->category join table) had no unique constraint on (manga, category), so racing check-then-insert code paths could create duplicate rows. Category.getCategorySize() does a plain row count (inflated by duplicates), while CategoryManga.getCategoryMangaList() groups by manga columns (duplicates collapse) - hence the mismatch between the displayed count and what you could actually select.

What changed

  • Added migration M0061_PreventDuplicatedCategoryManga: dedupes any existing duplicate (manga, category) rows, then adds a UNIQUE (manga, category) constraint. This is the core fix - counts are now correct by construction.
  • Hardened the insert paths (Library.addMangaToLibrary, CategoryManga.addMangasToCategories) against the underlying race using Exposed's native upsert/batchUpsert (compiles to MERGE/ON CONFLICT), keyed on the (manga, category) constraint. This gives real "insert if not exists" semantics on both H2 and PostgreSQL without relying on insertIgnore (unsupported by H2 outside MySQL compatibility mode, which this project doesn't use) or manual exception-driven retry logic.
  • Added regression tests proving the unique constraint is enforced and that adding a manga to the same category twice is idempotent (no duplicate rows).

Note: a manga can still belong to many different categories - the constraint only prevents the same manga+category pair from being duplicated.

Add a unique constraint on CategoryManga(manga, category) via migration
M0061, deduping any existing duplicate rows first. This was the root
cause of library/category counts not matching the number of manga
actually selectable: duplicate rows inflated Category.getCategorySize()
plain row count while getCategoryMangaList() grouped by manga and
collapsed duplicates.

Harden the insert paths against races using Exposed's native upsert/
batchUpsert (MERGE/ON CONFLICT), keyed on the (manga, category) unique
constraint, instead of insertIgnore (unsupported by H2 outside MySQL
mode) or manual try/catch retry loops. Add regression tests proving
the unique constraint is enforced and that adding a manga to the same
category twice is idempotent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants