]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_es_query.h
4375d93251cf609fdb3e3324918f3796f9749c24
[ceph.git] / 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;
106 set<string> *restricted_fields;
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