Merge pull request #1180 from ejurgensen/db_queue_refactor1

[db] Prepared statements for queue items + some refactoring
This commit is contained in:
ejurgensen 2021-02-16 17:34:26 +01:00 committed by GitHub
commit 07f012bd69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 548 additions and 427 deletions

782
src/db.c

File diff suppressed because it is too large Load Diff

View File

@ -197,7 +197,7 @@ struct media_file_info {
uint32_t time_played;
uint32_t time_skipped;
uint32_t disabled;
int64_t disabled; // Long because it stores up to INOTIFY_FAKE_COOKIE
uint64_t sample_count; //TODO [unused] sample count is never set and therefor always 0
char *codectype; /* song.codectype, 4 chars max (32 bits) */
@ -247,7 +247,7 @@ struct playlist_info {
enum pl_type type; /* see PL_ types */
char *query; /* where clause if type 1 (MSPS) */
uint32_t db_timestamp; /* time last updated */
uint32_t disabled;
int64_t disabled; /* long because it stores up to INOTIFY_FAKE_COOKIE */
char *path; /* path of underlying playlist */
uint32_t index; /* index of playlist for paths with multiple playlists */
uint32_t special_id; /* iTunes identifies certain 'special' playlists with special meaning */
@ -255,7 +255,7 @@ struct playlist_info {
uint32_t parent_id; /* Id of parent playlist if the playlist is nested */
uint32_t directory_id; /* Id of directory */
char *query_order; /* order by clause, used by e.g. a smart playlists */
int32_t query_limit; /* limit, used by e.g. smart playlists */
uint32_t query_limit; /* limit, used by e.g. smart playlists */
uint32_t media_kind;
char *artwork_url; /* optional artwork */
uint32_t items; /* number of items (mimc) */
@ -439,7 +439,7 @@ struct directory_info {
char *virtual_path;
char *path;
uint32_t db_timestamp;
uint32_t disabled;
int64_t disabled;
uint32_t parent_id;
};
@ -543,7 +543,7 @@ void
free_query_params(struct query_params *qp, int content_only);
void
free_queue_item(struct db_queue_item *queue_item, int content_only);
free_queue_item(struct db_queue_item *qi, int content_only);
/* Maintenance and DB hygiene */
void
@ -816,8 +816,14 @@ int
db_speaker_get(struct output_device *device, uint64_t id);
/* Queue */
void
db_queue_item_from_mfi(struct db_queue_item *qi, struct media_file_info *mfi); // Use free_queue_item(qi, 0) to free
void
db_queue_item_from_dbmfi(struct db_queue_item *qi, struct db_media_file_info *dbmfi); // Do not free qi content
int
db_queue_update_item(struct db_queue_item *queue_item);
db_queue_item_update(struct db_queue_item *qi);
int
db_queue_add_by_queryafteritemid(struct query_params *qp, uint32_t item_id);
@ -838,7 +844,7 @@ int
db_queue_add_end(struct db_queue_add_info *queue_add_info, char reshuffle, uint32_t item_id, int ret);
int
db_queue_add_item(struct db_queue_add_info *queue_add_info, struct db_queue_item *item);
db_queue_add_next(struct db_queue_add_info *queue_add_info, struct db_queue_item *qi);
int
db_queue_enum_start(struct query_params *qp);
@ -847,7 +853,7 @@ void
db_queue_enum_end(struct query_params *qp);
int
db_queue_enum_fetch(struct query_params *qp, struct db_queue_item *queue_item);
db_queue_enum_fetch(struct query_params *qp, struct db_queue_item *qi);
struct db_queue_item *
db_queue_fetch_byitemid(uint32_t item_id);

View File

@ -114,7 +114,7 @@
" parent_id INTEGER DEFAULT 0," \
" directory_id INTEGER DEFAULT 0," \
" query_order VARCHAR(1024)," \
" query_limit INTEGER DEFAULT -1," \
" query_limit INTEGER DEFAULT 0," \
" media_kind INTEGER DEFAULT 1," \
" artwork_url VARCHAR(4096) DEFAULT NULL" \
");"

View File

@ -26,7 +26,7 @@
* is a major upgrade. In other words minor version upgrades permit downgrading
* forked-daapd after the database was upgraded. */
#define SCHEMA_VERSION_MAJOR 21
#define SCHEMA_VERSION_MINOR 05
#define SCHEMA_VERSION_MINOR 06
int
db_init_indices(sqlite3 *hdl);

View File

@ -262,7 +262,8 @@ db_table_upgrade(sqlite3 *hdl, const char *name, const char *newtablequery)
return -1;
}
/* Upgrade from schema v17.00 to v18.00 */
/* ---------------------------- 17.00 -> 18.00 ------------------------------ */
/* Change playlist type enumeration and recreate filelist view (include smart
* playlists in view)
*/
@ -300,7 +301,7 @@ static const struct db_upgrade_query db_upgrade_v18_queries[] =
{ U_V18_SCVER_MINOR, "set schema_version_minor to 00" },
};
/* Upgrade from schema v18.00 to v18.01 */
/* ---------------------------- 18.00 -> 18.01 ------------------------------ */
/* Change virtual_path for playlists: remove file extension
*/
@ -326,7 +327,7 @@ static const struct db_upgrade_query db_upgrade_v1801_queries[] =
{ U_V1801_SCVER_MINOR, "set schema_version_minor to 01" },
};
/* Upgrade from schema v18.01 to v19.00 */
/* ---------------------------- 18.01 -> 19.00 ------------------------------ */
/* Replace 'filelist' view with new table 'directories'
*/
@ -601,7 +602,7 @@ db_upgrade_v19(sqlite3 *hdl)
return 0;
}
/* Upgrade from schema v19.00 to v19.01 */
/* ---------------------------- 19.00 -> 19.01 ------------------------------ */
/* Create new table queue for persistent playqueue
*/
@ -648,7 +649,7 @@ static const struct db_upgrade_query db_upgrade_v1901_queries[] =
{ U_V1901_SCVER_MINOR, "set schema_version_minor to 01" },
};
/* Upgrade from schema v19.01 to v19.02 */
/* ---------------------------- 19.01 -> 19.02 ------------------------------ */
/* Set key column as primary key in the admin table
*/
@ -690,6 +691,8 @@ static const struct db_upgrade_query db_upgrade_v1902_queries[] =
};
/* ---------------------------- 19.02 -> 19.03 ------------------------------ */
#define U_V1903_ALTER_QUEUE_ADD_ARTWORKURL \
"ALTER TABLE queue ADD COLUMN artwork_url VARCHAR(4096) DEFAULT NULL;"
@ -707,6 +710,8 @@ static const struct db_upgrade_query db_upgrade_v1903_queries[] =
};
/* ---------------------------- 19.03 -> 19.04 ------------------------------ */
#define U_V1904_ALTER_SPEAKERS_ADD_AUTHKEY \
"ALTER TABLE speakers ADD COLUMN auth_key VARCHAR(2048) DEFAULT NULL;"
@ -724,6 +729,8 @@ static const struct db_upgrade_query db_upgrade_v1904_queries[] =
};
/* ---------------------------- 19.04 -> 19.05 ------------------------------ */
#define U_V1905_SCVER_MINOR \
"UPDATE admin SET value = '05' WHERE key = 'schema_version_minor';"
@ -734,6 +741,8 @@ static const struct db_upgrade_query db_upgrade_v1905_queries[] =
};
/* ---------------------------- 19.05 -> 19.06 ------------------------------ */
#define U_V1906_DROP_TABLE_QUEUE \
"DROP TABLE queue;"
@ -784,6 +793,8 @@ static const struct db_upgrade_query db_upgrade_V1906_queries[] =
};
/* ---------------------------- 19.06 -> 19.07 ------------------------------ */
#define U_V1907_SCVER_MINOR \
"UPDATE admin SET value = '07' WHERE key = 'schema_version_minor';"
@ -794,6 +805,8 @@ static const struct db_upgrade_query db_upgrade_V1907_queries[] =
};
/* ---------------------------- 19.07 -> 19.08 ------------------------------ */
#define U_V1908_ALTER_PL_ADD_ORDER \
"ALTER TABLE playlists ADD COLUMN query_order VARCHAR(1024);"
#define U_V1908_ALTER_PL_ADD_LIMIT \
@ -811,6 +824,8 @@ static const struct db_upgrade_query db_upgrade_v1908_queries[] =
};
/* ---------------------------- 19.08 -> 19.09 ------------------------------ */
#define U_V1909_ALTER_FILES_ADD_SKIP_COUNT \
"ALTER TABLE files ADD COLUMN skip_count INTEGER DEFAULT 0;"
#define U_V1909_ALTER_FILES_ADD_TIME_SKIPPED \
@ -828,6 +843,8 @@ static const struct db_upgrade_query db_upgrade_v1909_queries[] =
};
/* ---------------------------- 19.09 -> 19.10 ------------------------------ */
// Clean up after bug in commit fde0a281 (schema 19.09)
#define U_V1910_CLEANUP_TIME_SKIPPED \
"UPDATE files SET time_skipped = 0 WHERE time_skipped > 2000000000;"
@ -843,6 +860,8 @@ static const struct db_upgrade_query db_upgrade_v1910_queries[] =
};
/* ---------------------------- 19.10 -> 19.11 ------------------------------ */
#define U_v1911_ALTER_QUEUE_ADD_COMPOSER \
"ALTER TABLE queue ADD COLUMN composer VARCHAR(1024) DEFAULT NULL;"
@ -860,6 +879,8 @@ static const struct db_upgrade_query db_upgrade_v1911_queries[] =
};
/* ---------------------------- 19.11 -> 19.12 ------------------------------ */
#define U_V1912_ALTER_DIRECTORIES_ADD_PATH \
"ALTER TABLE directories ADD COLUMN path VARCHAR(4096) DEFAULT NULL;"
@ -881,6 +902,8 @@ static const struct db_upgrade_query db_upgrade_v1912_queries[] =
};
/* ---------------------------- 19.12 -> 20.00 ------------------------------ */
#define U_V20_NEW_FILES_TABLE \
"CREATE TABLE new_files (" \
" id INTEGER PRIMARY KEY NOT NULL," \
@ -972,6 +995,9 @@ static const struct db_upgrade_query db_upgrade_v2000_queries[] =
{ U_V2000_SCVER_MINOR, "set schema_version_minor to 00" },
};
/* ---------------------------- 20.00 -> 20.01 ------------------------------ */
#define U_V2001_ALTER_QUEUE_ADD_SONGARTISTID \
"ALTER TABLE queue ADD COLUMN songartistid INTEGER NOT NULL default 0;"
#define U_V2001_SCVER_MINOR \
@ -983,6 +1009,9 @@ static const struct db_upgrade_query db_upgrade_v2001_queries[] =
{ U_V2001_SCVER_MINOR, "set schema_version_minor to 01" },
};
/* ---------------------------- 20.01 -> 21.00 ------------------------------ */
#define U_V2100_SCVER_MAJOR \
"UPDATE admin SET value = '21' WHERE key = 'schema_version_major';"
#define U_V2100_SCVER_MINOR \
@ -995,6 +1024,9 @@ static const struct db_upgrade_query db_upgrade_v2100_queries[] =
{ U_V2100_SCVER_MINOR, "set schema_version_minor to 00" },
};
/* ---------------------------- 21.00 -> 21.01 ------------------------------ */
#define U_v2101_ALTER_QUEUE_ADD_TYPE \
"ALTER TABLE queue ADD COLUMN type VARCHAR(8) DEFAULT NULL;"
#define U_v2101_ALTER_QUEUE_ADD_BITRATE \
@ -1020,6 +1052,9 @@ static const struct db_upgrade_query db_upgrade_v2101_queries[] =
{ U_v2101_SCVER_MINOR, "set schema_version_minor to 01" },
};
/* ---------------------------- 21.01 -> 21.02 ------------------------------ */
// This column added because Apple Music makes a DAAP request for playlists
// that has a query condition on extended-media-kind. We set the default value
// to 1 to signify music.
@ -1036,6 +1071,9 @@ static const struct db_upgrade_query db_upgrade_v2102_queries[] =
{ U_v2102_SCVER_MINOR, "set schema_version_minor to 02" },
};
/* ---------------------------- 21.02 -> 21.03 ------------------------------ */
#define U_V2103_SCVER_MAJOR \
"UPDATE admin SET value = '21' WHERE key = 'schema_version_major';"
#define U_V2103_SCVER_MINOR \
@ -1048,6 +1086,9 @@ static const struct db_upgrade_query db_upgrade_v2103_queries[] =
{ U_V2103_SCVER_MINOR, "set schema_version_minor to 03" },
};
/* ---------------------------- 21.03 -> 21.04 ------------------------------ */
#define U_v2104_ALTER_PLAYLISTS_ADD_ARTWORK_URL \
"ALTER TABLE playlists ADD COLUMN artwork_url VARCHAR(4096) DEFAULT NULL;"
#define U_v2104_SCVER_MINOR \
@ -1060,6 +1101,9 @@ static const struct db_upgrade_query db_upgrade_v2104_queries[] =
{ U_v2104_SCVER_MINOR, "set schema_version_minor to 04" },
};
/* ---------------------------- 21.04 -> 21.05 ------------------------------ */
// Previously, the auth_key contained the public key twice
#define U_v2105_UPDATE_SPEAKERS_AUTH_KEY \
"UPDATE speakers SET auth_key = SUBSTR(auth_key, LENGTH(auth_key) - 128 + 1, LENGTH(auth_key) + 1) WHERE LENGTH(auth_key) = 128 + 64;"
@ -1074,6 +1118,51 @@ static const struct db_upgrade_query db_upgrade_v2105_queries[] =
};
/* ---------------------------- 21.05 -> 21.06 ------------------------------ */
// Reload table, required for changing the default of query_limit from -1 to 0
#define U_V2106_NEW_PLAYLISTS_TABLE \
"CREATE TABLE new_playlists (" \
" id INTEGER PRIMARY KEY NOT NULL," \
" title VARCHAR(255) NOT NULL COLLATE DAAP," \
" type INTEGER NOT NULL," \
" query VARCHAR(1024)," \
" db_timestamp INTEGER NOT NULL," \
" disabled INTEGER DEFAULT 0," \
" path VARCHAR(4096)," \
" idx INTEGER NOT NULL," \
" special_id INTEGER DEFAULT 0," \
" virtual_path VARCHAR(4096)," \
" parent_id INTEGER DEFAULT 0," \
" directory_id INTEGER DEFAULT 0," \
" query_order VARCHAR(1024)," \
" query_limit INTEGER DEFAULT 0," \
" media_kind INTEGER DEFAULT 1," \
" artwork_url VARCHAR(4096) DEFAULT NULL" \
");"
static int
db_upgrade_v2106(sqlite3 *hdl)
{
return db_table_upgrade(hdl, "playlists", U_V2106_NEW_PLAYLISTS_TABLE);
}
// Previously, query_limit had multiple defaults: -1, 0 and UINT32_MAX
#define U_v2106_UPDATE_PLAYLISTS_QUERY_LIMIT \
"UPDATE playlists SET query_limit = 0 WHERE query_limit = -1 OR query_limit = 4294967295;"
#define U_v2106_SCVER_MINOR \
"UPDATE admin SET value = '06' WHERE key = 'schema_version_minor';"
static const struct db_upgrade_query db_upgrade_v2106_queries[] =
{
{ U_v2106_UPDATE_PLAYLISTS_QUERY_LIMIT, "update table playlists query_limit default" },
{ U_v2106_SCVER_MINOR, "set schema_version_minor to 06" },
};
/* -------------------------- Main upgrade handler -------------------------- */
int
db_upgrade(sqlite3 *hdl, int db_ver)
{
@ -1257,6 +1346,18 @@ db_upgrade(sqlite3 *hdl, int db_ver)
if (ret < 0)
return -1;
/* FALLTHROUGH */
case 2105:
ret = db_upgrade_v2106(hdl);
if (ret < 0)
return -1;
ret = db_generic_upgrade(hdl, db_upgrade_v2106_queries, ARRAY_SIZE(db_upgrade_v2106_queries));
if (ret < 0)
return -1;
/* Last case statement is the only one that ends with a break statement! */
break;

View File

@ -2607,7 +2607,7 @@ jsonapi_reply_queue_tracks_update(struct httpd_request *hreq)
return ret;
if (is_changed)
db_queue_update_item(queue_item);
db_queue_item_update(queue_item);
return HTTP_NOCONTENT;
}

View File

@ -1742,47 +1742,11 @@ filescanner_fullrescan()
return 0;
}
static void
map_media_file_to_queue_item(struct db_queue_item *queue_item, struct media_file_info *mfi)
{
memset(queue_item, 0, sizeof(struct db_queue_item));
if (mfi->id)
queue_item->file_id = mfi->id;
else
queue_item->file_id = DB_MEDIA_FILE_NON_PERSISTENT_ID;
queue_item->title = safe_strdup(mfi->title);
queue_item->artist = safe_strdup(mfi->artist);
queue_item->album_artist = safe_strdup(mfi->album_artist);
queue_item->album = safe_strdup(mfi->album);
queue_item->genre = safe_strdup(mfi->genre);
queue_item->artist_sort = safe_strdup(mfi->artist_sort);
queue_item->album_artist_sort = safe_strdup(mfi->album_artist_sort);
queue_item->album_sort = safe_strdup(mfi->album_sort);
queue_item->path = safe_strdup(mfi->path);
queue_item->virtual_path = safe_strdup(mfi->virtual_path);
queue_item->data_kind = mfi->data_kind;
queue_item->media_kind = mfi->media_kind;
queue_item->song_length = mfi->song_length;
queue_item->seek = mfi->seek;
queue_item->songalbumid = mfi->songalbumid;
queue_item->time_modified = mfi->time_modified;
queue_item->year = mfi->year;
queue_item->track = mfi->track;
queue_item->disc = mfi->disc;
//queue_item->artwork_url
queue_item->type = safe_strdup(mfi->type);
queue_item->channels = mfi->channels;
queue_item->samplerate = mfi->samplerate;
queue_item->bitrate = mfi->bitrate;
}
static int
queue_item_stream_add(const char *path, int position, char reshuffle, uint32_t item_id, int *count, int *new_item_id)
{
struct media_file_info mfi;
struct db_queue_item item;
struct db_queue_item qi;
struct db_queue_add_info queue_add_info;
int ret;
@ -1790,12 +1754,12 @@ queue_item_stream_add(const char *path, int position, char reshuffle, uint32_t i
scan_metadata_stream(&mfi, path);
map_media_file_to_queue_item(&item, &mfi);
db_queue_item_from_mfi(&qi, &mfi);
ret = db_queue_add_start(&queue_add_info, position);
if (ret == 0)
{
ret = db_queue_add_item(&queue_add_info, &item);
ret = db_queue_add_next(&queue_add_info, &qi);
ret = db_queue_add_end(&queue_add_info, reshuffle, item_id, ret);
if (ret == 0)
{
@ -1806,7 +1770,7 @@ queue_item_stream_add(const char *path, int position, char reshuffle, uint32_t i
}
}
free_queue_item(&item, 1);
free_queue_item(&qi, 1);
free_mfi(&mfi, 1);
return 0;

View File

@ -73,7 +73,7 @@ scan_smartpl(const char *file, time_t mtime, int dir_id)
swap_pointers(&pli->title, &smartpl.title);
swap_pointers(&pli->query, &smartpl.query_where);
swap_pointers(&pli->query_order, &smartpl.order);
pli->query_limit = smartpl.limit;
pli->query_limit = (smartpl.limit > 0) ? smartpl.limit : 0;
free_smartpl(&smartpl, 1);

View File

@ -601,7 +601,7 @@ metadata_update_queue_cb(void *arg)
if (metadata->len_ms)
queue_item->song_length = metadata->len_ms;
ret = db_queue_update_item(queue_item);
ret = db_queue_item_update(queue_item);
if (ret < 0)
DPRINTF(E_LOG, L_PLAYER, "Database error while updating queue with new metadata\n");
}

View File

@ -1080,7 +1080,7 @@ queue_add_track(const char *uri, int position, char reshuffle, uint32_t item_id,
ret = db_queue_add_start(&queue_add_info, position);
if (ret == 0)
{
ret = db_queue_add_item(&queue_add_info, &item);
ret = db_queue_add_next(&queue_add_info, &item);
ret = db_queue_add_end(&queue_add_info, reshuffle, item_id, ret);
if (ret == 0)
{
@ -1122,7 +1122,7 @@ queue_add_album_tracks(json_object *item, int index, int total, enum spotify_req
map_track_to_queueitem(&queue_item, &track, &param->album);
ret = db_queue_add_item(&param->queue_add_info, &queue_item);
ret = db_queue_add_next(&param->queue_add_info, &queue_item);
free_queue_item(&queue_item, 1);
@ -1236,7 +1236,7 @@ queue_add_playlist_tracks(json_object *item, int index, int total, enum spotify_
map_track_to_queueitem(&queue_item, &track, NULL);
ret = db_queue_add_item(queue_add_info, &queue_item);
ret = db_queue_add_next(queue_add_info, &queue_item);
free_queue_item(&queue_item, 1);