diff options
Diffstat (limited to '')
-rw-r--r-- | src/dbUtils.c | 267 | ||||
-rw-r--r-- | src/dbUtils.h | 42 |
2 files changed, 309 insertions, 0 deletions
diff --git a/src/dbUtils.c b/src/dbUtils.c new file mode 100644 index 000000000..5e73da348 --- /dev/null +++ b/src/dbUtils.c @@ -0,0 +1,267 @@ +#include "dbUtils.h" + +#include "directory.h" +#include "myfprintf.h" +#include "utils.h" +#include "playlist.h" +#include "tag.h" +#include "tagTracker.h" + +typedef struct ListCommandItem { + mpd_sint8 tagType; + int numConditionals; + LocateTagItem * conditionals; +} ListCommandItem; + +int getLocateTagItemType(char * str) { + int i; + + if(0 == strcasecmp(str, LOCATE_TAG_FILE_KEY)) { + return LOCATE_TAG_FILE_TYPE; + } + + for(i = 0; i < TAG_NUM_OF_ITEM_TYPES; i++) { + if(0 == strcasecmp(str, mpdTagItemKeys[i])) return i; + } + + return -1; +} + +LocateTagItem * newLocateTagItem(char * typeStr, char * needle) { + LocateTagItem * ret = malloc(sizeof(LocateTagItem)); + + ret->tagType = getLocateTagItemType(typeStr); + + if(ret->tagType < 0) { + free(ret); + return NULL; + } + + ret->needle = strdup(needle); + + return ret; +} + +void freeLocateTagItem(LocateTagItem * item) { + free(item->needle); + free(item); +} + +int countSongsInDirectory(FILE * fp, Directory * directory, void * data) { + int * count = (int *)data; + + *count+=directory->songs->numberOfNodes; + + return 0; +} + +int printDirectoryInDirectory(FILE * fp, Directory * directory, void * data) { + if(directory->utf8name) { + myfprintf(fp,"directory: %s\n",directory->utf8name); + } + return 0; +} + +int printSongInDirectory(FILE * fp, Song * song, void * data) { + myfprintf(fp,"file: %s\n",song->utf8url); + return 0; +} + +static inline int strstrSearchTag(Song * song, int type, char * str) { + int i; + char * dup; + int ret = 0; + + if(type == LOCATE_TAG_FILE_TYPE) { + dup = strDupToUpper(song->utf8url); + if(strstr(dup, str)) ret = 1; + free(dup); + return ret; + } + + if(!song->tag) return 0; + + for(i = 0; i < song->tag->numOfItems && !ret; i++) { + if(song->tag->items[i].type != type) continue; + + dup = strDupToUpper(song->tag->items[i].value); + if(strstr(dup, str)) ret = 1; + free(dup); + } + + return ret; +} + +int searchInDirectory(FILE * fp, Song * song, void * item) { + if(strstrSearchTag(song, ((LocateTagItem *)item)->tagType, + ((LocateTagItem *)item)->needle)) { + printSongInfo(fp, song); + } + return 0; +} + +int searchForSongsIn(FILE * fp, char * name, LocateTagItem * item) { + char * originalNeedle = item->needle; + int ret = -1; + + item->needle = strDupToUpper(originalNeedle); + + ret = traverseAllIn(fp,name,searchInDirectory, NULL, + (void *)item); + + free(item->needle); + item->needle = originalNeedle; + + return ret; +} + +static inline int tagItemFoundAndMatches(Song * song, int type, char * str) { + int i; + + if(type == LOCATE_TAG_FILE_TYPE) { + if(0 == strcmp(str, song->utf8url)) return 1; + } + + if(!song->tag) return 0; + + for(i = 0; i < song->tag->numOfItems; i++) { + if(song->tag->items[i].type != type) continue; + + if(0 == strcmp(str, song->tag->items[i].value)) return 1; + } + + return 0; +} + +int findInDirectory(FILE * fp, Song * song, void * item) { + if(tagItemFoundAndMatches(song, ((LocateTagItem *)item)->tagType, + ((LocateTagItem *)item)->needle)) { + printSongInfo(fp, song); + } + return 0; +} + +int findSongsIn(FILE * fp, char * name, LocateTagItem * item) { + return traverseAllIn(fp, name, findInDirectory, NULL, + (void *)item); +} + +int printAllIn(FILE * fp, char * name) { + return traverseAllIn(fp,name,printSongInDirectory, + printDirectoryInDirectory,NULL); +} + +int directoryAddSongToPlaylist(FILE * fp, Song * song, void * data) { + return addSongToPlaylist(fp, song, 0); +} + +int addAllIn(FILE * fp, char * name) { + return traverseAllIn(fp,name,directoryAddSongToPlaylist,NULL,NULL); +} + +int directoryPrintSongInfo(FILE * fp, Song * song, void * data) { + return printSongInfo(fp,song); +} + +int sumSongTime(FILE * fp, Song * song, void * data) { + unsigned long * time = (unsigned long *)data; + + if(song->tag && song->tag->time>=0) *time+=song->tag->time; + + return 0; +} + +int printInfoForAllIn(FILE * fp, char * name) { + return traverseAllIn(fp,name,directoryPrintSongInfo,printDirectoryInDirectory,NULL); +} + +int countSongsIn(FILE * fp, char * name) { + int count = 0; + void * ptr = (void *)&count; + + traverseAllIn(fp,name,NULL,countSongsInDirectory,ptr); + + return count; +} + +unsigned long sumSongTimesIn(FILE * fp, char * name) { + unsigned long dbPlayTime = 0; + void * ptr = (void *)&dbPlayTime; + + traverseAllIn(fp,name,sumSongTime,NULL,ptr); + + return dbPlayTime; +} + +ListCommandItem * newListCommandItem(int tagType, int numConditionals, + LocateTagItem * conditionals) +{ + ListCommandItem * item = malloc(sizeof(ListCommandItem)); + + item->tagType = tagType; + item->numConditionals = numConditionals; + item->conditionals = conditionals; + + return item; +} + +void freeListCommandItem(ListCommandItem * item) { + free(item); +} + +void printUnvisitedTags(FILE * fp, Song * song, int tagType) { + int i; + MpdTag * tag = song->tag; + + if(tagType == LOCATE_TAG_FILE_TYPE) { + myfprintf(fp, "file: %s\n", song->utf8url); + return; + } + + if(!tag) return; + + for(i = 0; i < tag->numOfItems; i++) { + if(tag->items[i].type == tagType && + !wasVisitedInTagTracker(tagType, tag->items[i].value)) + { + myfprintf(fp, "%s: %s\n", mpdTagItemKeys[tagType], + tag->items[i].value); + } + } +} + +int listUniqueTagsInDirectory(FILE * fp, Song * song, void * data) { + ListCommandItem * item = data; + int i; + + for(i = 0; i < item->numConditionals; i++) { + if(!tagItemFoundAndMatches(song, item->conditionals[i].tagType, + item->conditionals[i].needle)) + { + return 0; + } + } + + printUnvisitedTags(fp, song, item->tagType); + + return 0; +} + +int listAllUniqueTags(FILE * fp, int type, int numConditionals, + LocateTagItem * conditionals) +{ + int ret; + ListCommandItem * item = newListCommandItem(type, numConditionals, + conditionals); + + if(type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) { + resetVisitedFlagsInTagTracker(type); + } + + ret = traverseAllIn(fp, NULL, listUniqueTagsInDirectory, NULL, + (void *)item); + + freeListCommandItem(item); + + return ret; +} diff --git a/src/dbUtils.h b/src/dbUtils.h new file mode 100644 index 000000000..d0f084701 --- /dev/null +++ b/src/dbUtils.h @@ -0,0 +1,42 @@ +#ifndef DB_UTILS_H +#define DB_UTILS_H + +#include <stdio.h> + +#include "tag.h" + +#define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10 +#define LOCATE_TAG_FILE_KEY "filename" + +/* struct used for search, find, list queries */ +typedef struct _LocateTagItem { + mpd_sint8 tagType; + /* what we are looking for */ + char * needle; +} LocateTagItem; + +/* returns NULL if not a known type */ +LocateTagItem * newLocateTagItem(char * typeString, char * needle); + +int getLocateTagItemType(char * str); + +void freeLocateTagItem(LocateTagItem * item); + +int printAllIn(FILE * fp, char * name); + +int addAllIn(FILE * fp, char * name); + +int printInfoForAllIn(FILE * fp, char * name); + +int searchForSongsIn(FILE * fp, char * name, LocateTagItem * item); + +int findSongsIn(FILE * fp, char * name, LocateTagItem * item); + +int countSongsIn(FILE * fp, char * name); + +unsigned long sumSongTimesIn(FILE * fp, char * name); + +int listAllUniqueTags(FILE * fp, int type, int numConditiionals, + LocateTagItem * conditionals); + +#endif |