File indexing completed on 2024-05-19 16:38:20

0001 /*
0002     SPDX-FileCopyrightText: 2015, 2016 Ivan Cukic <ivan.cukic(at)kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "query.h"
0008 #include "common/specialvalues.h"
0009 #include <QDate>
0010 #include <QDebug>
0011 
0012 namespace KActivities
0013 {
0014 namespace Stats
0015 {
0016 namespace details
0017 {
0018 inline void validateTypes(QStringList &types)
0019 {
0020     // Nothing at the moment
0021     Q_UNUSED(types);
0022 }
0023 
0024 inline void validateAgents(QStringList &agents)
0025 {
0026     // Nothing at the moment
0027     Q_UNUSED(agents);
0028 }
0029 
0030 inline void validateActivities(QStringList &activities)
0031 {
0032     // Nothing at the moment
0033     Q_UNUSED(activities);
0034 }
0035 
0036 inline void validateUrlFilters(QStringList &urlFilters)
0037 {
0038     auto i = urlFilters.begin();
0039     const auto end = urlFilters.end();
0040 
0041     for (; i != end; ++i) {
0042         i->replace(QLatin1String("'"), QLatin1String(""));
0043     }
0044 }
0045 
0046 } // namespace details
0047 
0048 class QueryPrivate
0049 {
0050 public:
0051     QueryPrivate()
0052         : ordering(Terms::HighScoredFirst)
0053         , limit(0)
0054         , offset(0)
0055     {
0056     }
0057 
0058     Terms::Select selection;
0059     QStringList types;
0060     QStringList agents;
0061     QStringList activities;
0062     QStringList urlFilters;
0063     Terms::Order ordering;
0064     QDate start, end;
0065     int limit;
0066     int offset;
0067 };
0068 
0069 Query::Query(Terms::Select selection)
0070     : d(new QueryPrivate())
0071 {
0072     d->selection = selection;
0073 }
0074 
0075 Query::Query(Query &&source)
0076     : d(nullptr)
0077 {
0078     std::swap(d, source.d);
0079 }
0080 
0081 Query::Query(const Query &source)
0082     : d(new QueryPrivate(*source.d))
0083 {
0084 }
0085 
0086 Query &Query::operator=(Query source)
0087 {
0088     std::swap(d, source.d);
0089     return *this;
0090 }
0091 
0092 Query::~Query()
0093 {
0094     delete d;
0095 }
0096 
0097 bool Query::operator==(const Query &right) const
0098 {
0099     /* clang-format off */
0100     return selection() == right.selection()
0101         && types() == right.types()
0102         && agents() == right.agents()
0103         && activities() == right.activities()
0104         && selection() == right.selection()
0105         && urlFilters() == right.urlFilters()
0106         && dateStart() == right.dateStart()
0107         && dateEnd() == right.dateEnd();
0108     /* clang-format on */
0109 }
0110 
0111 bool Query::operator!=(const Query &right) const
0112 {
0113     return !(*this == right);
0114 }
0115 
0116 #define IMPLEMENT_QUERY_LIST_FIELD(WHAT, What, Term, Default)                                                                                                  \
0117     void Query::add##WHAT(const QStringList &What)                                                                                                             \
0118     {                                                                                                                                                          \
0119         d->What << What;                                                                                                                                       \
0120         details::validate##WHAT(d->What);                                                                                                                      \
0121     }                                                                                                                                                          \
0122                                                                                                                                                                \
0123     void Query::set##WHAT(const Terms::Term &What)                                                                                                             \
0124     {                                                                                                                                                          \
0125         d->What = What.values;                                                                                                                                 \
0126         details::validate##WHAT(d->What);                                                                                                                      \
0127     }                                                                                                                                                          \
0128                                                                                                                                                                \
0129     QStringList Query::What() const                                                                                                                            \
0130     {                                                                                                                                                          \
0131         return d->What.size() ? d->What : Default;                                                                                                             \
0132     }                                                                                                                                                          \
0133                                                                                                                                                                \
0134     void Query::clear##WHAT()                                                                                                                                  \
0135     {                                                                                                                                                          \
0136         d->What.clear();                                                                                                                                       \
0137     }
0138 
0139 IMPLEMENT_QUERY_LIST_FIELD(Types, types, Type, QStringList(ANY_TYPE_TAG))
0140 IMPLEMENT_QUERY_LIST_FIELD(Agents, agents, Agent, QStringList(CURRENT_AGENT_TAG))
0141 IMPLEMENT_QUERY_LIST_FIELD(Activities, activities, Activity, QStringList(CURRENT_ACTIVITY_TAG))
0142 IMPLEMENT_QUERY_LIST_FIELD(UrlFilters, urlFilters, Url, QStringList(QStringLiteral("*")))
0143 
0144 #undef IMPLEMENT_QUERY_LIST_FIELD
0145 
0146 void Query::setOrdering(Terms::Order ordering)
0147 {
0148     d->ordering = ordering;
0149 }
0150 
0151 void Query::setSelection(Terms::Select selection)
0152 {
0153     d->selection = selection;
0154 }
0155 
0156 void Query::setLimit(int limit)
0157 {
0158     d->limit = limit;
0159 }
0160 
0161 void Query::setOffset(int offset)
0162 {
0163     d->offset = offset;
0164 }
0165 
0166 void Query::setDate(const Terms::Date &date)
0167 {
0168     d->start = date.start;
0169     d->end = date.end;
0170 }
0171 
0172 void Query::setDateStart(QDate start)
0173 {
0174     d->start = start;
0175 }
0176 
0177 void Query::setDateEnd(QDate end)
0178 {
0179     d->end = end;
0180 }
0181 
0182 Terms::Order Query::ordering() const
0183 {
0184     return d->ordering;
0185 }
0186 
0187 Terms::Select Query::selection() const
0188 {
0189     return d->selection;
0190 }
0191 
0192 int Query::limit() const
0193 {
0194     return d->limit;
0195 }
0196 
0197 int Query::offset() const
0198 {
0199     Q_ASSERT_X(d->limit > 0, "Query::offset", "Offset can only be specified if limit is set");
0200     return d->offset;
0201 }
0202 
0203 QDate Query::dateStart() const
0204 {
0205     return d->start;
0206 }
0207 
0208 QDate Query::dateEnd() const
0209 {
0210     return d->end;
0211 }
0212 
0213 } // namespace Stats
0214 } // namespace KActivities
0215 
0216 namespace KAStats = KActivities::Stats;
0217 
0218 QDebug operator<<(QDebug dbg, const KAStats::Query &query)
0219 {
0220     using namespace KAStats::Terms;
0221 
0222     /* clang-format off */
0223     dbg.nospace()
0224         << "Query { "
0225         << query.selection()
0226         << ", " << Type(query.types())
0227         << ", " << Agent(query.agents())
0228         << ", " << Activity(query.activities())
0229         << ", " << Url(query.urlFilters())
0230         << ", " << Date(query.dateStart(), query.dateEnd())
0231         << ", " << query.ordering()
0232         << ", Limit: " << query.limit()
0233         << " }";
0234     /* clang-format on */
0235 
0236     return dbg;
0237 }