File indexing completed on 2024-05-19 05:11:52
0001 /* 0002 * This file is part of the KDE Akonadi Search Project 0003 * SPDX-FileCopyrightText: 2014-2024 Laurent Montel <montel@kde.org> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 * 0007 */ 0008 0009 #include <xapian.h> 0010 0011 #include "akonadi_search_pim_debug.h" 0012 #include "notequery.h" 0013 #include "resultiterator_p.h" 0014 0015 #include <QDebug> 0016 #include <QFile> 0017 #include <QList> 0018 #include <QStandardPaths> 0019 0020 using namespace Akonadi::Search::PIM; 0021 0022 class Akonadi::Search::PIM::NoteQueryPrivate 0023 { 0024 public: 0025 NoteQueryPrivate() = default; 0026 0027 QString title; 0028 QString note; 0029 int limit = 0; 0030 }; 0031 0032 NoteQuery::NoteQuery() 0033 : Query() 0034 , d(new NoteQueryPrivate) 0035 { 0036 } 0037 0038 NoteQuery::~NoteQuery() = default; 0039 0040 void NoteQuery::matchTitle(const QString &title) 0041 { 0042 d->title = title; 0043 } 0044 0045 void NoteQuery::matchNote(const QString ¬e) 0046 { 0047 d->note = note; 0048 } 0049 0050 void NoteQuery::setLimit(int limit) 0051 { 0052 d->limit = limit; 0053 } 0054 0055 int NoteQuery::limit() const 0056 { 0057 return d->limit; 0058 } 0059 0060 ResultIterator NoteQuery::exec() 0061 { 0062 const QString dir = defaultLocation(QStringLiteral("notes")); 0063 0064 Xapian::Database db; 0065 try { 0066 db = Xapian::Database(QFile::encodeName(dir).toStdString()); 0067 } catch (const Xapian::DatabaseOpeningError &) { 0068 qCWarning(AKONADI_SEARCH_PIM_LOG) << "Xapian Database does not exist at " << dir; 0069 return {}; 0070 } catch (const Xapian::DatabaseCorruptError &) { 0071 qCWarning(AKONADI_SEARCH_PIM_LOG) << "Xapian Database corrupted"; 0072 return {}; 0073 } catch (const Xapian::DatabaseError &e) { 0074 qCWarning(AKONADI_SEARCH_PIM_LOG) << "Failed to open Xapian database:" << QString::fromStdString(e.get_error_string()); 0075 return {}; 0076 } catch (...) { 0077 qCWarning(AKONADI_SEARCH_PIM_LOG) << "Random exception, but we do not want to crash"; 0078 return {}; 0079 } 0080 0081 QList<Xapian::Query> m_queries; 0082 0083 if (!d->note.isEmpty()) { 0084 Xapian::QueryParser parser; 0085 parser.set_database(db); 0086 parser.add_prefix("", "BO"); 0087 0088 const QByteArray baNote = d->note.toUtf8(); 0089 m_queries << parser.parse_query(baNote.constData(), Xapian::QueryParser::FLAG_PARTIAL); 0090 } 0091 0092 if (!d->title.isEmpty()) { 0093 Xapian::QueryParser parser; 0094 parser.set_database(db); 0095 parser.add_prefix("", "SU"); 0096 parser.set_default_op(Xapian::Query::OP_AND); 0097 0098 const QByteArray baTitle = d->title.toUtf8(); 0099 m_queries << parser.parse_query(baTitle.constData(), Xapian::QueryParser::FLAG_PARTIAL); 0100 } 0101 try { 0102 Xapian::Query query(Xapian::Query::OP_OR, m_queries.begin(), m_queries.end()); 0103 // qDebug() << query.get_description().c_str(); 0104 0105 Xapian::Enquire enquire(db); 0106 enquire.set_query(query); 0107 0108 if (d->limit == 0) { 0109 d->limit = 10000; 0110 } 0111 0112 Xapian::MSet matches = enquire.get_mset(0, d->limit); 0113 0114 ResultIterator iter; 0115 iter.d->init(matches); 0116 return iter; 0117 } catch (const Xapian::Error &e) { 0118 qCWarning(AKONADI_SEARCH_PIM_LOG) << QString::fromStdString(e.get_type()) << QString::fromStdString(e.get_description()); 0119 return {}; 0120 } 0121 }