// (c) 2004 Mark Kretschmann // (c) 2004 Christian Muehlhaeuser // (c) 2004 Sami Nieminen // See COPYING file for licensing information. #ifndef AMAROK_COLLECTIONDB_H #define AMAROK_COLLECTIONDB_H #include "engineobserver.h" #include "dbenginebase.h" #include #include //stack allocated #include //baseclass #include //baseclass #include //stack allocated #include //stack allocated class CoverFetcher; class MetaBundle; class Scrobbler; class DbConnectionPool : TQPtrQueue { public: DbConnectionPool(); ~DbConnectionPool(); const DbConnection::DbConnectionType getDbConnectionType() const { return m_dbConnType; } const DbConfig *getDbConfig() const { return m_dbConfig; } void createDbConnections(); DbConnection *getDbConnection(); void putDbConnection( const DbConnection* /* conn */ ); private: static const int POOL_SIZE = 5; TQSemaphore m_semaphore; DbConnection::DbConnectionType m_dbConnType; DbConfig *m_dbConfig; }; class CollectionDB : public TQObject, public EngineObserver { Q_OBJECT friend class SimilarArtistsInsertionJob; signals: void scanStarted(); void scanDone( bool changed ); void databaseEngineChanged(); void scoreChanged( const TQString &url, int score ); void coverFetched( const TQString &artist, const TQString &album ); void coverRemoved( const TQString &artist, const TQString &album ); void coverFetcherError( const TQString &error ); void similarArtistsFetched( const TQString &artist ); public: static CollectionDB *instance(); TQString escapeString( TQString string ) { return m_dbConnPool->escapeString(string); } int getType() { return m_dbConnPool->getDbConnectionType(); } /** * This method returns a static DbConnection for components that want to use * the same connection for the whole time. Should not be used anywhere else * but in CollectionReader. * * @return static DbConnection */ DbConnection *getStaticDbConnection(); /** * Returns the DbConnection back to connection pool. * * @param conn DbConnection to be returned */ void returnStaticDbConnection( DbConnection *conn ); //sql helper methods TQStringList query( const TQString& statement, DbConnection *conn = NULL ); int insert( const TQString& statement, const TQString& table, DbConnection *conn = NULL ); //table management methods bool isEmpty(); bool isValid(); void createTables( DbConnection *conn = NULL ); void dropTables( DbConnection *conn = NULL ); void clearTables( DbConnection *conn = NULL ); void moveTempTables( DbConnection *conn ); uint artistID( TQString value, bool autocreate = true, const bool temporary = false, const bool updateSpelling = false, DbConnection *conn = NULL ); uint albumID( TQString value, bool autocreate = true, const bool temporary = false, const bool updateSpelling = false, DbConnection *conn = NULL ); uint genreID( TQString value, bool autocreate = true, const bool temporary = false, const bool updateSpelling = false, DbConnection *conn = NULL ); uint yearID( TQString value, bool autocreate = true, const bool temporary = false, const bool updateSpelling = false, DbConnection *conn = NULL ); bool isDirInCollection( TQString path ); bool isFileInCollection( const TQString &url ); void removeDirFromCollection( TQString path ); void removeSongsInDir( TQString path ); void removeSongs( const KURL::List& urls ); void updateDirStats( TQString path, const long datetime, DbConnection *conn = NULL ); //song methods bool addSong( MetaBundle* bundle, const bool incremental = false, DbConnection *conn = NULL ); /** * The @p bundle parameter's url() will be looked up in the Collection * @param bundle this will be filled in with tags for you * @return true if in the collection */ bool bundleForUrl( MetaBundle* bundle ); TQValueList bundlesByUrls( const KURL::List& urls ); void addAudioproperties( const MetaBundle& bundle ); void updateTags( const TQString &url, const MetaBundle &bundle, const bool updateView = true ); void updateURL( const TQString &url, const bool updateView = true ); //statistics methods int addSongPercentage( const TQString &url, int percentage ); int getSongPercentage( const TQString &url ); void setSongPercentage( const TQString &url , int percentage ); //artist methods TQStringList similarArtists( const TQString &artist, uint count ); //album methods void checkCompilations( const TQString &path, const bool temporary = false, DbConnection *conn = NULL ); void setCompilation( const TQString &album, const bool enabled, const bool updateView = true ); TQString albumSongCount( const TQString &artist_id, const TQString &album_id ); bool albumIsCompilation( const TQString &album_id ); //list methods TQStringList artistList( bool withUnknowns = true, bool withCompilations = true ); TQStringList albumList( bool withUnknowns = true, bool withCompilations = true ); TQStringList genreList( bool withUnknowns = true, bool withCompilations = true ); TQStringList yearList( bool withUnknowns = true, bool withCompilations = true ); TQStringList albumListOfArtist( const TQString &artist, bool withUnknown = true, bool withCompilations = true ); TQStringList artistAlbumList( bool withUnknown = true, bool withCompilations = true ); TQStringList albumTracks( const TQString &artist_id, const TQString &album_id ); //cover management methods /** Returns the image from a given URL, network-transparently. * You must run TDEIO::NetAccess::removeTempFile( tmpFile ) when you are finished using the image; **/ static TQImage fetchImage(const KURL& url, TQString &tmpFile); /** Saves images located on the user's filesystem */ bool setAlbumImage( const TQString& artist, const TQString& album, const KURL& url ); /** Saves images obtained from CoverFetcher */ bool setAlbumImage( const TQString& artist, const TQString& album, TQImage img, const TQString& amazonUrl = TQString() ); TQString findImageByMetabundle( MetaBundle trackInformation, const uint = 1 ); TQString findImageByArtistAlbum( const TQString &artist, const TQString &album, const uint width = 1 ); TQString albumImage( MetaBundle trackInformation, const uint width = 1 ); TQString albumImage( const uint artist_id, const uint album_id, const uint width = 1 ); TQString albumImage( const TQString &artist, const TQString &album, const uint width = 1 ); bool removeAlbumImage( const uint artist_id, const uint album_id ); bool removeAlbumImage( const TQString &artist, const TQString &album ); //local cover methods void addImageToAlbum( const TQString& image, TQValueList< TQPair > info, DbConnection *conn = NULL ); TQString getImageForAlbum( const TQString& artist, const TQString& album, uint width = 0 ); TQString notAvailCover( int width = 0 ); void applySettings(); protected: CollectionDB(); ~CollectionDB(); TQCString md5sum( const TQString& artist, const TQString& album, const TQString& file = TQString() ); void engineTrackEnded( int finalPosition, int trackLength ); /** Manages regular folder monitoring scan */ void timerEvent( TQTimerEvent* e ); public slots: void fetchCover( TQWidget* parent, const TQString& artist, const TQString& album, bool noedit ); void scanMonitor(); void startScan(); void stopScan(); private slots: void dirDirty( const TQString& path ); void coverFetcherResult( CoverFetcher* ); void similarArtistsFetched( const TQString& artist, const TQStringList& suggestions ); private: //bump DATABASE_VERSION whenever changes to the table structure are made. will remove old db file. static const int DATABASE_VERSION = 18; static const int DATABASE_STATS_VERSION = 3; static const int MONITOR_INTERVAL = 60; //sec static const bool DEBUG = false; void initialize(); void destroy(); void customEvent( TQCustomEvent* ); //general management methods void createStatsTable(); void dropStatsTable(); void scanModifiedDirs(); TQCString makeWidthKey( uint width ); TQString artistValue( uint id ); TQString albumValue( uint id ); TQString genreValue( uint id ); TQString yearValue( uint id ); uint IDFromValue( TQString name, TQString value, bool autocreate = true, const bool temporary = false, const bool updateSpelling = false, DbConnection *conn = NULL ); TQString valueFromID( TQString table, uint id ); //member variables TQString m_amazonLicense; TQString m_cacheArtist; uint m_cacheArtistID; TQString m_cacheAlbum; uint m_cacheAlbumID; DBEngine* m_dbEngine; DbConnectionPool *m_dbConnPool; bool m_monitor; TQDir m_cacheDir; TQDir m_coverDir; }; #endif /* AMAROK_COLLECTIONDB_H */