mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Updates to EntrySearcher
* Only search custom named attributes * Search attribute values in addition to keys * Optimize search process
This commit is contained in:
parent
5cf50d9fae
commit
d0d1b25e5c
@ -67,6 +67,15 @@ QString EntryAttributes::value(const QString& key) const
|
||||
return m_attributes.value(key);
|
||||
}
|
||||
|
||||
QList<QString> EntryAttributes::values(const QList<QString>& keys) const
|
||||
{
|
||||
QList<QString> values;
|
||||
for (const QString& key : keys) {
|
||||
values.append(m_attributes.value(key));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
bool EntryAttributes::contains(const QString& key) const
|
||||
{
|
||||
return m_attributes.contains(key);
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
bool hasKey(const QString& key) const;
|
||||
QList<QString> customKeys() const;
|
||||
QString value(const QString& key) const;
|
||||
QList<QString> values(const QList<QString>& keys) const;
|
||||
bool contains(const QString& key) const;
|
||||
bool containsValue(const QString& value) const;
|
||||
bool isProtected(const QString& key) const;
|
||||
|
@ -32,21 +32,38 @@ QList<Entry*> EntrySearcher::search(const QString& searchString, const Group* ba
|
||||
{
|
||||
Q_ASSERT(baseGroup);
|
||||
|
||||
parseSearchTerms(searchString);
|
||||
return repeat(baseGroup, forceSearch);
|
||||
}
|
||||
|
||||
QList<Entry*> EntrySearcher::repeat(const Group* baseGroup, bool forceSearch)
|
||||
{
|
||||
Q_ASSERT(baseGroup);
|
||||
|
||||
QList<Entry*> results;
|
||||
for (const auto group : baseGroup->groupsRecursive(true)) {
|
||||
if (forceSearch || group->resolveSearchingEnabled()) {
|
||||
results.append(searchEntries(searchString, group->entries()));
|
||||
for (auto* entry : group->entries()) {
|
||||
if (searchEntryImpl(entry)) {
|
||||
results.append(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
QList<Entry*> EntrySearcher::searchEntries(const QString& searchString, const QList<Entry*>& entries)
|
||||
{
|
||||
parseSearchTerms(searchString);
|
||||
return repeatEntries(entries);
|
||||
}
|
||||
|
||||
QList<Entry*> EntrySearcher::repeatEntries(const QList<Entry*>& entries)
|
||||
{
|
||||
QList<Entry*> results;
|
||||
for (Entry* entry : entries) {
|
||||
if (searchEntryImpl(searchString, entry)) {
|
||||
for (auto* entry : entries) {
|
||||
if (searchEntryImpl(entry)) {
|
||||
results.append(entry);
|
||||
}
|
||||
}
|
||||
@ -63,16 +80,15 @@ bool EntrySearcher::isCaseSensitive()
|
||||
return m_caseSensitive;
|
||||
}
|
||||
|
||||
bool EntrySearcher::searchEntryImpl(const QString& searchString, Entry* entry)
|
||||
bool EntrySearcher::searchEntryImpl(Entry* entry)
|
||||
{
|
||||
// Pre-load in case they are needed
|
||||
auto attributes = QStringList(entry->attributes()->keys());
|
||||
auto attributes_keys = entry->attributes()->customKeys();
|
||||
auto attributes = QStringList(attributes_keys + entry->attributes()->values(attributes_keys));
|
||||
auto attachments = QStringList(entry->attachments()->keys());
|
||||
|
||||
bool found;
|
||||
auto searchTerms = parseSearchTerms(searchString);
|
||||
|
||||
for (const auto& term : searchTerms) {
|
||||
for (const auto& term : m_searchTerms) {
|
||||
switch (term->field) {
|
||||
case Field::Title:
|
||||
found = term->regex.match(entry->resolvePlaceholder(entry->title())).hasMatch();
|
||||
@ -112,10 +128,9 @@ bool EntrySearcher::searchEntryImpl(const QString& searchString, Entry* entry)
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<QSharedPointer<EntrySearcher::SearchTerm>> EntrySearcher::parseSearchTerms(const QString& searchString)
|
||||
void EntrySearcher::parseSearchTerms(const QString& searchString)
|
||||
{
|
||||
auto terms = QList<QSharedPointer<SearchTerm>>();
|
||||
|
||||
m_searchTerms.clear();
|
||||
auto results = m_termParser.globalMatch(searchString);
|
||||
while (results.hasNext()) {
|
||||
auto result = results.next();
|
||||
@ -165,8 +180,6 @@ QList<QSharedPointer<EntrySearcher::SearchTerm>> EntrySearcher::parseSearchTerms
|
||||
}
|
||||
}
|
||||
|
||||
terms.append(term);
|
||||
m_searchTerms.append(term);
|
||||
}
|
||||
|
||||
return terms;
|
||||
}
|
||||
|
@ -31,14 +31,15 @@ public:
|
||||
explicit EntrySearcher(bool caseSensitive = false);
|
||||
|
||||
QList<Entry*> search(const QString& searchString, const Group* baseGroup, bool forceSearch = false);
|
||||
QList<Entry*> repeat(const Group* baseGroup, bool forceSearch = false);
|
||||
|
||||
QList<Entry*> searchEntries(const QString& searchString, const QList<Entry*>& entries);
|
||||
QList<Entry*> repeatEntries(const QList<Entry*>& entries);
|
||||
|
||||
void setCaseSensitive(bool state);
|
||||
bool isCaseSensitive();
|
||||
|
||||
private:
|
||||
bool searchEntryImpl(const QString& searchString, Entry* entry);
|
||||
|
||||
enum class Field
|
||||
{
|
||||
Undefined,
|
||||
@ -59,10 +60,12 @@ private:
|
||||
bool exclude;
|
||||
};
|
||||
|
||||
QList<QSharedPointer<SearchTerm>> parseSearchTerms(const QString& searchString);
|
||||
bool searchEntryImpl(Entry* entry);
|
||||
void parseSearchTerms(const QString& searchString);
|
||||
|
||||
bool m_caseSensitive;
|
||||
QRegularExpression m_termParser;
|
||||
QList<QSharedPointer<SearchTerm>> m_searchTerms;
|
||||
|
||||
friend class TestEntrySearcher;
|
||||
};
|
||||
|
@ -177,8 +177,8 @@ void TestEntrySearcher::testAllAttributesAreSearched()
|
||||
void TestEntrySearcher::testSearchTermParser()
|
||||
{
|
||||
// Test standard search terms
|
||||
auto terms =
|
||||
m_entrySearcher.parseSearchTerms("-test \"quoted \\\"string\\\"\" user:user pass:\"test me\" noquote ");
|
||||
m_entrySearcher.parseSearchTerms("-test \"quoted \\\"string\\\"\" user:user pass:\"test me\" noquote ");
|
||||
auto terms = m_entrySearcher.m_searchTerms;
|
||||
|
||||
QCOMPARE(terms.length(), 5);
|
||||
|
||||
@ -200,7 +200,8 @@ void TestEntrySearcher::testSearchTermParser()
|
||||
QCOMPARE(terms[4]->word, QString("noquote"));
|
||||
|
||||
// Test wildcard and regex search terms
|
||||
terms = m_entrySearcher.parseSearchTerms("+url:*.google.com *user:\\d+\\w{2}");
|
||||
m_entrySearcher.parseSearchTerms("+url:*.google.com *user:\\d+\\w{2}");
|
||||
terms = m_entrySearcher.m_searchTerms;
|
||||
|
||||
QCOMPARE(terms.length(), 2);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user