mirror of
https://github.com/rommapp/romm.git
synced 2026-06-27 14:25:52 +00:00
cleanup
This commit is contained in:
@@ -1,11 +1,5 @@
|
||||
"""Enforce unique (platform_id, fs_name) on roms
|
||||
|
||||
A platform folder can't physically hold two entries with the same name, so a
|
||||
ROM is uniquely identified by (platform_id, fs_name). The index covering this
|
||||
pair was non-unique, which let two concurrent scans (e.g. the manual scan the
|
||||
patcher fires after uploading a patched ROM, racing a filesystem-watcher or
|
||||
scheduled scan) both insert the same ROM, producing duplicate library entries.
|
||||
|
||||
This migration removes any pre-existing duplicates (keeping the lowest id) and
|
||||
upgrades the index to unique so the duplicate can never be created again.
|
||||
|
||||
@@ -32,13 +26,7 @@ def upgrade() -> None:
|
||||
connection = op.get_bind()
|
||||
|
||||
# Drop duplicate roms sharing (platform_id, fs_name), keeping the lowest id.
|
||||
# The nested derived table is required so MySQL/MariaDB don't reject reading
|
||||
# the same table being deleted from; it's a valid no-op on PostgreSQL too.
|
||||
# Dependent rows (files, user props, assets, collections, ...) are removed by
|
||||
# their ON DELETE CASCADE foreign keys.
|
||||
connection.execute(
|
||||
sa.text(
|
||||
"""
|
||||
connection.execute(sa.text("""
|
||||
DELETE FROM roms
|
||||
WHERE id NOT IN (
|
||||
SELECT keep_id FROM (
|
||||
@@ -47,9 +35,7 @@ def upgrade() -> None:
|
||||
GROUP BY platform_id, fs_name
|
||||
) AS keepers
|
||||
)
|
||||
"""
|
||||
)
|
||||
)
|
||||
"""))
|
||||
|
||||
with op.batch_alter_table("roms", schema=None) as batch_op:
|
||||
batch_op.drop_index(INDEX_NAME, if_exists=True)
|
||||
|
||||
@@ -28,6 +28,7 @@ from fastapi.responses import Response
|
||||
from fastapi_pagination import resolve_params
|
||||
from fastapi_pagination.limit_offset import LimitOffsetPage, LimitOffsetParams
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from starlette.responses import FileResponse
|
||||
|
||||
from config import (
|
||||
@@ -1484,16 +1485,6 @@ async def update_rom(
|
||||
# Re-parse tags from the filename so region/language/revision/version/tags
|
||||
# stay in sync whenever the fs_name changes.
|
||||
if new_fs_name != rom.fs_name:
|
||||
# (platform_id, fs_name) is unique, so reject a rename that would collide
|
||||
# with another ROM on this platform before the DB update would fail.
|
||||
if db_rom_handler.get_roms_by_fs_name(
|
||||
platform_id=rom.platform_id, fs_names={new_fs_name}
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail=f"A ROM named '{new_fs_name}' already exists on this platform",
|
||||
)
|
||||
|
||||
parsed_tags = fs_rom_handler.parse_tags(new_fs_name)
|
||||
cleaned_data.update(
|
||||
{
|
||||
@@ -1608,7 +1599,14 @@ async def update_rom(
|
||||
f"Updating {hl(cleaned_data.get('name', ''), color=BLUE)} [{hl(cleaned_data.get('fs_name', ''))}] with data {cleaned_data}"
|
||||
)
|
||||
|
||||
db_rom_handler.update_rom(id, cleaned_data)
|
||||
try:
|
||||
db_rom_handler.update_rom(id, cleaned_data)
|
||||
except IntegrityError as exc:
|
||||
log.error(f"Failed to update ROM {id}: {exc}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Failed to update ROM {id}: {exc}",
|
||||
) from exc
|
||||
|
||||
# Rename the file/folder if the name has changed
|
||||
should_update_fs = new_fs_name != rom.fs_name
|
||||
|
||||
@@ -271,9 +271,7 @@ async def _identify_rom(
|
||||
)
|
||||
)
|
||||
except IntegrityError:
|
||||
# A concurrent scan already created this ROM ((platform_id, fs_name)
|
||||
# is unique). That scan owns the full processing of this file, so
|
||||
# skip it here instead of inserting a duplicate library entry.
|
||||
# A concurrent scan already created this ROM, so skip it here.
|
||||
log.debug(
|
||||
f"Skipping {hl(fs_rom['fs_name'])}: already created by a concurrent scan"
|
||||
)
|
||||
|
||||
@@ -208,9 +208,7 @@ class Rom(BaseModel):
|
||||
libretro_id: Mapped[str | None] = mapped_column(String(length=64), default=None)
|
||||
|
||||
__table_args__ = (
|
||||
# A platform folder can't hold two entries with the same name on disk,
|
||||
# so (platform_id, fs_name) is unique. Enforcing it also stops racing
|
||||
# scans from inserting the same ROM twice.
|
||||
# Enforce unique fs name per platform to avoid duplicates
|
||||
Index("idx_roms_platform_id_fs_name", "platform_id", "fs_name", unique=True),
|
||||
# Covers the sibling_roms view self-join
|
||||
Index(
|
||||
|
||||
Reference in New Issue
Block a user