aboutsummaryrefslogtreecommitdiffstats
path: root/src/db
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dbUtils.c91
-rw-r--r--src/dbUtils.h8
-rw-r--r--src/db_error.h39
-rw-r--r--src/db_print.c144
-rw-r--r--src/db_print.h31
-rw-r--r--src/db_visitor.h43
6 files changed, 257 insertions, 99 deletions
diff --git a/src/dbUtils.c b/src/dbUtils.c
index e0d8c5379..827d0a0c1 100644
--- a/src/dbUtils.c
+++ b/src/dbUtils.c
@@ -21,52 +21,66 @@
#include "dbUtils.h"
#include "locate.h"
#include "database.h"
+#include "db_visitor.h"
#include "playlist.h"
#include "stored_playlist.h"
#include <glib.h>
-static int
-directoryAddSongToPlaylist(struct song *song, void *data)
+static bool
+add_to_queue_song(struct song *song, void *ctx, GError **error_r)
{
- struct player_control *pc = data;
+ struct player_control *pc = ctx;
+
+ enum playlist_result result =
+ playlist_append_song(&g_playlist, pc, song, NULL);
+ if (result != PLAYLIST_RESULT_SUCCESS) {
+ g_set_error(error_r, playlist_quark(), result,
+ "Playlist error");
+ return false;
+ }
+
+ return true;
+}
+
+static const struct db_visitor add_to_queue_visitor = {
+ .song = add_to_queue_song,
+};
- return playlist_append_song(&g_playlist, pc, song, NULL);
+bool
+addAllIn(struct player_control *pc, const char *uri, GError **error_r)
+{
+ return db_walk(uri, &add_to_queue_visitor, pc, error_r);
}
struct add_data {
const char *path;
- GError **error_r;
};
-static int
-directoryAddSongToStoredPlaylist(struct song *song, void *_data)
+static bool
+add_to_spl_song(struct song *song, void *ctx, GError **error_r)
{
- struct add_data *data = _data;
+ struct add_data *data = ctx;
- if (!spl_append_song(data->path, song, data->error_r)) {
- return -1;
- }
+ if (!spl_append_song(data->path, song, error_r))
+ return false;
- return 0;
+ return true;
}
-int
-addAllIn(struct player_control *pc, const char *name)
-{
- return db_walk(name, directoryAddSongToPlaylist, NULL, pc);
-}
+static const struct db_visitor add_to_spl_visitor = {
+ .song = add_to_spl_song,
+};
bool
-addAllInToStoredPlaylist(const char *name, const char *utf8file,
+addAllInToStoredPlaylist(const char *uri_utf8, const char *path_utf8,
GError **error_r)
{
struct add_data data = {
- .path = utf8file,
- .error_r = error_r,
+ .path = path_utf8,
};
- return db_walk(name, directoryAddSongToStoredPlaylist, NULL, &data) == 0;
+ return db_walk(uri_utf8, &add_to_spl_visitor, &data, error_r);
}
struct find_add_data {
@@ -74,26 +88,37 @@ struct find_add_data {
const struct locate_item_list *criteria;
};
-static int
-findAddInDirectory(struct song *song, void *_data)
+static bool
+find_add_song(struct song *song, void *ctx, GError **error_r)
{
- struct find_add_data *data = _data;
-
- if (locate_song_match(song, data->criteria))
- return playlist_append_song(&g_playlist,
- data->pc,
- song, NULL);
+ struct find_add_data *data = ctx;
+
+ if (!locate_song_match(song, data->criteria))
+ return true;
+
+ enum playlist_result result =
+ playlist_append_song(&g_playlist, data->pc,
+ song, NULL);
+ if (result != PLAYLIST_RESULT_SUCCESS) {
+ g_set_error(error_r, playlist_quark(), result,
+ "Playlist error");
+ return false;
+ }
- return 0;
+ return true;
}
-int
+static const struct db_visitor find_add_visitor = {
+ .song = find_add_song,
+};
+
+bool
findAddIn(struct player_control *pc, const char *name,
- const struct locate_item_list *criteria)
+ const struct locate_item_list *criteria, GError **error_r)
{
struct find_add_data data;
data.pc = pc;
data.criteria = criteria;
- return db_walk(name, findAddInDirectory, NULL, &data);
+ return db_walk(name, &find_add_visitor, &data, error_r);
}
diff --git a/src/dbUtils.h b/src/dbUtils.h
index 65349a32f..f693a7793 100644
--- a/src/dbUtils.h
+++ b/src/dbUtils.h
@@ -26,16 +26,16 @@
struct locate_item_list;
struct player_control;
-int
-addAllIn(struct player_control *pc, const char *name);
+bool
+addAllIn(struct player_control *pc, const char *uri, GError **error_r);
bool
addAllInToStoredPlaylist(const char *uri_utf8, const char *path_utf8,
GError **error_r);
-int
+bool
findAddIn(struct player_control *pc, const char *name,
- const struct locate_item_list *criteria);
+ const struct locate_item_list *criteria, GError **error_r);
unsigned long sumSongTimesIn(const char *name);
diff --git a/src/db_error.h b/src/db_error.h
new file mode 100644
index 000000000..35051c40c
--- /dev/null
+++ b/src/db_error.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_DB_ERROR_H
+#define MPD_DB_ERROR_H
+
+#include <glib.h>
+
+enum db_error {
+ DB_NOT_FOUND,
+};
+
+/**
+ * Quark for GError.domain; the code is an enum #db_error.
+ */
+G_GNUC_CONST
+static inline GQuark
+db_quark(void)
+{
+ return g_quark_from_static_string("db");
+}
+
+#endif
diff --git a/src/db_print.c b/src/db_print.c
index 629832a3d..c4086a387 100644
--- a/src/db_print.c
+++ b/src/db_print.c
@@ -19,6 +19,7 @@
#include "config.h"
#include "db_print.h"
+#include "db_visitor.h"
#include "locate.h"
#include "directory.h"
#include "database.h"
@@ -41,46 +42,72 @@ typedef struct _SearchStats {
unsigned long playTime;
} SearchStats;
-static int
-printDirectoryInDirectory(struct directory *directory, void *data)
+static bool
+print_visitor_directory(const struct directory *directory, void *data,
+ G_GNUC_UNUSED GError **error_r)
{
struct client *client = data;
if (!directory_is_root(directory))
client_printf(client, "directory: %s\n", directory_get_path(directory));
- return 0;
+ return true;
}
-static int
-printSongInDirectory(struct song *song, G_GNUC_UNUSED void *data)
+static bool
+print_visitor_song(struct song *song, void *data,
+ G_GNUC_UNUSED GError **error_r)
{
struct client *client = data;
song_print_uri(client, song);
- return 0;
+ return true;
}
+static bool
+print_visitor_song_info(struct song *song, void *data,
+ G_GNUC_UNUSED GError **error_r)
+{
+ struct client *client = data;
+ song_print_info(client, song);
+ return true;
+}
+
+static const struct db_visitor print_visitor = {
+ .directory = print_visitor_directory,
+ .song = print_visitor_song,
+};
+
+static const struct db_visitor print_info_visitor = {
+ .directory = print_visitor_directory,
+ .song = print_visitor_song_info,
+};
+
struct search_data {
struct client *client;
const struct locate_item_list *criteria;
};
-static int
-searchInDirectory(struct song *song, void *_data)
+static bool
+search_visitor_song(struct song *song, void *_data,
+ G_GNUC_UNUSED GError **error_r)
{
struct search_data *data = _data;
if (locate_song_search(song, data->criteria))
song_print_info(data->client, song);
- return 0;
+ return true;
}
-int
+static const struct db_visitor search_visitor = {
+ .song = search_visitor_song,
+};
+
+bool
searchForSongsIn(struct client *client, const char *name,
- const struct locate_item_list *criteria)
+ const struct locate_item_list *criteria,
+ GError **error_r)
{
- int ret;
struct locate_item_list *new_list
= locate_item_list_casefold(criteria);
struct search_data data;
@@ -88,34 +115,40 @@ searchForSongsIn(struct client *client, const char *name,
data.client = client;
data.criteria = new_list;
- ret = db_walk(name, searchInDirectory, NULL, &data);
+ bool success = db_walk(name, &search_visitor, &data, error_r);
locate_item_list_free(new_list);
- return ret;
+ return success;
}
-static int
-findInDirectory(struct song *song, void *_data)
+static bool
+find_visitor_song(struct song *song, void *_data,
+ G_GNUC_UNUSED GError **error_r)
{
struct search_data *data = _data;
if (locate_song_match(song, data->criteria))
song_print_info(data->client, song);
- return 0;
+ return true;
}
-int
+static const struct db_visitor find_visitor = {
+ .song = find_visitor_song,
+};
+
+bool
findSongsIn(struct client *client, const char *name,
- const struct locate_item_list *criteria)
+ const struct locate_item_list *criteria,
+ GError **error_r)
{
struct search_data data;
data.client = client;
data.criteria = criteria;
- return db_walk(name, findInDirectory, NULL, &data);
+ return db_walk(name, &find_visitor, &data, error_r);
}
static void printSearchStats(struct client *client, SearchStats *stats)
@@ -124,8 +157,9 @@ static void printSearchStats(struct client *client, SearchStats *stats)
client_printf(client, "playtime: %li\n", stats->playTime);
}
-static int
-searchStatsInDirectory(struct song *song, void *data)
+static bool
+stats_visitor_song(struct song *song, void *data,
+ G_GNUC_UNUSED GError **error_r)
{
SearchStats *stats = data;
@@ -134,45 +168,42 @@ searchStatsInDirectory(struct song *song, void *data)
stats->playTime += song_get_duration(song);
}
- return 0;
+ return true;
}
-int
+static const struct db_visitor stats_visitor = {
+ .song = stats_visitor_song,
+};
+
+bool
searchStatsForSongsIn(struct client *client, const char *name,
- const struct locate_item_list *criteria)
+ const struct locate_item_list *criteria,
+ GError **error_r)
{
SearchStats stats;
- int ret;
stats.criteria = criteria;
stats.numberOfSongs = 0;
stats.playTime = 0;
- ret = db_walk(name, searchStatsInDirectory, NULL, &stats);
- if (ret == 0)
- printSearchStats(client, &stats);
+ if (!db_walk(name, &stats_visitor, &stats, error_r))
+ return false;
- return ret;
+ printSearchStats(client, &stats);
+ return true;
}
-int printAllIn(struct client *client, const char *name)
+bool
+printAllIn(struct client *client, const char *uri_utf8, GError **error_r)
{
- return db_walk(name, printSongInDirectory,
- printDirectoryInDirectory, client);
+ return db_walk(uri_utf8, &print_visitor, client, error_r);
}
-static int
-directoryPrintSongInfo(struct song *song, void *data)
+bool
+printInfoForAllIn(struct client *client, const char *uri_utf8,
+ GError **error_r)
{
- struct client *client = data;
- song_print_info(client, song);
- return 0;
-}
-
-int printInfoForAllIn(struct client *client, const char *name)
-{
- return db_walk(name, directoryPrintSongInfo,
- printDirectoryInDirectory, client);
+ return db_walk(uri_utf8, &print_info_visitor, client, error_r);
}
static ListCommandItem *
@@ -223,8 +254,9 @@ struct list_tags_data {
struct strset *set;
};
-static int
-listUniqueTagsInDirectory(struct song *song, void *_data)
+static bool
+unique_tags_visitor_song(struct song *song, void *_data,
+ G_GNUC_UNUSED GError **error_r)
{
struct list_tags_data *data = _data;
ListCommandItem *item = data->item;
@@ -232,13 +264,18 @@ listUniqueTagsInDirectory(struct song *song, void *_data)
if (locate_song_match(song, item->criteria))
visitTag(data->client, data->set, song, item->tagType);
- return 0;
+ return true;
}
-int listAllUniqueTags(struct client *client, int type,
- const struct locate_item_list *criteria)
+static const struct db_visitor unique_tags_visitor = {
+ .song = unique_tags_visitor_song,
+};
+
+bool
+listAllUniqueTags(struct client *client, int type,
+ const struct locate_item_list *criteria,
+ GError **error_r)
{
- int ret;
ListCommandItem *item = newListCommandItem(type, criteria);
struct list_tags_data data = {
.client = client,
@@ -249,7 +286,10 @@ int listAllUniqueTags(struct client *client, int type,
data.set = strset_new();
}
- ret = db_walk(NULL, listUniqueTagsInDirectory, NULL, &data);
+ if (!db_walk(NULL, &unique_tags_visitor, &data, error_r)) {
+ freeListCommandItem(item);
+ return false;
+ }
if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
const char *value;
@@ -266,5 +306,5 @@ int listAllUniqueTags(struct client *client, int type,
freeListCommandItem(item);
- return ret;
+ return true;
}
diff --git a/src/db_print.h b/src/db_print.h
index a02e7e3d8..7d6309517 100644
--- a/src/db_print.h
+++ b/src/db_print.h
@@ -20,27 +20,38 @@
#ifndef MPD_DB_PRINT_H
#define MPD_DB_PRINT_H
+#include <glib.h>
+#include <stdbool.h>
+
struct client;
struct locate_item_list;
+struct db_visitor;
-int printAllIn(struct client *client, const char *name);
+bool
+printAllIn(struct client *client, const char *uri_utf8, GError **error_r);
-int printInfoForAllIn(struct client *client, const char *name);
+bool
+printInfoForAllIn(struct client *client, const char *uri_utf8,
+ GError **error_r);
-int
+bool
searchForSongsIn(struct client *client, const char *name,
- const struct locate_item_list *criteria);
+ const struct locate_item_list *criteria,
+ GError **error_r);
-int
+bool
findSongsIn(struct client *client, const char *name,
- const struct locate_item_list *criteria);
+ const struct locate_item_list *criteria,
+ GError **error_r);
-int
+bool
searchStatsForSongsIn(struct client *client, const char *name,
- const struct locate_item_list *criteria);
+ const struct locate_item_list *criteria,
+ GError **error_r);
-int
+bool
listAllUniqueTags(struct client *client, int type,
- const struct locate_item_list *criteria);
+ const struct locate_item_list *criteria,
+ GError **error_r);
#endif
diff --git a/src/db_visitor.h b/src/db_visitor.h
new file mode 100644
index 000000000..3eb215c86
--- /dev/null
+++ b/src/db_visitor.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2003-2011 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_DB_VISITOR_H
+#define MPD_DB_VISITOR_H
+
+struct directory;
+struct song;
+
+struct db_visitor {
+ /**
+ * Visit a directory. Optional method.
+ *
+ * @return true to continue the operation, false on error (set error_r)
+ */
+ bool (*directory)(const struct directory *directory, void *ctx,
+ GError **error_r);
+
+ /**
+ * Visit a song. Optional method.
+ *
+ * @return true to continue the operation, false on error (set error_r)
+ */
+ bool (*song)(struct song *song, void *ctx, GError **error_r);
+};
+
+#endif