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);
|
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
|
bool EntryAttributes::contains(const QString& key) const
|
||||||
{
|
{
|
||||||
return m_attributes.contains(key);
|
return m_attributes.contains(key);
|
||||||
|
@ -36,6 +36,7 @@ public:
|
|||||||
bool hasKey(const QString& key) const;
|
bool hasKey(const QString& key) const;
|
||||||
QList<QString> customKeys() const;
|
QList<QString> customKeys() const;
|
||||||
QString value(const QString& key) const;
|
QString value(const QString& key) const;
|
||||||
|
QList<QString> values(const QList<QString>& keys) const;
|
||||||
bool contains(const QString& key) const;
|
bool contains(const QString& key) const;
|
||||||
bool containsValue(const QString& value) const;
|
bool containsValue(const QString& value) const;
|
||||||
bool isProtected(const QString& key) const;
|
bool isProtected(const QString& key) const;
|
||||||
|
@ -32,21 +32,38 @@ QList<Entry*> EntrySearcher::search(const QString& searchString, const Group* ba
|
|||||||
{
|
{
|
||||||
Q_ASSERT(baseGroup);
|
Q_ASSERT(baseGroup);
|
||||||
|
|
||||||
|
parseSearchTerms(searchString);
|
||||||
|
return repeat(baseGroup, forceSearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Entry*> EntrySearcher::repeat(const Group* baseGroup, bool forceSearch)
|
||||||
|
{
|
||||||
|
Q_ASSERT(baseGroup);
|
||||||
|
|
||||||
QList<Entry*> results;
|
QList<Entry*> results;
|
||||||
for (const auto group : baseGroup->groupsRecursive(true)) {
|
for (const auto group : baseGroup->groupsRecursive(true)) {
|
||||||
if (forceSearch || group->resolveSearchingEnabled()) {
|
if (forceSearch || group->resolveSearchingEnabled()) {
|
||||||
results.append(searchEntries(searchString, group->entries()));
|
for (auto* entry : group->entries()) {
|
||||||
|
if (searchEntryImpl(entry)) {
|
||||||
|
results.append(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Entry*> EntrySearcher::searchEntries(const QString& searchString, const QList<Entry*>& entries)
|
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;
|
QList<Entry*> results;
|
||||||
for (Entry* entry : entries) {
|
for (auto* entry : entries) {
|
||||||
if (searchEntryImpl(searchString, entry)) {
|
if (searchEntryImpl(entry)) {
|
||||||
results.append(entry);
|
results.append(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,16 +80,15 @@ bool EntrySearcher::isCaseSensitive()
|
|||||||
return m_caseSensitive;
|
return m_caseSensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntrySearcher::searchEntryImpl(const QString& searchString, Entry* entry)
|
bool EntrySearcher::searchEntryImpl(Entry* entry)
|
||||||
{
|
{
|
||||||
// Pre-load in case they are needed
|
// 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());
|
auto attachments = QStringList(entry->attachments()->keys());
|
||||||
|
|
||||||
bool found;
|
bool found;
|
||||||
auto searchTerms = parseSearchTerms(searchString);
|
for (const auto& term : m_searchTerms) {
|
||||||
|
|
||||||
for (const auto& term : searchTerms) {
|
|
||||||
switch (term->field) {
|
switch (term->field) {
|
||||||
case Field::Title:
|
case Field::Title:
|
||||||
found = term->regex.match(entry->resolvePlaceholder(entry->title())).hasMatch();
|
found = term->regex.match(entry->resolvePlaceholder(entry->title())).hasMatch();
|
||||||
@ -112,10 +128,9 @@ bool EntrySearcher::searchEntryImpl(const QString& searchString, Entry* entry)
|
|||||||
return true;
|
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);
|
auto results = m_termParser.globalMatch(searchString);
|
||||||
while (results.hasNext()) {
|
while (results.hasNext()) {
|
||||||
auto result = results.next();
|
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);
|
explicit EntrySearcher(bool caseSensitive = false);
|
||||||
|
|
||||||
QList<Entry*> search(const QString& searchString, const Group* baseGroup, bool forceSearch = 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*> searchEntries(const QString& searchString, const QList<Entry*>& entries);
|
||||||
|
QList<Entry*> repeatEntries(const QList<Entry*>& entries);
|
||||||
|
|
||||||
void setCaseSensitive(bool state);
|
void setCaseSensitive(bool state);
|
||||||
bool isCaseSensitive();
|
bool isCaseSensitive();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool searchEntryImpl(const QString& searchString, Entry* entry);
|
|
||||||
|
|
||||||
enum class Field
|
enum class Field
|
||||||
{
|
{
|
||||||
Undefined,
|
Undefined,
|
||||||
@ -59,10 +60,12 @@ private:
|
|||||||
bool exclude;
|
bool exclude;
|
||||||
};
|
};
|
||||||
|
|
||||||
QList<QSharedPointer<SearchTerm>> parseSearchTerms(const QString& searchString);
|
bool searchEntryImpl(Entry* entry);
|
||||||
|
void parseSearchTerms(const QString& searchString);
|
||||||
|
|
||||||
bool m_caseSensitive;
|
bool m_caseSensitive;
|
||||||
QRegularExpression m_termParser;
|
QRegularExpression m_termParser;
|
||||||
|
QList<QSharedPointer<SearchTerm>> m_searchTerms;
|
||||||
|
|
||||||
friend class TestEntrySearcher;
|
friend class TestEntrySearcher;
|
||||||
};
|
};
|
||||||
|
@ -177,8 +177,8 @@ void TestEntrySearcher::testAllAttributesAreSearched()
|
|||||||
void TestEntrySearcher::testSearchTermParser()
|
void TestEntrySearcher::testSearchTermParser()
|
||||||
{
|
{
|
||||||
// Test standard search terms
|
// 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);
|
QCOMPARE(terms.length(), 5);
|
||||||
|
|
||||||
@ -200,7 +200,8 @@ void TestEntrySearcher::testSearchTermParser()
|
|||||||
QCOMPARE(terms[4]->word, QString("noquote"));
|
QCOMPARE(terms[4]->word, QString("noquote"));
|
||||||
|
|
||||||
// Test wildcard and regex search terms
|
// 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);
|
QCOMPARE(terms.length(), 2);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user