void MusicSearchEngine::watchForChanges()
{
	// Gather all folders registered on music locations
	QFileInfoList dirs;
	for (QString musicPath : SettingsPrivate::instance()->musicLocations()) {
		QFileInfo location(musicPath);
		QDirIterator it(location.absoluteFilePath(), QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
		while (it.hasNext()) {
			QString entry = it.next();
			QFileInfo qFileInfo(entry);
			dirs << qFileInfo;
		}
	}

	SqlDatabase *db = SqlDatabase::instance();
	db->open();
	db->exec("PRAGMA journal_mode = MEMORY");
	db->exec("PRAGMA synchronous = OFF");
	db->exec("PRAGMA temp_store = 2");
	db->exec("PRAGMA foreign_keys = 1");

	QStringList newFoldersToAddInLibrary;
	// Add folders that were not found first
	for (QFileInfo f : dirs) {
		QSqlQuery query = db->exec("SELECT * FROM filesystem WHERE path = \"" + f.absoluteFilePath() + "\"");
		if (!query.next()) {
			newFoldersToAddInLibrary << f.absoluteFilePath();
			QSqlQuery prepared(*db);
			prepared.prepare("INSERT INTO filesystem (path, lastModified) VALUES (?, ?)");
			prepared.addBindValue(f.absoluteFilePath());
			prepared.addBindValue(f.lastModified().toTime_t());
			prepared.exec();
		}
	}

	if (!newFoldersToAddInLibrary.isEmpty()) {
		this->doSearch(newFoldersToAddInLibrary);
	}

	// Process in reverse mode to clean cache: from database file and check if entry exists in database
	QStringList oldLocations;
	QSqlQuery cache = db->exec("SELECT * FROM filesystem");
	while (cache.next()) {
		QDir d(cache.record().value(0).toString());
		d.exists();
		QFileInfo fileInfo(cache.record().value(0).toString());
		// Remove folder in database because it couldn't be find in the filesystem
		if (!fileInfo.exists()) {
			db->exec("DELETE FROM filesystem WHERE path = \"" + fileInfo.absoluteFilePath() + "\"");
			oldLocations << fileInfo.absoluteFilePath();
		}
	}
	if (!oldLocations.isEmpty()) {
		db->rebuild(oldLocations, QStringList());
	}
}
Пример #2
0
// Check if the expected rows in the DB are non-empty. Note that in some cases they might be, then we cannot use this function
// https://github.com/owncloud/client/issues/2038
static void assertCsyncJournalOk(SyncJournalDb &journal)
{
    // The DB is openend in locked mode: close to allow us to access.
    journal.close();

    SqlDatabase db;
    QVERIFY(db.openReadOnly(journal.databaseFilePath()));
    SqlQuery q("SELECT count(*) from metadata where length(fileId) == 0", db);
    QVERIFY(q.exec());
    QVERIFY(q.next().hasData);
    QCOMPARE(q.intValue(0), 0);
#if defined(Q_OS_WIN) // Make sure the file does not appear in the FileInfo
    FileSystem::setFileHidden(journal.databaseFilePath() + "-shm", true);
#endif
}
Пример #3
0
void RemoteControl::sendTrackInfos(const QString &track)
{
	if (!_webSocket) {
		return;
	}

	QStringList args;
	args << QString::number(CMD_Track);

	SqlDatabase db;
	TrackDAO dao = db.selectTrackByURI(track);
	args << dao.uri();
	args << dao.artistAlbum();
	args << dao.album();
	args << dao.title();
	args << dao.trackNumber();
	args << QString::number(dao.rating());
	_webSocket->sendTextMessage(args.join(QChar::Null));

	// Send cover if any
	if (Cover *cover = db.selectCoverFromURI(track)) {
		_webSocket->sendBinaryMessage(cover->byteArray());
	}
}
Пример #4
0
/** Rebuild the list of separators when one has changed grammatical articles in options. */
void LibraryItemModel::rebuildSeparators()
{
	SqlDatabase db;
	auto s = SettingsPrivate::instance();
	QStringList filters;
	if (s->isLibraryFilteredByArticles() && !s->libraryFilteredByArticles().isEmpty()) {
		filters = s->libraryFilteredByArticles();
	}

	// Reset custom displayed text, like "Artist, the"
	QHashIterator<SeparatorItem*, QModelIndex> i(_topLevelItems);
	while (i.hasNext()) {
		i.next();
		if (auto item = itemFromIndex(i.value())) {
			if (!i.value().data(Miam::DF_CustomDisplayText).toString().isEmpty()) {
				item->setData(QString(), Miam::DF_CustomDisplayText);
				// Recompute standard normalized name: "The Artist" -> "theartist"
				item->setData(db.normalizeField(item->text()), Miam::DF_NormalizedString);
			} else if (!filters.isEmpty()) {
				for (QString filter : filters) {
					QString text = item->text();
					if (text.startsWith(filter + " ", Qt::CaseInsensitive)) {
						text = text.mid(filter.length() + 1);
						item->setData(text + ", " + filter, Miam::DF_CustomDisplayText);
						item->setData(db.normalizeField(text), Miam::DF_NormalizedString);
						break;
					}
				}
			}
		}
	}

	// Delete separators first
	QSet<int> setRows;
	QHashIterator<QString, SeparatorItem*> it(_letters);
	while (it.hasNext()) {
		it.next();
		setRows << it.value()->index().row();
	}

	// Always remove items (rows) in reverse order
	QList<int> rows = setRows.toList();
	std::sort(rows.begin(), rows.end(), std::greater<int>());
	for (int row : rows) {
		auto item = takeItem(row);
		removeRow(row);
		delete item;
	}
	_letters.clear();
	_topLevelItems.clear();

	// Insert once again new separators
	for (int row = 0; row < rowCount(); row++) {
		auto item = this->item(row);
		if (item->type() != Miam::IT_Separator) {
			if (auto separator = this->insertSeparator(item)) {
				_topLevelItems.insert(separator, item->index());
			}
		}
	}
}
/** Redefined from MiamSortFilterProxyModel. */
bool UniqueLibraryFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
	QStandardItem *item = _model->itemFromIndex(_model->index(sourceRow, 1, sourceParent));
	if (!item) {
		return false;
	}
	bool result = false;
	switch (item->type()) {
	case Miam::IT_Artist:
		if (MiamSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent)) {
			result = true;
		} else {
			SqlDatabase db;
			db.open();
			QSqlQuery getArtist(db);
			getArtist.setForwardOnly(true);
			getArtist.prepare("SELECT * FROM tracks WHERE title LIKE ? AND artistId = ?");
			getArtist.addBindValue("%" + filterRegExp().pattern() + "%");
			getArtist.addBindValue(item->data(Miam::DF_ID).toUInt());
			result = getArtist.exec() && getArtist.next();
		}
		break;
	case Miam::IT_Album:
		if (MiamSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent)) {
			result = true;
		} else if (filterRegExp().indexIn(item->data(Miam::DF_Artist).toString()) != -1) {
			result = true;
		} else {
			SqlDatabase db;
			db.open();
			QSqlQuery getAlbum(db);
			getAlbum.setForwardOnly(true);
			getAlbum.prepare("SELECT * FROM tracks WHERE title LIKE ? AND albumId = ?");
			getAlbum.addBindValue("%" + filterRegExp().pattern() + "%");
			getAlbum.addBindValue(item->data(Miam::DF_ID).toUInt());
			result = getAlbum.exec() && getAlbum.next();
		}
		break;
	case Miam::IT_Disc:
		if (filterRegExp().indexIn(item->data(Miam::DF_Artist).toString()) != -1) {
			result = true;
		} else {
			SqlDatabase db;
			db.open();
			QSqlQuery getDiscAlbum(db);
			getDiscAlbum.setForwardOnly(true);
			getDiscAlbum.prepare("SELECT * FROM tracks WHERE disc > 0 AND title LIKE ? AND albumId = ?");
			getDiscAlbum.addBindValue("%" + filterRegExp().pattern() + "%");
			getDiscAlbum.addBindValue(item->data(Miam::DF_ID).toUInt());
			result = getDiscAlbum.exec() && getDiscAlbum.next();
		}
		break;
	case Miam::IT_Track:
		if (MiamSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent)) {
			result = true;
		} else {
			result = filterRegExp().indexIn(item->data(Miam::DF_Artist).toString()) != -1 ||
					filterRegExp().indexIn(item->data(Miam::DF_Album).toString()) != -1;
		}
		break;
	case Miam::IT_Separator:
		for (QModelIndex index : _topLevelItems.values(static_cast<SeparatorItem*>(item))) {
			if (filterAcceptsRow(index.row(), sourceParent)) {
				result = true;
			}
		}
		break;
	default:
		break;
	}
	return result;
}
Пример #6
0
SqlQuery::SqlQuery(const QString& sql, SqlDatabase& db)
    :_db(db.sqliteDb()),
      _stmt(0), _errId(0)
{
    prepare(sql);
}
Пример #7
0
SqlQuery::SqlQuery( SqlDatabase& db )
    :_db(db.sqliteDb()),
      _stmt(0), _errId(0)
{

}
Пример #8
0
SqlQuery::SqlQuery(const QByteArray &sql, SqlDatabase &db)
    : _sqldb(&db)
    , _db(db.sqliteDb())
{
    prepare(sql);
}
Пример #9
0
SqlQuery::SqlQuery(SqlDatabase &db)
    : _sqldb(&db)
    , _db(db.sqliteDb())
{
}