Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rgw / rgw_es_query.h
1 #ifndef CEPH_RGW_ES_QUERY_H
2 #define CEPH_RGW_ES_QUERY_H
3
4 #include "rgw_string.h"
5
6 class ESQueryStack {
7   list<string> l;
8   list<string>::iterator iter;
9
10 public:
11   ESQueryStack(list<string>& src) {
12     assign(src);
13   }
14
15   ESQueryStack() {}
16
17   void assign(list<string>& src) {
18     l.swap(src);
19     iter = l.begin();
20   }
21
22   bool peek(string *dest) {
23     if (done()) {
24       return false;
25     }
26     *dest = *iter;
27     return true;
28   }
29
30   bool pop(string *dest) {
31     bool valid = peek(dest);
32     if (!valid) {
33       return false;
34     }
35     ++iter;
36     return true;
37   }
38
39   bool done() {
40     return (iter == l.end());
41   }
42 };
43
44 class ESInfixQueryParser {
45   string query;
46   int size;
47   const char *str;
48   int pos{0};
49   list<string> args;
50
51   void skip_whitespace(const char *str, int size, int& pos);
52   bool get_next_token(bool (*filter)(char));
53
54   bool parse_condition();
55   bool parse_and_or();
56   bool parse_specific_char(const char *pchar);
57   bool parse_open_bracket();
58   bool parse_close_bracket();
59
60 public:
61   ESInfixQueryParser(const string& _query) : query(_query), size(query.size()), str(query.c_str()) {}
62   bool parse(list<string> *result);
63 };
64
65 class ESQueryNode;
66
67 struct ESEntityTypeMap {
68   enum EntityType {
69     ES_ENTITY_NONE = 0,
70     ES_ENTITY_STR  = 1,
71     ES_ENTITY_INT  = 2,
72     ES_ENTITY_DATE = 3,
73   };
74
75   map<string, EntityType> m;
76
77   ESEntityTypeMap(map<string, EntityType>& _m) : m(_m) {}
78
79   bool find(const string& entity, EntityType *ptype) {
80     auto i = m.find(entity);
81     if (i != m.end()) {
82       *ptype = i->second;
83       return true;
84     }
85
86     *ptype = ES_ENTITY_NONE;
87     return false;
88   }
89 };
90
91 class ESQueryCompiler {
92   ESInfixQueryParser parser;
93   ESQueryStack stack;
94   ESQueryNode *query_root{nullptr};
95
96   string custom_prefix;
97
98   bool convert(list<string>& infix, string *perr);
99
100   list<pair<string, string> > eq_conds;
101
102   ESEntityTypeMap *generic_type_map{nullptr};
103   ESEntityTypeMap *custom_type_map{nullptr};
104
105   map<string, string, ltstr_nocase> *field_aliases = nullptr;
106   set<string> *restricted_fields = nullptr;
107
108 public:
109   ESQueryCompiler(const string& query, list<pair<string, string> > *prepend_eq_conds, const string& _custom_prefix) : parser(query), custom_prefix(_custom_prefix) {
110     if (prepend_eq_conds) {
111       eq_conds = std::move(*prepend_eq_conds);
112     }
113   }
114   ~ESQueryCompiler();
115
116   bool compile(string *perr);
117   void dump(Formatter *f) const;
118   
119   void set_generic_type_map(ESEntityTypeMap *entity_map) {
120     generic_type_map = entity_map;
121   }
122
123   ESEntityTypeMap *get_generic_type_map() {
124     return generic_type_map;
125   }
126   const string& get_custom_prefix() { return custom_prefix; }
127
128   void set_custom_type_map(ESEntityTypeMap *entity_map) {
129     custom_type_map = entity_map;
130   }
131
132   ESEntityTypeMap *get_custom_type_map() {
133     return custom_type_map;
134   }
135
136   void set_field_aliases(map<string, string, ltstr_nocase> *fa) {
137     field_aliases = fa;
138   }
139
140   string unalias_field(const string& field) {
141     if (!field_aliases) {
142       return field;
143     }
144     auto i = field_aliases->find(field);
145     if (i == field_aliases->end()) {
146       return field;
147     }
148
149     return i->second;
150   }
151
152   void set_restricted_fields(set<string> *rf) {
153     restricted_fields = rf;
154   }
155
156   bool is_restricted(const string& f) {
157     return (restricted_fields && restricted_fields->find(f) != restricted_fields->end());
158   }
159 };
160
161
162 #endif