DatabaseSelection: add "match" attribute
Let the database plugin do the match.
This commit is contained in:
parent
8d2725234e
commit
733d6a6b16
@ -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)
|
|||||||
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 @@
|
|||||||
|
|
||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
addAllInToStoredPlaylist(const char *uri_utf8, const char *playlist_path_utf8,
|
search_add_to_playlist(const char *uri, const char *playlist_path_utf8,
|
||||||
GError **error_r)
|
const struct locate_item_list *criteria,
|
||||||
|
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 @@
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
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,11 +236,9 @@ 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,
|
|||||||
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;
|
||||||
|
@ -44,12 +44,6 @@ bool
|
|||||||
printInfoForAllIn(struct client *client, const char *uri_utf8,
|
printInfoForAllIn(struct client *client, const char *uri_utf8,
|
||||||
GError **error_r);
|
GError **error_r);
|
||||||
|
|
||||||
gcc_nonnull(1,2,3)
|
|
||||||
bool
|
|
||||||
findSongsIn(struct client *client, const char *name,
|
|
||||||
const struct locate_item_list *criteria,
|
|
||||||
GError **error_r);
|
|
||||||
|
|
||||||
gcc_nonnull(1,2,3)
|
gcc_nonnull(1,2,3)
|
||||||
bool
|
bool
|
||||||
searchStatsForSongsIn(struct client *client, const char *name,
|
searchStatsForSongsIn(struct client *client, const char *name,
|
||||||
|
@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@
|
|||||||
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 @@
|
|||||||
#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 {
|
|||||||
*/
|
*/
|
||||||
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" {
|
|||||||
#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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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" {
|
|||||||
#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,
|
|||||||
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,
|
|||||||
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 @@
|
|||||||
|
|
||||||
struct song;
|
struct song;
|
||||||
struct db_visitor;
|
struct db_visitor;
|
||||||
|
struct locate_item_list;
|
||||||
|
|
||||||
struct directory {
|
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user