From 2425ec34e51563b2baefc18ce70ad8903ba6112e Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 3 Jun 2012 15:38:36 +0200 Subject: [PATCH] * Use a separate database connection for each db-worker thread. --- src/libtomahawk/database/Database.cpp | 11 +-- src/libtomahawk/database/Database.h | 7 +- src/libtomahawk/database/DatabaseImpl.cpp | 74 +++++++++++++++------ src/libtomahawk/database/DatabaseImpl.h | 11 ++- src/libtomahawk/database/DatabaseWorker.cpp | 6 +- src/libtomahawk/database/DatabaseWorker.h | 3 +- 6 files changed, 76 insertions(+), 36 deletions(-) diff --git a/src/libtomahawk/database/Database.cpp b/src/libtomahawk/database/Database.cpp index 8c7199092..eea51aca0 100644 --- a/src/libtomahawk/database/Database.cpp +++ b/src/libtomahawk/database/Database.cpp @@ -26,12 +26,7 @@ #include "Source.h" #define DEFAULT_WORKER_THREADS 4 - -#if ( QT_VERSION >= QT_VERSION_CHECK(4, 8, 2) ) - #define MAX_WORKER_THREADS 1 -#else - #define MAX_WORKER_THREADS 16 -#endif +#define MAX_WORKER_THREADS 16 Database* Database::s_instance = 0; @@ -47,7 +42,7 @@ Database::Database( const QString& dbname, QObject* parent ) : QObject( parent ) , m_ready( false ) , m_impl( new DatabaseImpl( dbname, this ) ) - , m_workerRW( new DatabaseWorker( m_impl, this, true ) ) + , m_workerRW( new DatabaseWorker( this, true ) ) { s_instance = this; @@ -105,7 +100,7 @@ Database::enqueue( const QSharedPointer& lc ) // create new thread if < WORKER_THREADS if ( m_workers.count() < m_maxConcurrentThreads ) { - DatabaseWorker* worker = new DatabaseWorker( m_impl, this, false ); + DatabaseWorker* worker = new DatabaseWorker( this, false ); worker->start(); m_workers << worker; diff --git a/src/libtomahawk/database/Database.h b/src/libtomahawk/database/Database.h index b265bd39c..7bf05a09e 100644 --- a/src/libtomahawk/database/Database.h +++ b/src/libtomahawk/database/Database.h @@ -53,12 +53,13 @@ public: ~Database(); QString dbid() const; - bool indexReady() const { return m_indexReady; } void loadIndex(); - + bool indexReady() const { return m_indexReady; } bool isReady() const { return m_ready; } + DatabaseImpl* impl() const { return m_impl; } + signals: void indexReady(); // search index void ready(); @@ -74,8 +75,6 @@ private slots: void setIsReadyTrue() { m_ready = true; } private: - DatabaseImpl* impl() const { return m_impl; } - bool m_ready; DatabaseImpl* m_impl; DatabaseWorker* m_workerRW; diff --git a/src/libtomahawk/database/DatabaseImpl.cpp b/src/libtomahawk/database/DatabaseImpl.cpp index 3c13d975e..60c34f9ae 100644 --- a/src/libtomahawk/database/DatabaseImpl.cpp +++ b/src/libtomahawk/database/DatabaseImpl.cpp @@ -46,9 +46,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) : QObject( (QObject*) parent ) - , m_lastartid( 0 ) - , m_lastalbid( 0 ) - , m_lasttrkid( 0 ) + , m_parent( parent ) { QTime t; t.start(); @@ -67,13 +65,10 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) m_dbid = uuid(); query.exec( QString( "INSERT INTO settings(k,v) VALUES('dbid','%1')" ).arg( m_dbid ) ); } - tLog() << "Database ID:" << m_dbid; - // make sqlite behave how we want: - query.exec( "PRAGMA auto_vacuum = FULL" ); - query.exec( "PRAGMA synchronous = ON" ); - query.exec( "PRAGMA foreign_keys = ON" ); - //query.exec( "PRAGMA temp_store = MEMORY" ); + tLog() << "Database ID:" << m_dbid; + init(); + tDebug( LOGVERBOSE ) << "Tweaked db pragmas:" << t.elapsed(); // in case of unclean shutdown last time: @@ -84,7 +79,6 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) QTimer::singleShot( 0, this, SLOT( updateIndex() ) ); tDebug( LOGVERBOSE ) << "Loaded index:" << t.elapsed(); - if ( qApp->arguments().contains( "--dumpdb" ) ) { dumpDatabase(); @@ -93,6 +87,30 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) } +DatabaseImpl::DatabaseImpl( Database* parent, const QString& dbname ) + : QObject( (QObject*) QThread::currentThread() ) + , m_parent( parent ) +{ + openDatabase( dbname, false ); + init(); +} + + +void +DatabaseImpl::init() +{ + m_lastartid = m_lastalbid = m_lasttrkid = 0; + + TomahawkSqlQuery query = newquery(); + + // make sqlite behave how we want: + query.exec( "PRAGMA auto_vacuum = FULL" ); + query.exec( "PRAGMA synchronous = ON" ); + query.exec( "PRAGMA foreign_keys = ON" ); + //query.exec( "PRAGMA temp_store = MEMORY" ); +} + + DatabaseImpl::~DatabaseImpl() { delete m_fuzzyIndex; @@ -115,6 +133,16 @@ DatabaseImpl::~DatabaseImpl() } +DatabaseImpl* +DatabaseImpl::clone() const +{ + DatabaseImpl* impl = new DatabaseImpl( m_parent, m_db.databaseName() ); + impl->setDatabaseID( m_dbid ); + impl->setFuzzyIndex( m_fuzzyIndex ); + return impl; +} + + void DatabaseImpl::dumpDatabase() { @@ -681,27 +709,35 @@ DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery ) bool -DatabaseImpl::openDatabase( const QString& dbname ) +DatabaseImpl::openDatabase( const QString& dbname, bool checkSchema ) { + const QStringList conns = QSqlDatabase::connectionNames(); + const QString connName = QString( "tomahawk%1" ).arg( conns.count() ? QString::number( conns.count() ) : "" ); + bool schemaUpdated = false; int version = -1; { - QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE", "tomahawk" ); + QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE", connName ); db.setDatabaseName( dbname ); if ( !db.open() ) { tLog() << "Failed to open database" << dbname; throw "failed to open db"; // TODO } - - QSqlQuery qry = QSqlQuery( db ); - qry.exec( "SELECT v FROM settings WHERE k='schema_version'" ); - if ( qry.next() ) + + if ( checkSchema ) { - version = qry.value( 0 ).toInt(); - tLog() << "Database schema of" << dbname << "is" << version; + QSqlQuery qry = QSqlQuery( db ); + qry.exec( "SELECT v FROM settings WHERE k='schema_version'" ); + if ( qry.next() ) + { + version = qry.value( 0 ).toInt(); + tLog() << "Database schema of" << dbname << "is" << version; + } } - + else + version = CURRENT_SCHEMA_VERSION; + if ( version < 0 || version == CURRENT_SCHEMA_VERSION ) m_db = db; } diff --git a/src/libtomahawk/database/DatabaseImpl.h b/src/libtomahawk/database/DatabaseImpl.h index f734f171f..671c86018 100644 --- a/src/libtomahawk/database/DatabaseImpl.h +++ b/src/libtomahawk/database/DatabaseImpl.h @@ -48,7 +48,7 @@ public: DatabaseImpl( const QString& dbname, Database* parent = 0 ); ~DatabaseImpl(); - bool openDatabase( const QString& dbname ); + DatabaseImpl* clone() const; TomahawkSqlQuery newquery() { return TomahawkSqlQuery( m_db ); } QSqlDatabase& database() { return m_db; } @@ -85,10 +85,17 @@ private slots: void updateIndex(); private: - QString cleanSql( const QString& sql ); + DatabaseImpl( Database* parent, const QString& dbname ); + void setFuzzyIndex( FuzzyIndex* fi ) { m_fuzzyIndex = fi; } + void setDatabaseID( const QString& dbid ) { m_dbid = dbid; } + + void init(); + bool openDatabase( const QString& dbname, bool checkSchema = true ); bool updateSchema( int oldVersion ); void dumpDatabase(); + QString cleanSql( const QString& sql ); + Database* m_parent; bool m_ready; QSqlDatabase m_db; diff --git a/src/libtomahawk/database/DatabaseWorker.cpp b/src/libtomahawk/database/DatabaseWorker.cpp index bf4972fb0..30481bde3 100644 --- a/src/libtomahawk/database/DatabaseWorker.cpp +++ b/src/libtomahawk/database/DatabaseWorker.cpp @@ -34,9 +34,9 @@ //#define DEBUG_TIMING TRUE #endif -DatabaseWorker::DatabaseWorker( DatabaseImpl* lib, Database* db, bool mutates ) +DatabaseWorker::DatabaseWorker( Database* db, bool mutates ) : QThread() - , m_dbimpl( lib ) + , m_db( db ) , m_outstanding( 0 ) { Q_UNUSED( db ); @@ -68,6 +68,8 @@ DatabaseWorker::~DatabaseWorker() void DatabaseWorker::run() { + m_dbimpl = m_db->impl()->clone(); + tDebug() << "New db connection with name:" << m_dbimpl->database().connectionName(); exec(); qDebug() << Q_FUNC_INFO << "DatabaseWorker finishing..."; } diff --git a/src/libtomahawk/database/DatabaseWorker.h b/src/libtomahawk/database/DatabaseWorker.h index 458d4d427..7da0acc6c 100644 --- a/src/libtomahawk/database/DatabaseWorker.h +++ b/src/libtomahawk/database/DatabaseWorker.h @@ -39,7 +39,7 @@ class DatabaseWorker : public QThread Q_OBJECT public: - DatabaseWorker( DatabaseImpl*, Database*, bool mutates ); + DatabaseWorker( Database*, bool mutates ); ~DatabaseWorker(); bool busy() const { return m_outstanding > 0; } @@ -59,6 +59,7 @@ private: void logOp( DatabaseCommandLoggable* command ); QMutex m_mut; + Database* m_db; DatabaseImpl* m_dbimpl; QList< QSharedPointer > m_commands; int m_outstanding;