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"
21 #include <QDir> //stack allocated
25 #include <QObject> //baseclass
26 #include <q3ptrqueue.h> //baseclass
27 #include <q3semaphore.h> //stack allocated
28 #include <QStringList> //stack allocated
29 #include <q3ptrvector.h>
31 #include <q3valuestack.h>
33 #include <QTimerEvent>
35 #include <Q3ValueList>
39 namespace KIO
{ class Job
; }
44 //class OrganizeCollectionDialog;
45 class PodcastChannelBundle
;
46 class PodcastEpisodeBundle
;
53 class SqliteConfig
: public DbConfig
56 SqliteConfig( const QString
& /* dbfile */ );
58 QString
dbFile() const { return m_dbfile
; }
65 class MySqlConfig
: public DbConfig
69 const QString
& /* host */,
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
; }
90 class PostgresqlConfig
: public DbConfig
94 const QString
& /* host */,
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
; }
115 class AMAROK_EXPORT DbConnection
118 enum DbConnectionType
{ sqlite
= 0, mysql
= 1, postgresql
= 2 };
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"; }
134 typedef struct sqlite3 sqlite3
;
135 typedef struct sqlite3_context sqlite3_context
;
136 typedef struct Mem sqlite3_value
;
138 class SqliteConnection
: public DbConnection
141 SqliteConnection( const SqliteConfig
* /* config */ );
144 QStringList
query( const QString
& /* statement */, bool suppressDebug
= false );
145 int insert( const QString
& /* statement */, const QString
& /* table */ );
146 bool isConnected()const { return true; }
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
);
157 typedef struct st_mysql MYSQL
;
159 class MySqlConnection
: public DbConnection
162 MySqlConnection( const MySqlConfig
* /* config */ );
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
; }
170 void setMysqlError();
178 #ifdef USE_POSTGRESQL
179 typedef struct pg_conn PGconn
;
181 class PostgresqlConnection
: public DbConnection
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
; }
192 void setPostgresqlError();
200 class AMAROK_EXPORT CollectionDB
: public QObject
, public EngineObserver
204 friend class SimilarArtistsInsertionJob
;
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
238 /*AMAROK_EXPORT*/ static CollectionDB
*instance();
241 * performs all initializations which require directory or URL data stored in the
244 void initDirOperations();
246 enum labelTypes
{ typeUser
= 1 }; //add new types add the end!
248 QString
escapeString(QString string
) const
252 // We have to escape "\" for mysql, but can't do so for sqlite
253 ( m_dbConnType
== DbConnection::mysql
)
254 ? string
.replace("\\", "\\\\").replace( '\'', "''" ) :
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(); }
279 /*AMAROK_EXPORT*/ QStringList
query( const QString
& statement
, bool suppressDebug
= false );
280 /*AMAROK_EXPORT*/ int insert( const QString
& statement
, const QString
& table
);
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
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 );
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
);
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
);
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
);
399 QStringList
similarArtists( const QString
&artist
, uint count
);
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();
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
);
416 QStringList
favoriteLabels( int type
= CollectionDB::typeUser
, int count
= 10 );
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
; }
498 void releasePreviousConnection(QThread
*currThread
);
500 void invalidateArtistAlbumCache() { m_validArtistCache
=false; m_validComposerCache
=false; m_validAlbumCache
=false; }
505 * Cancel the underlying move/copy file action
507 void cancelMovingFileJob();
510 QByteArray
md5sum( const QString
& artist
, const QString
& album
, const QString
& file
= QString() );
511 /** Manages regular folder monitoring scan */
512 void timerEvent( QTimerEvent
* e
);
515 // void fetchCover( QWidget* parent, const QString& artist, const QString& album, bool noedit, Q3ListViewItem* item = 0 );
519 void scanModifiedDirs();
520 void disableAutoScoring( bool disable
= true ) { m_autoScoring
= !disable
; }
522 void checkDatabase();
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
);
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();
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
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
);
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];
620 static QMap
<Q3ListViewItem
*, CoverFetcher
*> *itemCoverMap
;
621 static QMutex
*itemCoverMapMutex
;
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
647 class INotify
: public ThreadManager::DependentJob
652 INotify( CollectionDB
*parent
, int fd
);
655 static INotify
*instance() { return s_instance
; }
657 bool watchDir( const QString directory
);
658 int fd() { return m_fd
; }
661 virtual bool doJob();
663 CollectionDB
* m_parent
;
666 static INotify
* s_instance
;
669 #endif /* AMAROK_COLLECTIONDB_H */