[scan] Fix for issue #463, fname not getting updated on file rename

Also modify code style of _enable/_disable functions in db.c
This commit is contained in:
ejurgensen 2017-12-16 23:09:29 +01:00
parent 387b79496d
commit b428760599
4 changed files with 96 additions and 90 deletions

121
src/db.c
View File

@ -2548,61 +2548,66 @@ db_file_delete_bypath(const char *path)
}
void
db_file_disable_bypath(const char *path, char *strip, uint32_t cookie)
db_file_disable_bypath(const char *path, enum strip_type strip, uint32_t cookie)
{
#define Q_TMPL "UPDATE files SET path = substr(path, %d), virtual_path = substr(virtual_path, %d), disabled = %" PRIi64 " WHERE path = '%q';"
char *query;
int64_t disabled;
int striplen;
int striplenvpath;
int path_striplen;
int vpath_striplen;
disabled = (cookie != 0) ? cookie : INOTIFY_FAKE_COOKIE;
striplen = strlen(strip) + 1;
if (strlen(strip) > 0)
striplenvpath = strlen(strip) + strlen("/file:/");
else
striplenvpath = 0;
query = sqlite3_mprintf(Q_TMPL, striplen, striplenvpath, disabled, path);
path_striplen = (strip == STRIP_PATH) ? strlen(path) : 0;
vpath_striplen = (strip == STRIP_PATH) ? strlen("/file:") + path_striplen : 0;
query = sqlite3_mprintf(Q_TMPL, path_striplen + 1, vpath_striplen + 1, disabled, path);
db_query_run(query, 1, LISTENER_DATABASE);
#undef Q_TMPL
}
void
db_file_disable_bymatch(const char *path, char *strip, uint32_t cookie)
db_file_disable_bymatch(const char *path, enum strip_type strip, uint32_t cookie)
{
#define Q_TMPL "UPDATE files SET path = substr(path, %d), virtual_path = substr(virtual_path, %d), disabled = %" PRIi64 " WHERE path LIKE '%q/%%';"
char *query;
int64_t disabled;
int striplen;
int striplenvpath;
int path_striplen;
int vpath_striplen;
disabled = (cookie != 0) ? cookie : INOTIFY_FAKE_COOKIE;
striplen = strlen(strip) + 1;
if (strlen(strip) > 0)
striplenvpath = strlen(strip) + strlen("/file:/");
else
striplenvpath = 0;
query = sqlite3_mprintf(Q_TMPL, striplen, striplenvpath, disabled, path);
path_striplen = (strip == STRIP_PATH) ? strlen(path) : 0;
vpath_striplen = (strip == STRIP_PATH) ? strlen("/file:") + path_striplen : 0;
query = sqlite3_mprintf(Q_TMPL, path_striplen + 1, vpath_striplen + 1, disabled, path);
db_query_run(query, 1, LISTENER_DATABASE);
#undef Q_TMPL
}
// "path" will be the directory part for directory updates (dir moved) and the
// full path for file updates (file moved). The db will have the filename in
// the path field for the former case (with a "/" prefix), and an empty path
// field for the latter.
int
db_file_enable_bycookie(uint32_t cookie, const char *path)
db_file_enable_bycookie(uint32_t cookie, const char *path, const char *filename)
{
#define Q_TMPL "UPDATE files SET path = '%q' || path, virtual_path = '/file:%q' || virtual_path, disabled = 0 WHERE disabled = %" PRIi64 ";"
#define Q_TMPL_UPDATE_FNAME "UPDATE files SET path = ('%q' || path), virtual_path = ('/file:%q' || virtual_path), fname = '%q', disabled = 0 WHERE disabled = %" PRIi64 ";"
#define Q_TMPL "UPDATE files SET path = ('%q' || path), virtual_path = ('/file:%q' || virtual_path), disabled = 0 WHERE disabled = %" PRIi64 ";"
char *query;
int ret;
query = sqlite3_mprintf(Q_TMPL, path, path, (int64_t)cookie);
if (filename)
query = sqlite3_mprintf(Q_TMPL_UPDATE_FNAME, path, path, filename, (int64_t)cookie);
else
query = sqlite3_mprintf(Q_TMPL, path, path, (int64_t)cookie);
ret = db_query_run(query, 1, 1);
ret = db_query_run(query, 1, LISTENER_DATABASE);
return ((ret < 0) ? -1 : sqlite3_changes(hdl));
#undef Q_TMPL_UPDATE_FNAME
#undef Q_TMPL
}
@ -3125,44 +3130,40 @@ db_pl_delete_bypath(const char *path)
}
void
db_pl_disable_bypath(const char *path, char *strip, uint32_t cookie)
db_pl_disable_bypath(const char *path, enum strip_type strip, uint32_t cookie)
{
#define Q_TMPL "UPDATE playlists SET path = substr(path, %d), virtual_path = substr(virtual_path, %d), disabled = %" PRIi64 " WHERE path = '%q';"
char *query;
int64_t disabled;
int striplen;
int striplenvpath;
int path_striplen;
int vpath_striplen;
disabled = (cookie != 0) ? cookie : INOTIFY_FAKE_COOKIE;
striplen = strlen(strip) + 1;
if (strlen(strip) > 0)
striplenvpath = strlen(strip) + strlen("/file:/");
else
striplenvpath = 0;
query = sqlite3_mprintf(Q_TMPL, striplen, striplenvpath, disabled, path);
path_striplen = (strip == STRIP_PATH) ? strlen(path) : 0;
vpath_striplen = (strip == STRIP_PATH) ? strlen("/file:") + path_striplen : 0;
query = sqlite3_mprintf(Q_TMPL, path_striplen + 1, vpath_striplen + 1, disabled, path);
db_query_run(query, 1, 0);
#undef Q_TMPL
}
void
db_pl_disable_bymatch(const char *path, char *strip, uint32_t cookie)
db_pl_disable_bymatch(const char *path, enum strip_type strip, uint32_t cookie)
{
#define Q_TMPL "UPDATE playlists SET path = substr(path, %d), virtual_path = substr(virtual_path, %d), disabled = %" PRIi64 " WHERE path LIKE '%q/%%';"
char *query;
int64_t disabled;
int striplen;
int striplenvpath;
int path_striplen;
int vpath_striplen;
disabled = (cookie != 0) ? cookie : INOTIFY_FAKE_COOKIE;
striplen = strlen(strip) + 1;
if (strlen(strip) > 0)
striplenvpath = strlen(strip) + strlen("/file:/");
else
striplenvpath = 0;
query = sqlite3_mprintf(Q_TMPL, striplen, striplenvpath, disabled, path);
path_striplen = (strip == STRIP_PATH) ? strlen(path) : 0;
vpath_striplen = (strip == STRIP_PATH) ? strlen("/file:") + path_striplen : 0;
query = sqlite3_mprintf(Q_TMPL, path_striplen + 1, vpath_striplen + 1, disabled, path);
db_query_run(query, 1, 0);
#undef Q_TMPL
@ -3171,7 +3172,7 @@ db_pl_disable_bymatch(const char *path, char *strip, uint32_t cookie)
int
db_pl_enable_bycookie(uint32_t cookie, const char *path)
{
#define Q_TMPL "UPDATE playlists SET path = '%q' || path, virtual_path = '/file:%q' || virtual_path, disabled = 0 WHERE disabled = %" PRIi64 ";"
#define Q_TMPL "UPDATE playlists SET path = ('%q' || path), virtual_path = ('/file:%q' || virtual_path), disabled = 0 WHERE disabled = %" PRIi64 ";"
char *query;
int ret;
@ -3459,7 +3460,7 @@ db_directory_add(struct directory_info *di, int *id)
/* Since sqlite removes the trailing space, so these
* directories will be found as new in perpetuity.
*/
DPRINTF(E_LOG, L_DB, "Directory name ends with space: [%s]\n", di->virtual_path);
DPRINTF(E_LOG, L_DB, "Directory name ends with space: '%s'\n", di->virtual_path);
}
query = sqlite3_mprintf(QADD_TMPL, di->virtual_path, di->db_timestamp, di->disabled, di->parent_id);
@ -3491,7 +3492,7 @@ db_directory_add(struct directory_info *di, int *id)
return -1;
}
DPRINTF(E_DBG, L_DB, "Added directory %s with id %d\n", di->virtual_path, *id);
DPRINTF(E_DBG, L_DB, "Added directory '%s' with id %d\n", di->virtual_path, *id);
return 0;
@ -3530,7 +3531,7 @@ db_directory_update(struct directory_info *di)
sqlite3_free(query);
DPRINTF(E_DBG, L_DB, "Updated directory %s with id %d\n", di->virtual_path, di->id);
DPRINTF(E_DBG, L_DB, "Updated directory '%s' with id %d\n", di->virtual_path, di->id);
return 0;
@ -3579,20 +3580,18 @@ db_directory_ping_bymatch(char *virtual_path)
}
void
db_directory_disable_bymatch(char *path, char *strip, uint32_t cookie)
db_directory_disable_bymatch(char *path, enum strip_type strip, uint32_t cookie)
{
#define Q_TMPL "UPDATE directories SET virtual_path = substr(virtual_path, %d), disabled = %" PRIi64 " WHERE virtual_path = '/file:%q' OR virtual_path LIKE '/file:%q/%%';"
char *query;
int64_t disabled;
int striplen;
int vpath_striplen;
disabled = (cookie != 0) ? cookie : INOTIFY_FAKE_COOKIE;
if (strlen(strip) > 0)
striplen = strlen(strip) + strlen("/file:/");
else
striplen = 0;
query = sqlite3_mprintf(Q_TMPL, striplen, disabled, path, path, path);
vpath_striplen = (strip == STRIP_PATH) ? strlen("/file:") + strlen(path) : 0;
query = sqlite3_mprintf(Q_TMPL, vpath_striplen + 1, disabled, path, path, path);
db_query_run(query, 1, LISTENER_DATABASE);
#undef Q_TMPL
@ -3601,7 +3600,7 @@ db_directory_disable_bymatch(char *path, char *strip, uint32_t cookie)
int
db_directory_enable_bycookie(uint32_t cookie, char *path)
{
#define Q_TMPL "UPDATE directories SET virtual_path = '/file:%q' || virtual_path, disabled = 0 WHERE disabled = %" PRIi64 ";"
#define Q_TMPL "UPDATE directories SET virtual_path = ('/file:%q' || virtual_path), disabled = 0 WHERE disabled = %" PRIi64 ";"
char *query;
int ret;
@ -5643,34 +5642,36 @@ db_watch_get_bypath(struct watch_info *wi)
}
void
db_watch_mark_bypath(char *path, char *strip, uint32_t cookie)
db_watch_mark_bypath(char *path, enum strip_type strip, uint32_t cookie)
{
#define Q_TMPL "UPDATE inotify SET path = substr(path, %d), cookie = %" PRIi64 " WHERE path = '%q';"
char *query;
int64_t disabled;
int striplen;
int path_striplen;
disabled = (cookie != 0) ? cookie : INOTIFY_FAKE_COOKIE;
striplen = strlen(strip) + 1;
query = sqlite3_mprintf(Q_TMPL, striplen, disabled, path);
path_striplen = (strip == STRIP_PATH) ? strlen(path) : 0;
query = sqlite3_mprintf(Q_TMPL, path_striplen + 1, disabled, path);
db_query_run(query, 1, 0);
#undef Q_TMPL
}
void
db_watch_mark_bymatch(char *path, char *strip, uint32_t cookie)
db_watch_mark_bymatch(char *path, enum strip_type strip, uint32_t cookie)
{
#define Q_TMPL "UPDATE inotify SET path = substr(path, %d), cookie = %" PRIi64 " WHERE path LIKE '%q/%%';"
char *query;
int64_t disabled;
int striplen;
int path_striplen;
disabled = (cookie != 0) ? cookie : INOTIFY_FAKE_COOKIE;
striplen = strlen(strip) + 1;
query = sqlite3_mprintf(Q_TMPL, striplen, disabled, path);
path_striplen = (strip == STRIP_PATH) ? strlen(path) : 0;
query = sqlite3_mprintf(Q_TMPL, path_striplen + 1, disabled, path);
db_query_run(query, 1, 0);
#undef Q_TMPL

View File

@ -343,6 +343,11 @@ struct db_media_file_info {
#define dbmfi_offsetof(field) offsetof(struct db_media_file_info, field)
enum strip_type {
STRIP_NONE,
STRIP_PATH,
};
struct watch_info {
int wd;
char *path;
@ -572,13 +577,13 @@ void
db_file_delete_bypath(const char *path);
void
db_file_disable_bypath(const char *path, char *strip, uint32_t cookie);
db_file_disable_bypath(const char *path, enum strip_type strip, uint32_t cookie);
void
db_file_disable_bymatch(const char *path, char *strip, uint32_t cookie);
db_file_disable_bymatch(const char *path, enum strip_type strip, uint32_t cookie);
int
db_file_enable_bycookie(uint32_t cookie, const char *path);
db_file_enable_bycookie(uint32_t cookie, const char *path, const char *filename);
int
db_file_update_directoryid(const char *path, int dir_id);
@ -633,10 +638,10 @@ void
db_pl_delete_bypath(const char *path);
void
db_pl_disable_bypath(const char *path, char *strip, uint32_t cookie);
db_pl_disable_bypath(const char *path, enum strip_type strip, uint32_t cookie);
void
db_pl_disable_bymatch(const char *path, char *strip, uint32_t cookie);
db_pl_disable_bymatch(const char *path, enum strip_type strip, uint32_t cookie);
int
db_pl_enable_bycookie(uint32_t cookie, const char *path);
@ -669,7 +674,7 @@ void
db_directory_ping_bymatch(char *virtual_path);
void
db_directory_disable_bymatch(char *path, char *strip, uint32_t cookie);
db_directory_disable_bymatch(char *path, enum strip_type strip, uint32_t cookie);
int
db_directory_enable_bycookie(uint32_t cookie, char *path);
@ -836,10 +841,10 @@ int
db_watch_get_bypath(struct watch_info *wi);
void
db_watch_mark_bypath(char *path, char *strip, uint32_t cookie);
db_watch_mark_bypath(char *path, enum strip_type strip, uint32_t cookie);
void
db_watch_mark_bymatch(char *path, char *strip, uint32_t cookie);
db_watch_mark_bymatch(char *path, enum strip_type strip, uint32_t cookie);
void
db_watch_move_bycookie(uint32_t cookie, char *path);

View File

@ -948,9 +948,9 @@ bulk_scan(int flags)
DPRINTF(E_LOG, L_SCAN, "Skipping library directory %s, could not dereference: %s\n", path, strerror(errno));
/* Assume dir is mistakenly not mounted, so just disable everything and update timestamps */
db_file_disable_bymatch(path, "", 0);
db_pl_disable_bymatch(path, "", 0);
db_directory_disable_bymatch(path, "", 0);
db_file_disable_bymatch(path, STRIP_NONE, 0);
db_pl_disable_bymatch(path, STRIP_NONE, 0);
db_directory_disable_bymatch(path, STRIP_NONE, 0);
db_file_ping_bymatch(path, 1);
db_pl_ping_bymatch(path, 1);
@ -1063,9 +1063,9 @@ process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie)
if (ie->mask & IN_UNMOUNT)
{
db_file_disable_bymatch(path, "", 0);
db_pl_disable_bymatch(path, "", 0);
db_directory_disable_bymatch(path, "", 0);
db_file_disable_bymatch(path, STRIP_NONE, 0);
db_pl_disable_bymatch(path, STRIP_NONE, 0);
db_directory_disable_bymatch(path, STRIP_NONE, 0);
}
if (ie->mask & IN_MOVE_SELF)
@ -1109,18 +1109,18 @@ process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie)
if (ret < 0)
return;
db_file_disable_bymatch(path, "", 0);
db_pl_disable_bymatch(path, "", 0);
db_file_disable_bymatch(path, STRIP_NONE, 0);
db_pl_disable_bymatch(path, STRIP_NONE, 0);
}
}
if (ie->mask & IN_MOVED_FROM)
{
db_watch_mark_bypath(path, path, ie->cookie);
db_watch_mark_bymatch(path, path, ie->cookie);
db_file_disable_bymatch(path, path, ie->cookie);
db_pl_disable_bymatch(path, path, ie->cookie);
db_directory_disable_bymatch(path, path, ie->cookie);
db_watch_mark_bypath(path, STRIP_PATH, ie->cookie);
db_watch_mark_bymatch(path, STRIP_PATH, ie->cookie);
db_file_disable_bymatch(path, STRIP_PATH, ie->cookie);
db_pl_disable_bymatch(path, STRIP_PATH, ie->cookie);
db_directory_disable_bymatch(path, STRIP_PATH, ie->cookie);
}
if (ie->mask & IN_MOVED_TO)
@ -1128,7 +1128,7 @@ process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie)
if (db_watch_cookie_known(ie->cookie))
{
db_watch_move_bycookie(ie->cookie, path);
db_file_enable_bycookie(ie->cookie, path);
db_file_enable_bycookie(ie->cookie, path, NULL);
db_pl_enable_bycookie(ie->cookie, path);
db_directory_enable_bycookie(ie->cookie, path);
@ -1162,9 +1162,9 @@ process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie)
if (ret == 0)
watches_clear(wi->wd, path);
db_file_disable_bymatch(path, "", 0);
db_pl_disable_bymatch(path, "", 0);
db_directory_disable_bymatch(path, "", 0);
db_file_disable_bymatch(path, STRIP_NONE, 0);
db_pl_disable_bymatch(path, STRIP_NONE, 0);
db_directory_disable_bymatch(path, STRIP_NONE, 0);
}
else if (ret < 0)
{
@ -1222,8 +1222,8 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
{
DPRINTF(E_DBG, L_SCAN, "File moved from: %s\n", path);
db_file_disable_bypath(path, path, ie->cookie);
db_pl_disable_bypath(path, path, ie->cookie);
db_file_disable_bypath(path, STRIP_PATH, ie->cookie);
db_pl_disable_bypath(path, STRIP_PATH, ie->cookie);
}
if (ie->mask & IN_ATTRIB)
@ -1260,7 +1260,7 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
{
DPRINTF(E_DBG, L_SCAN, "File moved to: %s\n", path);
ret = db_file_enable_bycookie(ie->cookie, path);
ret = db_file_enable_bycookie(ie->cookie, path, filename_from_path(path));
if (ret > 0)
{

View File

@ -855,7 +855,7 @@ scan_itunes_itml(const char *file, time_t mtime, int dir_id)
if (pli)
{
db_pl_ping(pli->id);
db_pl_disable_bypath(file, "", 0);
db_pl_disable_bypath(file, STRIP_NONE, 0);
if (mtime && (pli->db_timestamp >= mtime))
{
@ -891,7 +891,7 @@ scan_itunes_itml(const char *file, time_t mtime, int dir_id)
return;
}
db_pl_disable_bypath(file, "", 0);
db_pl_disable_bypath(file, STRIP_NONE, 0);
}
free_pli(pli, 0);