diff --git a/src/collection/collectionmodel.cpp b/src/collection/collectionmodel.cpp index cbc58ea54..12f428db0 100644 --- a/src/collection/collectionmodel.cpp +++ b/src/collection/collectionmodel.cpp @@ -754,11 +754,10 @@ CollectionModel::QueryResult CollectionModel::RunQuery(CollectionItem *parent) { // Execute the query QMutexLocker l(backend_->db()->Mutex()); - - if (!backend_->ExecQuery(&q)) return result; - - while (q.Next()) { - result.rows << SqlRow(q); + if (backend_->ExecQuery(&q)) { + while (q.Next()) { + result.rows << SqlRow(q); + } } if (QThread::currentThread() != thread() && QThread::currentThread() != backend_->thread()) { @@ -811,6 +810,10 @@ void CollectionModel::ResetAsync() { void CollectionModel::ResetAsyncQueryFinished(QFuture future) { + if (QThread::currentThread() != thread() && QThread::currentThread() != backend_->thread()) { + backend_->Close(); + } + const struct QueryResult result = future.result(); BeginReset(); diff --git a/src/core/database.cpp b/src/core/database.cpp index 28e2e9dc5..b8c7baa3e 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -250,13 +250,10 @@ Database::~Database() { QMutexLocker l(&connect_mutex_); - for (QString connection : connections_) { - qLog(Error) << connection << "still open!"; + for (QString &connection_id : QSqlDatabase::connectionNames()) { + qLog(Error) << "Connection" << connection_id << "is still open!"; } - if (!connections_.isEmpty()) - qLog(Error) << connections_.count() << "connections still open!"; - if (sFTSTokenizer) delete sFTSTokenizer; @@ -288,18 +285,18 @@ QSqlDatabase Database::Connect() { const QString connection_id = QString("%1_thread_%2").arg(connection_id_).arg(reinterpret_cast(QThread::currentThread())); - if (!connections_.contains(connection_id)) { - //qLog(Debug) << "Opened database with connection id" << connection_id; - connections_ << connection_id; - } - // Try to find an existing connection for this thread - QSqlDatabase db = QSqlDatabase::database(connection_id); + QSqlDatabase db; + if (QSqlDatabase::connectionNames().contains(connection_id)) { + db = QSqlDatabase::database(connection_id); + } + else { + db = QSqlDatabase::addDatabase("QSQLITE", connection_id); + } if (db.isOpen()) { return db; } - - db = QSqlDatabase::addDatabase("QSQLITE", connection_id); + //qLog(Debug) << "Opened database with connection id" << connection_id; if (!injected_database_name_.isNull()) db.setDatabaseName(injected_database_name_); @@ -389,14 +386,15 @@ void Database::Close() { const QString connection_id = QString("%1_thread_%2").arg(connection_id_).arg(reinterpret_cast(QThread::currentThread())); // Try to find an existing connection for this thread - QSqlDatabase db = QSqlDatabase::database(connection_id); - if (db.isOpen()) { - db.close(); - } - - if (connections_.contains(connection_id)) { - //qLog(Debug) << "Closed database with connection id" << connection_id; - connections_.removeAll(connection_id); + if (QSqlDatabase::connectionNames().contains(connection_id)) { + { + QSqlDatabase db = QSqlDatabase::database(connection_id); + if (db.isOpen()) { + db.close(); + //qLog(Debug) << "Closed database with connection id" << connection_id; + } + } + QSqlDatabase::removeDatabase(connection_id); } } diff --git a/src/core/database.h b/src/core/database.h index 77d636e99..17ea464bf 100644 --- a/src/core/database.h +++ b/src/core/database.h @@ -118,7 +118,6 @@ class Database : public QObject { // This ID makes the QSqlDatabase name unique to the object as well as the thread int connection_id_; - QStringList connections_; static QMutex sNextConnectionIdMutex; static int sNextConnectionId; diff --git a/src/device/connecteddevice.cpp b/src/device/connecteddevice.cpp index 18b7ca1a8..e7b4d78ba 100644 --- a/src/device/connecteddevice.cpp +++ b/src/device/connecteddevice.cpp @@ -70,6 +70,7 @@ ConnectedDevice::ConnectedDevice(const QUrl &url, DeviceLister *lister, const QS } ConnectedDevice::~ConnectedDevice() { + backend_->Close(); backend_->deleteLater(); } diff --git a/src/device/devicedatabasebackend.cpp b/src/device/devicedatabasebackend.cpp index d28ab9dca..31c1cb242 100644 --- a/src/device/devicedatabasebackend.cpp +++ b/src/device/devicedatabasebackend.cpp @@ -80,27 +80,31 @@ void DeviceDatabaseBackend::Exit() { DeviceDatabaseBackend::DeviceList DeviceDatabaseBackend::GetAllDevices() { - QMutexLocker l(db_->Mutex()); - QSqlDatabase db(db_->Connect()); - DeviceList ret; - QSqlQuery q(db); - q.prepare("SELECT ROWID, unique_id, friendly_name, size, icon, transcode_mode, transcode_format FROM devices"); - q.exec(); - if (db_->CheckErrors(q)) return ret; + { + QMutexLocker l(db_->Mutex()); + QSqlDatabase db(db_->Connect()); + QSqlQuery q(db); + q.prepare("SELECT ROWID, unique_id, friendly_name, size, icon, transcode_mode, transcode_format FROM devices"); + q.exec(); + if (db_->CheckErrors(q)) return ret; - while (q.next()) { - Device dev; - dev.id_ = q.value(0).toInt(); - dev.unique_id_ = q.value(1).toString(); - dev.friendly_name_ = q.value(2).toString(); - dev.size_ = q.value(3).toLongLong(); - dev.icon_name_ = q.value(4).toString(); - dev.transcode_mode_ = MusicStorage::TranscodeMode(q.value(5).toInt()); - dev.transcode_format_ = Song::FileType(q.value(6).toInt()); - ret << dev; + while (q.next()) { + Device dev; + dev.id_ = q.value(0).toInt(); + dev.unique_id_ = q.value(1).toString(); + dev.friendly_name_ = q.value(2).toString(); + dev.size_ = q.value(3).toLongLong(); + dev.icon_name_ = q.value(4).toString(); + dev.transcode_mode_ = MusicStorage::TranscodeMode(q.value(5).toInt()); + dev.transcode_format_ = Song::FileType(q.value(6).toInt()); + ret << dev; + } } + + Close(); + return ret; } diff --git a/src/device/devicemanager.cpp b/src/device/devicemanager.cpp index 0b0c0aa2f..c7d63de3e 100644 --- a/src/device/devicemanager.cpp +++ b/src/device/devicemanager.cpp @@ -182,6 +182,7 @@ void DeviceManager::LoadAllDevices() { info->InitFromDb(device); emit DeviceCreatedFromDB(info); } + backend_->Close(); } diff --git a/src/device/gpoddevice.cpp b/src/device/gpoddevice.cpp index d49d37586..964a68e3b 100644 --- a/src/device/gpoddevice.cpp +++ b/src/device/gpoddevice.cpp @@ -219,6 +219,8 @@ void GPodDevice::WriteDatabase(bool success) { } } + backend_->Close(); + songs_to_add_.clear(); songs_to_remove_.clear(); db_busy_.unlock(); diff --git a/src/device/mtpdevice.cpp b/src/device/mtpdevice.cpp index 655798b3d..3226eb1bc 100644 --- a/src/device/mtpdevice.cpp +++ b/src/device/mtpdevice.cpp @@ -184,6 +184,8 @@ void MtpDevice::FinishCopy(bool success) { songs_to_add_.clear(); songs_to_remove_.clear(); + backend_->Close(); + db_busy_.unlock(); ConnectedDevice::FinishCopy(success); diff --git a/src/playlist/playlistbackend.cpp b/src/playlist/playlistbackend.cpp index 8fe251a9b..666ae624d 100644 --- a/src/playlist/playlistbackend.cpp +++ b/src/playlist/playlistbackend.cpp @@ -195,19 +195,24 @@ QSqlQuery PlaylistBackend::GetPlaylistRows(int playlist) { QList PlaylistBackend::GetPlaylistItems(int playlist) { - QSqlQuery q = GetPlaylistRows(playlist); - // Note that as this only accesses the query, not the db, we don't need the mutex. - if (db_->CheckErrors(q)) return QList(); - - // it's probable that we'll have a few songs associated with the same CUE so we're caching results of parsing CUEs - std::shared_ptr state_ptr(new NewSongFromQueryState()); QList playlistitems; - while (q.next()) { - playlistitems << NewPlaylistItemFromQuery(SqlRow(q), state_ptr); + + { + + QSqlQuery q = GetPlaylistRows(playlist); + // Note that as this only accesses the query, not the db, we don't need the mutex. + if (db_->CheckErrors(q)) return QList(); + + // it's probable that we'll have a few songs associated with the same CUE so we're caching results of parsing CUEs + std::shared_ptr state_ptr(new NewSongFromQueryState()); + while (q.next()) { + playlistitems << NewPlaylistItemFromQuery(SqlRow(q), state_ptr); + } + } if (QThread::currentThread() != thread() && QThread::currentThread() != qApp->thread()) { - db_->Close(); + Close(); } return playlistitems; @@ -216,19 +221,24 @@ QList PlaylistBackend::GetPlaylistItems(int playlist) { QList PlaylistBackend::GetPlaylistSongs(int playlist) { - QSqlQuery q = GetPlaylistRows(playlist); - // Note that as this only accesses the query, not the db, we don't need the mutex. - if (db_->CheckErrors(q)) return QList(); + SongList songs; + + { + + QSqlQuery q = GetPlaylistRows(playlist); + // Note that as this only accesses the query, not the db, we don't need the mutex. + if (db_->CheckErrors(q)) return QList(); + + // it's probable that we'll have a few songs associated with the same CUE so we're caching results of parsing CUEs + std::shared_ptr state_ptr(new NewSongFromQueryState()); + while (q.next()) { + songs << NewSongFromQuery(SqlRow(q), state_ptr); + } - // it's probable that we'll have a few songs associated with the same CUE so we're caching results of parsing CUEs - std::shared_ptr state_ptr(new NewSongFromQueryState()); - QList songs; - while (q.next()) { - songs << NewSongFromQuery(SqlRow(q), state_ptr); } if (QThread::currentThread() != thread() && QThread::currentThread() != qApp->thread()) { - db_->Close(); + Close(); } return songs; diff --git a/src/playlist/playlistdelegates.cpp b/src/playlist/playlistdelegates.cpp index 620b92c22..1d3be1f81 100644 --- a/src/playlist/playlistdelegates.cpp +++ b/src/playlist/playlistdelegates.cpp @@ -353,7 +353,6 @@ QString FileTypeItemDelegate::displayText(const QVariant &value, const QLocale & } QWidget *TextItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { - return new QLineEdit(parent); }