Commit 733d6a6b authored by Max Kellermann's avatar Max Kellermann

DatabaseSelection: add "match" attribute

Let the database plugin do the match.
parent 8d272523
...@@ -1054,6 +1054,7 @@ test_DumpDatabase_SOURCES = test/DumpDatabase.cxx \ ...@@ -1054,6 +1054,7 @@ test_DumpDatabase_SOURCES = test/DumpDatabase.cxx \
src/song.c src/song_sort.c src/song_save.c \ src/song.c src/song_sort.c src/song_save.c \
src/tag.c src/tag_pool.c src/tag_save.c \ src/tag.c src/tag_pool.c src/tag_save.c \
src/path.c \ src/path.c \
src/locate.c \
src/text_file.c \ src/text_file.c \
src/conf.c src/tokenizer.c src/utils.c src/string_util.c src/conf.c src/tokenizer.c src/utils.c src/string_util.c
......
...@@ -67,8 +67,11 @@ handle_match(struct client *client, int argc, char *argv[], bool fold_case) ...@@ -67,8 +67,11 @@ handle_match(struct client *client, int argc, char *argv[], bool fold_case)
return COMMAND_RETURN_ERROR; return COMMAND_RETURN_ERROR;
} }
const DatabaseSelection selection("", true, list);
GError *error = NULL; GError *error = NULL;
enum command_return ret = findSongsIn(client, "", list, &error) enum command_return ret =
db_selection_print(client, selection, true, &error)
? COMMAND_RETURN_OK ? COMMAND_RETURN_OK
: print_error(client, error); : print_error(client, error);
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
extern "C" { extern "C" {
#include "dbUtils.h" #include "dbUtils.h"
#include "locate.h"
#include "stored_playlist.h" #include "stored_playlist.h"
} }
...@@ -40,34 +39,21 @@ AddSong(const char *playlist_path_utf8, ...@@ -40,34 +39,21 @@ AddSong(const char *playlist_path_utf8,
} }
bool bool
addAllInToStoredPlaylist(const char *uri_utf8, const char *playlist_path_utf8, search_add_to_playlist(const char *uri, const char *playlist_path_utf8,
const struct locate_item_list *criteria,
GError **error_r) GError **error_r)
{ {
const DatabaseSelection selection(uri_utf8, true); const DatabaseSelection selection(uri, true, criteria);
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(AddSong, playlist_path_utf8, _1, _2); const auto f = std::bind(AddSong, playlist_path_utf8, _1, _2);
return GetDatabase()->Visit(selection, f, error_r); return GetDatabase()->Visit(selection, f, error_r);
} }
static bool
SearchAddSong(const char *playlist_path_utf8,
const struct locate_item_list *criteria,
song &song, GError **error_r)
{
return !locate_list_song_match(&song, criteria) ||
spl_append_song(playlist_path_utf8, &song, error_r);
}
bool bool
search_add_to_playlist(const char *uri, const char *playlist_path_utf8, addAllInToStoredPlaylist(const char *uri_utf8, const char *playlist_path_utf8,
const struct locate_item_list *criteria,
GError **error_r) GError **error_r)
{ {
const DatabaseSelection selection(uri, true); return search_add_to_playlist(uri_utf8, playlist_path_utf8, nullptr,
error_r);
using namespace std::placeholders;
const auto f = std::bind(SearchAddSong, playlist_path_utf8,
criteria, _1, _2);
return GetDatabase()->Visit(selection, f, error_r);
} }
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
struct locate_item_list; struct locate_item_list;
gcc_nonnull(1,2,3) gcc_nonnull(1,2)
bool bool
search_add_to_playlist(const char *uri, const char *path_utf8, search_add_to_playlist(const char *uri, const char *path_utf8,
const struct locate_item_list *criteria, const struct locate_item_list *criteria,
......
...@@ -129,37 +129,19 @@ db_selection_print(struct client *client, const DatabaseSelection &selection, ...@@ -129,37 +129,19 @@ db_selection_print(struct client *client, const DatabaseSelection &selection,
bool full, GError **error_r) bool full, GError **error_r)
{ {
using namespace std::placeholders; using namespace std::placeholders;
const auto d = std::bind(PrintDirectory, client, _1); const auto d = selection.match == nullptr
? std::bind(PrintDirectory, client, _1)
: VisitDirectory();
const auto s = std::bind(full ? PrintSongFull : PrintSongBrief, const auto s = std::bind(full ? PrintSongFull : PrintSongBrief,
client, _1); client, _1);
const auto p = std::bind(full ? PrintPlaylistFull : PrintPlaylistBrief, const auto p = selection.match == nullptr
client, _1, _2); ? std::bind(full ? PrintPlaylistFull : PrintPlaylistBrief,
client, _1, _2)
: VisitPlaylist();
return GetDatabase()->Visit(selection, d, s, p, error_r); return GetDatabase()->Visit(selection, d, s, p, error_r);
} }
static bool
MatchPrintSong(struct client *client, const struct locate_item_list *criteria,
song &song)
{
if (locate_list_song_match(&song, criteria))
song_print_info(client, &song);
return true;
}
bool
findSongsIn(struct client *client, const char *uri,
const struct locate_item_list *criteria,
GError **error_r)
{
const DatabaseSelection selection(uri, true);
using namespace std::placeholders;
const auto f = std::bind(MatchPrintSong, client, criteria, _1);
return GetDatabase()->Visit(selection, f, error_r);
}
struct SearchStats { struct SearchStats {
int numberOfSongs; int numberOfSongs;
unsigned long playTime; unsigned long playTime;
...@@ -172,13 +154,10 @@ static void printSearchStats(struct client *client, SearchStats *stats) ...@@ -172,13 +154,10 @@ static void printSearchStats(struct client *client, SearchStats *stats)
} }
static bool static bool
stats_visitor_song(SearchStats &stats, const struct locate_item_list *criteria, stats_visitor_song(SearchStats &stats, song &song)
song &song)
{ {
if (locate_list_song_match(&song, criteria)) {
stats.numberOfSongs++; stats.numberOfSongs++;
stats.playTime += song_get_duration(&song); stats.playTime += song_get_duration(&song);
}
return true; return true;
} }
...@@ -188,14 +167,14 @@ searchStatsForSongsIn(struct client *client, const char *name, ...@@ -188,14 +167,14 @@ searchStatsForSongsIn(struct client *client, const char *name,
const struct locate_item_list *criteria, const struct locate_item_list *criteria,
GError **error_r) GError **error_r)
{ {
const DatabaseSelection selection(name, true); const DatabaseSelection selection(name, true, criteria);
SearchStats stats; SearchStats stats;
stats.numberOfSongs = 0; stats.numberOfSongs = 0;
stats.playTime = 0; stats.playTime = 0;
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(stats_visitor_song, std::ref(stats), criteria, const auto f = std::bind(stats_visitor_song, std::ref(stats),
_1); _1);
if (!GetDatabase()->Visit(selection, f, error_r)) if (!GetDatabase()->Visit(selection, f, error_r))
return false; return false;
...@@ -257,10 +236,8 @@ visitTag(struct client *client, StringSet &set, ...@@ -257,10 +236,8 @@ visitTag(struct client *client, StringSet &set,
static bool static bool
unique_tags_visitor_song(struct client *client, unique_tags_visitor_song(struct client *client,
enum tag_type tag_type, enum tag_type tag_type,
const struct locate_item_list *criteria,
StringSet &set, song &song) StringSet &set, song &song)
{ {
if (locate_list_song_match(&song, criteria))
visitTag(client, set, song, tag_type); visitTag(client, set, song, tag_type);
return true; return true;
...@@ -271,13 +248,13 @@ listAllUniqueTags(struct client *client, int type, ...@@ -271,13 +248,13 @@ listAllUniqueTags(struct client *client, int type,
const struct locate_item_list *criteria, const struct locate_item_list *criteria,
GError **error_r) GError **error_r)
{ {
const DatabaseSelection selection("", true); const DatabaseSelection selection("", true, criteria);
StringSet set; StringSet set;
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(unique_tags_visitor_song, client, const auto f = std::bind(unique_tags_visitor_song, client,
(enum tag_type)type, criteria, std::ref(set), (enum tag_type)type, std::ref(set),
_1); _1);
if (!GetDatabase()->Visit(selection, f, error_r)) if (!GetDatabase()->Visit(selection, f, error_r))
return false; return false;
......
...@@ -46,12 +46,6 @@ printInfoForAllIn(struct client *client, const char *uri_utf8, ...@@ -46,12 +46,6 @@ printInfoForAllIn(struct client *client, const char *uri_utf8,
gcc_nonnull(1,2,3) gcc_nonnull(1,2,3)
bool bool
findSongsIn(struct client *client, const char *name,
const struct locate_item_list *criteria,
GError **error_r);
gcc_nonnull(1,2,3)
bool
searchStatsForSongsIn(struct client *client, const char *name, searchStatsForSongsIn(struct client *client, const char *name,
const struct locate_item_list *criteria, const struct locate_item_list *criteria,
GError **error_r); GError **error_r);
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
extern "C" { extern "C" {
#include "dbUtils.h" #include "dbUtils.h"
#include "locate.h"
#include "playlist.h" #include "playlist.h"
} }
...@@ -47,31 +46,18 @@ AddToQueue(struct player_control *pc, song &song, GError **error_r) ...@@ -47,31 +46,18 @@ AddToQueue(struct player_control *pc, song &song, GError **error_r)
} }
bool bool
addAllIn(struct player_control *pc, const char *uri, GError **error_r) findAddIn(struct player_control *pc, const char *uri,
const struct locate_item_list *criteria, GError **error_r)
{ {
const DatabaseSelection selection(uri, true); const DatabaseSelection selection(uri, true, criteria);
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(AddToQueue, pc, _1, _2); const auto f = std::bind(AddToQueue, pc, _1, _2);
return GetDatabase()->Visit(selection, f, error_r); return GetDatabase()->Visit(selection, f, error_r);
} }
static bool
MatchAddSong(struct player_control *pc,
const struct locate_item_list *criteria,
song &song, GError **error_r)
{
return !locate_list_song_match(&song, criteria) ||
AddToQueue(pc, song, error_r);
}
bool bool
findAddIn(struct player_control *pc, const char *uri, addAllIn(struct player_control *pc, const char *uri, GError **error_r)
const struct locate_item_list *criteria, GError **error_r)
{ {
const DatabaseSelection selection(uri, true); return findAddIn(pc, uri, nullptr, error_r);
using namespace std::placeholders;
const auto f = std::bind(MatchAddSong, pc, criteria, _1, _2);
return GetDatabase()->Visit(selection, f, error_r);
} }
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
struct locate_item_list; struct locate_item_list;
struct player_control; struct player_control;
gcc_nonnull(1,2,3) gcc_nonnull(1,2)
bool bool
findAddIn(struct player_control *pc, const char *name, findAddIn(struct player_control *pc, const char *name,
const struct locate_item_list *criteria, GError **error_r); const struct locate_item_list *criteria, GError **error_r);
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <assert.h> #include <assert.h>
#include <stddef.h> #include <stddef.h>
struct locate_item_list;
struct DatabaseSelection { struct DatabaseSelection {
/** /**
* The base URI of the search (UTF-8). Must not begin or end * The base URI of the search (UTF-8). Must not begin or end
...@@ -38,8 +40,11 @@ struct DatabaseSelection { ...@@ -38,8 +40,11 @@ struct DatabaseSelection {
*/ */
bool recursive; bool recursive;
DatabaseSelection(const char *_uri, bool _recursive) const locate_item_list *match;
:uri(_uri), recursive(_recursive) {
DatabaseSelection(const char *_uri, bool _recursive,
const locate_item_list *_match=nullptr)
:uri(_uri), recursive(_recursive), match(_match) {
assert(uri != NULL); assert(uri != NULL);
} }
}; };
......
...@@ -28,6 +28,7 @@ extern "C" { ...@@ -28,6 +28,7 @@ extern "C" {
#include "util/list_sort.h" #include "util/list_sort.h"
#include "db_visitor.h" #include "db_visitor.h"
#include "db_lock.h" #include "db_lock.h"
#include "locate.h"
} }
#include <glib.h> #include <glib.h>
...@@ -281,7 +282,7 @@ directory_sort(struct directory *directory) ...@@ -281,7 +282,7 @@ directory_sort(struct directory *directory)
} }
bool bool
directory::Walk(bool recursive, directory::Walk(bool recursive, const locate_item_list *match,
VisitDirectory visit_directory, VisitSong visit_song, VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist,
GError **error_r) const GError **error_r) const
...@@ -291,7 +292,9 @@ directory::Walk(bool recursive, ...@@ -291,7 +292,9 @@ directory::Walk(bool recursive,
if (visit_song) { if (visit_song) {
struct song *song; struct song *song;
directory_for_each_song(song, this) directory_for_each_song(song, this)
if (!visit_song(*song, error_r)) if ((match == NULL ||
locate_list_song_match(song, match)) &&
!visit_song(*song, error_r))
return false; return false;
} }
...@@ -309,8 +312,9 @@ directory::Walk(bool recursive, ...@@ -309,8 +312,9 @@ directory::Walk(bool recursive,
return false; return false;
if (recursive && if (recursive &&
!child->Walk(recursive, visit_directory, visit_song, !child->Walk(recursive, match,
visit_playlist, error_r)) visit_directory, visit_song, visit_playlist,
error_r))
return false; return false;
} }
......
...@@ -27,6 +27,7 @@ extern "C" { ...@@ -27,6 +27,7 @@ extern "C" {
#include "db_save.h" #include "db_save.h"
#include "db_lock.h" #include "db_lock.h"
#include "conf.h" #include "conf.h"
#include "locate.h"
} }
#include "directory.h" #include "directory.h"
...@@ -247,7 +248,9 @@ SimpleDatabase::Visit(const DatabaseSelection &selection, ...@@ -247,7 +248,9 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
if (directory == NULL) { if (directory == NULL) {
struct song *song; struct song *song;
if (visit_song && if (visit_song &&
(song = GetSong(selection.uri, NULL)) != NULL) (song = GetSong(selection.uri, NULL)) != NULL &&
(selection.match == NULL ||
locate_list_song_match(song, selection.match)))
return visit_song(*song, error_r); return visit_song(*song, error_r);
g_set_error(error_r, db_quark(), DB_NOT_FOUND, g_set_error(error_r, db_quark(), DB_NOT_FOUND,
...@@ -260,7 +263,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection, ...@@ -260,7 +263,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
return false; return false;
db_lock(); db_lock();
bool ret = directory->Walk(selection.recursive, bool ret = directory->Walk(selection.recursive, selection.match,
visit_directory, visit_song, visit_playlist, visit_directory, visit_song, visit_playlist,
error_r); error_r);
db_unlock(); db_unlock();
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
struct song; struct song;
struct db_visitor; struct db_visitor;
struct locate_item_list;
struct directory { struct directory {
/** /**
...@@ -95,7 +96,7 @@ struct directory { ...@@ -95,7 +96,7 @@ struct directory {
/** /**
* Caller must lock #db_mutex. * Caller must lock #db_mutex.
*/ */
bool Walk(bool recursive, bool Walk(bool recursive, const locate_item_list *match,
VisitDirectory visit_directory, VisitSong visit_song, VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist,
GError **error_r) const; GError **error_r) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment