diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index 7fee8000..5f795e6a 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -9,6 +9,7 @@ #include "qnaturalsorting.h" #include "comic_db.h" #include "db_helper.h" +#include "query_parser.h" //ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read #include "QsLog.h" @@ -607,40 +608,40 @@ void ComicModel::setupModelData(const SearchModifiers modifier, const QString &f QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); QSqlQuery selectQuery(db); - switch (modifier) { - case YACReader::NoModifiers: - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " - "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " - "WHERE UPPER(ci.title) LIKE UPPER(:filter) OR UPPER(c.fileName) LIKE UPPER(:filter) LIMIT :limit"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":limit", 500); //TODO, load this value from settings - break; + std::string queryString("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " + "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) LEFT JOIN folder f ON (f.id == c.parentId) WHERE "); - case YACReader::OnlyRead: - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " - "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " - "WHERE (UPPER(ci.title) LIKE UPPER(:filter) OR UPPER(c.fileName) LIKE UPPER(:filter)) AND ci.read = 1 LIMIT :limit"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":limit", 500); //TODO, load this value from settings - break; + try { + QueryParser parser; + auto result = parser.parse(filter.toStdString()); + result.buildSqlString(queryString); - case YACReader::OnlyUnread: - selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened " - "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " - "WHERE (UPPER(ci.title) LIKE UPPER(:filter) OR UPPER(c.fileName) LIKE UPPER(:filter)) AND ci.read = 0 LIMIT :limit"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":limit", 500); //TODO, load this value from settings - break; + switch (modifier) { + case YACReader::NoModifiers: + queryString += "LIMIT :limit"; + break; - default: - QLOG_ERROR() << "not implemented"; - break; + case YACReader::OnlyRead: + queryString += "AND ci.read = 1 LIMIT :limit"; + break; + + case YACReader::OnlyUnread: + queryString += "AND ci.read = 0 LIMIT :limit"; + break; + + default: + queryString += "LIMIT :limit"; + QLOG_ERROR() << "not implemented"; + break; + } + selectQuery.prepare(QString(queryString.c_str())); + selectQuery.bindValue(":limit", 500); //TODO, load this value from settings + result.bindValues(selectQuery); + } catch (const std::exception &e) { + QLOG_ERROR() << "Unable to parse query: " << e.what(); } - selectQuery.exec(); - QLOG_DEBUG() << selectQuery.lastError() << "--"; - setupModelData(selectQuery); connectionName = db.connectionName(); } diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 640462d7..902ada19 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -55,6 +55,7 @@ #include "qnaturalsorting.h" #include "yacreader_global_gui.h" #include "QsLog.h" +#include "query_parser.h" #ifdef Q_OS_MAC #include @@ -689,37 +690,43 @@ void FolderModelProxy::setupFilteredModelData() selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name "); selectQuery.bindValue(":filter", "%%" + filter + "%%"); } else { - switch (modifier) { - case YACReader::NoModifiers: - selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " + std::string queryString("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " "FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) " - "WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) ORDER BY f.parentId,f.name"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":filter2", "%%" + filter + "%%"); - break; + "INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) WHERE "); - case YACReader::OnlyRead: - selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " - "FROM folder f LEFT JOIN (comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)) ON (f.id = c.parentId) " - "WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) AND ci.read = 1 ORDER BY f.parentId,f.name;"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":filter2", "%%" + filter + "%%"); - break; + try { + QueryParser parser; + auto result = parser.parse(filter.toStdString()); + result.buildSqlString(queryString); - case YACReader::OnlyUnread: - selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed " - "FROM folder f LEFT JOIN (comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)) ON (f.id = c.parentId) " - "WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) AND ci.read = 0 ORDER BY f.parentId,f.name;"); - selectQuery.bindValue(":filter", "%%" + filter + "%%"); - selectQuery.bindValue(":filter2", "%%" + filter + "%%"); - break; + switch (modifier) { + case YACReader::NoModifiers: + queryString += "AND f.id <> 1 ORDER BY f.parentId,f.name"; + break; - default: - QLOG_ERROR() << "not implemented"; - break; + case YACReader::OnlyRead: + queryString += "AND f.id <> 1 AND ci.read = 1 ORDER BY f.parentId,f.name"; + break; + + case YACReader::OnlyUnread: + queryString += "AND f.id <> 1 AND ci.read = 0 ORDER BY f.parentId,f.name"; + break; + + default: + queryString += "AND f.id <> 1 ORDER BY f.parentId,f.name"; + QLOG_ERROR() << "not implemented"; + break; + } + + selectQuery.prepare(QString(queryString.c_str())); + result.bindValues(selectQuery); + + } catch (const std::exception &e) { + QLOG_ERROR() << "Unable to parse query: " << e.what(); } } selectQuery.exec(); + QLOG_DEBUG() << selectQuery.lastError() << "--"; setupFilteredModelData(selectQuery, rootItem); connectionName = db.connectionName();