mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-28 08:05:56 -05:00
[db] Add support to add items to the queue at specified position
This commit is contained in:
parent
197fc6402e
commit
7252b3e509
119
src/db.c
119
src/db.c
@ -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;
|
||||
}
|
||||
|
6
src/db.h
6
src/db.h
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
25
src/mpd.c
25
src/mpd.c
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user