diff options
author | MountainMan <MountainMan@e10066b5-e1e2-0310-b819-94efdf66514b> | 2004-02-02 02:01:11 +0000 |
---|---|---|
committer | MountainMan <MountainMan@e10066b5-e1e2-0310-b819-94efdf66514b> | 2004-02-02 02:01:11 +0000 |
commit | d79d2d24fcf5a3b4594face6a8c7e7bcb36d1dbc (patch) | |
tree | e22a8fc06e480c3a738e52aea73ccf55476ab77c | |
parent | f93735c67796b4d300737aff8cff39061dae465e (diff) | |
download | vdr-plugin-muggle-d79d2d24fcf5a3b4594face6a8c7e7bcb36d1dbc.tar.gz vdr-plugin-muggle-d79d2d24fcf5a3b4594face6a8c7e7bcb36d1dbc.tar.bz2 |
data structures for filters prepared and partially implemented
git-svn-id: https://vdr-muggle.svn.sourceforge.net/svnroot/vdr-muggle/trunk/muggle-plugin@14 e10066b5-e1e2-0310-b819-94efdf66514b
-rw-r--r-- | gd_content_interface.c | 169 | ||||
-rw-r--r-- | gd_content_interface.h | 23 | ||||
-rw-r--r-- | mg_media.c | 165 | ||||
-rw-r--r-- | mg_media.h | 133 | ||||
-rw-r--r-- | sh_dummy_content.c | 56 | ||||
-rw-r--r-- | sh_dummy_content.h | 11 |
6 files changed, 436 insertions, 121 deletions
diff --git a/gd_content_interface.c b/gd_content_interface.c index cf8e89b..ed74d9d 100644 --- a/gd_content_interface.c +++ b/gd_content_interface.c @@ -3,10 +3,10 @@ * \brief Data Objects for content (e.g. mp3 files, movies) * for the vdr muggle plugindatabase ******************************************************************** - * \version $Revision: 1.4 $ - * \date $Date: 2004/02/01 23:13:33 $ + * \version $Revision: 1.5 $ + * \date $Date: 2004/02/02 02:01:11 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner - * \author file owner: $Author: RaK $ + * \author file owner: $Author: MountainMan $ * * DUMMY * Implements main classes of for content items and interfaces to SQL databases @@ -47,9 +47,9 @@ int GdInitDatabase(MYSQL *db) return 0; } -vector<string> GdGetStoredPlaylists(MYSQL db) +vector<string> *GdGetStoredPlaylists(MYSQL db) { - vector<string> list; + vector<string>* list = new vector<string>(); MYSQL_RES *result; MYSQL_ROW row; @@ -57,12 +57,85 @@ vector<string> GdGetStoredPlaylists(MYSQL db) while((row = mysql_fetch_row(result)) != NULL) { - list.push_back(row[0]); + list->push_back(row[0]); } return list; } /*******************************************************************/ +/* class class gdTrackFilters */ +/********************************************************************/ +gdTrackFilters::gdTrackFilters() +{ + clear(); +} +gdTrackFilters::~gdTrackFilters() +{ +} +void gdTrackFilters::clear() +{ + mgFilter* filter ; + // remove old filters + for(vector<mgFilter*>::iterator iter = m_filters.begin(); + iter != m_filters.end(); iter++) + { + delete (*iter); + } + m_filters.clear(); + + // create an initial set of filters with empty values + // title + filter = new mgFilterString("title", ""); + m_filters.push_back(filter); + // artist + filter = new mgFilterString("artist", ""); + m_filters.push_back(filter); + // genre + filter = new mgFilterString("genre", ""); + m_filters.push_back(filter); + // year + filter = new mgFilterInt("year", -1); + m_filters.push_back(filter); + // rating + filter = new mgFilterInt("rating", -1); + m_filters.push_back(filter); +} + +string gdTrackFilters::CreateSQL() +{ + string sql_str = "1"; + + for(vector<mgFilter*>::iterator iter = m_filters.begin(); + iter != m_filters.end(); iter++) + { + if(strcmp((*iter)->getName(), "title") == 0 ) + { + sql_str = "AND tracks.title like '" + + (*iter)->getStrVal() + "%'"; + } + else if(strcmp((*iter)->getName(), "artist") == 0 ) + { + sql_str = "AND tracks.artist like '" + + (*iter)->getStrVal() + "%'"; + } + else if(strcmp((*iter)->getName(), "genre") == 0 ) + { + sql_str = "AND genre.name like '" + + (*iter)->getStrVal() + "%'"; + } + else if(strcmp((*iter)->getName(), "year") == 0 ) + { + sql_str = "AND tracks.year = " + (*iter)->getStrVal(); + } + else if(strcmp((*iter)->getName(), "rating") == 0 ) + { + sql_str = "AND tracks.rating >= " + (*iter)->getStrVal(); + } + } + return sql_str; +} + +/*******************************************************************/ /* class mgTack */ /********************************************************************/ mgGdTrack mgGdTrack::UNDEFINED = mgGdTrack(); @@ -700,6 +773,42 @@ GdTreeNode::~GdTreeNode() /*! ***************************************************************************** + * \brief checks if this node can be further expandded or not + * \true, if node ia leaf node, false if node can be expanded + * + ****************************************************************************/ +bool GdTreeNode::isLeafNode() +{ + if( m_level == 0) + return false; + switch(m_view) + { + case 1: // artist -> album -> title + if( m_level <= 3 ) + { + return false; + } + break; + case 2: // genre -> artist -> album -> track + if( m_level <= 3 ) + { + return false; + } + break; + case 3: // Artist -> Track + if( m_level <= 2 ) + { + return false; + } + break; + default: + mgError("View '%d' not yet implemented", m_view); + } + return true; +} + +/*! + ***************************************************************************** * \brief compute children on the fly * * \return: true, if the node could be expanded (or was already), false,of @@ -1044,10 +1153,46 @@ vector<mgContentItem*>* GdTreeNode::getTracks() } +/*! + ***************************************************************************** + * \brief returns the first track matchin the restrictions of this node + * assuming we are in a leaf node, this returns the track represented by the + * the leaf + ****************************************************************************/ +mgContentItem* GdTreeNode::getSingleTrack() +{ + MYSQL_ROW row; + MYSQL_RES *result; + int nrows; + int nfields; + mgContentItem* track = NULL; + int trackid; - - - - - - + // get all tracks satisying the restrictions of this node + mgDebug(5, "getTracks(): query '%s'", m_restriction.c_str()); + + result = mgSqlReadQuery(&m_db, + "SELECT tracks.id FROM tracks, album, genre WHERE %s" + " AND album.cddbid=tracks.sourceid AND genre.id=tracks.genre1", + m_restriction.c_str()); + nrows = mysql_num_rows(result); + nfields = mysql_num_fields(result); + + if( nrows != 1 ) + { + mgWarning( "GdTreeNode::getSingleTrack() :SQL call returned %d tracks, using only the first", + nrows ); + } + // get the first row + if( ( row = mysql_fetch_row(result)) != NULL ) + { + // row[0] is the trackid + if(sscanf(row[0], "%d", &trackid) != 1) + { + mgError("Can not extract integer track id from '%s'", + row[0]); + } + track = new mgGdTrack(trackid, m_db); + } + return track; +} diff --git a/gd_content_interface.h b/gd_content_interface.h index 8e63956..2c2cbef 100644 --- a/gd_content_interface.h +++ b/gd_content_interface.h @@ -4,10 +4,10 @@ * \brief Data Objects for content (e.g. mp3 files, movies) * for the vdr muggle plugindatabase ******************************************************************** - * \version $Revision: 1.1 $ - * \date $Date: 2004/02/01 18:22:53 $ + * \version $Revision: 1.2 $ + * \date $Date: 2004/02/02 02:01:11 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner - * \author file owner: $Author: LarsAC $ + * \author file owner: $Author: MountainMan $ * * Declares main classes of for content items and interfaces to SQL databases * @@ -29,10 +29,23 @@ #include <mysql/mysql.h> #include "mg_content_interface.h" +#include "mg_media.h" // non-member function int GdInitDatabase(MYSQL *db); -std::vector<std::string> GdGetStoredPlaylists(MYSQL db); +std::vector<std::string> *GdGetStoredPlaylists(MYSQL db); + + +class gdTrackFilters: public mgTrackFilters +{ + public: + gdTrackFilters(); + ~gdTrackFilters(); + + virtual std::string CreateSQL(); + virtual void clear(); + +}; /*! ******************************************************************* @@ -187,10 +200,12 @@ public: virtual ~GdTreeNode(); // compute children on the fly + virtual bool isLeafNode(); virtual bool expand(); // access data in current node virtual std::vector<mgContentItem*>* getTracks(); + virtual mgContentItem* getSingleTrack(); }; #endif /* END _GD_CONTENT_INTERFACE_H */ @@ -3,10 +3,10 @@ * \brief Top level access to media in vdr plugin muggle * for the vdr muggle plugindatabase ******************************************************************** - * \version $Revision: 1.1 $ - * \date $Date: 2004/02/01 18:22:53 $ + * \version $Revision: 1.2 $ + * \date $Date: 2004/02/02 02:01:11 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner - * \author file owner: $Author: LarsAC $ + * \author file owner: $Author: MountainMan $ * * */ @@ -22,78 +22,133 @@ using namespace std; -mgFilters::mgFilters() +mgFilter::mgFilter(const char* name) { + m_name = strdup(name); } - -mgFilters::~mgFilters() +mgFilter::~mgFilter() { + free(m_name); } -int mgFilters::getNumFilters() +const char* mgFilter::getName() { - return 0; + return m_name; } -string mgFilters::getName(int filter) +mgFilterInt::mgFilterInt(const char *name, int value, int min, int max) + : mgFilter(name) +{ + m_type = INT; + m_intval = value; + m_min = min; + m_max = max; +} +mgFilterInt::~mgFilterInt() { - return 0; } -int mgFilters::getValue(int filter) +int mgFilterInt::getVal() { - return 0; + return m_intval; } +string mgFilterInt::getStrVal() +{ + char buffer[20]; + sprintf(buffer, "%d", m_intval); -mgFilters::filterType mgFilters::getType(int filter) + return (string)buffer; +} +int mgFilterInt::getMin() { - return NUMBER; + return m_min; +} +int mgFilterInt::getMax() +{ + return m_max; } -// for NUMBER filters +void mgFilterInt::setVal(int value) +{ + m_intval = value; +} -int mgFilters::getMin(int filter) +mgFilterString::mgFilterString(const char *name, const char* value) + : mgFilter(name) { - return 0; + m_type = STRING; + m_strval = strdup(value); +} +mgFilterString::~mgFilterString() +{ + if(m_strval) + { + free(m_strval); + } } -int mgFilters::getMax(int filter) +const char* mgFilterString::getVal() { - return 0; + return m_strval; +} +string mgFilterString::getStrVal() +{ + + return (string) m_strval; } -// for CHOICE +void mgFilterString::setVal(const char* value) +{ + if(m_strval) + { + free(m_strval); + } + m_strval = strdup(value); +} +mgFilterBool::mgFilterBool(const char *name, bool value) + : mgFilter(name) +{ + m_type = BOOL; + m_bval = value; +} +mgFilterBool::~mgFilterBool() +{ +} -vector<string> mgFilters::getChoices() +bool mgFilterBool::getVal() { - return vector<string>(); + return m_bval; } -int mgFilters::getCurrent(int filter) +string mgFilterBool::getStrVal() { - return 0; + if(m_bval) + return "true"; + else + return "false"; } - // check, if a value is correct -bool mgFilters::checkValue(int filter, string value) +void mgFilterBool::setVal(bool value) { - return false; + m_bval = value; } -bool mgFilters::checkValue(int filter, int value) +mgTrackFilters::mgTrackFilters() { - return false; } - -// finally set the values -bool mgFilters::setValue(int filter, string value) +mgTrackFilters::~mgTrackFilters() { - return false; + for(vector<mgFilter*>::iterator iter = m_filters.begin(); + iter != m_filters.end(); iter++) + { + delete (*iter); + } + m_filters.clear(); } -bool mgFilters::setValue(int filter, int value) +vector<mgFilter*> *mgTrackFilters::getFilters() { - return false; + return &m_filters; } /*! @@ -105,9 +160,9 @@ bool mgFilters::setValue(int filter, int value) mgMedia::mgMedia(contentType mediatype) { int errval = 0; - + mgTrackFilters *m_trackfilter; m_mediatype = mediatype; - m_filter = "1"; + m_sql_trackfilter = "1"; m_defaultView = 1; // now initialize the database @@ -130,6 +185,20 @@ mgMedia::mgMedia(contentType mediatype) mgError("Error connecting to database\n"); } + mgDebug(3, "Initializing track filters"); + switch(m_mediatype) + { + case DUMMY: + { + errval = DummyInitDatabase(&m_db); + break; + } + case GD_MP3: + { + errval = GdInitDatabase(&m_db); + mgDebug(3, "Successfully conntected to sql database 'GiantDisc'"); + } + } } mgMedia::~mgMedia() @@ -157,26 +226,28 @@ mgSelectionTreeNode* mgMedia::getSelectionRoot() case DUMMY: return new DummyTreeNode(m_db, m_defaultView); case GD_MP3: - return new GdTreeNode(m_db, m_defaultView, m_filter); + return new GdTreeNode(m_db, m_defaultView, m_sql_trackfilter); } mgError("implementation Error"); // we should never get here return NULL; } -mgFilters mgMedia::getActiveFilters() +vector<mgFilter*> *mgMedia::getTrackFilters() { switch(m_mediatype) { case DUMMY: - return mgFilters(); + //return mgFilters(); case GD_MP3: - return mgFilters(); + // return m_trackfilters; + default: + break; } mgError("implementation Error"); // we should never get here - return mgFilters(); + return NULL; } -void mgMedia::setFilters(mgFilters filters) +void mgMedia::setTrackFilters(vector<mgFilter*> *filters) { } @@ -204,7 +275,7 @@ mgPlaylist* mgMedia::loadPlaylist(string name) return NULL; } -vector<string> mgMedia::getStoredPlaylists() +vector<string> *mgMedia::getStoredPlaylists() { switch(m_mediatype) { @@ -214,7 +285,7 @@ vector<string> mgMedia::getStoredPlaylists() return GdGetStoredPlaylists(m_db); } mgError("implementation Error"); // we should never get here - return vector<string>(); + return new vector<string>(); } vector<int> mgMedia::getDefaultCols() @@ -243,11 +314,11 @@ mgTracklist* mgMedia::getTracks() { case DUMMY: - tracks = new DummyTracklist(m_db, m_filter); + tracks = new DummyTracklist(m_db, m_sql_trackfilter); tracks->setDisplayColumns(getDefaultCols()); return tracks; case GD_MP3: - tracks = new GdTracklist(m_db, m_filter); + tracks = new GdTracklist(m_db, m_sql_trackfilter); tracks->setDisplayColumns(getDefaultCols()); return tracks; } @@ -3,10 +3,10 @@ * \brief Top level access to media in vdr plugin muggle * for the vdr muggle plugindatabase ******************************************************************** - * \version $Revision: 1.1 $ - * \date $Date: 2004/02/01 18:22:53 $ + * \version $Revision: 1.2 $ + * \date $Date: 2004/02/02 02:01:11 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner - * \author file owner: $Author: LarsAC $ + * \author file owner: $Author: MountainMan $ * * */ @@ -26,50 +26,89 @@ class mgSelectionTreeNode; /*! ******************************************************************* - * \class mgFilters + * \class mgFilter * - * \brief stores a set of search constraints to the media database ********************************************************************/ -class mgFilters +class mgFilter { - typedef enum filterType - { - NUMBER, // integer number (with upper and lower limits) - STRING, // any string - REGEXP_STRING, // string containing wildcard symbol '*' - CHOICE // value fro ma list of choices - }filterType; - public: - std::vector<std::string> fields; - std::vector<std::string> values; - - mgFilters(); - ~mgFilters(); - - int getNumFilters(); - std::string getName(int filter); - int getValue(int filter); - filterType getType(int filter); - - // for NUMBER filters - int getMin(int filter); - int getMax(int filter); - - // for CHOICE - std::vector<std::string> getChoices(); - int getCurrent(int filter); - - // check, if a value is correct - bool checkValue(int filter, std::string value); - bool checkValue(int filter, int value); - - // finally set the values - - bool setValue(int filter, std::string value); - bool setValue(int filter, int value); + typedef enum filterType { UNDEF=0, INT, STRING, BOOL }filterType; + protected: + filterType m_type; + char* m_name; + + public: + + mgFilter(const char* name); + virtual ~mgFilter(); + filterType getType(); + const char* getName(); + virtual std::string getStrVal()=0; }; +class mgFilterInt : public mgFilter +{ + private: + int m_min; + int m_max; + int m_intval; + + public: + mgFilterInt(const char *name, int value, int min = 0, int max = INT_MAX); + virtual ~mgFilterInt(); + + int getVal(); + int getMin(); + int getMax(); + virtual std::string getStrVal(); + + void setVal(int value); +}; + +class mgFilterString : public mgFilter +{ + private: + char* m_strval; + + public: + mgFilterString(const char *name, const char* value); + virtual ~mgFilterString(); + + const char* getVal(); + virtual std::string getStrVal(); + + void setVal(const char* val); +}; + +class mgFilterBool : public mgFilter +{ + private: + bool m_bval; + + public: + mgFilterBool(const char *name, bool value); + virtual ~mgFilterBool(); + + bool getVal(); + virtual std::string getStrVal(); + + void setVal(bool val); +}; + +class mgTrackFilters +{ + protected: + std::vector<mgFilter*> m_filters; + public: + mgTrackFilters(); + virtual ~mgTrackFilters(); + + std::vector<mgFilter*> *getFilters(); + + virtual std::string CreateSQL()=0; + virtual void clear()=0; + +}; /*! ******************************************************************* @@ -89,7 +128,7 @@ class mgMedia private: MYSQL m_db; contentType m_mediatype; - std::string m_filter; + std::string m_sql_trackfilter; int m_defaultView; public: @@ -100,18 +139,14 @@ class mgMedia mgSelectionTreeNode* getSelectionRoot(); - mgFilters getActiveFilters(); + std::vector<mgFilter*> *getTrackFilters(); - void setFilters(mgFilters filters); - void setFilters(std::string sql) - { - m_filter=sql; - } + void setTrackFilters(std::vector<mgFilter*> *filters); // playlist management mgPlaylist* createTemporaryPlaylist(); mgPlaylist* loadPlaylist( std::string name ); - std::vector<std::string> getStoredPlaylists(); + std::vector<std::string> *getStoredPlaylists(); std::vector<int> getDefaultCols(); mgTracklist* getTracks(); diff --git a/sh_dummy_content.c b/sh_dummy_content.c index a6afcd9..27c23bd 100644 --- a/sh_dummy_content.c +++ b/sh_dummy_content.c @@ -3,10 +3,10 @@ * \brief Data Objects for content (e.g. mp3 files, movies) * for the vdr muggle plugindatabase ******************************************************************** - * \version $Revision: 1.1 $ - * \date $Date: 2004/02/01 18:22:53 $ + * \version $Revision: 1.2 $ + * \date $Date: 2004/02/02 02:01:11 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner - * \author file owner: $Author: LarsAC $ + * \author file owner: $Author: MountainMan $ * * DUMMY * @@ -34,7 +34,7 @@ #define NUM_TRACKS_PER_ALBUM 9 int DummyInitDatabase(MYSQL *db){return 0;} -vector<string> DummyGetStoredPlaylists(MYSQL db){ return vector<string>();} +vector<string> *DummyGetStoredPlaylists(MYSQL db){ return new vector<string>();} /*******************************************************************/ /* class mgTack */ @@ -423,6 +423,27 @@ DummyTreeNode::~DummyTreeNode() m_children.clear(); } +/*! + ***************************************************************************** + * \brief checks if this node can be further expandded or not + * \true, if node ia leaf node, false if node can be expanded + * + ****************************************************************************/ +bool DummyTreeNode::isLeafNode() +{ + switch(m_view) + { + case 1: // artist -> album -> title + if( m_level <= 3 ) + { + return true; + } + break; + default: + mgError("View '%d' not yet implemented", m_view); + } + return false; +} /*! @@ -549,6 +570,33 @@ vector<mgContentItem*>* DummyTreeNode::getTracks() return dummy; } +/*! + ***************************************************************************** + * \brief returns the first track matchin the restrictions of this node + * assuming we are in a leaf node, this returns the track represented by the + * the leaf + ****************************************************************************/ +mgContentItem* DummyTreeNode::getSingleTrack() +{ + // get all tracks satisying the restrictions of this node + mgDebug(5, "getTracks(): query '%s'", m_restriction.c_str()); + + mgContentItem* track = new DummyTrack(atoi(m_id.c_str()), m_db); + + return track; +} + + + + + + + + + + + + diff --git a/sh_dummy_content.h b/sh_dummy_content.h index 71d3ce7..41e526f 100644 --- a/sh_dummy_content.h +++ b/sh_dummy_content.h @@ -2,10 +2,10 @@ /*! \file dummy_content.h * \brief Dummy Data Objects for testing Muggle ******************************************************************** - * \version $Revision: 1.1 $ - * \date $Date: 2004/02/01 18:22:53 $ + * \version $Revision: 1.2 $ + * \date $Date: 2004/02/02 02:01:11 $ * \author Ralf Klueber, Lars von Wedel, Andreas Kellner - * \author file owner: $Author: LarsAC $ + * \author file owner: $Author: MountainMan $ * * Declares main classes of for content items and interfaces to SQL databases * @@ -22,8 +22,7 @@ using namespace std; // non-member function int DummyInitDatabase(MYSQL *db); -vector<string> DummyGetStoredPlaylists(MYSQL db); - +vector<string> *DummyGetStoredPlaylists(MYSQL db); /*! ******************************************************************* * \class DummyTrack @@ -152,9 +151,11 @@ public: ~DummyTreeNode(); // compute children o^xn the fly + virtual bool isLeafNode(); virtual bool expand(); virtual vector<mgContentItem*>* getTracks(); + virtual mgContentItem* getSingleTrack(); }; #endif /* END _CONTENT_INTERFACE_H */ |