directory: don't pass fd to traverseAllIn() callbacks
Database traversal should be generic, and not bound to a client connection. This is the first step: no file descriptor for the callback functions forEachSong() and forEachDir(). If a callback needs the file descriptor, it has to be passed in the void*data pointer somehow; some callbacks might need a new struct for passing more than one parameter. This might look a bit cumbersome right now, but our goal is to have a clean API.
This commit is contained in:
parent
d8ef33b710
commit
528be8a0a9
103
src/dbUtils.c
103
src/dbUtils.c
@ -46,7 +46,7 @@ typedef struct _SearchStats {
|
|||||||
unsigned long playTime;
|
unsigned long playTime;
|
||||||
} SearchStats;
|
} SearchStats;
|
||||||
|
|
||||||
static int countSongsInDirectory(mpd_unused int fd, Directory * directory,
|
static int countSongsInDirectory(Directory * directory,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
int *count = (int *)data;
|
int *count = (int *)data;
|
||||||
@ -56,24 +56,32 @@ static int countSongsInDirectory(mpd_unused int fd, Directory * directory,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int printDirectoryInDirectory(int fd, Directory * directory,
|
static int printDirectoryInDirectory(Directory * directory, void *data)
|
||||||
mpd_unused void *data)
|
|
||||||
{
|
{
|
||||||
|
int fd = (int)(size_t)data;
|
||||||
if (directory->path) {
|
if (directory->path) {
|
||||||
fdprintf(fd, "directory: %s\n", getDirectoryPath(directory));
|
fdprintf(fd, "directory: %s\n", getDirectoryPath(directory));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int printSongInDirectory(int fd, Song * song, mpd_unused void *data)
|
static int printSongInDirectory(Song * song, mpd_unused void *data)
|
||||||
{
|
{
|
||||||
|
int fd = (int)(size_t)data;
|
||||||
printSongUrl(fd, song);
|
printSongUrl(fd, song);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int searchInDirectory(int fd, Song * song, void *data)
|
struct search_data {
|
||||||
|
int fd;
|
||||||
|
LocateTagItemArray array;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int searchInDirectory(Song * song, void *_data)
|
||||||
{
|
{
|
||||||
LocateTagItemArray *array = data;
|
struct search_data *data = _data;
|
||||||
|
int fd = data->fd;
|
||||||
|
LocateTagItemArray *array = &data->array;
|
||||||
|
|
||||||
if (strstrSearchTags(song, array->numItems, array->items))
|
if (strstrSearchTags(song, array->numItems, array->items))
|
||||||
printSongInfo(fd, song);
|
printSongInfo(fd, song);
|
||||||
@ -88,17 +96,18 @@ int searchForSongsIn(int fd, const char *name, int numItems,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
char **originalNeedles = xmalloc(numItems * sizeof(char *));
|
char **originalNeedles = xmalloc(numItems * sizeof(char *));
|
||||||
LocateTagItemArray array;
|
struct search_data data;
|
||||||
|
|
||||||
for (i = 0; i < numItems; i++) {
|
for (i = 0; i < numItems; i++) {
|
||||||
originalNeedles[i] = items[i].needle;
|
originalNeedles[i] = items[i].needle;
|
||||||
items[i].needle = strDupToUpper(originalNeedles[i]);
|
items[i].needle = strDupToUpper(originalNeedles[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
array.numItems = numItems;
|
data.fd = fd;
|
||||||
array.items = items;
|
data.array.numItems = numItems;
|
||||||
|
data.array.items = items;
|
||||||
|
|
||||||
ret = traverseAllIn(fd, name, searchInDirectory, NULL, &array);
|
ret = traverseAllIn(fd, name, searchInDirectory, NULL, &data);
|
||||||
|
|
||||||
for (i = 0; i < numItems; i++) {
|
for (i = 0; i < numItems; i++) {
|
||||||
free(items[i].needle);
|
free(items[i].needle);
|
||||||
@ -110,9 +119,11 @@ int searchForSongsIn(int fd, const char *name, int numItems,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findInDirectory(int fd, Song * song, void *data)
|
static int findInDirectory(Song * song, void *_data)
|
||||||
{
|
{
|
||||||
LocateTagItemArray *array = data;
|
struct search_data *data = _data;
|
||||||
|
int fd = data->fd;
|
||||||
|
LocateTagItemArray *array = &data->array;
|
||||||
|
|
||||||
if (tagItemsFoundAndMatches(song, array->numItems, array->items))
|
if (tagItemsFoundAndMatches(song, array->numItems, array->items))
|
||||||
printSongInfo(fd, song);
|
printSongInfo(fd, song);
|
||||||
@ -122,12 +133,13 @@ static int findInDirectory(int fd, Song * song, void *data)
|
|||||||
|
|
||||||
int findSongsIn(int fd, const char *name, int numItems, LocateTagItem * items)
|
int findSongsIn(int fd, const char *name, int numItems, LocateTagItem * items)
|
||||||
{
|
{
|
||||||
LocateTagItemArray array;
|
struct search_data data;
|
||||||
|
|
||||||
array.numItems = numItems;
|
data.fd = fd;
|
||||||
array.items = items;
|
data.array.numItems = numItems;
|
||||||
|
data.array.items = items;
|
||||||
|
|
||||||
return traverseAllIn(fd, name, findInDirectory, NULL, (void *)&array);
|
return traverseAllIn(fd, name, findInDirectory, NULL, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printSearchStats(int fd, SearchStats *stats)
|
static void printSearchStats(int fd, SearchStats *stats)
|
||||||
@ -136,7 +148,7 @@ static void printSearchStats(int fd, SearchStats *stats)
|
|||||||
fdprintf(fd, "playtime: %li\n", stats->playTime);
|
fdprintf(fd, "playtime: %li\n", stats->playTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int searchStatsInDirectory(mpd_unused int fd, Song * song, void *data)
|
static int searchStatsInDirectory(Song * song, void *data)
|
||||||
{
|
{
|
||||||
SearchStats *stats = data;
|
SearchStats *stats = data;
|
||||||
|
|
||||||
@ -171,19 +183,25 @@ int searchStatsForSongsIn(int fd, const char *name, int numItems,
|
|||||||
int printAllIn(int fd, const char *name)
|
int printAllIn(int fd, const char *name)
|
||||||
{
|
{
|
||||||
return traverseAllIn(fd, name, printSongInDirectory,
|
return traverseAllIn(fd, name, printSongInDirectory,
|
||||||
printDirectoryInDirectory, NULL);
|
printDirectoryInDirectory, (void*)(size_t)fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int directoryAddSongToPlaylist(mpd_unused int fd, Song * song,
|
static int directoryAddSongToPlaylist(Song * song, mpd_unused void *data)
|
||||||
mpd_unused void *data)
|
|
||||||
{
|
{
|
||||||
return addSongToPlaylist(song, NULL);
|
return addSongToPlaylist(song, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int directoryAddSongToStoredPlaylist(mpd_unused int fd, Song *song,
|
struct add_data {
|
||||||
void *data)
|
const char *path;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int directoryAddSongToStoredPlaylist(Song *song, void *_data)
|
||||||
{
|
{
|
||||||
return appendSongToStoredPlaylistByPath((char *)data, song);
|
struct add_data *data = _data;
|
||||||
|
|
||||||
|
if (appendSongToStoredPlaylistByPath(data->path, song) != 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int addAllIn(int fd, const char *name)
|
int addAllIn(int fd, const char *name)
|
||||||
@ -193,16 +211,22 @@ int addAllIn(int fd, const char *name)
|
|||||||
|
|
||||||
int addAllInToStoredPlaylist(int fd, const char *name, const char *utf8file)
|
int addAllInToStoredPlaylist(int fd, const char *name, const char *utf8file)
|
||||||
{
|
{
|
||||||
|
struct add_data data = {
|
||||||
|
.path = utf8file,
|
||||||
|
};
|
||||||
|
|
||||||
return traverseAllIn(fd, name, directoryAddSongToStoredPlaylist, NULL,
|
return traverseAllIn(fd, name, directoryAddSongToStoredPlaylist, NULL,
|
||||||
(void *)utf8file);
|
&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int directoryPrintSongInfo(int fd, Song * song, mpd_unused void *data)
|
static int directoryPrintSongInfo(Song * song, void *data)
|
||||||
{
|
{
|
||||||
|
int fd = (int)(size_t)data;
|
||||||
|
|
||||||
return printSongInfo(fd, song);
|
return printSongInfo(fd, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sumSongTime(mpd_unused int fd, Song * song, void *data)
|
static int sumSongTime(Song * song, void *data)
|
||||||
{
|
{
|
||||||
unsigned long *sum_time = (unsigned long *)data;
|
unsigned long *sum_time = (unsigned long *)data;
|
||||||
|
|
||||||
@ -215,7 +239,7 @@ static int sumSongTime(mpd_unused int fd, Song * song, void *data)
|
|||||||
int printInfoForAllIn(int fd, const char *name)
|
int printInfoForAllIn(int fd, const char *name)
|
||||||
{
|
{
|
||||||
return traverseAllIn(fd, name, directoryPrintSongInfo,
|
return traverseAllIn(fd, name, directoryPrintSongInfo,
|
||||||
printDirectoryInDirectory, NULL);
|
printDirectoryInDirectory, (void*)(size_t)fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int countSongsIn(int fd, const char *name)
|
int countSongsIn(int fd, const char *name)
|
||||||
@ -275,13 +299,19 @@ static void visitTag(int fd, Song * song, enum tag_type tagType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int listUniqueTagsInDirectory(int fd, Song * song, void *data)
|
struct list_tags_data {
|
||||||
|
int fd;
|
||||||
|
ListCommandItem *item;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int listUniqueTagsInDirectory(Song * song, void *_data)
|
||||||
{
|
{
|
||||||
ListCommandItem *item = data;
|
struct list_tags_data *data = _data;
|
||||||
|
ListCommandItem *item = data->item;
|
||||||
|
|
||||||
if (tagItemsFoundAndMatches(song, item->numConditionals,
|
if (tagItemsFoundAndMatches(song, item->numConditionals,
|
||||||
item->conditionals)) {
|
item->conditionals)) {
|
||||||
visitTag(fd, song, item->tagType);
|
visitTag(data->fd, song, item->tagType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -293,13 +323,17 @@ int listAllUniqueTags(int fd, int type, int numConditionals,
|
|||||||
int ret;
|
int ret;
|
||||||
ListCommandItem *item = newListCommandItem(type, numConditionals,
|
ListCommandItem *item = newListCommandItem(type, numConditionals,
|
||||||
conditionals);
|
conditionals);
|
||||||
|
struct list_tags_data data = {
|
||||||
|
.fd = fd,
|
||||||
|
.item = item,
|
||||||
|
};
|
||||||
|
|
||||||
if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
|
if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
|
||||||
resetVisitedFlagsInTagTracker(type);
|
resetVisitedFlagsInTagTracker(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = traverseAllIn(fd, NULL, listUniqueTagsInDirectory, NULL,
|
ret = traverseAllIn(fd, NULL, listUniqueTagsInDirectory, NULL,
|
||||||
(void *)item);
|
&data);
|
||||||
|
|
||||||
if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
|
if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
|
||||||
printVisitedInTagTracker(fd, type);
|
printVisitedInTagTracker(fd, type);
|
||||||
@ -310,9 +344,7 @@ int listAllUniqueTags(int fd, int type, int numConditionals,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sumSavedFilenameMemoryInDirectory(mpd_unused int fd,
|
static int sumSavedFilenameMemoryInDirectory(Directory * dir, void *data)
|
||||||
Directory * dir,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
int *sum = data;
|
int *sum = data;
|
||||||
|
|
||||||
@ -325,8 +357,7 @@ static int sumSavedFilenameMemoryInDirectory(mpd_unused int fd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sumSavedFilenameMemoryInSong(mpd_unused int fd, Song * song,
|
static int sumSavedFilenameMemoryInSong(Song * song, void *data)
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
int *sum = data;
|
int *sum = data;
|
||||||
|
|
||||||
|
@ -1182,11 +1182,10 @@ void updateMp3Directory(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int traverseAllInSubDirectory(int fd, Directory * directory,
|
static int traverseAllInSubDirectory(Directory * directory,
|
||||||
int (*forEachSong) (int, Song *,
|
int (*forEachSong) (Song *, void *),
|
||||||
void *),
|
int (*forEachDir) (Directory *, void *),
|
||||||
int (*forEachDir) (int, Directory *,
|
void *data)
|
||||||
void *), void *data)
|
|
||||||
{
|
{
|
||||||
ListNode *node = directory->songs->firstNode;
|
ListNode *node = directory->songs->firstNode;
|
||||||
Song *song;
|
Song *song;
|
||||||
@ -1194,7 +1193,7 @@ static int traverseAllInSubDirectory(int fd, Directory * directory,
|
|||||||
int errFlag = 0;
|
int errFlag = 0;
|
||||||
|
|
||||||
if (forEachDir) {
|
if (forEachDir) {
|
||||||
errFlag = forEachDir(fd, directory, data);
|
errFlag = forEachDir(directory, data);
|
||||||
if (errFlag)
|
if (errFlag)
|
||||||
return errFlag;
|
return errFlag;
|
||||||
}
|
}
|
||||||
@ -1202,7 +1201,7 @@ static int traverseAllInSubDirectory(int fd, Directory * directory,
|
|||||||
if (forEachSong) {
|
if (forEachSong) {
|
||||||
while (node != NULL && !errFlag) {
|
while (node != NULL && !errFlag) {
|
||||||
song = (Song *) node->data;
|
song = (Song *) node->data;
|
||||||
errFlag = forEachSong(fd, song, data);
|
errFlag = forEachSong(song, data);
|
||||||
node = node->nextNode;
|
node = node->nextNode;
|
||||||
}
|
}
|
||||||
if (errFlag)
|
if (errFlag)
|
||||||
@ -1213,7 +1212,7 @@ static int traverseAllInSubDirectory(int fd, Directory * directory,
|
|||||||
|
|
||||||
while (node != NULL && !errFlag) {
|
while (node != NULL && !errFlag) {
|
||||||
dir = (Directory *) node->data;
|
dir = (Directory *) node->data;
|
||||||
errFlag = traverseAllInSubDirectory(fd, dir, forEachSong,
|
errFlag = traverseAllInSubDirectory(dir, forEachSong,
|
||||||
forEachDir, data);
|
forEachDir, data);
|
||||||
node = node->nextNode;
|
node = node->nextNode;
|
||||||
}
|
}
|
||||||
@ -1222,22 +1221,22 @@ static int traverseAllInSubDirectory(int fd, Directory * directory,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int traverseAllIn(int fd, const char *name,
|
int traverseAllIn(int fd, const char *name,
|
||||||
int (*forEachSong) (int, Song *, void *),
|
int (*forEachSong) (Song *, void *),
|
||||||
int (*forEachDir) (int, Directory *, void *), void *data)
|
int (*forEachDir) (Directory *, void *), void *data)
|
||||||
{
|
{
|
||||||
Directory *directory;
|
Directory *directory;
|
||||||
|
|
||||||
if ((directory = getDirectory(name)) == NULL) {
|
if ((directory = getDirectory(name)) == NULL) {
|
||||||
Song *song;
|
Song *song;
|
||||||
if ((song = getSongFromDB(name)) && forEachSong) {
|
if ((song = getSongFromDB(name)) && forEachSong) {
|
||||||
return forEachSong(fd, song, data);
|
return forEachSong(song, data);
|
||||||
}
|
}
|
||||||
commandError(fd, ACK_ERROR_NO_EXIST,
|
commandError(fd, ACK_ERROR_NO_EXIST,
|
||||||
"directory or file not found");
|
"directory or file not found");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return traverseAllInSubDirectory(fd, directory, forEachSong, forEachDir,
|
return traverseAllInSubDirectory(directory, forEachSong, forEachDir,
|
||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +65,8 @@ Song *getSongFromDB(const char *file);
|
|||||||
time_t getDbModTime(void);
|
time_t getDbModTime(void);
|
||||||
|
|
||||||
int traverseAllIn(int fd, const char *name,
|
int traverseAllIn(int fd, const char *name,
|
||||||
int (*forEachSong) (int, Song *, void *),
|
int (*forEachSong) (Song *, void *),
|
||||||
int (*forEachDir) (int, Directory *, void *), void *data);
|
int (*forEachDir) (Directory *, void *), void *data);
|
||||||
|
|
||||||
#define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "")
|
#define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "")
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ struct visited {
|
|||||||
static struct visited *visited_heads[TAG_NUM_OF_ITEM_TYPES];
|
static struct visited *visited_heads[TAG_NUM_OF_ITEM_TYPES];
|
||||||
static unsigned num_visited[TAG_NUM_OF_ITEM_TYPES];
|
static unsigned num_visited[TAG_NUM_OF_ITEM_TYPES];
|
||||||
|
|
||||||
static int visit_tag_items(int fd mpd_unused, Song *song, void *data)
|
static int visit_tag_items(Song *song, void *data)
|
||||||
{
|
{
|
||||||
enum tag_type type = (enum tag_type)(size_t)data;
|
enum tag_type type = (enum tag_type)(size_t)data;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
Loading…
Reference in New Issue
Block a user