feat: Add position shifting logic for adding sounds to playlists in repository

This commit is contained in:
JSC
2025-08-10 21:33:06 +02:00
parent 357fbcecac
commit 13e0db1fe9
2 changed files with 196 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
"""Playlist repository for database operations."""
from enum import Enum
from sqlalchemy import func
from sqlalchemy import func, update
from sqlalchemy.orm import selectinload
from sqlmodel import col, select
from sqlmodel.ext.asyncio.session import AsyncSession
@@ -120,6 +120,20 @@ class PlaylistRepository(BaseRepository[Playlist]):
logger.exception("Failed to get sounds for playlist: %s", playlist_id)
raise
async def get_playlist_sound_entries(self, playlist_id: int) -> list[PlaylistSound]:
"""Get all PlaylistSound entries for a playlist, ordered by position."""
try:
statement = (
select(PlaylistSound)
.where(PlaylistSound.playlist_id == playlist_id)
.order_by(PlaylistSound.position)
)
result = await self.session.exec(statement)
return list(result.all())
except Exception:
logger.exception("Failed to get playlist sound entries for playlist: %s", playlist_id)
raise
async def add_sound_to_playlist(
self,
playlist_id: int,
@@ -135,6 +149,35 @@ class PlaylistRepository(BaseRepository[Playlist]):
).where(PlaylistSound.playlist_id == playlist_id)
result = await self.session.exec(statement)
position = result.first() or 0
else:
# Shift existing positions to make room for the new sound
# Use a two-step approach to avoid unique constraint violations:
# 1. Move all affected positions to negative temporary positions
# 2. Then move them to their final positions
# Step 1: Move to temporary negative positions
update_to_negative = (
update(PlaylistSound)
.where(
PlaylistSound.playlist_id == playlist_id,
PlaylistSound.position >= position,
)
.values(position=PlaylistSound.position - 10000)
)
await self.session.exec(update_to_negative)
await self.session.commit()
# Step 2: Move from temporary negative positions to final positions
update_to_final = (
update(PlaylistSound)
.where(
PlaylistSound.playlist_id == playlist_id,
PlaylistSound.position < 0,
)
.values(position=PlaylistSound.position + 10001)
)
await self.session.exec(update_to_final)
await self.session.commit()
playlist_sound = PlaylistSound(
playlist_id=playlist_id,