From df5b0f779a2ae96f72d702e5d4af87ea0064e6f2 Mon Sep 17 00:00:00 2001 From: chme Date: Sat, 14 Feb 2015 08:46:21 +0100 Subject: [PATCH] Use view for filelist instead of separate table --- sqlext/sqlext.c | 124 +++++++++++++++ src/db.c | 399 ++++++++++-------------------------------------- src/db.h | 11 +- src/mpd.c | 19 +-- 4 files changed, 218 insertions(+), 335 deletions(-) diff --git a/sqlext/sqlext.c b/sqlext/sqlext.c index da993b24..4c3759e9 100644 --- a/sqlext/sqlext.c +++ b/sqlext/sqlext.c @@ -244,6 +244,112 @@ sqlext_daap_unicode_xcollation(void *notused, int llen, const void *left, int rl return rpp; } +static void +sqlext_daap_substring_xfunc(sqlite3_context *pv, int n, sqlite3_value **ppv) +{ + const unsigned char *s1; + const unsigned char *s2; + int index; + + char *start; + char *end; + char *result; + + if (n < 2) + { + sqlite3_result_error(pv, "daap_substring() requires at least 2 parameters", -1); + return; + } + + if (SQLITE_TEXT != sqlite3_value_type(ppv[0]) || SQLITE_TEXT != sqlite3_value_type(ppv[1])) + { + sqlite3_result_null(pv); + return; + } + + s1 = sqlite3_value_text(ppv[0]); + s2 = sqlite3_value_text(ppv[1]); + + if (n > 2) + index = sqlite3_value_int(ppv[2]); + else + index = 0; + + if (strlen((char *) s1) < index) + { + sqlite3_result_null(pv); + return; + } + + start = (char *) s1 + index; + end = strstr(start, (char *) s2); + + if (!end) + { + sqlite3_result_null(pv); + return; + } + + result = sqlite3_malloc(end - (char *) s1 + 1); + if (!result) + { + sqlite3_result_error_nomem(pv); + return; + } + + strncpy((char*) result, (char*) s1, end - (char *) s1); + *(result + (end - (char *) s1)) = '\0'; + sqlite3_result_text(pv, (char*) result, -1, SQLITE_TRANSIENT); + sqlite3_free(result); +} + +static void +sqlext_daap_charindex_xfunc(sqlite3_context *pv, int n, sqlite3_value **ppv) +{ + const unsigned char *s1; + const unsigned char *s2; + int index; + + char *start; + char *end; + + if (n < 2) + { + sqlite3_result_error(pv, "daap_charindex() requires at least 2 parameters", -1); + return; + } + + if (SQLITE_TEXT != sqlite3_value_type(ppv[0]) || SQLITE_TEXT != sqlite3_value_type(ppv[1])) + { + sqlite3_result_int(pv, -1); + return; + } + + s1 = sqlite3_value_text(ppv[0]); + s2 = sqlite3_value_text(ppv[1]); + + if (n > 2) + index = sqlite3_value_int(ppv[2]); + else + index = 0; + + if (strlen((char *) s1) < index) + { + sqlite3_result_int(pv, -1); + return; + } + + start = (char *) s1 + index; + end = strstr(start, (char *) s2); + + if (!end) + { + sqlite3_result_int(pv, -1); + return; + } + + sqlite3_result_int(pv, end - (char *) s1); +} int sqlite3_extension_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) @@ -269,5 +375,23 @@ sqlite3_extension_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines return -1; } + ret = sqlite3_create_function(db, "daap_substring", 3, SQLITE_UTF8, NULL, sqlext_daap_substring_xfunc, NULL, NULL); + if (ret != SQLITE_OK) + { + if (pzErrMsg) + *pzErrMsg = sqlite3_mprintf("Could not create daap_substring function: %s\n", sqlite3_errmsg(db)); + + return -1; + } + + ret = sqlite3_create_function(db, "daap_charindex", 3, SQLITE_UTF8, NULL, sqlext_daap_charindex_xfunc, NULL, NULL); + if (ret != SQLITE_OK) + { + if (pzErrMsg) + *pzErrMsg = sqlite3_mprintf("Could not create daap_charindex function: %s\n", sqlite3_errmsg(db)); + + return -1; + } + return 0; } diff --git a/src/db.c b/src/db.c index 12f29c25..e90ca3ba 100644 --- a/src/db.c +++ b/src/db.c @@ -324,12 +324,8 @@ db_escape_string(const char *str) void free_fi(struct filelist_info *fi, int content_only) { - if (fi->path) - free(fi->path); - if (fi->name) - free(fi->name); - if (fi->parentpath) - free(fi->parentpath); + if (fi->virtual_path) + free(fi->virtual_path); if (!content_only) free(fi); @@ -769,13 +765,9 @@ db_purge_cruft(time_t ref) char *errmsg; int i; int ret; - int changes; - char *query; - char *queries[5] = { NULL, NULL, NULL, NULL, NULL }; - char *queries_tmpl[5] = + char *queries[3] = { NULL, NULL, NULL }; + char *queries_tmpl[3] = { - "DELETE FROM filelist WHERE type = 3 AND path IN (SELECT path FROM files f WHERE f.db_timestamp < %" PRIi64 ");", - "DELETE FROM filelist WHERE type = 1 AND path IN (SELECT path FROM playlists p WHERE p.type <> 1 AND p.db_timestamp < %" PRIi64 ");", "DELETE FROM playlistitems WHERE playlistid IN (SELECT id FROM playlists p WHERE p.type <> 1 AND p.db_timestamp < %" PRIi64 ");", "DELETE FROM playlists WHERE type <> 1 AND db_timestamp < %" PRIi64 ";", "DELETE FROM files WHERE db_timestamp < %" PRIi64 ";" @@ -812,29 +804,6 @@ db_purge_cruft(time_t ref) DPRINTF(E_DBG, L_DB, "Purged %d rows\n", sqlite3_changes(hdl)); } - // Remove empty directories from filelist table - query = "DELETE FROM filelist WHERE type = 2 AND 0 = (SELECT COUNT(path) FROM filelist f WHERE f.parentpath = filelist.path);"; - - do - { - DPRINTF(E_DBG, L_DB, "Running purge query '%s'\n", query); - - ret = db_exec(query, &errmsg); - if (ret != SQLITE_OK) - { - DPRINTF(E_LOG, L_DB, "Purge query %d error: %s\n", i, errmsg); - - sqlite3_free(errmsg); - break; - } - else - { - changes = sqlite3_changes(hdl); - DPRINTF(E_DBG, L_DB, "Purged %d rows\n", changes); - } - - } while (changes > 0); - purge_fail: for (i = 0; i < (sizeof(queries) / sizeof(queries[0])); i++) { @@ -853,7 +822,6 @@ db_purge_all(void) "DELETE FROM playlists WHERE type <> 1;", "DELETE FROM files;", "DELETE FROM groups;", - "DELETE FROM filelist;" }; char *errmsg; int i; @@ -1909,85 +1877,54 @@ db_query_fetch_string_sort(struct query_params *qp, char **string, char **sortst /* Filelist */ -static int -db_filelist_add(const char *virtual_path, enum filelistitem_type type) -{ - char path[PATH_MAX]; - char parentpath[PATH_MAX]; - char *name; - char *query; - char *errmsg; - int ret; - - DPRINTF(E_DBG, L_DB, "Add file to filelist with type %d and virtual path '%s'\n", type, virtual_path); - - strcpy(path, virtual_path); - strcpy(parentpath, path); - name = strrchr(parentpath, '/'); - *name = '\0'; - name++; - - query = sqlite3_mprintf("INSERT INTO filelist (path, name, type, parentpath, disabled) VALUES ('%q', '%q', %d, '%q', %d);", - path, name, type, parentpath, 0); - DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query); - ret = db_exec(query, &errmsg); - - if (ret == SQLITE_CONSTRAINT) - { - DPRINTF(E_DBG, L_DB, "Path already exists in filelist '%s'\n", path); - sqlite3_free(errmsg); - sqlite3_free(query); - return 0; - } - else if (ret != SQLITE_OK) - { - DPRINTF(E_LOG, L_DB, "Error '%s' while runnning '%s'\n", errmsg, query); - sqlite3_free(errmsg); - sqlite3_free(query); - return -1; - } - - sqlite3_free(query); - - while ((name = strrchr(parentpath, '/'))) - { - strcpy(path, parentpath); - *name = '\0'; - name++; - - query = sqlite3_mprintf("INSERT INTO filelist (path, name, type, parentpath, disabled) VALUES ('%q', '%q', %d, '%q', %d);", - path, name, F_DIR, (*parentpath == '\0' ? "/" : parentpath), 0); - DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query); - ret = db_exec(query, &errmsg); - - if (ret == SQLITE_CONSTRAINT) - { - DPRINTF(E_DBG, L_DB, "Path already exists in filelist '%s'\n", path); - sqlite3_free(errmsg); - sqlite3_free(query); - return 0; - } - else if (ret != SQLITE_OK) - { - DPRINTF(E_LOG, L_DB, "Error '%s' while runnning '%s'\n", errmsg, query); - sqlite3_free(errmsg); - sqlite3_free(query); - return -1; - } - - sqlite3_free(query); - } - - return 0; -} - int -db_build_query_filelist(struct query_params *qp, char *parentpath) +db_mpd_build_query_filelist(struct query_params *qp, char *parentpath) { char *query; int ret; - query = sqlite3_mprintf("SELECT * FROM filelist WHERE disabled = 0 AND parentpath = '%q' ORDER BY type, name;", parentpath); + /* + query = sqlite3_mprintf( + "SELECT " + " CASE WHEN INSTR(SUBSTR(virtual_path, LENGTH(%Q)+1), '/') = 0 " + " THEN " + " virtual_path " + " ELSE " + " SUBSTR(virtual_path, 1, LENGTH(%Q)+INSTR(SUBSTR(virtual_path, LENGTH(%Q)+1), '/')-1) " + " END AS path, " + " MAX(time_modified), " + " CASE WHEN INSTR(SUBSTR(virtual_path, LENGTH(%Q)+1), '/') = 0 " + " THEN " + " type " + " ELSE " + " 2 " + " END AS ftype, " + " disabled " + "FROM filelist " + "WHERE virtual_path LIKE '%q%%' " + "GROUP BY ftype, path " + "ORDER BY ftype, path;", parentpath, parentpath, parentpath, parentpath, parentpath); + */ + query = sqlite3_mprintf( + "SELECT " + " CASE WHEN daap_charindex(virtual_path, '/', LENGTH(%Q)) = -1 " + " THEN " + " virtual_path " + " ELSE " + " daap_substring(virtual_path, '/', LENGTH(%Q)) " + " END AS path, " + " MAX(time_modified), " + " CASE WHEN daap_charindex(virtual_path, '/', LENGTH(%Q)) = -1 " + " THEN " + " type " + " ELSE " + " 2 " + " END AS ftype " + "FROM filelist " + "WHERE virtual_path LIKE '%q%%' " + "GROUP BY ftype, path " + "ORDER BY ftype, path;", parentpath, parentpath, parentpath, parentpath); + if (!query) { DPRINTF(E_LOG, L_DB, "Out of memory for query string\n"); @@ -2011,7 +1948,7 @@ db_build_query_filelist(struct query_params *qp, char *parentpath) } int -db_query_fetch_filelist(struct query_params *qp, struct filelist_info *fi) +db_mpd_query_fetch_filelist(struct query_params *qp, struct filelist_info *fi) { int ret; @@ -2027,7 +1964,7 @@ db_query_fetch_filelist(struct query_params *qp, struct filelist_info *fi) if (ret == SQLITE_DONE) { DPRINTF(E_DBG, L_DB, "End of query results\n"); - fi->path = NULL; + fi->virtual_path = NULL; return 0; } else if (ret != SQLITE_ROW) @@ -2036,93 +1973,13 @@ db_query_fetch_filelist(struct query_params *qp, struct filelist_info *fi) return -1; } - fi->path = strdup((char *)sqlite3_column_text(qp->stmt, 0)); - fi->name = strdup((char *)sqlite3_column_text(qp->stmt, 1)); + fi->virtual_path = strdup((char *)sqlite3_column_text(qp->stmt, 0)); + fi->time_modified = sqlite3_column_int(qp->stmt, 1); fi->type = sqlite3_column_int(qp->stmt, 2); - fi->parentpath = strdup((char *)sqlite3_column_text(qp->stmt, 3)); - fi->disabled = sqlite3_column_int(qp->stmt, 4); return 0; } -static struct filelist_info * -db_filelist_fetch_byquery(char *query) -{ - struct filelist_info *fi; - sqlite3_stmt *stmt; - int ret; - - if (!query) - return NULL; - - DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query); - - fi = (struct filelist_info *)malloc(sizeof(struct filelist_info)); - if (!fi) - { - DPRINTF(E_LOG, L_DB, "Could not allocate struct filelist_info, out of memory\n"); - return NULL; - } - memset(fi, 0, sizeof(struct filelist_info)); - - ret = db_blocking_prepare_v2(query, -1, &stmt, NULL); - if (ret != SQLITE_OK) - { - DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl)); - - free(fi); - return NULL; - } - - ret = db_blocking_step(stmt); - - if (ret != SQLITE_ROW) - { - if (ret == SQLITE_DONE) - DPRINTF(E_DBG, L_DB, "No results\n"); - else - DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl)); - - sqlite3_finalize(stmt); - free(fi); - return NULL; - } - - - fi->path = strdup((char *)sqlite3_column_text(stmt, 0)); - fi->name = strdup((char *)sqlite3_column_text(stmt, 1)); - fi->type = sqlite3_column_int(stmt, 2); - fi->parentpath = strdup((char *)sqlite3_column_text(stmt, 3)); - fi->disabled = sqlite3_column_int(stmt, 4); - - sqlite3_finalize(stmt); - - return fi; -} - -struct filelist_info * -db_filelist_fetch_bypath(const char *path) -{ -#define Q_TMPL "SELECT f.* FROM filelist f WHERE f.path = %Q;" - struct filelist_info *fi; - char *query; - - query = sqlite3_mprintf(Q_TMPL, path); - if (!query) - { - DPRINTF(E_LOG, L_DB, "Out of memory for query string\n"); - - return NULL; - } - - fi = db_filelist_fetch_byquery(query); - - sqlite3_free(query); - - return fi; - -#undef Q_TMPL -} /* Files */ int @@ -2728,8 +2585,6 @@ db_file_add(struct media_file_info *mfi) sqlite3_free(query); - db_filelist_add(mfi->virtual_path, F_FILE); - cache_daap_trigger(); return 0; @@ -2821,8 +2676,6 @@ db_file_update(struct media_file_info *mfi) sqlite3_free(query); - db_filelist_add(mfi->virtual_path, F_FILE); - cache_daap_trigger(); return 0; @@ -3310,8 +3163,6 @@ db_pl_add(char *title, char *path, char *virtual_path, int *id) DPRINTF(E_DBG, L_DB, "Added playlist %s (path %s) with id %d\n", title, path, *id); - db_filelist_add(virtual_path, F_PLAYLIST); - return 0; #undef QDUP_TMPL @@ -3353,11 +3204,6 @@ db_pl_update(char *title, char *path, char *virtual_path, int id) ret = db_query_run(query, 1, 0); - if (ret == 0) - { - db_filelist_add(virtual_path, F_PLAYLIST); - } - return ret; #undef Q_TMPL } @@ -3663,12 +3509,11 @@ db_pairing_fetch_byguid(struct pairing_info *pi) void db_spotify_purge(void) { - char *queries[4] = + char *queries[3] = { "DELETE FROM files WHERE path LIKE 'spotify:%%';", "DELETE FROM playlistitems WHERE filepath LIKE 'spotify:%%';", "DELETE FROM playlists WHERE path LIKE 'spotify:%%';", - "DELETE FROM filelist WHERE path LIKE '/spotify:%%';", }; int i; int ret; @@ -3686,13 +3531,11 @@ db_spotify_purge(void) void db_spotify_pl_delete(int id) { - char *queries_tmpl[5] = + char *queries_tmpl[3] = { - "DELETE FROM filelist WHERE path IN (SELECT virtual_path FROM playlists WHERE id = %d);", "DELETE FROM playlists WHERE id = %d;", "DELETE FROM playlistitems WHERE playlistid = %d;", "DELETE FROM files WHERE path LIKE 'spotify:%%' AND NOT path IN (SELECT filepath FROM playlistitems);", - "DELETE FROM filelist WHERE path LIKE 'spotify:%%' AND NOT path IN (SELECT virtual_path FROM FILES WHERE path LIKE 'spotify:%%');", }; char *query; int i; @@ -4682,14 +4525,16 @@ db_perthread_deinit(void) " path VARCHAR(4096) NOT NULL" \ ");" -#define T_FILELIST \ - "CREATE TABLE IF NOT EXISTS filelist (" \ - " path VARCHAR(4096) PRIMARY KEY NOT NULL," \ - " name VARCHAR(255) NOT NULL," \ - " type INTEGER NOT NULL," \ - " parentpath VARCHAR(4096) NOT NULL," \ - " disabled INTEGER DEFAULT 0" \ - ");" +#define V_FILELIST \ + "CREATE VIEW IF NOT EXISTS filelist as" \ + " SELECT " \ + " virtual_path, time_modified, 3 as type " \ + " FROM files WHERE disabled = 0" \ + " UNION " \ + " SELECT " \ + " virtual_path, db_timestamp, 1 as type " \ + " FROM playlists where disabled = 0 AND type = 0" \ + ";" #define TRG_GROUPS_INSERT_FILES \ "CREATE TRIGGER update_groups_new_file AFTER INSERT ON files FOR EACH ROW" \ @@ -4761,7 +4606,7 @@ static const struct db_init_query db_init_table_queries[] = { T_SPEAKERS, "create table speakers" }, { T_INOTIFY, "create table inotify" }, - { T_FILELIST, "create table filelist" }, + { V_FILELIST, "create view filelist" }, { TRG_GROUPS_INSERT_FILES, "create trigger update_groups_new_file" }, { TRG_GROUPS_UPDATE_FILES, "create trigger update_groups_update_file" }, @@ -4819,11 +4664,14 @@ static const struct db_init_query db_init_table_queries[] = #define I_ALBUM \ "CREATE INDEX IF NOT EXISTS idx_album ON files(album, album_sort);" +#define I_FILELIST \ + "CREATE INDEX IF NOT EXISTS idx_filelist ON files(disabled, virtual_path, time_modified);" + #define I_PL_PATH \ "CREATE INDEX IF NOT EXISTS idx_pl_path ON playlists(path);" #define I_PL_DISABLED \ - "CREATE INDEX IF NOT EXISTS idx_pl_disabled ON playlists(disabled);" + "CREATE INDEX IF NOT EXISTS idx_pl_disabled ON playlists(disabled, type, virtual_path, db_timestamp);" #define I_FILEPATH \ "CREATE INDEX IF NOT EXISTS idx_filepath ON playlistitems(filepath ASC);" @@ -4837,9 +4685,6 @@ static const struct db_init_query db_init_table_queries[] = #define I_PAIRING \ "CREATE INDEX IF NOT EXISTS idx_pairingguid ON pairings(guid);" -#define I_FILELIST \ - "CREATE INDEX IF NOT EXISTS idx_parentpath_disabled ON filelist(disabled, parentpath, type, name);" - static const struct db_init_query db_init_index_queries[] = { { I_RESCAN, "create rescan index" }, @@ -4854,6 +4699,7 @@ static const struct db_init_query db_init_index_queries[] = { I_GENRE, "create genre index" }, { I_TITLE, "create title index" }, { I_ALBUM, "create album index" }, + { I_FILELIST, "create filelist index" }, { I_PL_PATH, "create playlist path index" }, { I_PL_DISABLED, "create playlist state index" }, @@ -4864,8 +4710,6 @@ static const struct db_init_query db_init_index_queries[] = { I_GRP_PERSIST, "create groups persistentid index" }, { I_PAIRING, "create pairing guid index" }, - - { I_FILELIST, "create filelist index" }, }; static int @@ -5800,14 +5644,16 @@ static const struct db_init_query db_upgrade_v1501_queries[] = /* Upgrade from schema v15.01 to v16 */ -#define U_V16_CREATE_TBL_FILELIST \ - "CREATE TABLE IF NOT EXISTS filelist (" \ - " path VARCHAR(4096) PRIMARY KEY NOT NULL,"\ - " name VARCHAR(255) NOT NULL," \ - " type INTEGER NOT NULL," \ - " parentpath VARCHAR(4096) NOT NULL," \ - " disabled INTEGER DEFAULT 0" \ - ");" +#define U_V16_CREATE_VIEW_FILELIST \ + "CREATE VIEW IF NOT EXISTS filelist as" \ + " SELECT " \ + " virtual_path, time_modified, 3 as type " \ + " FROM files WHERE disabled = 0" \ + " UNION " \ + " SELECT " \ + " virtual_path, db_timestamp, 1 as type " \ + " FROM playlists WHERE disabled = 0 AND type = 0" \ + ";" #define U_V16_ALTER_TBL_FILES_ADD_COL \ "ALTER TABLE files ADD COLUMN virtual_path VARCHAR(4096) DEFAULT NULL;" @@ -5824,83 +5670,15 @@ static const struct db_init_query db_upgrade_v1501_queries[] = static const struct db_init_query db_upgrade_v16_queries[] = { - { U_V16_CREATE_TBL_FILELIST, "create new table filelist" }, { U_V16_ALTER_TBL_FILES_ADD_COL, "alter table files add column virtual_path" }, { U_V16_ALTER_TBL_PL_ADD_COL, "alter table playlists add column virtual_path" }, + { U_V16_CREATE_VIEW_FILELIST, "create new view filelist" }, { U_V16_SCVER, "set schema_version to 16" }, { U_V1600_SCVER_MAJOR, "set schema_version_major to 16" }, { U_V1600_SCVER_MINOR, "set schema_version_minor to 00" }, }; -static int -db_upgrade_v16_filelist_add(const char *virtual_path, int type) -{ - char path[PATH_MAX]; - char parentpath[PATH_MAX]; - char *name; - char *query; - char *errmsg; - int ret; - - strcpy(path, virtual_path); - strcpy(parentpath, path); - name = strrchr(parentpath, '/'); - *name = '\0'; - name++; - - query = sqlite3_mprintf("INSERT INTO filelist (path, name, type, parentpath, disabled) VALUES ('%q', '%q', %d, '%q', %d);", path, name, type, parentpath, 0); - DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query); - ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg); - - if (ret == SQLITE_CONSTRAINT) - { - DPRINTF(E_DBG, L_DB, "Path already exists in filelist '%s'\n", path); - sqlite3_free(errmsg); - sqlite3_free(query); - return 0; - } - else if (ret != SQLITE_OK) - { - DPRINTF(E_LOG, L_DB, "Error '%s' while runnning '%s'\n", errmsg, query); - sqlite3_free(errmsg); - sqlite3_free(query); - return -1; - } - - sqlite3_free(query); - - while ((name = strrchr(parentpath, '/'))) - { - strcpy(path, parentpath); - *name = '\0'; - name++; - - query = sqlite3_mprintf("INSERT INTO filelist (path, name, type, parentpath, disabled) VALUES ('%q', '%q', %d, '%q', %d);", path, name, F_DIR, (*parentpath == '\0' ? "/" : parentpath), 0); - DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query); - ret = sqlite3_exec(hdl, query, NULL, NULL, &errmsg); - - if (ret == SQLITE_CONSTRAINT) - { - DPRINTF(E_DBG, L_DB, "Path already exists in filelist '%s'\n", path); - sqlite3_free(errmsg); - sqlite3_free(query); - return 0; - } - else if (ret != SQLITE_OK) - { - DPRINTF(E_LOG, L_DB, "Error '%s' while runnning '%s'\n", errmsg, query); - sqlite3_free(errmsg); - sqlite3_free(query); - return -1; - } - - sqlite3_free(query); - } - - return 0; -} - static int db_upgrade_v16(void) { @@ -5957,17 +5735,6 @@ db_upgrade_v16(void) DPRINTF(E_LOG, L_DB, "Error updating files: %s\n", errmsg); } - if (data_kind == 0 /* Real file*/ - || data_kind == 1 /* URL */ - || data_kind == 2 /* Spotify */) - { - ret = db_upgrade_v16_filelist_add(virtual_path, 3); /* Real file, spotify url, http url */ - if (ret < 0) - { - DPRINTF(E_LOG, L_DB, "Error updating filelist for file %d\n", id); - } - } - sqlite3_free(uquery); sqlite3_free(errmsg); } @@ -6013,12 +5780,6 @@ db_upgrade_v16(void) sqlite3_free(uquery); sqlite3_free(errmsg); - - ret = db_upgrade_v16_filelist_add(virtual_path, 1); /* Playlists */ - if (ret < 0) - { - DPRINTF(E_LOG, L_DB, "Error updating filelist for playlist %d\n", id); - } } } diff --git a/src/db.h b/src/db.h index df0fbd5e..dc57a06e 100644 --- a/src/db.h +++ b/src/db.h @@ -52,7 +52,6 @@ enum filelistitem_type { F_PLAYLIST = 1, F_DIR = 2, F_FILE = 3, - F_URL = 4, }; struct query_params { @@ -289,11 +288,9 @@ struct db_media_file_info { #define dbmfi_offsetof(field) offsetof(struct db_media_file_info, field) struct filelist_info { - char *path; - char *name; + char *virtual_path; + uint32_t time_modified; enum filelistitem_type type; - char *parentpath; - int disabled; }; struct watch_info { @@ -495,10 +492,10 @@ db_group_persistentid_byid(int id, int64_t *persistentid); /* Filelist */ int -db_build_query_filelist(struct query_params *qp, char *path); +db_mpd_build_query_filelist(struct query_params *qp, char *path); int -db_query_fetch_filelist(struct query_params *qp, struct filelist_info *fi); +db_mpd_query_fetch_filelist(struct query_params *qp, struct filelist_info *fi); struct filelist_info * db_filelist_fetch_bypath(const char *path); diff --git a/src/mpd.c b/src/mpd.c index 0b1389a8..1456ed29 100644 --- a/src/mpd.c +++ b/src/mpd.c @@ -1685,17 +1685,18 @@ mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg) struct media_file_info *mfi; int ret; - if (argc < 2) + if (argc < 2 || strlen(argv[1]) == 0 + || (strncmp(argv[1], "/", 1) == 0 && strlen(argv[1]) == 1)) { ret = snprintf(parent, sizeof(parent), "/"); } else if (strncmp(argv[1], "/", 1) == 0) { - ret = snprintf(parent, sizeof(parent), "%s", argv[1]); + ret = snprintf(parent, sizeof(parent), "%s/", argv[1]); } else { - ret = snprintf(parent, sizeof(parent), "/%s", argv[1]); + ret = snprintf(parent, sizeof(parent), "/%s/", argv[1]); } if ((ret < 0) || (ret >= sizeof(parent))) @@ -1713,7 +1714,7 @@ mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg) memset(&qp, 0, sizeof(struct query_params)); - ret = db_build_query_filelist(&qp, parent); + ret = db_mpd_build_query_filelist(&qp, parent); if (ret < 0) { DPRINTF(E_LOG, L_MPD, "Could not start query for path '%s'\n", argv[1]); @@ -1725,31 +1726,31 @@ mpd_command_lsinfo(struct evbuffer *evbuf, int argc, char **argv, char **errmsg) return ACK_ERROR_UNKNOWN; } - while (((ret = db_query_fetch_filelist(&qp, fi)) == 0) && (fi->path)) + while (((ret = db_mpd_query_fetch_filelist(&qp, fi)) == 0) && (fi->virtual_path)) { if (fi->type == F_DIR) { evbuffer_add_printf(evbuf, "directory: %s\n" "Last-Modified: 2014-07-11T14:13:56Z\n", //TODO Send correct last modified timestamp - (fi->path + 1)); + (fi->virtual_path + 1)); } else if (fi->type == F_PLAYLIST) { evbuffer_add_printf(evbuf, "playlist: %s\n" "Last-Modified: 2014-07-11T14:13:56Z\n", //TODO Send correct last modified timestamp - (fi->path + 1)); + (fi->virtual_path + 1)); } else if (fi->type == F_FILE) { - mfi = db_file_fetch_byvirtualpath(fi->path); + mfi = db_file_fetch_byvirtualpath(fi->virtual_path); if (mfi) { ret = mpd_add_mediainfo(evbuf, mfi, -1); if (ret < 0) { - DPRINTF(E_LOG, L_MPD, "Could not add mediainfo for path '%s'\n", fi->path); + DPRINTF(E_LOG, L_MPD, "Could not add mediainfo for path '%s'\n", fi->virtual_path); } free_mfi(mfi, 0);