[db] Add support to add items to the queue at specified position

This commit is contained in:
chme 2018-09-06 21:16:27 +02:00
parent 197fc6402e
commit 7252b3e509
6 changed files with 77 additions and 89 deletions

119
src/db.c
View File

@ -4612,7 +4612,7 @@ queue_add_file(struct db_media_file_info *dbmfi, int pos, int shuffle_pos, int q
query = sqlite3_mprintf(Q_TMPL,
dbmfi->id, dbmfi->song_length, dbmfi->data_kind, dbmfi->media_kind,
pos, pos, dbmfi->path, dbmfi->virtual_path, dbmfi->title,
pos, shuffle_pos, dbmfi->path, dbmfi->virtual_path, dbmfi->title,
dbmfi->artist, dbmfi->album_artist, dbmfi->album, dbmfi->genre, dbmfi->songalbumid,
dbmfi->time_modified, dbmfi->artist_sort, dbmfi->album_sort, dbmfi->album_artist_sort, dbmfi->year,
dbmfi->track, dbmfi->disc, queue_version);
@ -4710,66 +4710,18 @@ db_queue_update_item(struct db_queue_item *qi)
int
db_queue_add_by_queryafteritemid(struct query_params *qp, uint32_t item_id)
{
int queue_version;
struct db_media_file_info dbmfi;
char *query;
int shuffle_pos;
int pos;
int ret;
queue_version = queue_transaction_begin();
// Position of the first new item
pos = db_queue_get_pos(item_id, 0);
if (pos < 0)
{
ret = -1;
goto end_transaction;
return -1;
}
pos++;
// Shuffle position of the first new item
shuffle_pos = db_queue_get_count();
if (shuffle_pos < 0)
{
ret = -1;
goto end_transaction;
}
// Start query for new items from files table
ret = db_query_start(qp);
if (ret < 0)
goto end_transaction;
DPRINTF(E_DBG, L_DB, "Player queue query returned %d items\n", qp->results);
// Update pos for all items after the item with item_id
query = sqlite3_mprintf("UPDATE queue SET pos = pos + %d, queue_version = %d WHERE pos > %d;", qp->results, queue_version, (pos - 1));
ret = db_query_run(query, 1, 0);
if (ret < 0)
goto end_transaction;
// Iterate over new items from files table and insert into queue
while (((ret = db_query_fetch_file(qp, &dbmfi)) == 0) && (dbmfi.id))
{
ret = queue_add_file(&dbmfi, pos, shuffle_pos, queue_version);
if (ret < 0)
{
DPRINTF(E_LOG, L_DB, "Failed to add song with id %s (%s) to queue\n", dbmfi.id, dbmfi.title);
break;
}
DPRINTF(E_DBG, L_DB, "Added song with id %s (%s) to queue\n", dbmfi.id, dbmfi.title);
shuffle_pos++;
pos++;
}
db_query_end(qp);
end_transaction:
queue_transaction_end(ret, queue_version);
ret = db_queue_add_by_query(qp, 0, 0, pos, NULL, NULL);
return ret;
}
@ -4825,21 +4777,30 @@ db_queue_add_item(struct db_queue_add_info *queue_add_info, struct db_queue_item
* @param qp Query parameters for the files table
* @param reshuffle If 1 queue will be reshuffled after adding new items
* @param item_id The base item id, all items after this will be reshuffled
* @return Item id of the last inserted item on success, -1 on failure
* @param position The position in the queue for the new queue item, -1 to add at end of queue
* @param count If not NULL returns the number of items added to the queue
* @param new_item_id If not NULL return the queue item id of the first new queue item
* @return 0 on success, -1 on failure
*/
int
db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id)
db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id, int position, int *count, int *new_item_id)
{
struct db_media_file_info dbmfi;
char *query;
int queue_version;
int queue_count;
int pos;
int new_item_id = 0; // Quell compiler warning about uninitialized use of new_item_id
int ret;
if (new_item_id)
*new_item_id = 0;
if (count)
*count = 0;
queue_version = queue_transaction_begin();
pos = db_queue_get_count();
if (pos < 0)
queue_count = db_queue_get_count();
if (queue_count < 0)
{
ret = -1;
goto end_transaction;
@ -4858,9 +4819,24 @@ db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id)
return 0;
}
if (position < 0 || position > queue_count)
{
pos = queue_count;
}
else
{
pos = position;
// Update pos for all items from the given position (make room for the new items in the queue)
query = sqlite3_mprintf("UPDATE queue SET pos = pos + %d, queue_version = %d WHERE pos >= %d;", qp->results, queue_version, pos);
ret = db_query_run(query, 1, 0);
if (ret < 0)
goto end_transaction;
}
while (((ret = db_query_fetch_file(qp, &dbmfi)) == 0) && (dbmfi.id))
{
ret = queue_add_file(&dbmfi, pos, pos, queue_version);
ret = queue_add_file(&dbmfi, pos, queue_count, queue_version);
if (ret < 0)
{
@ -4869,7 +4845,14 @@ db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id)
}
DPRINTF(E_DBG, L_DB, "Added song id %s (%s) to queue\n", dbmfi.id, dbmfi.title);
if (new_item_id && *new_item_id == 0)
*new_item_id = (int) sqlite3_last_insert_rowid(hdl);
if (count)
(*count)++;
pos++;
queue_count++;
}
db_query_end(qp);
@ -4877,8 +4860,6 @@ db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id)
if (ret < 0)
goto end_transaction;
new_item_id = (int) sqlite3_last_insert_rowid(hdl);
// Reshuffle after adding new items
if (reshuffle)
{
@ -4888,7 +4869,7 @@ db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id)
end_transaction:
queue_transaction_end(ret, queue_version);
return (ret == 0) ? new_item_id : ret;
return ret;
}
/*
@ -4897,10 +4878,13 @@ db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id)
* @param plid Id of the stored playlist
* @param reshuffle If 1 queue will be reshuffled after adding new items
* @param item_id The base item id, all items after this will be reshuffled
* @return Item id of the last inserted item on success, -1 on failure
* @param position The position in the queue for the new queue item, -1 to add at end of queue
* @param count If not NULL returns the number of items added to the queue
* @param new_item_id If not NULL return the queue item id of the first new queue item
* @return 0 on success, -1 on failure
*/
int
db_queue_add_by_playlistid(int plid, char reshuffle, uint32_t item_id)
db_queue_add_by_playlistid(int plid, char reshuffle, uint32_t item_id, int position, int *count, int *new_item_id)
{
struct query_params qp;
int ret;
@ -4910,7 +4894,7 @@ db_queue_add_by_playlistid(int plid, char reshuffle, uint32_t item_id)
qp.id = plid;
qp.type = Q_PLITEMS;
ret = db_queue_add_by_query(&qp, reshuffle, item_id);
ret = db_queue_add_by_query(&qp, reshuffle, item_id, position, count, new_item_id);
return ret;
}
@ -4921,10 +4905,13 @@ db_queue_add_by_playlistid(int plid, char reshuffle, uint32_t item_id)
* @param id Id of the file
* @param reshuffle If 1 queue will be reshuffled after adding new items
* @param item_id The base item id, all items after this will be reshuffled
* @return Item id of the last inserted item on success, -1 on failure
* @param position The position in the queue for the new queue item, -1 to add at end of queue
* @param count If not NULL returns the number of items added to the queue
* @param new_item_id If not NULL return the queue item id of the first new queue item
* @return 0 on success, -1 on failure
*/
int
db_queue_add_by_fileid(int id, char reshuffle, uint32_t item_id)
db_queue_add_by_fileid(int id, char reshuffle, uint32_t item_id, int position, int *count, int *new_item_id)
{
struct query_params qp;
char buf[124];
@ -4936,7 +4923,7 @@ db_queue_add_by_fileid(int id, char reshuffle, uint32_t item_id)
snprintf(buf, sizeof(buf), "f.id = %" PRIu32, id);
qp.filter = buf;
ret = db_queue_add_by_query(&qp, reshuffle, item_id);
ret = db_queue_add_by_query(&qp, reshuffle, item_id, position, count, new_item_id);
return ret;
}

View File

@ -778,13 +778,13 @@ int
db_queue_add_by_queryafteritemid(struct query_params *qp, uint32_t item_id);
int
db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id);
db_queue_add_by_query(struct query_params *qp, char reshuffle, uint32_t item_id, int position, int *count, int *new_item_id);
int
db_queue_add_by_playlistid(int plid, char reshuffle, uint32_t item_id);
db_queue_add_by_playlistid(int plid, char reshuffle, uint32_t item_id, int position, int *count, int *new_item_id);
int
db_queue_add_by_fileid(int id, char reshuffle, uint32_t item_id);
db_queue_add_by_fileid(int id, char reshuffle, uint32_t item_id, int position, int *count, int *new_item_id);
int
db_queue_add_start(struct db_queue_add_info *queue_add_info);

View File

@ -414,7 +414,7 @@ dacp_queueitem_add(const char *query, const char *queuefilter, const char *sort,
if (mode == 3)
ret = db_queue_add_by_queryafteritemid(&qp, status.item_id);
else
ret = db_queue_add_by_query(&qp, status.shuffle, status.item_id);
ret = db_queue_add_by_query(&qp, status.shuffle, status.item_id, -1, NULL, NULL);
if (qp.filter)
free(qp.filter);
@ -1446,9 +1446,9 @@ dacp_reply_playspec(struct httpd_request *hreq)
db_queue_clear(0);
if (plid > 0)
ret = db_queue_add_by_playlistid(plid, status.shuffle, status.item_id);
ret = db_queue_add_by_playlistid(plid, status.shuffle, status.item_id, -1, NULL, NULL);
else if (id > 0)
ret = db_queue_add_by_fileid(id, status.shuffle, status.item_id);
ret = db_queue_add_by_fileid(id, status.shuffle, status.item_id, -1, NULL, NULL);
if (ret < 0)
{

View File

@ -1559,7 +1559,7 @@ queue_tracks_add_artist(const char *id)
player_get_status(&status);
ret = db_queue_add_by_query(&query_params, status.shuffle, status.item_id);
ret = db_queue_add_by_query(&query_params, status.shuffle, status.item_id, -1, NULL, NULL);
free(query_params.filter);
@ -1582,7 +1582,7 @@ queue_tracks_add_album(const char *id)
player_get_status(&status);
ret = db_queue_add_by_query(&query_params, status.shuffle, status.item_id);
ret = db_queue_add_by_query(&query_params, status.shuffle, status.item_id, -1, NULL, NULL);
free(query_params.filter);
@ -1605,7 +1605,7 @@ queue_tracks_add_track(const char *id)
player_get_status(&status);
ret = db_queue_add_by_query(&query_params, status.shuffle, status.item_id);
ret = db_queue_add_by_query(&query_params, status.shuffle, status.item_id, -1, NULL, NULL);
free(query_params.filter);
@ -1629,7 +1629,7 @@ queue_tracks_add_playlist(const char *id)
player_get_status(&status);
ret = db_queue_add_by_playlistid(playlist_id, status.shuffle, status.item_id);
ret = db_queue_add_by_playlistid(playlist_id, status.shuffle, status.item_id, -1, NULL, NULL);
return ret;
}

View File

@ -1641,12 +1641,14 @@ mpd_command_stop(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, s
* @return The queue item id of the last inserted item or -1 on failure
*/
static int
mpd_queue_add(char *path, bool exact_match)
mpd_queue_add(char *path, bool exact_match, int position)
{
struct query_params qp;
struct player_status status;
int new_item_id;
int ret;
new_item_id = 0;
memset(&qp, 0, sizeof(struct query_params));
qp.type = Q_ITEMS;
@ -1666,9 +1668,13 @@ mpd_queue_add(char *path, bool exact_match)
player_get_status(&status);
ret = db_queue_add_by_query(&qp, status.shuffle, status.item_id);
ret = db_queue_add_by_query(&qp, status.shuffle, status.item_id, position, NULL, &new_item_id);
free(qp.filter);
if (ret == 0)
return new_item_id;
return ret;
}
@ -1682,7 +1688,7 @@ mpd_command_add(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, st
{
int ret;
ret = mpd_queue_add(argv[1], false);
ret = mpd_queue_add(argv[1], false, -1);
if (ret < 0)
{
@ -1726,7 +1732,7 @@ mpd_command_addid(struct evbuffer *evbuf, int argc, char **argv, char **errmsg,
}
}
ret = mpd_queue_add(argv[1], true);
ret = mpd_queue_add(argv[1], true, to_pos);
if (ret == 0)
{
@ -1745,11 +1751,6 @@ mpd_command_addid(struct evbuffer *evbuf, int argc, char **argv, char **errmsg,
return ACK_ERROR_UNKNOWN;
}
if (to_pos >= 0)
{
db_queue_move_byitemid(ret, to_pos, 0);
}
evbuffer_add_printf(evbuf,
"Id: %d\n",
ret); // mpd_queue_add returns the item_id of the last inserted queue item
@ -2463,7 +2464,7 @@ mpd_command_load(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, s
player_get_status(&status);
ret = db_queue_add_by_playlistid(pli->id, status.shuffle, status.item_id);
ret = db_queue_add_by_playlistid(pli->id, status.shuffle, status.item_id, -1, NULL, NULL);
free_pli(pli, 0);
if (ret < 0)
{
@ -2687,7 +2688,7 @@ mpd_command_findadd(struct evbuffer *evbuf, int argc, char **argv, char **errmsg
player_get_status(&status);
ret = db_queue_add_by_query(&qp, status.shuffle, status.item_id);
ret = db_queue_add_by_query(&qp, status.shuffle, status.item_id, -1, NULL, NULL);
free(qp.filter);
if (ret < 0)
{
@ -3175,7 +3176,7 @@ mpd_command_searchadd(struct evbuffer *evbuf, int argc, char **argv, char **errm
player_get_status(&status);
ret = db_queue_add_by_query(&qp, status.shuffle, status.item_id);
ret = db_queue_add_by_query(&qp, status.shuffle, status.item_id, -1, NULL, NULL);
free(qp.filter);
if (ret < 0)
{

View File

@ -2111,7 +2111,7 @@ playback_start_id(void *arg, int *retval)
{
db_queue_clear(0);
ret = db_queue_add_by_fileid(cmdarg->id, 0, 0);
ret = db_queue_add_by_fileid(cmdarg->id, 0, 0, -1, NULL, NULL);
if (ret < 0)
return COMMAND_END;