1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-06 06:07:37 +02:00

* Use a separate database connection for each db-worker thread.

This commit is contained in:
Christian Muehlhaeuser
2012-06-03 15:38:36 +02:00
parent 93a062c07f
commit 2425ec34e5
6 changed files with 76 additions and 36 deletions

View File

@@ -26,12 +26,7 @@
#include "Source.h" #include "Source.h"
#define DEFAULT_WORKER_THREADS 4 #define DEFAULT_WORKER_THREADS 4
#define MAX_WORKER_THREADS 16
#if ( QT_VERSION >= QT_VERSION_CHECK(4, 8, 2) )
#define MAX_WORKER_THREADS 1
#else
#define MAX_WORKER_THREADS 16
#endif
Database* Database::s_instance = 0; Database* Database::s_instance = 0;
@@ -47,7 +42,7 @@ Database::Database( const QString& dbname, QObject* parent )
: QObject( parent ) : QObject( parent )
, m_ready( false ) , m_ready( false )
, m_impl( new DatabaseImpl( dbname, this ) ) , m_impl( new DatabaseImpl( dbname, this ) )
, m_workerRW( new DatabaseWorker( m_impl, this, true ) ) , m_workerRW( new DatabaseWorker( this, true ) )
{ {
s_instance = this; s_instance = this;
@@ -105,7 +100,7 @@ Database::enqueue( const QSharedPointer<DatabaseCommand>& lc )
// create new thread if < WORKER_THREADS // create new thread if < WORKER_THREADS
if ( m_workers.count() < m_maxConcurrentThreads ) if ( m_workers.count() < m_maxConcurrentThreads )
{ {
DatabaseWorker* worker = new DatabaseWorker( m_impl, this, false ); DatabaseWorker* worker = new DatabaseWorker( this, false );
worker->start(); worker->start();
m_workers << worker; m_workers << worker;

View File

@@ -53,12 +53,13 @@ public:
~Database(); ~Database();
QString dbid() const; QString dbid() const;
bool indexReady() const { return m_indexReady; }
void loadIndex(); void loadIndex();
bool indexReady() const { return m_indexReady; }
bool isReady() const { return m_ready; } bool isReady() const { return m_ready; }
DatabaseImpl* impl() const { return m_impl; }
signals: signals:
void indexReady(); // search index void indexReady(); // search index
void ready(); void ready();
@@ -74,8 +75,6 @@ private slots:
void setIsReadyTrue() { m_ready = true; } void setIsReadyTrue() { m_ready = true; }
private: private:
DatabaseImpl* impl() const { return m_impl; }
bool m_ready; bool m_ready;
DatabaseImpl* m_impl; DatabaseImpl* m_impl;
DatabaseWorker* m_workerRW; DatabaseWorker* m_workerRW;

View File

@@ -46,9 +46,7 @@
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
: QObject( (QObject*) parent ) : QObject( (QObject*) parent )
, m_lastartid( 0 ) , m_parent( parent )
, m_lastalbid( 0 )
, m_lasttrkid( 0 )
{ {
QTime t; QTime t;
t.start(); t.start();
@@ -67,13 +65,10 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
m_dbid = uuid(); m_dbid = uuid();
query.exec( QString( "INSERT INTO settings(k,v) VALUES('dbid','%1')" ).arg( m_dbid ) ); 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: tLog() << "Database ID:" << m_dbid;
query.exec( "PRAGMA auto_vacuum = FULL" ); init();
query.exec( "PRAGMA synchronous = ON" );
query.exec( "PRAGMA foreign_keys = ON" );
//query.exec( "PRAGMA temp_store = MEMORY" );
tDebug( LOGVERBOSE ) << "Tweaked db pragmas:" << t.elapsed(); tDebug( LOGVERBOSE ) << "Tweaked db pragmas:" << t.elapsed();
// in case of unclean shutdown last time: // in case of unclean shutdown last time:
@@ -84,7 +79,6 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
QTimer::singleShot( 0, this, SLOT( updateIndex() ) ); QTimer::singleShot( 0, this, SLOT( updateIndex() ) );
tDebug( LOGVERBOSE ) << "Loaded index:" << t.elapsed(); tDebug( LOGVERBOSE ) << "Loaded index:" << t.elapsed();
if ( qApp->arguments().contains( "--dumpdb" ) ) if ( qApp->arguments().contains( "--dumpdb" ) )
{ {
dumpDatabase(); 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() DatabaseImpl::~DatabaseImpl()
{ {
delete m_fuzzyIndex; 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 void
DatabaseImpl::dumpDatabase() DatabaseImpl::dumpDatabase()
{ {
@@ -681,27 +709,35 @@ DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery )
bool 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; bool schemaUpdated = false;
int version = -1; int version = -1;
{ {
QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE", "tomahawk" ); QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE", connName );
db.setDatabaseName( dbname ); db.setDatabaseName( dbname );
if ( !db.open() ) if ( !db.open() )
{ {
tLog() << "Failed to open database" << dbname; tLog() << "Failed to open database" << dbname;
throw "failed to open db"; // TODO throw "failed to open db"; // TODO
} }
QSqlQuery qry = QSqlQuery( db ); if ( checkSchema )
qry.exec( "SELECT v FROM settings WHERE k='schema_version'" );
if ( qry.next() )
{ {
version = qry.value( 0 ).toInt(); QSqlQuery qry = QSqlQuery( db );
tLog() << "Database schema of" << dbname << "is" << version; 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 ) if ( version < 0 || version == CURRENT_SCHEMA_VERSION )
m_db = db; m_db = db;
} }

View File

@@ -48,7 +48,7 @@ public:
DatabaseImpl( const QString& dbname, Database* parent = 0 ); DatabaseImpl( const QString& dbname, Database* parent = 0 );
~DatabaseImpl(); ~DatabaseImpl();
bool openDatabase( const QString& dbname ); DatabaseImpl* clone() const;
TomahawkSqlQuery newquery() { return TomahawkSqlQuery( m_db ); } TomahawkSqlQuery newquery() { return TomahawkSqlQuery( m_db ); }
QSqlDatabase& database() { return m_db; } QSqlDatabase& database() { return m_db; }
@@ -85,10 +85,17 @@ private slots:
void updateIndex(); void updateIndex();
private: 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 ); bool updateSchema( int oldVersion );
void dumpDatabase(); void dumpDatabase();
QString cleanSql( const QString& sql );
Database* m_parent;
bool m_ready; bool m_ready;
QSqlDatabase m_db; QSqlDatabase m_db;

View File

@@ -34,9 +34,9 @@
//#define DEBUG_TIMING TRUE //#define DEBUG_TIMING TRUE
#endif #endif
DatabaseWorker::DatabaseWorker( DatabaseImpl* lib, Database* db, bool mutates ) DatabaseWorker::DatabaseWorker( Database* db, bool mutates )
: QThread() : QThread()
, m_dbimpl( lib ) , m_db( db )
, m_outstanding( 0 ) , m_outstanding( 0 )
{ {
Q_UNUSED( db ); Q_UNUSED( db );
@@ -68,6 +68,8 @@ DatabaseWorker::~DatabaseWorker()
void void
DatabaseWorker::run() DatabaseWorker::run()
{ {
m_dbimpl = m_db->impl()->clone();
tDebug() << "New db connection with name:" << m_dbimpl->database().connectionName();
exec(); exec();
qDebug() << Q_FUNC_INFO << "DatabaseWorker finishing..."; qDebug() << Q_FUNC_INFO << "DatabaseWorker finishing...";
} }

View File

@@ -39,7 +39,7 @@ class DatabaseWorker : public QThread
Q_OBJECT Q_OBJECT
public: public:
DatabaseWorker( DatabaseImpl*, Database*, bool mutates ); DatabaseWorker( Database*, bool mutates );
~DatabaseWorker(); ~DatabaseWorker();
bool busy() const { return m_outstanding > 0; } bool busy() const { return m_outstanding > 0; }
@@ -59,6 +59,7 @@ private:
void logOp( DatabaseCommandLoggable* command ); void logOp( DatabaseCommandLoggable* command );
QMutex m_mut; QMutex m_mut;
Database* m_db;
DatabaseImpl* m_dbimpl; DatabaseImpl* m_dbimpl;
QList< QSharedPointer<DatabaseCommand> > m_commands; QList< QSharedPointer<DatabaseCommand> > m_commands;
int m_outstanding; int m_outstanding;