mirror of
https://github.com/owntone/owntone-server.git
synced 2025-11-24 03:27:46 -05:00
[db/filescanner/spotify] Replace filelist-view with separate
directories-table to increase the performance of the mpd command 'lsinfo'
This commit is contained in:
130
src/mpd.c
130
src/mpd.c
@@ -2692,12 +2692,16 @@ mpd_command_list(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
static int
|
||||
mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
{
|
||||
int dir_id;
|
||||
struct directory_info subdir;
|
||||
struct query_params qp;
|
||||
struct directory_enum dir_enum;
|
||||
char parent[PATH_MAX];
|
||||
struct filelist_info *fi;
|
||||
struct media_file_info *mfi;
|
||||
char modified[32];
|
||||
int print_playlists;
|
||||
struct db_playlist_info dbpli;
|
||||
char modified[32];
|
||||
uint32_t time_modified;
|
||||
struct db_media_file_info dbmfi;
|
||||
int ret;
|
||||
|
||||
if (argc < 2 || strlen(argv[1]) == 0
|
||||
@@ -2711,7 +2715,7 @@ mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = snprintf(parent, sizeof(parent), "/%s/", argv[1]);
|
||||
ret = snprintf(parent, sizeof(parent), "/%s", argv[1]);
|
||||
}
|
||||
|
||||
if ((ret < 0) || (ret >= sizeof(parent)))
|
||||
@@ -2731,72 +2735,94 @@ mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||
print_playlists = 1;
|
||||
}
|
||||
|
||||
fi = (struct filelist_info*)malloc(sizeof(struct filelist_info));
|
||||
if (!fi)
|
||||
|
||||
// Load dir-id from db for parent-path
|
||||
dir_id = db_directory_id_byvirtualpath(parent);
|
||||
if (dir_id == 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory for fi\n");
|
||||
return ACK_ERROR_UNKNOWN;
|
||||
DPRINTF(E_LOG, L_MPD, "Directory info not found for virtual-path '%s'\n", parent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load playlists for dir-id
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
|
||||
ret = db_mpd_start_query_filelist(&qp, parent);
|
||||
qp.type = Q_PL;
|
||||
qp.sort = S_PLAYLIST;
|
||||
qp.idx_type = I_NONE;
|
||||
qp.filter = sqlite3_mprintf("(directory_id = %d AND (f.type = %d OR f.type = %d))", dir_id, PL_PLAIN, PL_SMART);
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = asprintf(errmsg, "Could not start query for path '%s'", argv[1]);
|
||||
db_query_end(&qp);
|
||||
ret = asprintf(errmsg, "Could not start query");
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||
|
||||
free_fi(fi, 0);
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||
return ACK_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
while (((ret = db_mpd_query_fetch_filelist(&qp, fi)) == 0) && (fi->virtual_path))
|
||||
while (((ret = db_query_fetch_pl(&qp, &dbpli)) == 0) && (dbpli.id))
|
||||
{
|
||||
if (fi->type == F_DIR)
|
||||
if (safe_atou32(dbpli.db_timestamp, &time_modified) != 0)
|
||||
{
|
||||
mpd_time(modified, sizeof(modified), fi->time_modified);
|
||||
|
||||
evbuffer_add_printf(evbuf,
|
||||
"directory: %s\n"
|
||||
"Last-Modified: %s\n",
|
||||
(fi->virtual_path + 1),
|
||||
modified);
|
||||
}
|
||||
else if (fi->type == F_PLAYLIST)
|
||||
{
|
||||
mpd_time(modified, sizeof(modified), fi->time_modified);
|
||||
|
||||
evbuffer_add_printf(evbuf,
|
||||
"playlist: %s\n"
|
||||
"Last-Modified: %s\n",
|
||||
(fi->virtual_path + 1),
|
||||
modified);
|
||||
}
|
||||
else if (fi->type == F_FILE)
|
||||
{
|
||||
mfi = db_file_fetch_byvirtualpath(fi->virtual_path);
|
||||
if (mfi)
|
||||
{
|
||||
ret = mpd_add_mediainfo(evbuf, mfi, 0, -1);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Could not add mediainfo for path '%s'\n", fi->virtual_path);
|
||||
}
|
||||
|
||||
free_mfi(mfi, 0);
|
||||
}
|
||||
DPRINTF(E_LOG, L_MPD, "Error converting time modified to uint32_t: %s\n", dbpli.db_timestamp);
|
||||
return -1;
|
||||
}
|
||||
mpd_time(modified, sizeof(modified), time_modified);
|
||||
evbuffer_add_printf(evbuf,
|
||||
"playlist: %s\n"
|
||||
"Last-Modified: %s\n",
|
||||
(dbpli.virtual_path + 1),
|
||||
modified);
|
||||
}
|
||||
db_query_end(&qp);
|
||||
sqlite3_free(qp.filter);
|
||||
|
||||
// Load sub directories for dir-id
|
||||
memset(&dir_enum, 0, sizeof(struct directory_enum));
|
||||
dir_enum.parent_id = dir_id;
|
||||
ret = db_directory_enum_start(&dir_enum);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Failed to start directory enum for parent_id %d\n", dir_id);
|
||||
return -1;
|
||||
}
|
||||
while ((ret = db_directory_enum_fetch(&dir_enum, &subdir)) == 0 && subdir.id > 0)
|
||||
{
|
||||
evbuffer_add_printf(evbuf,
|
||||
"directory: %s\n"
|
||||
"Last-Modified: %s\n",
|
||||
(subdir.virtual_path + 1),
|
||||
"2015-12-01 00:00");
|
||||
}
|
||||
db_directory_enum_end(&dir_enum);
|
||||
|
||||
// Load files for dir-id
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
qp.type = Q_ITEMS;
|
||||
qp.sort = S_ARTIST;
|
||||
qp.idx_type = I_NONE;
|
||||
qp.filter = sqlite3_mprintf("(directory_id = %d)", dir_id);
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
db_query_end(&qp);
|
||||
ret = asprintf(errmsg, "Could not start query");
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
|
||||
return ACK_ERROR_UNKNOWN;
|
||||
}
|
||||
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
|
||||
{
|
||||
ret = mpd_add_db_media_file_info(evbuf, &dbmfi);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MPD, "Error adding song to the evbuffer, song id: %s\n", dbmfi.id);
|
||||
}
|
||||
}
|
||||
db_query_end(&qp);
|
||||
|
||||
if (fi)
|
||||
free_fi(fi, 0);
|
||||
|
||||
// If the root directory was passed as argument add the stored playlists to the response
|
||||
if (print_playlists)
|
||||
{
|
||||
// If the root directory was passed as argument add the stored playlists to the response
|
||||
return mpd_command_listplaylists(evbuf, argc, argv, errmsg);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user