Cope with removable media changing mount point
This commit is contained in:
parent
8c0b714791
commit
4a8bff5f4e
@ -46,7 +46,6 @@ ConnectedDevice::ConnectedDevice(DeviceLister* lister, const QString& unique_id,
|
|||||||
|
|
||||||
// Create the model
|
// Create the model
|
||||||
model_ = new LibraryModel(backend_, this);
|
model_ = new LibraryModel(backend_, this);
|
||||||
model_->Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectedDevice::~ConnectedDevice() {
|
ConnectedDevice::~ConnectedDevice() {
|
||||||
|
@ -58,8 +58,26 @@ FilesystemDevice::FilesystemDevice(
|
|||||||
|
|
||||||
if (first_time)
|
if (first_time)
|
||||||
backend_->AddDirectory(mount_point);
|
backend_->AddDirectory(mount_point);
|
||||||
else
|
else {
|
||||||
|
// This is a bit of a hack. The device might not be mounted at the same
|
||||||
|
// path each time, so if it's different we have to munge all the paths in
|
||||||
|
// the database to fix it. This can be done entirely in sqlite so it's
|
||||||
|
// relatively fast...
|
||||||
|
|
||||||
|
// Get the directory it was mounted at last time. Devices only have one
|
||||||
|
// directory (the root).
|
||||||
|
Directory dir = backend_->GetAllDirectories()[0];
|
||||||
|
if (dir.path != mount_point) {
|
||||||
|
// The directory is different, commence the munging.
|
||||||
|
qDebug() << "Changing path from" << dir.path << "to" << mount_point;
|
||||||
|
backend_->ChangeDirPath(dir.id, mount_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the directory properly now, this signals the watcher as well.
|
||||||
backend_->LoadDirectoriesAsync();
|
backend_->LoadDirectoriesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
model_->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
FilesystemDevice::~FilesystemDevice() {
|
FilesystemDevice::~FilesystemDevice() {
|
||||||
|
@ -49,20 +49,67 @@ void LibraryBackend::UpdateTotalSongCountAsync() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LibraryBackend::LoadDirectories() {
|
void LibraryBackend::LoadDirectories() {
|
||||||
|
DirectoryList dirs = GetAllDirectories();
|
||||||
|
|
||||||
QMutexLocker l(db_->Mutex());
|
QMutexLocker l(db_->Mutex());
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
QSqlQuery q(QString("SELECT ROWID, path FROM %1").arg(dirs_table_), db);
|
foreach (const Directory& dir, dirs) {
|
||||||
|
emit DirectoryDiscovered(dir, SubdirsInDirectory(dir.id, db));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibraryBackend::ChangeDirPath(int id, const QString &new_path) {
|
||||||
|
QMutexLocker l(db_->Mutex());
|
||||||
|
QSqlDatabase db(db_->Connect());
|
||||||
|
ScopedTransaction t(&db);
|
||||||
|
|
||||||
|
// Do the dirs table
|
||||||
|
QSqlQuery q(QString("UPDATE %1 SET path=:path WHERE ROWID=:id").arg(dirs_table_), db);
|
||||||
|
q.bindValue(":path", new_path);
|
||||||
|
q.bindValue(":id", id);
|
||||||
q.exec();
|
q.exec();
|
||||||
if (db_->CheckErrors(q.lastError())) return;
|
if (db_->CheckErrors(q.lastError())) return;
|
||||||
|
|
||||||
|
const int path_len = new_path.length();
|
||||||
|
|
||||||
|
// Do the subdirs table
|
||||||
|
q = QSqlQuery(QString("UPDATE %1 SET path=:path || substr(path, %2)"
|
||||||
|
" WHERE directory=:id").arg(subdirs_table_).arg(path_len), db);
|
||||||
|
q.bindValue(":path", new_path);
|
||||||
|
q.bindValue(":id", id);
|
||||||
|
q.exec();
|
||||||
|
if (db_->CheckErrors(q.lastError())) return;
|
||||||
|
|
||||||
|
// Do the songs table
|
||||||
|
q = QSqlQuery(QString("UPDATE %1 SET filename=:path || substr(filename, %2)"
|
||||||
|
" WHERE directory=:id").arg(songs_table_).arg(path_len), db);
|
||||||
|
q.bindValue(":path", new_path);
|
||||||
|
q.bindValue(":id", id);
|
||||||
|
q.exec();
|
||||||
|
if (db_->CheckErrors(q.lastError())) return;
|
||||||
|
|
||||||
|
t.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectoryList LibraryBackend::GetAllDirectories() {
|
||||||
|
QMutexLocker l(db_->Mutex());
|
||||||
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
|
DirectoryList ret;
|
||||||
|
|
||||||
|
QSqlQuery q(QString("SELECT ROWID, path FROM %1").arg(dirs_table_), db);
|
||||||
|
q.exec();
|
||||||
|
if (db_->CheckErrors(q.lastError())) return ret;
|
||||||
|
|
||||||
while (q.next()) {
|
while (q.next()) {
|
||||||
Directory dir;
|
Directory dir;
|
||||||
dir.id = q.value(0).toInt();
|
dir.id = q.value(0).toInt();
|
||||||
dir.path = q.value(1).toString();
|
dir.path = q.value(1).toString();
|
||||||
|
|
||||||
emit DirectoryDiscovered(dir, SubdirsInDirectory(dir.id, db));
|
ret << dir;
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SubdirectoryList LibraryBackend::SubdirsInDirectory(int id) {
|
SubdirectoryList LibraryBackend::SubdirsInDirectory(int id) {
|
||||||
|
@ -66,6 +66,8 @@ class LibraryBackend : public QObject {
|
|||||||
|
|
||||||
SongList FindSongsInDirectory(int id);
|
SongList FindSongsInDirectory(int id);
|
||||||
SubdirectoryList SubdirsInDirectory(int id);
|
SubdirectoryList SubdirsInDirectory(int id);
|
||||||
|
DirectoryList GetAllDirectories();
|
||||||
|
void ChangeDirPath(int id, const QString& new_path);
|
||||||
|
|
||||||
QStringList GetAllArtists(const QueryOptions& opt = QueryOptions());
|
QStringList GetAllArtists(const QueryOptions& opt = QueryOptions());
|
||||||
QStringList GetAllArtistsWithAlbums(const QueryOptions& opt = QueryOptions());
|
QStringList GetAllArtistsWithAlbums(const QueryOptions& opt = QueryOptions());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user