New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/extended search #36
Merged
luisangelsm
merged 32 commits into
YACReader:develop
from
iain-benson:feature/extended_search
Jan 14, 2021
Merged
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
d3de52c
Add commit 43aab01 of BenHanson/lexertl14 from github
iain-benson 4a50d43
Add query parser class
iain-benson 5fa7da1
Add folder into the query parser
iain-benson 673ee1f
Use the query parser in the comic and folder model
iain-benson 30529dc
Some small tidy ups
iain-benson 9a66035
Add some documentation and attribution to the query parser
iain-benson 7ccb338
Apply clang-format
luisangelsm 2d3888b
Fix scopes
luisangelsm 4990093
Remove c++17 dependency
luisangelsm 8efb991
Use concatenation, rather than ostringstream
iain-benson 255e51d
Fix binding values to search query
luisangelsm 6438c92
Move query execution and model setup to the right scope
luisangelsm 5037f3a
Fix data base removal in FolderModel
luisangelsm a777aa3
Replace lexertl with a custom lexeter implementation
luisangelsm ddb140d
Remove misplaced code
luisangelsm f09c595
Remove space and atWord tokens
luisangelsm 260f538
Use an explicit constructor for TreeNode
luisangelsm 7b36100
Use QString::fromStdString
luisangelsm fa5ce25
Add concurrent queue based on lambdas
luisangelsm dbdc7bd
Add a class for processing search queries and create the comics model…
luisangelsm ccc382d
Use ComicQueryResultProcesor
luisangelsm 047fd24
Make the search line edit bigger
luisangelsm 5343d24
Run folder search filtering in the background
luisangelsm c3b0780
Remove unused constant
luisangelsm dde60b7
YACReaderLibrary compiles using c++11 just fine
luisangelsm f803b54
Add support for boolean folder fields
luisangelsm f03ad84
Add support for `true` and `false` literals to be used with bool fields
luisangelsm 82eb5c0
Add fallback for qt < 5.15
luisangelsm 24c0a78
Remove reference to lexertl's license
luisangelsm 6bb64c5
Import non-gui global header
luisangelsm 76a307d
Remove comments
luisangelsm 7e72c8b
Update CHANGELOG
luisangelsm File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
#include "comic_query_result_procesor.h" | ||
|
||
#include "comic_item.h" | ||
#include "comic_model.h" | ||
#include "data_base_management.h" | ||
#include "qnaturalsorting.h" | ||
#include "db_helper.h" | ||
#include "query_parser.h" | ||
|
||
#include "QsLog.h" | ||
|
||
QString getLastExecutedQuery(const QSqlQuery &query) | ||
{ | ||
QString str = query.lastQuery(); | ||
QMapIterator<QString, QVariant> it(query.boundValues()); | ||
while (it.hasNext()) { | ||
it.next(); | ||
str.replace(it.key(), it.value().toString()); | ||
} | ||
return str; | ||
} | ||
|
||
YACReader::ComicQueryResultProcesor::ComicQueryResultProcesor() | ||
: querySearchQueue(1) | ||
{ | ||
} | ||
|
||
void YACReader::ComicQueryResultProcesor::createModelData(const YACReader::SearchModifiers modifier, const QString &filter, const QString &databasePath) | ||
{ | ||
querySearchQueue.cancellPending(); | ||
|
||
querySearchQueue.enqueue([=] { | ||
QString connectionName = ""; | ||
{ | ||
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); | ||
QSqlQuery selectQuery(db); | ||
|
||
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 "); | ||
|
||
try { | ||
QueryParser parser; | ||
auto result = parser.parse(filter.toStdString()); | ||
result.buildSqlString(queryString); | ||
|
||
switch (modifier) { | ||
case YACReader::NoModifiers: | ||
queryString += " LIMIT :limit"; | ||
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(queryString.c_str()); | ||
selectQuery.bindValue(":limit", 500); //TODO, load this value from settings | ||
result.bindValues(selectQuery); | ||
|
||
selectQuery.exec(); | ||
|
||
auto data = modelData(selectQuery); | ||
|
||
emit newData(data, databasePath); | ||
} catch (const std::exception &e) { | ||
//Do nothing, uncomplete search string will end here and it is part of how the QueryParser works | ||
//I don't like the idea of using exceptions for this though | ||
} | ||
|
||
connectionName = db.connectionName(); | ||
} | ||
QSqlDatabase::removeDatabase(connectionName); | ||
}); | ||
} | ||
|
||
QList<ComicItem *> *YACReader::ComicQueryResultProcesor::modelData(QSqlQuery &sqlquery) | ||
{ | ||
auto list = new QList<ComicItem *>(); | ||
|
||
int numColumns = sqlquery.record().count(); | ||
|
||
while (sqlquery.next()) { | ||
QList<QVariant> data; | ||
|
||
for (int i = 0; i < numColumns; i++) | ||
data << sqlquery.value(i); | ||
|
||
list->append(new ComicItem(data)); | ||
} | ||
|
||
std::sort(list->begin(), list->end(), [](const ComicItem *c1, const ComicItem *c2) { | ||
if (c1->data(ComicModel::Number).isNull() && c2->data(ComicModel::Number).isNull()) { | ||
return naturalSortLessThanCI(c1->data(ComicModel::FileName).toString(), c2->data(ComicModel::FileName).toString()); | ||
} else { | ||
if (c1->data(ComicModel::Number).isNull() == false && c2->data(ComicModel::Number).isNull() == false) { | ||
return c1->data(ComicModel::Number).toInt() < c2->data(ComicModel::Number).toInt(); | ||
} else { | ||
return c2->data(ComicModel::Number).isNull(); | ||
} | ||
} | ||
}); | ||
|
||
return list; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#ifndef COMIC_QUERY_RESULT_PROCESOR_H | ||
#define COMIC_QUERY_RESULT_PROCESOR_H | ||
|
||
#include <QtCore> | ||
#include <QSqlQuery> | ||
|
||
#include "yacreader_global.h" | ||
#include "concurrent_queue.h" | ||
|
||
class ComicItem; | ||
|
||
namespace YACReader { | ||
|
||
class ComicQueryResultProcesor : public QObject | ||
{ | ||
Q_OBJECT | ||
public: | ||
ComicQueryResultProcesor(); | ||
|
||
public slots: | ||
void createModelData(const SearchModifiers modifier, const QString &filter, const QString &databasePath); | ||
signals: | ||
void newData(QList<ComicItem *> *, const QString &); | ||
|
||
private: | ||
ConcurrentQueue querySearchQueue; | ||
|
||
QList<ComicItem *> *modelData(QSqlQuery &sqlquery); | ||
}; | ||
}; | ||
|
||
#endif // COMIC_QUERY_RESULT_PROCESOR_H |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this line left here by mistake? It spams error messages every time the search edit's text changes to a non-empty value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, my bad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this line be removed or converted to
QLOG_TRACE
orQLOG_DEBUG
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed, I used that log to catch some issues while I was working on this PR but it doesn't have a purpose anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed in #194.