Я бы сказал, что этот подход в корне неверен и чрезмерно хрупок. Вместо отслеживания позиции absolute в списке воспроизведения, отслеживайте позицию относительно . Таким образом, вам не нужно обновлять позиции при вставке или удалении песен:
Если первые три песни имеют значения posicao
1,2,3, и вы хотите добавить песню в позицию 2, вместо обновления текущих 2 на 3, текущих 3 на 4 и т. Д., Используйте новое значение на полпути между текущими 1 и 2 позициями posicao
's: 1,5 в этом случае.
При удалении не беспокойтесь о заполнении пробела; posicao
по обе стороны от удаленной песни все еще находятся в правильном порядке.
Если вам по какой-то причине нужна абсолютная позиция, вы можете рассчитать ее в SELECT
на лету с современными версиями sqlite (3.25 или новее) с чем-то вроде
SELECT idMusica, row_number() OVER (ORDER BY posicao) AS pos
FROM playlist_songs
WHERE idPlaylist = :playlistid
ORDER BY posicao
или просто увеличивая счетчик в вашей программе каждый раз, когда вы выбираете строку из заданного списка воспроизведения, если он упорядочен по posicao
.
Запросы на основе оконных функций для вставки в середину списка воспроизведения и удаления с учетом абсолютной позиции (хотя для удаления, если ваша соединительная таблица не является WITHOUT ROWID
, легче отследить rowid песен в свою программу и удалите, используя ту, что для выбранной песни):
INSERT INTO playlist_songs(idMusica, idPlaylist, posicao)
VALUES(:songid, :playlistid
, (SELECT (pos + prev_pos) / 2.0
FROM (SELECT posicao AS pos
, lag(posicao, 1, 0.0) OVER (ORDER BY posicao) AS prev_pos
, row_number() OVER (ORDER BY posicao) AS rn
FROM playlist_songs WHERE idPlaylist = :playlistid)
WHERE rn = :position));
DELETE FROM playlist_songs
WHERE rowid = (SELECT rowid
FROM (SELECT rowid, row_number() OVER (ORDER BY posicao) AS rn
FROM playlist_songs WHERE idPlaylist = :playlistid)
WHERE rn = :position);