btrtracks/src/playlist.js

102 lines
3.9 KiB
JavaScript

import { dbPromise } from './database'
async function getPlaylist (id, order = 'ntry.indx', direction = 'ASC') {
const db = await dbPromise
const p = await db.get('SELECT * FROM Playlist WHERE id = ?', id)
if (!p) throw new Error('No such playlist!')
const q = await db.all(`SELECT ntry.id,ntry.trackId,ntry.playlistId,ntry.indx,ntry.userId,
trck.title,trck.artist,trck.genre,trck.year,trck.duration,trck.track,trck.album
FROM PlaylistEntry ntry INNER JOIN Track
trck ON ntry.trackId = trck.id WHERE ntry.playlistId = ? ORDER BY ${order} ${direction}`, id)
p.tracks = q || []
return p
}
async function getPlaylists (userId) {
const db = await dbPromise
return db.all('SELECT * FROM Playlist WHERE userId = ? OR userId = NULL', userId)
}
async function createPlaylist (userId, title) {
const db = await dbPromise
const alreadyExists = await db.get('SELECT * FROM Playlist WHERE userId = ? AND title = ?', userId, title)
if (alreadyExists) throw new Error('Playlist with the same name already exists!')
await db.run('INSERT INTO Playlist (title,userId) VALUES (?,?)', title, userId)
return db.get('SELECT id FROM Playlist WHERE title = ? AND userId = ?', title, userId)
}
async function deletePlaylist (userId, playlistId) {
const db = await dbPromise
const ply = await db.get('SELECT * FROM Playlist WHERE id = ?', playlistId)
if (!ply) throw new Error('Could not find playlist specified.')
if (ply.userId !== userId) throw new Error(ply.userId == null ? 'This public playlist cannot be deleted through the interface.' : 'Permission denied.')
db.run('DELETE Playlist WHERE id = ?', playlistId)
db.run('DELETE PlaylistEntry WHERE playlistId = ?', playlistId)
return true
}
async function addTrack (userId, playlistId, trackId) {
const db = await dbPromise
const p = await getPlaylist(playlistId)
if (!p) throw new Error('Invalid playlist.')
if (p.userId != null && p.userId !== userId) throw new Error('Permission denied.')
let alreadyExists = false
for (const i in p.tracks) {
const tr = p.tracks[i]
if (tr.trackId === parseInt(trackId)) {
alreadyExists = true
break
}
}
if (alreadyExists) throw new Error('This track is already in the playlist.')
return db.run('INSERT INTO PlaylistEntry (playlistId,trackId,userId,indx) VALUES (?,?,?,?)', playlistId, trackId, userId, p.tracks.length)
}
async function removeTrack (userId, playlistId, trackId) {
const db = await dbPromise
const p = await getPlaylist(playlistId)
if (!p) throw new Error('Invalid playlist.')
if (p.userId != null && p.userId !== userId) throw new Error('Permission denied.')
const trackEntry = await db.get('SELECT * FROM PlaylistEntry WHERE playlistId = ? AND trackId = ?', playlistId, trackId)
if (!trackEntry) throw new Error('This track is not in the playlist.')
return db.run('DELETE FROM PlaylistEntry WHERE id = ?', trackEntry.id)
}
async function moveTrack (userId, playlistId, trackId, position) {
const db = await dbPromise
const p = await getPlaylist(playlistId)
if (!p) throw new Error('Invalid playlist.')
if (p.userId != null && p.userId !== userId) throw new Error('Permission denied.')
const trackEntry = await db.get('SELECT * FROM PlaylistEntry WHERE playlistId = ? AND trackId = ?', playlistId, trackId)
if (!trackEntry) throw new Error('This track is not in the playlist.')
const trcksNew = []
for (const i in p.tracks) {
const trck = p.tracks[i]
if (trck.trackId === trackId) {
trck.indx = position
continue
}
if (trck.indx >= position) {
trck.indx++
}
trcksNew.push(trck)
}
// Update indexes
for (const i in trcksNew) {
const trck = trcksNew[i]
await db.run('UPDATE PlaylistEntry SET indx = ? WHERE trackId = ? AND playlistId = ?', trck.indx, trck.trackId, playlistId)
}
return true
}
export { getPlaylist, getPlaylists, createPlaylist, deletePlaylist, addTrack, removeTrack, moveTrack }