add mp3 and ogg torrent url info to JamendoAlbum
[amarok.git] / src / collectiondb.h
blob636b2e1de3d445f225426c5209159f47a978fb91
1 // (c) 2004 Mark Kretschmann <markey@web.de>
2 // (c) 2004 Christian Muehlhaeuser <chris@chris.de>
3 // (c) 2004 Sami Nieminen <sami.nieminen@iki.fi>
4 // (c) 2005 Ian Monroe <ian@monroe.nu>
5 // (c) 2005 Jeff Mitchell <kde-dev@emailgoeshere.com>
6 // (c) 2005 Isaiah Damron <xepo@trifault.net>
7 // (c) 2005 Alexandre Pereira de Oliveira <aleprj@gmail.com>
8 // (c) 2006 Jonas Hurrelmann <j@outpo.st>
9 // (c) 2006 Shane King <kde@dontletsstart.com>
10 // (c) 2006 Peter C. Ndikuwera <pndiku@gmail.com>
11 // See COPYING file for licensing information.
13 #ifndef AMAROK_COLLECTIONDB_H
14 #define AMAROK_COLLECTIONDB_H
16 #include "engineobserver.h"
17 #include "threadmanager.h" //baseclass
18 #include "amarok_export.h"
20 #include <kurl.h>
21 #include <QDir> //stack allocated
22 #include <QDateTime>
23 #include <QImage>
24 #include <QMutex>
25 #include <QObject> //baseclass
26 #include <q3ptrqueue.h> //baseclass
27 #include <q3semaphore.h> //stack allocated
28 #include <QStringList> //stack allocated
29 #include <q3ptrvector.h>
30 #include <QThread>
31 #include <q3valuestack.h>
32 //Added by qt3to4:
33 #include <QTimerEvent>
34 #include <QPixmap>
35 #include <Q3ValueList>
36 #include <QEvent>
37 #include <QByteArray>
39 namespace KIO { class Job; }
41 class DbConnection;
42 class CoverFetcher;
43 class MetaBundle;
44 //class OrganizeCollectionDialog;
45 class PodcastChannelBundle;
46 class PodcastEpisodeBundle;
47 class Q3ListViewItem;
49 class DbConfig
50 {};
53 class SqliteConfig : public DbConfig
55 public:
56 SqliteConfig( const QString& /* dbfile */ );
58 QString dbFile() const { return m_dbfile; }
60 private:
61 QString m_dbfile;
65 class MySqlConfig : public DbConfig
67 public:
68 MySqlConfig(
69 const QString& /* host */,
70 const int /* port */,
71 const QString& /* database */,
72 const QString& /* username */,
73 const QString& /* password */);
75 QString host() const { return m_host; }
76 int port() const { return m_port; }
77 QString database() const { return m_database; }
78 QString username() const { return m_username; }
79 QString password() const { return m_password; }
81 private:
82 QString m_host;
83 int m_port;
84 QString m_database;
85 QString m_username;
86 QString m_password;
90 class PostgresqlConfig : public DbConfig
92 public:
93 PostgresqlConfig(
94 const QString& /* host */,
95 const int /* port */,
96 const QString& /* database */,
97 const QString& /* username */,
98 const QString& /* password */);
100 QString host() const { return m_host; }
101 int port() const { return m_port; }
102 QString database() const { return m_database; }
103 QString username() const { return m_username; }
104 QString password() const { return m_password; }
106 private:
107 QString m_host;
108 int m_port;
109 QString m_database;
110 QString m_username;
111 QString m_password;
115 class AMAROK_EXPORT DbConnection
117 public:
118 enum DbConnectionType { sqlite = 0, mysql = 1, postgresql = 2 };
120 DbConnection();
121 virtual ~DbConnection() {}
123 virtual QStringList query( const QString& /* statement */, bool suppressDebug ) = 0;
124 virtual int insert( const QString& /* statement */, const QString& /* table */ ) = 0;
125 bool isInitialized() const { return m_initialized; }
126 virtual bool isConnected() const = 0;
127 virtual QString lastError() const { return "None"; }
129 protected:
130 bool m_initialized;
134 typedef struct sqlite3 sqlite3;
135 typedef struct sqlite3_context sqlite3_context;
136 typedef struct Mem sqlite3_value;
138 class SqliteConnection : public DbConnection
140 public:
141 SqliteConnection( const SqliteConfig* /* config */ );
142 ~SqliteConnection();
144 QStringList query( const QString& /* statement */, bool suppressDebug = false );
145 int insert( const QString& /* statement */, const QString& /* table */ );
146 bool isConnected()const { return true; }
147 private:
148 static void sqlite_rand( sqlite3_context *context, int /*argc*/, sqlite3_value ** /*argv*/ );
149 static void sqlite_power( sqlite3_context *context, int argc, sqlite3_value **argv );
150 static void sqlite_like_new( sqlite3_context *context, int argc, sqlite3_value **argv );
152 sqlite3* m_db;
156 #ifdef USE_MYSQL
157 typedef struct st_mysql MYSQL;
159 class MySqlConnection : public DbConnection
161 public:
162 MySqlConnection( const MySqlConfig* /* config */ );
163 ~MySqlConnection();
165 QStringList query( const QString& /* statement */, bool suppressDebug = false );
166 int insert( const QString& /* statement */, const QString& /* table */ );
167 bool isConnected()const { return m_connected; }
168 QString lastError() const { return m_error; }
169 private:
170 void setMysqlError();
171 MYSQL* m_db;
172 bool m_connected;
173 QString m_error;
175 #endif
178 #ifdef USE_POSTGRESQL
179 typedef struct pg_conn PGconn;
181 class PostgresqlConnection : public DbConnection
183 public:
184 PostgresqlConnection( const PostgresqlConfig* /* config */ );
185 ~PostgresqlConnection();
187 QStringList query( const QString& /* statement */, bool suppressDebug = false );
188 int insert( const QString& /* statement */, const QString& /* table */ );
189 bool isConnected()const { return m_connected; }
190 QString lastError() const { return m_error; }
191 private:
192 void setPostgresqlError();
193 PGconn* m_db;
194 bool m_connected;
195 QString m_error;
197 #endif
200 class AMAROK_EXPORT CollectionDB : public QObject, public EngineObserver
202 Q_OBJECT
204 friend class SimilarArtistsInsertionJob;
206 signals:
207 void scanStarted();
208 void scanDone( bool changed );
209 void databaseEngineChanged();
211 void databaseUpdateDone();
213 void scoreChanged( const QString &url, float score );
214 void ratingChanged( const QString &url, int rating );
215 void labelsChanged( const QString &url );
216 void fileMoved( const QString &srcUrl, const QString &dstUrl );
217 void fileMoved( const QString &srcUrl, const QString &dstUrl, const QString &uniqueid );
218 void fileDeleted( const QString &absPath );
219 void fileDeleted( const QString &absPath, const QString &uniqueid );
220 void fileAdded( const QString &absPath );
221 void fileAdded( const QString &absPath, const QString &uniqueid );
222 void filesAdded( const QMap<QString,QString> &map );
223 void uniqueIdChanged( const QString &url, const QString &originalid, const QString &newid );
224 void coverChanged( const QString &artist, const QString &album ); //whenever a cover changes
225 void coverFetched( const QString &artist, const QString &album ); //only when fetching from amazon
226 void coverRemoved( const QString &artist, const QString &album );
227 void coverFetcherError( const QString &error );
229 void similarArtistsFetched( const QString &artist );
230 void tagsChanged( const MetaBundle &bundle );
231 void tagsChanged( const QString &oldArtist, const QString &oldAlbum );
232 void imageFetched( const QString &remoteURL ); //for fetching remote podcast images
234 public:
235 CollectionDB();
236 ~CollectionDB();
238 AMAROK_EXPORT static CollectionDB *instance();
241 * performs all initializations which require directory or URL data stored in the
242 * database.
244 void initDirOperations();
246 enum labelTypes { typeUser = 1 }; //add new types add the end!
248 QString escapeString(QString string ) const
250 return
251 #ifdef USE_MYSQL
252 // We have to escape "\" for mysql, but can't do so for sqlite
253 ( m_dbConnType == DbConnection::mysql )
254 ? string.replace("\\", "\\\\").replace( '\'', "''" ) :
255 #endif
256 string.replace( '\'', "''" );
259 QString boolT() const { if (getDbConnectionType() == DbConnection::postgresql) return "true"; else return "1"; }
260 QString boolF() const { if (getDbConnectionType() == DbConnection::postgresql) return "false"; else return "0"; }
261 //textColumnType should be used for normal strings, which need to be compared
262 //either case-sensitively or -insensitively
263 QString textColumnType( int length=255 ) const { if ( getDbConnectionType() == DbConnection::postgresql ) return "TEXT"; else return QString("VARCHAR(%1)").arg(length); }
264 //exactTextColumnType should be used for strings that must be stored exactly, such
265 //as URLs (necessary for holding control chars etc. if present in URL), except for
266 //trailing spaces. Comparisions should always be done case-sensitively.
267 //As we create indices on these columns, we have to restrict them to
268 //<= 255 chars for mysql < 5.0.3
269 QString exactTextColumnType( int length=1024 ) const { if ( getDbConnectionType() == DbConnection::mysql ) return QString( "VARBINARY(%1)" ).arg( length>255 ? 255 : length ); else return textColumnType( length ); }
270 // We might consider using LONGTEXT type, as some lyrics could be VERY long..???
271 QString longTextColumnType() const { if ( getDbConnectionType() == DbConnection::postgresql ) return "TEXT"; else return "TEXT"; }
272 QString randomFunc() const { if ( getDbConnectionType() == DbConnection::postgresql ) return "random()"; else return "RAND()"; }
274 static QString exactCondition( const QString &right );
275 static QString likeCondition( const QString &right, bool anyBegin=false, bool anyEnd=false );
276 int getType() { return getDbConnectionType(); }
278 //sql helper methods
279 AMAROK_EXPORT QStringList query( const QString& statement, bool suppressDebug = false );
280 AMAROK_EXPORT int insert( const QString& statement, const QString& table );
283 * TODO: write doc
284 * @param showAll
285 * @return a string which can be appended to an existing sql where statement
287 QString deviceidSelection( const bool showAll = false );
290 * converts the result of a query which contains a deviceid and a relative path
291 * to a list of absolute paths. the order of entries in each result row must be
292 * deviceid first, relative path second.
293 * @param result the result of the sql query, deviceid first, relative path second
294 * @return a list of urls
296 QStringList URLsFromQuery( const QStringList &result ) const;
299 * converts the result list of a amarok-sql query to a list of urls
301 KUrl::List URLsFromSqlDrag( const QStringList &values ) const;
303 //table management methods
304 bool isEmpty();
305 bool isValid();
306 QString adminValue( QString noption );
307 void setAdminValue( QString noption, QString value );
308 void createTables( const bool temporary = false );
309 void createIndices( );
310 void createPermanentIndices();
311 void dropTables( const bool temporary = false);
312 void clearTables( const bool temporary = false);
313 void copyTempTables( );
314 void prepareTempTables();
316 uint artistID( QString value, bool autocreate = true, const bool temporary = false, bool exact = true );
317 uint composerID( QString value, bool autocreate = true, const bool temporary = false, bool exact = true );
318 uint albumID( QString value, bool autocreate = true, const bool temporary = false, bool exact = true );
319 uint genreID( QString value, bool autocreate = true, const bool temporary = false, bool exact = true );
320 uint yearID( QString value, bool autocreate = true, const bool temporary = false, bool exact = true );
322 bool isDirInCollection( QString path );
323 bool isFileInCollection( const QString &url );
324 QString getURL( const MetaBundle &bundle );
325 void removeDirFromCollection( QString path );
326 void removeSongsInDir( QString path, QMap<QString,QString> *tagsRemoved = 0 );
327 void removeSongs( const KUrl::List& urls );
328 void updateDirStats( QString path, const long datetime, const bool temporary = false );
330 //song methods
331 bool addSong( MetaBundle* bundle, const bool incremental = false );
332 void aftCheckPermanentTables( const QString &currdeviceid, const QString &currid, const QString &currurl );
333 void doAFTStuff( MetaBundle *bundle, const bool tempTables = true );
334 void emitFileAdded( const QString &absPath,
335 const QString &uniqueid = QString() );
336 void emitFilesAdded( const QMap<QString,QString> &map ) { emit filesAdded( map ); }
337 void emitFileDeleted( const QString &absPath,
338 const QString &uniqueid = QString() );
339 bool newUniqueIdForFile( const QString &path );
340 bool removeUniqueIdFromFile( const QString &path );
341 QString urlFromUniqueId( const QString &id );
342 QString uniqueIdFromUrl( const KUrl &url );
344 //podcast methods
345 /// Insert a podcast channel into the database. If @param replace is true, replace the row
346 /// use updatePodcastChannel() always in preference
347 bool addPodcastChannel( const PodcastChannelBundle &pcb, const bool &replace=false );
348 /// Insert a podcast episode into the database. If @param idToUpdate is provided, replace the row
349 /// use updatePodcastEpisode() always in preference
350 int addPodcastEpisode( const PodcastEpisodeBundle &episode, const int idToUpdate=0 );
351 int addPodcastFolder( const QString &name, const int parent_id=0, const bool isOpen=false );
352 Q3ValueList<PodcastChannelBundle> getPodcastChannels();
353 PodcastEpisodeBundle getPodcastEpisodeById( int id );
354 Q3ValueList<PodcastEpisodeBundle> getPodcastEpisodes( const KUrl &parent, bool newOnly=false, int limit=-1 );
355 void removePodcastChannel( const KUrl &url ); // will remove all episodes too
356 void removePodcastEpisode( const int id );
357 void removePodcastFolder( const int id );
358 void updatePodcastChannel( const PodcastChannelBundle &b );
359 void updatePodcastEpisode( const int id, const PodcastEpisodeBundle &b );
360 void updatePodcastFolder( const int folder_id, const QString &name, const int parent_id=0, const bool isOpen=false );
361 // these return false when no bundle was available
362 bool getPodcastChannelBundle( const KUrl &url, PodcastChannelBundle *channel );
363 bool getPodcastEpisodeBundle( const KUrl &url, PodcastEpisodeBundle *channel );
365 MetaBundle bundleFromQuery( QStringList::const_iterator *iter );
367 * The @p bundle parameter's url() will be looked up in the Collection
368 * @param bundle this will be filled in with tags for you
369 * @return true if in the collection
371 bool bundleForUrl( MetaBundle* bundle );
372 Q3ValueList<MetaBundle> bundlesByUrls( const KUrl::List& urls );
373 void addAudioproperties( const MetaBundle& bundle );
375 //Helper function for updateTags
376 void deleteRedundantName( const QString &table, const QString &id );
378 void deleteAllRedundant( const QString &table );
380 void updateTags( const QString &url, const MetaBundle &bundle, const bool updateView = true);
381 void updateURL( const QString &url, const bool updateView = true );
382 QString getUniqueId( const QString &url );
384 //statistics methods
385 void addSongPercentage( const QString &url, float percentage,
386 const QString &reason, const QDateTime *playtime = 0 );
387 float getSongPercentage( const QString &url );
388 int getSongRating( const QString &url );
389 void setSongPercentage( const QString &url, float percentage );
390 void setSongRating( const QString &url, int percentage, bool toggleHalf = false );
391 int getPlayCount( const QString &url );
392 QDateTime getFirstPlay( const QString &url );
393 QDateTime getLastPlay( const QString &url );
394 void migrateFile( const QString &oldURL, const QString &newURL );
395 bool moveFile( const QString &src, const QString &dest, bool overwrite, bool copy = false );
396 bool organizeFile( const KUrl &src, /*const OrganizeCollectionDialog &dialog,*/ bool copy );
398 //artist methods
399 QStringList similarArtists( const QString &artist, uint count );
401 //album methods
402 void checkCompilations( const QString &path, const bool temporary = false );
403 void setCompilation( const KUrl::List &urls, bool enabled, bool updateView );
404 QString albumSongCount( const QString &artist_id, const QString &album_id );
405 bool albumIsCompilation( const QString &album_id );
406 void sanitizeCompilations();
408 //label methods
409 QStringList getLabels( const QString &url, const uint type );
410 void removeLabels( const QString &url, const QStringList &labels, const uint type );
411 bool addLabel( const QString &url, const QString &label, const QString &uid, const uint type );
412 void setLabels( const QString &url, const QStringList &labels, const QString &uid, const uint type );
414 void cleanLabels();
416 QStringList favoriteLabels( int type = CollectionDB::typeUser, int count = 10 );
418 //list methods
419 QStringList artistList( bool withUnknowns = true, bool withCompilations = true );
420 QStringList composerList( bool withUnknowns = true, bool withCompilations = true );
421 QStringList albumList( bool withUnknowns = true, bool withCompilations = true );
422 QStringList genreList( bool withUnknowns = true, bool withCompilations = true );
423 QStringList yearList( bool withUnknowns = true, bool withCompilations = true );
424 QStringList labelList();
426 QStringList albumListOfArtist( const QString &artist, bool withUnknown = true, bool withCompilations = true );
427 QStringList artistAlbumList( bool withUnknown = true, bool withCompilations = true );
429 QStringList albumTracks( const QString &artist_id, const QString &album_id );
430 QStringList albumDiscTracks( const QString &artist_id, const QString &album_id, const QString &discNumber );
431 QStringList artistTracks( const QString &artist_id );
433 //cover management methods
434 /** Returns the image from a given URL, network-transparently.
435 * You must run KIO::NetAccess::removeTempFile( tmpFile ) when you are finished using the image;
437 static QImage fetchImage( const KUrl& url, QString &tmpFile );
438 /** Saves images located on the user's filesystem */
439 bool setAlbumImage( const QString& artist, const QString& album, const KUrl& url );
440 /** Saves images obtained from CoverFetcher */
441 bool setAlbumImage( const QString& artist, const QString& album, QImage img, const QString& amazonUrl = QString(), const QString& asin = QString() );
443 QString findAmazonImage( const QString &artist, const QString &album, const uint width = 1 );
444 QString findDirectoryImage( const QString& artist, const QString& album, uint width = 0 );
445 QString findEmbeddedImage( const QString& artist, const QString& album, uint width = 1 );
446 QString findMetaBundleImage( const MetaBundle &trackInformation, const uint = 1 );
448 /// ensure the sql only return urls to tracks for efficiency
449 static QPixmap createDragPixmapFromSQL( const QString &sql, QString textOverRide=QString() );
450 static QPixmap createDragPixmap( const KUrl::List &urls, QString textOverRide=QString() );
451 static const int DRAGPIXMAP_OFFSET_X = -12;
452 static const int DRAGPIXMAP_OFFSET_Y = -28;
455 * Retrieves the path to the local copy of the image pointed to by url,
456 * initiates fetching of the remote image if necessary.
457 * @param width the size of the image. 0 == full size, 1 == preview size
459 QString podcastImage( const MetaBundle &bundle, const bool withShadow = false, uint width = 1 );
460 QString podcastImage( const QString &remoteURL, const bool withShadow = false, uint width = 1 );
463 * Retrieves the path to the image for the album of the requested item
464 * @param width the size of the image. 0 == full size, 1 == preview size
465 * @param embedded if not NULL, sets a bool indicating whether the path is an embedded image
467 QString albumImage( const MetaBundle &trackInformation, const bool withShadow = false, uint width = 1, bool* embedded = 0 );
468 QString albumImage( const uint artist_id, const uint album_id, const bool withShadow = false, uint width = 1, bool* embedded = 0 );
469 QString albumImage( const QString &artist, const QString &album, const bool withShadow = false, uint width = 1, bool* embedded = 0 );
470 QMap<Q3ListViewItem*, CoverFetcher*> * getItemCoverMap() { return itemCoverMap; }
471 QMutex * getItemCoverMapMutex() { return itemCoverMapMutex; }
473 bool removeAlbumImage( const uint artist_id, const uint album_id );
474 bool removeAlbumImage( const QString &artist, const QString &album );
476 static QString makeShadowedImage( const QString& albumImage, bool cache = true );
478 //local cover methods
479 void addImageToAlbum( const QString& image, Q3ValueList< QPair<QString, QString> > info, const bool temporary );
480 QString notAvailCover( const bool withShadow = false, int width = 1 );
482 //embedded cover methods
483 void addEmbeddedImage( const QString& path, const QString& hash, const QString& description );
484 void removeOrphanedEmbeddedImages();
486 void applySettings();
488 void setLyrics( const QString& url, const QString& lyrics, const QString &uniqueid = QString() );
489 QString getLyrics( const QString& url );
491 /** Remove from the amazon table the item with the specified md5sum **/
492 void removeInvalidAmazonInfo( const QString& md5sum );
493 void newAmazonReloadDate( const QString& asin, const QString& locale, const QString& md5sum );
494 QStringList staleImages();
496 AMAROK_EXPORT DbConnection::DbConnectionType getDbConnectionType() const { return m_dbConnType; }
497 bool isConnected();
498 void releasePreviousConnection(QThread *currThread);
500 void invalidateArtistAlbumCache() { m_validArtistCache=false; m_validComposerCache=false; m_validAlbumCache=false; }
502 void vacuum();
505 * Cancel the underlying move/copy file action
507 void cancelMovingFileJob();
509 protected:
510 QByteArray md5sum( const QString& artist, const QString& album, const QString& file = QString() );
511 /** Manages regular folder monitoring scan */
512 void timerEvent( QTimerEvent* e );
514 public slots:
515 void fetchCover( QWidget* parent, const QString& artist, const QString& album, bool noedit, Q3ListViewItem* item = 0 );
516 void scanMonitor();
517 void startScan();
518 void stopScan();
519 void scanModifiedDirs();
520 void disableAutoScoring( bool disable = true ) { m_autoScoring = !disable; }
522 void checkDatabase();
524 private slots:
525 void dirDirty( const QString& path );
526 void coverFetcherResult( CoverFetcher* );
527 void similarArtistsFetched( const QString& artist, const QStringList& suggestions );
528 void fileOperationResult( KIO::Job *job ); // moveFile depends on it
529 void podcastImageResult( KIO::Job *job ); //for fetching remote podcast images
530 void aftMigratePermanentTablesUrl( const QString& oldUrl, const QString& newUrl, const QString& uniqueid ); //AFT-enable stats
531 void aftMigratePermanentTablesUniqueId( const QString& url, const QString& oldid, const QString& newid );
533 private:
534 //bump DATABASE_VERSION whenever changes to the table structure are made.
535 // This erases tags, album, artist, composer, genre, year, images, embed, directory and related_artists tables.
536 static const int DATABASE_VERSION;
537 // Persistent Tables hold data that is somehow valuable to the user, and can't be erased when rescaning.
538 // When bumping this, write code to convert the data!
539 static const int DATABASE_PERSISTENT_TABLES_VERSION;
540 // Bumping this erases stats table. If you ever need to, write code to convert the data!
541 static const int DATABASE_STATS_VERSION;
542 // When bumping this, you should provide code to convert the data.
543 static const int DATABASE_PODCAST_TABLES_VERSION;
544 static const int DATABASE_AFT_VERSION;
545 // persistent table. you should provide code to convert the data when bumping this
546 static const int DATABASE_DEVICES_VERSION;
548 static const int MONITOR_INTERVAL; //sec
550 static QDir largeCoverDir();
551 static QDir tagCoverDir();
552 static QDir cacheCoverDir();
554 void initialize();
555 void destroy();
556 DbConnection* getMyConnection();
558 //helper methods which perform updates of amarok's database
559 void updateStatsTables();
560 void updatePersistentTables();
561 void updatePodcastTables();
563 void customEvent( QEvent * );
565 // helpers for embedded images
566 QString loadHashFile( const QByteArray& hash, uint width );
567 bool extractEmbeddedImage( const MetaBundle &trackInformation, QByteArray& hash );
569 //general management methods
570 void createStatsTable();
571 void dropStatsTable();
572 void createPersistentTables();
573 void dropPersistentTables();
574 void createPodcastTables();
575 void dropPodcastTables();
576 void createDevicesTable();
577 void dropDevicesTable();
579 //Archived forms of the above. useful for providing a linear upgrade routine that
580 //stays the same
581 void createStatsTableV8();
582 void createStatsTableV10( bool temp );
583 void dropStatsTableV1();
584 void createPersistentTablesV12();
585 void createPersistentTablesV14( bool temp );
586 void dropPersistentTablesV14();
587 void createPodcastTablesV2( bool temp );
588 void dropPodcastTablesV2();
591 QByteArray makeWidthKey( uint width );
592 QString artistValue( uint id );
593 QString composerValue( uint id );
594 QString albumValue( uint id );
595 QString genreValue( uint id );
596 QString yearValue( uint id );
598 //These should be avoided as they will be slow and potentially unsafe.
599 //Use the Exact version where possible (faster and safer).
600 //To convert output from Exact version from QString to uint, use .toUInt()
601 uint IDFromValue( QString name, QString value, bool autocreate = true, const bool temporary = false );
602 QString IDFromExactValue( QString table, QString value, bool autocreate = true, bool temporary = false );
603 QString valueFromID( QString table, uint id );
605 //member variables
606 QString m_amazonLicense;
607 bool m_validArtistCache;
608 bool m_validComposerCache;
609 bool m_validAlbumCache;
610 QString m_cacheArtist[2];
611 uint m_cacheArtistID[2];
612 QString m_cacheComposer[2];
613 uint m_cacheComposerID[2];
614 QString m_cacheAlbum[2];
615 uint m_cacheAlbumID[2];
617 bool m_monitor;
618 bool m_autoScoring;
620 static QMap<Q3ListViewItem*, CoverFetcher*> *itemCoverMap;
621 static QMutex *itemCoverMapMutex;
622 QImage m_noCover;
624 static QMap<QThread *, DbConnection *> *threadConnections;
625 static QMutex *connectionMutex;
626 DbConnection::DbConnectionType m_dbConnType;
627 DbConfig *m_dbConfig;
629 //organize files stuff
630 bool m_waitForFileOperation;
631 bool m_fileOperationFailed;
632 bool m_scanInProgress;
633 bool m_rescanRequired;
635 QStringList m_aftEnabledPersistentTables;
637 // Cancel move/copy job
638 bool m_moveFileJobCancelled;
640 // for handling podcast image url redirects
641 QMap<KIO::Job *, QString> m_podcastImageJobs;
643 // protect against multiple simultaneous queries/inserts
644 QMutex m_mutex;
647 class INotify : public ThreadManager::DependentJob
649 Q_OBJECT
651 public:
652 INotify( CollectionDB *parent, int fd );
653 ~INotify();
655 static INotify *instance() { return s_instance; }
657 bool watchDir( const QString directory );
658 int fd() { return m_fd; }
660 private:
661 virtual bool doJob();
663 CollectionDB* m_parent;
664 int m_fd;
666 static INotify* s_instance;
669 #endif /* AMAROK_COLLECTIONDB_H */