From d2dcc2f95b2c57a8ac5d0ff6297da99f0cb4669e Mon Sep 17 00:00:00 2001 From: Albert S Date: Mon, 10 Apr 2023 18:25:49 +0200 Subject: [PATCH] shared: sqlitedbservice: Add setTags(),getTagsForPath(),getTags() --- shared/sqlitedbservice.cpp | 92 ++++++++++++++++++++++++++++++++++++++ shared/sqlitedbservice.h | 8 +++- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/shared/sqlitedbservice.cpp b/shared/sqlitedbservice.cpp index 915fe31..c508d6b 100644 --- a/shared/sqlitedbservice.cpp +++ b/shared/sqlitedbservice.cpp @@ -104,6 +104,96 @@ unsigned int SqliteDbService::getFiles(QVector &results, QString wildC return processedRows; } +QVector SqliteDbService::getTags() +{ + QVector result; + auto query = QSqlQuery(dbFactory->forCurrentThread()); + query.prepare("SELECT name FROM tag ORDER by name ASC"); + query.setForwardOnly(true); + if(!query.exec()) + { + throw LooqsGeneralException("Error while trying to retrieve tags from database: " + query.lastError().text()); + } + while(query.next()) + { + QString tagname = query.value(0).toString(); + result.append(tagname); + } + return result; +} + +QVector SqliteDbService::getTagsForPath(QString path) +{ + QVector result; + auto query = QSqlQuery(dbFactory->forCurrentThread()); + query.prepare("SELECT name FROM tag INNER JOIN filetag ON tag.id = filetag.tagid INNER JOIN file ON filetag.fileid " + "= file.id WHERE file.path = ? ORDER BY name ASC"); + query.addBindValue(path); + query.setForwardOnly(true); + if(!query.exec()) + { + throw LooqsGeneralException("Error while trying to retrieve tags from database: " + query.lastError().text()); + } + while(query.next()) + { + QString tagname = query.value(0).toString(); + result.append(tagname); + } + return result; +} + +bool SqliteDbService::setTags(QString path, const QSet &tags) +{ + QSqlDatabase db = dbFactory->forCurrentThread(); + if(!db.transaction()) + { + Logger::error() << "Failed to open transaction for " << path << " : " << db.lastError() << Qt::endl; + return false; + } + + QSqlQuery deletionQuery = QSqlQuery(db); + deletionQuery.prepare("DELETE FROM filetag WHERE fileid = (SELECT id FROM file WHERE path = ?)"); + deletionQuery.addBindValue(path); + if(!deletionQuery.exec()) + { + db.rollback(); + Logger::error() << "Failed to delete existing tags " << deletionQuery.lastError() << Qt::endl; + return false; + } + + for(const QString &tag : tags) + { + QSqlQuery tagQuery = QSqlQuery(db); + tagQuery.prepare("INSERT OR IGNORE INTO tag (name) VALUES(?)"); + tagQuery.addBindValue(tag.toLower()); + if(!tagQuery.exec()) + { + db.rollback(); + Logger::error() << "Failed to insert tag " << tagQuery.lastError() << Qt::endl; + return false; + } + QSqlQuery fileTagQuery(db); + fileTagQuery.prepare( + "INSERT INTO filetag(fileid, tagid) VALUES((SELECT id FROM file WHERE path = ?), (SELECT id " + "FROM tag WHERE name = ?))"); + fileTagQuery.bindValue(0, path); + fileTagQuery.bindValue(1, tag); + if(!fileTagQuery.exec()) + { + db.rollback(); + Logger::error() << "Failed to assign tag to file" << Qt::endl; + return false; + } + } + if(!db.commit()) + { + db.rollback(); + Logger::error() << "Failed to commit transaction when saving tags" << Qt::endl; + return false; + } + return true; +} + bool SqliteDbService::insertToFTS(bool useTrigrams, QSqlDatabase &db, int fileid, QVector &pageData) { QString ftsInsertStatement; @@ -248,6 +338,8 @@ bool SqliteDbService::addTag(QString tag, const QVector &paths) QSqlQuery tagQuery(db); QSqlQuery fileTagQuery(db); + tag = tag.toLower(); + tagQuery.prepare("INSERT OR IGNORE INTO tag (name) VALUES(?)"); tagQuery.addBindValue(tag); diff --git a/shared/sqlitedbservice.h b/shared/sqlitedbservice.h index 2ae8b9c..6174d44 100644 --- a/shared/sqlitedbservice.h +++ b/shared/sqlitedbservice.h @@ -23,13 +23,19 @@ class SqliteDbService public: SqliteDbService(DatabaseFactory &dbFactory); SaveFileResult saveFile(QFileInfo fileInfo, QVector &pageData, bool pathsOnly); - unsigned int getFiles(QVector &results, QString wildCardPattern, int offset, int limit); + bool deleteFile(QString path); bool fileExistsInDatabase(QString path); bool fileExistsInDatabase(QString path, qint64 mtime); bool fileExistsInDatabase(QString path, qint64 mtime, QChar filetype); + unsigned int getFiles(QVector &results, QString wildCardPattern, int offset, int limit); + bool addTag(QString tag, QString path); bool addTag(QString tag, const QVector &paths); + QVector getTags(); + QVector getTagsForPath(QString path); + bool setTags(QString path, const QSet &tags); + QVector search(const LooqsQuery &query); std::optional queryFileType(QString absPath);