diff options
author | Max Kellermann <max@duempel.org> | 2012-08-15 20:57:45 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2012-08-15 23:10:59 +0200 |
commit | e391f4b17b2fdd092b729f0dfec0b84265894e41 (patch) | |
tree | aaf52d9a958c811737d4fca9b046a5f90b0cc831 | |
parent | 2bd344549b5cfcb6d9a1e1e092c034e68d3071bc (diff) | |
download | mpd-e391f4b17b2fdd092b729f0dfec0b84265894e41.tar.gz mpd-e391f4b17b2fdd092b729f0dfec0b84265894e41.tar.xz mpd-e391f4b17b2fdd092b729f0dfec0b84265894e41.zip |
ProxyDatabase: pass "detached" objects to visitors
Fixes wrong object URIs with duplicate base names.
-rw-r--r-- | src/Song.cxx | 10 | ||||
-rw-r--r-- | src/db/ProxyDatabasePlugin.cxx | 73 | ||||
-rw-r--r-- | src/song.h | 6 |
3 files changed, 49 insertions, 40 deletions
diff --git a/src/Song.cxx b/src/Song.cxx index 2ef690fb0..eb4c2e53e 100644 --- a/src/Song.cxx +++ b/src/Song.cxx @@ -79,6 +79,14 @@ song_replace_uri(struct song *old_song, const char *uri) } struct song * +song_detached_new(const char *uri) +{ + assert(uri != nullptr); + + return song_alloc(uri, &detached_root); +} + +struct song * song_dup_detached(const struct song *src) { assert(src != nullptr); @@ -86,7 +94,7 @@ song_dup_detached(const struct song *src) struct song *song; if (song_in_database(src)) { char *uri = song_get_uri(src); - song = song_alloc(uri, &detached_root); + song = song_detached_new(uri); g_free(uri); } else song = song_alloc(src->uri, nullptr); diff --git a/src/db/ProxyDatabasePlugin.cxx b/src/db/ProxyDatabasePlugin.cxx index 3525e6f09..26e7b4b84 100644 --- a/src/db/ProxyDatabasePlugin.cxx +++ b/src/db/ProxyDatabasePlugin.cxx @@ -192,29 +192,33 @@ ProxyDatabase::GetSong(const char *uri, GError **error_r) const } static bool -Visit(struct mpd_connection *connection, directory &parent, +Visit(struct mpd_connection *connection, const char *uri, bool recursive, VisitDirectory visit_directory, VisitSong visit_song, VisitPlaylist visit_playlist, GError **error_r); static bool -Visit(struct mpd_connection *connection, directory &parent, +Visit(struct mpd_connection *connection, bool recursive, const struct mpd_directory *directory, VisitDirectory visit_directory, VisitSong visit_song, VisitPlaylist visit_playlist, GError **error_r) { - if (!recursive && !visit_directory) - return true; - - struct directory *d = - directory_new(mpd_directory_get_path(directory), &parent); + const char *path = mpd_directory_get_path(directory); + + if (visit_directory) { + struct directory *d = + directory_new(path, &detached_root); + bool success = visit_directory(*d, error_r); + directory_free(d); + if (!success) + return false; + } - bool success = (!visit_directory || visit_directory(*d, error_r)) && - (!recursive || - Visit(connection, *d, recursive, - visit_directory, visit_song, visit_playlist, error_r)); - directory_free(d); + if (recursive && + !Visit(connection, path, recursive, + visit_directory, visit_song, visit_playlist, error_r)) + return false; - return success; + return true; } static void @@ -232,11 +236,9 @@ Copy(struct tag *tag, enum tag_type d_tag, } static song * -Convert(struct directory &parent, const struct mpd_song *song) +Convert(const struct mpd_song *song) { - char *name = g_path_get_basename(mpd_song_get_uri(song)); - struct song *s = song_file_new(name, &parent); - g_free(name); + struct song *s = song_detached_new(mpd_song_get_uri(song)); s->mtime = mpd_song_get_last_modified(song); s->start_ms = mpd_song_get_start(song) * 1000; @@ -256,13 +258,13 @@ Convert(struct directory &parent, const struct mpd_song *song) } static bool -Visit(struct directory &parent, const struct mpd_song *song, +Visit(const struct mpd_song *song, VisitSong visit_song, GError **error_r) { if (!visit_song) return true; - struct song *s = Convert(parent, song); + struct song *s = Convert(song); bool success = visit_song(*s, error_r); song_free(s); @@ -270,19 +272,18 @@ Visit(struct directory &parent, const struct mpd_song *song, } static bool -Visit(struct directory &parent, const struct mpd_playlist *playlist, +Visit(const struct mpd_playlist *playlist, VisitPlaylist visit_playlist, GError **error_r) { if (!visit_playlist) return true; - char *name = g_path_get_basename(mpd_playlist_get_path(playlist)); struct playlist_metadata p; - p.name = name; + p.name = g_strdup(mpd_playlist_get_path(playlist)); p.mtime = mpd_playlist_get_last_modified(playlist); - bool success = visit_playlist(p, parent, error_r); - g_free(name); + bool success = visit_playlist(p, detached_root, error_r); + g_free(p.name); return success; } @@ -326,11 +327,11 @@ ReceiveEntities(struct mpd_connection *connection) } static bool -Visit(struct mpd_connection *connection, struct directory &parent, +Visit(struct mpd_connection *connection, const char *uri, bool recursive, VisitDirectory visit_directory, VisitSong visit_song, VisitPlaylist visit_playlist, GError **error_r) { - if (!mpd_send_list_meta(connection, directory_get_path(&parent))) + if (!mpd_send_list_meta(connection, uri)) return CheckError(connection, error_r); std::list<ProxyEntity> entities(ReceiveEntities(connection)); @@ -343,7 +344,7 @@ Visit(struct mpd_connection *connection, struct directory &parent, break; case MPD_ENTITY_TYPE_DIRECTORY: - if (!Visit(connection, parent, recursive, + if (!Visit(connection, recursive, mpd_entity_get_directory(entity), visit_directory, visit_song, visit_playlist, error_r)) @@ -351,13 +352,13 @@ Visit(struct mpd_connection *connection, struct directory &parent, break; case MPD_ENTITY_TYPE_SONG: - if (!Visit(parent, mpd_entity_get_song(entity), - visit_song, error_r)) + if (!Visit(mpd_entity_get_song(entity), visit_song, + error_r)) return false; break; case MPD_ENTITY_TYPE_PLAYLIST: - if (!Visit(parent, mpd_entity_get_playlist(entity), + if (!Visit(mpd_entity_get_playlist(entity), visit_playlist, error_r)) return false; break; @@ -377,15 +378,9 @@ ProxyDatabase::Visit(const DatabaseSelection &selection, // TODO: match // TODO: auto-reconnect - struct directory *parent = *selection.uri == 0 - ? root - : directory_new(selection.uri, root); - bool success = ::Visit(connection, *parent, selection.recursive, - visit_directory, visit_song, visit_playlist, - error_r); - if (parent != root) - directory_free(parent); - return success; + return ::Visit(connection, selection.uri, selection.recursive, + visit_directory, visit_song, visit_playlist, + error_r); } bool diff --git a/src/song.h b/src/song.h index a09b69df2..39f916a6a 100644 --- a/src/song.h +++ b/src/song.h @@ -94,6 +94,12 @@ struct song * song_replace_uri(struct song *song, const char *uri); /** + * Creates a "detached" song object. + */ +struct song * +song_detached_new(const char *uri); + +/** * Creates a duplicate of the song object. If the object is in the * database, it creates a "detached" copy of this song, see * song_is_detached(). |