1 /// 2 /// Convert a filter into a list of queries based on a list of capabilities. 3 /// @file querylist.h - pianod 4 /// @author Perette Barella 5 /// @date 2015-01-21 6 /// @copyright Copyright (c) 2015-2017 Devious Fish. All rights reserved. 7 /// 8 9 #ifndef __pianod__querylist__ 10 #define __pianod__querylist__ 11 12 #include <config.h> 13 14 #include <cstdint> 15 16 #include <typeinfo> 17 #include <vector> 18 #include <stdexcept> 19 20 #include "enumeratedarray.h" 21 #include "querylist.h" 22 #include "filter.h" 23 24 /// Filter-to-query converter. 25 namespace Query { 26 /// Exception indicating a query is impossible to perform on a source. 27 class impossible : public std::invalid_argument { 28 public: impossible(void)29 explicit impossible (void) : invalid_argument ("impossible") { }; 30 }; 31 typedef int8_t Preference; 32 33 /// Manners in which fields may be queried for a source. 34 typedef enum search_methods_t { 35 SearchMethodNone, 36 ExactCompare, 37 MatchBeginning, 38 SubstringMatch, 39 Fuzzy 40 } SearchMethod; 41 42 /** Media sources mark the available fields (array index) to 43 true to indicate they are capable of searching in that manner. */ 44 struct Constraints { 45 /// Fields searched by permuted filters, i.e., 'like'. 46 EnumeratedArray<Filter::Field, bool> participatesInFuzzy; 47 EnumeratedArray<Filter::Field, bool> canExactCompare; 48 EnumeratedArray<Filter::Field, bool> canMatchBeginning; 49 EnumeratedArray<Filter::Field, bool> canSubstringMatch; 50 /// Fields that can't be properly searched on, but are part of Field::Search searches. 51 EnumeratedArray<Filter::Field, bool> fieldInGeneralSearch; 52 /// Relative field preferences: higher is better 53 EnumeratedArray<Filter::Field, Preference> fieldPreference; 54 /// May query with 'AND' semantics. 55 bool andCapable = false; 56 }; 57 58 class DetailList; 59 class Queries; 60 class List; 61 62 /// Information about how a query should be performed by a source. 63 class Details { 64 friend class DetailList; // Collection manages quality. 65 private: 66 float quality = 1; /// Specificity of the search; more is better. 67 Filter::Field filterField = Filter::Field::Invalid; /// Field filtered on 68 public: 69 Filter::Field searchField = Filter::Field::Invalid; ///< Field to search on 70 SearchMethod searchMethod = SearchMethodNone; ///< Method of comparison 71 std::string value; ///< Value to search for 72 73 Details (Filter::Field filter_field, 74 Filter::Field field, SearchMethod method, const char *val); 75 }; 76 77 /** A list of queries representing a filter expression or portion thereof. 78 Queries represent intersection (AND) of data. */ 79 class DetailList : public std::vector<Details> { 80 friend class Queries; 81 unsigned preference (const Constraints &con) const; ///< Field Preference of searches 82 float quality (void) const; ///< Specificity of the collection of searches. 83 84 }; 85 86 87 /** A list of queries representing a filter expression or portion thereof. 88 Queries represent union (OR) of data. */ 89 class Queries: public std::vector<DetailList> { 90 friend class List; 91 unsigned preference (const Constraints &con) const; ///< Field Preference of searches 92 float quality (void) const; ///< Specificity of the collection of searches. 93 }; 94 95 /** A adapter to convert filters into a list of queries for a source. */ 96 class List : public Queries { 97 public: 98 const Constraints &capabilities; 99 SearchMethod findMethodForField (SearchMethod requestedMethod, 100 Filter::Field field); 101 Details interpretComparison (const Filter::Operation *filter); 102 Queries interpretAnd (const Filter::Operation *filter); 103 Queries interpret (const Filter::Operation *filter); 104 Queries interpretFuzzy (const PermutedFilter &filter); 105 List (const Filter &filter, const Constraints &constraints); 106 }; 107 } 108 109 #endif // defined(__pianod__querylist__) 110