File indexing completed on 2024-05-19 05:26:13

0001 /*
0002  * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) version 3, or any
0008  * later version accepted by the membership of KDE e.V. (or its
0009  * successor approved by the membership of KDE e.V.), which shall
0010  * act as a proxy defined in Section 6 of version 3 of the license.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Lesser General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Lesser General Public
0018  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0019  */
0020 #include "query.h"
0021 
0022 #include <QList>
0023 #include <QDataStream>
0024 
0025 using namespace Sink;
0026 
0027 static const int registerQuery = qRegisterMetaTypeStreamOperators<Sink::QueryBase>();
0028 static const int registerQuery2 = qRegisterMetaTypeStreamOperators<Sink::Query>();
0029 static const int registerQuery3 = qRegisterMetaTypeStreamOperators<Sink::SyncScope>();
0030 
0031 QDebug operator<<(QDebug dbg, const Sink::QueryBase::Comparator &c)
0032 {
0033     if (c.comparator == Sink::Query::Comparator::Equals) {
0034         dbg.nospace() << "== " << c.value;
0035     } else if (c.comparator == Sink::Query::Comparator::Contains) {
0036         dbg.nospace() << "contains " << c.value;
0037     } else if (c.comparator == Sink::Query::Comparator::In) {
0038         dbg.nospace() << "in " << c.value;
0039     } else if (c.comparator == Sink::Query::Comparator::Fulltext) {
0040         dbg.nospace() << "fulltext contains " << c.value;
0041     } else {
0042         dbg.nospace() << "unknown comparator: " << c.value;
0043     }
0044 
0045     return dbg.space();
0046 }
0047 
0048 QDebug operator<<(QDebug dbg, const Sink::QueryBase::Filter &filter)
0049 {
0050     if (filter.ids.isEmpty()) {
0051         dbg.nospace() << "Filter(" << filter.propertyFilter << ")";
0052     } else {
0053         dbg.nospace() << "Filter(" << filter.ids << ")";
0054     }
0055     return dbg.maybeSpace();
0056 }
0057 
0058 QDebug operator<<(QDebug dbg, const Sink::QueryBase &query)
0059 {
0060     dbg.nospace() << "Query [" << query.type() << "] << Id: " << query.id() << "\n";
0061     dbg.nospace() << "  Filter: " << query.getBaseFilters() << "\n";
0062     dbg.nospace() << "  Ids: " << query.ids() << "\n";
0063     dbg.nospace() << "  Sorting: " << query.sortProperty() << "\n";
0064     return dbg.maybeSpace();
0065 }
0066 
0067 QDebug operator<<(QDebug dbg, const Sink::Query &query)
0068 {
0069     dbg << static_cast<Sink::QueryBase>(query);
0070     dbg.nospace() << "  Requested: " << query.requestedProperties << "\n";
0071     dbg.nospace() << "  Parent: " << query.parentProperty() << "\n";
0072     dbg.nospace() << "  IsLive: " << query.liveQuery() << "\n";
0073     dbg.nospace() << "  ResourceFilter: " << query.getResourceFilter() << "\n";
0074     dbg.nospace() << "  limit: " << query.limit() << "\n";
0075     return dbg.maybeSpace();
0076 }
0077 
0078 QDataStream & operator<< (QDataStream &stream, const Sink::QueryBase::Comparator &comparator)
0079 {
0080     stream << comparator.comparator;
0081     stream << comparator.value;
0082     return stream;
0083 }
0084 
0085 QDataStream & operator>> (QDataStream &stream, Sink::QueryBase::Comparator &comparator)
0086 {
0087     int c;
0088     stream >> c;
0089     comparator.comparator = static_cast<Sink::QueryBase::Comparator::Comparators>(c);
0090     stream >> comparator.value;
0091     return stream;
0092 }
0093 
0094 QDataStream & operator<< (QDataStream &stream, const Sink::QueryBase::Filter &filter)
0095 {
0096     stream << filter.ids;
0097     stream << filter.propertyFilter;
0098     return stream;
0099 }
0100 
0101 QDataStream & operator>> (QDataStream &stream, Sink::QueryBase::Filter &filter)
0102 {
0103     stream >> filter.ids;
0104     stream >> filter.propertyFilter;
0105     return stream;
0106 }
0107 
0108 QDataStream & operator<< (QDataStream &stream, const Sink::QueryBase &query)
0109 {
0110     stream << query.type();
0111     stream << query.sortProperty();
0112     stream << query.getFilter();
0113     return stream;
0114 }
0115 
0116 QDataStream & operator>> (QDataStream &stream, Sink::QueryBase &query)
0117 {
0118     QByteArray type;
0119     stream >> type;
0120     query.setType(type);
0121     QByteArray sortProperty;
0122     stream >> sortProperty;
0123     query.setSortProperty(sortProperty);
0124     Sink::QueryBase::Filter filter;
0125     stream >> filter;
0126     query.setFilter(filter);
0127     return stream;
0128 }
0129 
0130 bool QueryBase::Filter::operator==(const QueryBase::Filter &other) const
0131 {
0132     auto ret = ids == other.ids && propertyFilter == other.propertyFilter;
0133     return ret;
0134 }
0135 
0136 bool QueryBase::operator==(const QueryBase &other) const
0137 {
0138     auto ret = mType == other.mType
0139         && mSortProperty == other.mSortProperty
0140         && mBaseFilterStage == other.mBaseFilterStage
0141         && mId == mId
0142         && mLimit == other.mLimit;
0143     return ret;
0144 }
0145 
0146 QueryBase::Comparator::Comparator() : comparator(Invalid)
0147 {
0148 }
0149 
0150 QueryBase::Comparator::Comparator(const QVariant &v) : value(v), comparator(Equals)
0151 {
0152 }
0153 
0154 QueryBase::Comparator::Comparator(const QVariant &v, Comparators c) : value(v), comparator(c)
0155 {
0156 }
0157 
0158 bool QueryBase::Comparator::matches(const QVariant &v) const
0159 {
0160     switch(comparator) {
0161         case Equals:
0162             if (!v.isValid()) {
0163                 if (!value.isValid()) {
0164                     return true;
0165                 }
0166                 return false;
0167             }
0168             return v == value;
0169         case Contains:
0170             if (!v.isValid()) {
0171                 return false;
0172             }
0173             return v.value<QByteArrayList>().contains(value.toByteArray());
0174         case In:
0175             if (!v.isValid()) {
0176                 return false;
0177             }
0178             return value.value<QByteArrayList>().contains(v.toByteArray());
0179         case Within: {
0180             auto range = value.value<QList<QVariant>>();
0181             if (range.size() < 2) {
0182                 return false;
0183             }
0184 
0185             return range[0] <= v && v <= range[1];
0186         }
0187         case Overlap: {
0188             auto bounds = value.value<QList<QVariant>>();
0189             if (bounds.size() < 2) {
0190                 return false;
0191             }
0192 
0193             auto range = v.value<QList<QVariant>>();
0194             if (range.size() < 2) {
0195                 return false;
0196             }
0197 
0198             return range[0] <= bounds[1] && bounds[0] <= range[1];
0199         }
0200         case Fulltext:
0201         case Invalid:
0202         default:
0203             break;
0204     }
0205     return false;
0206 }
0207 
0208 bool Query::Comparator::operator==(const Query::Comparator &other) const
0209 {
0210     return value == other.value && comparator == other.comparator;
0211 }
0212 
0213 bool Query::operator==(const Query &other) const
0214 {
0215     const auto ret = mResourceFilter == other.mResourceFilter
0216         && mFlags == other.mFlags
0217         && mParentProperty == other.mParentProperty
0218         && QueryBase::operator==(other);
0219 
0220     return ret;
0221 }