File indexing completed on 2024-05-26 05:27:32

0001 /*
0002  *   Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm>
0003  *
0004  *   This program is free software; you can redistribute it and/or modify
0005  *   it under the terms of the GNU General Public License as published by
0006  *   the Free Software Foundation; either version 2 of the License, or
0007  *   (at your option) any later version.
0008  *
0009  *   This program is distributed in the hope that it will be useful,
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *   GNU General Public License for more details.
0013  *
0014  *   You should have received a copy of the GNU General Public License
0015  *   along with this program; if not, write to the
0016  *   Free Software Foundation, Inc.,
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
0018  */
0019 
0020 #include "typeindex.h"
0021 #include <QMap>
0022 
0023 template <typename T, typename First>
0024 void mergeImpl(T &map, First f)
0025 {
0026     for (auto it = f.constBegin(); it != f.constEnd(); it++) {
0027         map.insert(it.key(), it.value());
0028     }
0029 }
0030 
0031 template <typename T, typename First, typename ... Tail>
0032 void mergeImpl(T &map, First f, Tail ...maps)
0033 {
0034     for (auto it = f.constBegin(); it != f.constEnd(); it++) {
0035         map.insert(it.key(), it.value());
0036     }
0037     mergeImpl<T, Tail...>(map, maps...);
0038 }
0039 
0040 template <typename First, typename ... Tail>
0041 First merge(First f, Tail ...maps)
0042 {
0043     First map;
0044     mergeImpl(map, f, maps...);
0045     return map;
0046 }
0047 
0048 template <typename Property>
0049 class ValueIndex
0050 {
0051 public:
0052     static void configure(TypeIndex &index)
0053     {
0054         index.addProperty<Property>();
0055     }
0056 
0057     template <typename EntityType>
0058     static QMap<QByteArray, int> databases()
0059     {
0060         return {{QByteArray{EntityType::name} +".index." + Property::name, Sink::Storage::AllowDuplicates}};
0061     }
0062 };
0063 
0064 
0065 template <typename Property, typename SortProperty = void>
0066 class SortedIndex
0067 {
0068 public:
0069     static void configure(TypeIndex &index)
0070     {
0071         index.addPropertyWithSorting<Property, SortProperty>();
0072     }
0073 
0074     template <typename EntityType>
0075     static QMap<QByteArray, int> databases()
0076     {
0077         return {{QByteArray{EntityType::name} +".index." + Property::name + ".sort." + SortProperty::name, Sink::Storage::AllowDuplicates}};
0078     }
0079 };
0080 
0081 template <typename SortProperty>
0082 class SortedIndex<SortProperty, void>
0083 {
0084 public:
0085     static void configure(TypeIndex &index)
0086     {
0087         index.addSortedProperty<SortProperty>();
0088     }
0089 
0090     template <typename EntityType>
0091     static QMap<QByteArray, int> databases()
0092     {
0093         return {{QByteArray{EntityType::name} +".index." + SortProperty::name + ".sorted", Sink::Storage::AllowDuplicates}};
0094     }
0095 };
0096 
0097 template <typename Property, typename SecondaryProperty>
0098 class SecondaryIndex
0099 {
0100 public:
0101     static void configure(TypeIndex &index)
0102     {
0103         index.addSecondaryProperty<Property, SecondaryProperty>();
0104     }
0105 
0106     template <typename EntityType>
0107     static QMap<QByteArray, int> databases()
0108     {
0109         return {{QByteArray{EntityType::name} +".index." + Property::name + SecondaryProperty::name, Sink::Storage::AllowDuplicates}};
0110     }
0111 };
0112 
0113 template <typename Property, typename SecondaryProperty, typename Indexer>
0114 class CustomSecondaryIndex
0115 {
0116 public:
0117     static void configure(TypeIndex &index)
0118     {
0119         index.addSecondaryPropertyIndexer<Property, SecondaryProperty, Indexer>();
0120     }
0121 
0122     template <typename EntityType>
0123     static QMap<QByteArray, int> databases()
0124     {
0125         return Indexer::databases();
0126     }
0127 };
0128 
0129 template <typename RangeBeginProperty, typename RangeEndProperty>
0130 class SampledPeriodIndex
0131 {
0132     static_assert(std::is_same<typename RangeBeginProperty::Type, QDateTime>::value &&
0133                       std::is_same<typename RangeEndProperty::Type, QDateTime>::value,
0134         "Date range index is not supported for types other than 'QDateTime's");
0135 
0136 public:
0137     static void configure(TypeIndex &index)
0138     {
0139         index.addSampledPeriodIndex<RangeBeginProperty, RangeEndProperty>();
0140     }
0141 
0142     template <typename EntityType>
0143     static QMap<QByteArray, int> databases()
0144     {
0145         return {{QByteArray{EntityType::name} +".index." + RangeBeginProperty::name + ".range." + RangeEndProperty::name, Sink::Storage::AllowDuplicates}};
0146     }
0147 };
0148 
0149 template <typename EntityType, typename ... Indexes>
0150 class IndexConfig
0151 {
0152     template <typename T>
0153     static void applyIndex(TypeIndex &index)
0154     {
0155         T::configure(index);
0156     }
0157 
0158     ///Apply recursively for parameter pack
0159     template <typename First, typename Second, typename ... Tail>
0160     static void applyIndex(TypeIndex &index)
0161     {
0162         applyIndex<First>(index);
0163         applyIndex<Second, Tail...>(index);
0164     }
0165 
0166     template <typename T>
0167     static QMap<QByteArray, int> getDbs()
0168     {
0169         return T::template databases<EntityType>();
0170     }
0171 
0172     template <typename First, typename Second, typename ... Tail>
0173     static QMap<QByteArray, int> getDbs()
0174     {
0175         return merge(getDbs<First>(), getDbs<Second, Tail...>());
0176     }
0177 
0178 public:
0179     static void configure(TypeIndex &index)
0180     {
0181         applyIndex<Indexes...>(index);
0182     }
0183 
0184     static QMap<QByteArray, int> databases()
0185     {
0186         return getDbs<Indexes...>();
0187     }
0188 
0189 };
0190