[db/filescanner/spotify] Replace filelist-view with separate

directories-table
to increase the performance of the mpd command 'lsinfo'
This commit is contained in:
chme
2015-12-27 07:16:50 +01:00
parent 3740486348
commit 7703a997c4
9 changed files with 1008 additions and 266 deletions

130
src/mpd.c
View File

@@ -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);
}