summary refs log tree commit diff stats
path: root/lib/statement.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/statement.h')
-rw-r--r--lib/statement.h272
1 files changed, 272 insertions, 0 deletions
diff --git a/lib/statement.h b/lib/statement.h new file mode 100644 index 0000000..a528d60 --- /dev/null +++ b/lib/statement.h
@@ -0,0 +1,272 @@
1#ifndef STATEMENT_H_29F51659
2#define STATEMENT_H_29F51659
3
4#include <string>
5#include <list>
6#include <map>
7#include <set>
8#include "binding.h"
9#include "enums.h"
10#include "field.h"
11#include "filter.h"
12
13namespace verbly {
14
15 class filter;
16
17 class statement {
18 public:
19
20 statement(object context, filter queryFilter);
21
22 std::string getQueryString(std::list<std::string> select, bool random, int limit) const;
23
24 std::list<binding> getBindings() const;
25
26 private:
27
28 class join {
29 public:
30
31 join(
32 bool outer,
33 std::string foreignTableName,
34 std::string joinTable,
35 std::string joinColumn,
36 std::string foreignTable,
37 std::string foreignColumn) :
38 outer_(outer),
39 foreignTableName_(std::move(foreignTableName)),
40 joinTable_(std::move(joinTable)),
41 joinColumn_(std::move(joinColumn)),
42 foreignTable_(std::move(foreignTable)),
43 foreignColumn_(std::move(foreignColumn))
44 {
45 }
46
47 bool isOuterJoin() const
48 {
49 return outer_;
50 }
51
52 const std::string& getForeignTableName() const
53 {
54 return foreignTableName_;
55 }
56
57 const std::string& getJoinTable() const
58 {
59 return joinTable_;
60 }
61
62 const std::string& getJoinColumn() const
63 {
64 return joinColumn_;
65 }
66
67 const std::string& getForeignTable() const
68 {
69 return foreignTable_;
70 }
71
72 const std::string& getForeignColumn() const
73 {
74 return foreignColumn_;
75 }
76
77 private:
78 bool outer_ = false;
79 std::string foreignTableName_;
80 std::string joinTable_;
81 std::string joinColumn_;
82 std::string foreignTable_;
83 std::string foreignColumn_;
84
85 };
86
87 friend std::ostream& operator<<(std::ostream& oss, const join& j);
88
89 class condition {
90 public:
91 enum class type {
92 empty,
93 singleton,
94 group
95 };
96
97 enum class comparison {
98 equals,
99 does_not_equal,
100 is_greater_than,
101 is_at_most,
102 is_less_than,
103 is_at_least,
104 is_like,
105 is_not_like,
106 is_not_null,
107 is_null
108 };
109
110 // Copy and move constructors
111
112 condition(const condition& other);
113 condition(condition&& other);
114
115 // Assignment
116
117 condition& operator=(condition other);
118
119 // Swap
120
121 friend void swap(condition& first, condition& second);
122
123 // Destructor
124
125 ~condition();
126
127 // Accessors
128
129 type getType() const
130 {
131 return type_;
132 }
133
134 // Empty
135
136 condition();
137
138 // Singleton
139
140 condition(std::string table, std::string column, bool isNull);
141
142 condition(std::string table, std::string column, comparison comp, binding value);
143
144 // Group
145
146 explicit condition(bool orlogic);
147
148 condition& operator+=(condition n);
149
150 condition& operator&=(condition n);
151
152 const std::list<condition>& getChildren() const;
153
154 // Utility
155
156 std::string toSql() const;
157
158 std::list<binding> flattenBindings() const;
159
160 private:
161 union {
162 struct {
163 std::string table_;
164 std::string column_;
165 comparison comparison_;
166 binding value_;
167 } singleton_;
168 struct {
169 std::list<condition> children_;
170 bool orlogic_;
171 } group_;
172 };
173 type type_;
174 };
175
176 friend void swap(condition& first, condition& second);
177
178 class with {
179 public:
180
181 with(
182 std::string identifier,
183 field f,
184 std::map<std::string, std::string> tables,
185 std::string topTable,
186 condition where,
187 std::list<join> joins) :
188 identifier_(std::move(identifier)),
189 field_(f),
190 tables_(std::move(tables)),
191 topTable_(std::move(topTable)),
192 topCondition_(std::move(where)),
193 joins_(std::move(joins))
194 {
195 }
196
197 const std::string& getIdentifier() const
198 {
199 return identifier_;
200 }
201
202 field getField() const
203 {
204 return field_;
205 }
206
207 std::string getTableForId(std::string identifier) const
208 {
209 return tables_.at(identifier);
210 }
211
212 const std::string& getTopTable() const
213 {
214 return topTable_;
215 }
216
217 const condition& getCondition() const
218 {
219 return topCondition_;
220 }
221
222 const std::list<join>& getJoins() const
223 {
224 return joins_;
225 }
226
227 private:
228 std::string identifier_;
229 field field_;
230 std::map<std::string, std::string> tables_;
231 std::string topTable_;
232 condition topCondition_;
233 std::list<join> joins_;
234
235 };
236
237 static constexpr const char* getTableForContext(object context)
238 {
239 return (context == object::notion) ? "notions"
240 : (context == object::word) ? "words"
241 : (context == object::group) ? "groups"
242 : (context == object::frame) ? "frames"
243 : (context == object::lemma) ? "lemmas_forms"
244 : (context == object::form) ? "forms"
245 : (context == object::pronunciation) ? "pronunciations"
246 : throw std::domain_error("Provided context has no associated table");
247 }
248
249 static const std::list<field> getSelectForContext(object context);
250
251 statement(std::string tableName, filter clause, int nextTableId = 0, int nextWithId = 0);
252
253 condition parseFilter(filter queryFilter);
254
255 std::string instantiateTable(std::string name);
256
257 condition integrate(statement subStmt);
258
259 int nextTableId_;
260 int nextWithId_;
261
262 std::map<std::string, std::string> tables_;
263 std::string topTable_;
264 std::list<join> joins_;
265 std::list<with> withs_;
266 condition topCondition_;
267
268 };
269
270};
271
272#endif /* end of include guard: STATEMENT_H_29F51659 */