diff options
Diffstat (limited to 'lib/field.h')
-rw-r--r-- | lib/field.h | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/lib/field.h b/lib/field.h new file mode 100644 index 0000000..30c62be --- /dev/null +++ b/lib/field.h | |||
@@ -0,0 +1,306 @@ | |||
1 | #ifndef FIELD_H_43258321 | ||
2 | #define FIELD_H_43258321 | ||
3 | |||
4 | #include "enums.h" | ||
5 | #include <stdexcept> | ||
6 | #include <tuple> | ||
7 | |||
8 | namespace verbly { | ||
9 | |||
10 | class filter; | ||
11 | |||
12 | class field { | ||
13 | public: | ||
14 | enum class type { | ||
15 | undefined, | ||
16 | string, | ||
17 | integer, | ||
18 | boolean, | ||
19 | join, | ||
20 | join_through, | ||
21 | hierarchal_join | ||
22 | }; | ||
23 | |||
24 | // Default constructor | ||
25 | |||
26 | field() | ||
27 | { | ||
28 | } | ||
29 | |||
30 | // Static factories | ||
31 | |||
32 | static field stringField( | ||
33 | object obj, | ||
34 | const char* name, | ||
35 | bool nullable = false) | ||
36 | { | ||
37 | return field(obj, type::string, name, nullable); | ||
38 | } | ||
39 | |||
40 | static field stringField( | ||
41 | const char* table, | ||
42 | const char* name, | ||
43 | bool nullable = false) | ||
44 | { | ||
45 | return field(object::undefined, type::string, name, nullable, table); | ||
46 | } | ||
47 | |||
48 | static field integerField( | ||
49 | object obj, | ||
50 | const char* name, | ||
51 | bool nullable = false) | ||
52 | { | ||
53 | return field(obj, type::integer, name, nullable); | ||
54 | } | ||
55 | |||
56 | static field integerField( | ||
57 | const char* table, | ||
58 | const char* name, | ||
59 | bool nullable = false) | ||
60 | { | ||
61 | return field(object::undefined, type::integer, name, nullable, table); | ||
62 | } | ||
63 | |||
64 | static field booleanField( | ||
65 | object obj, | ||
66 | const char* name, | ||
67 | bool nullable = false) | ||
68 | { | ||
69 | return field(obj, type::boolean, name, nullable); | ||
70 | } | ||
71 | |||
72 | static field booleanField( | ||
73 | const char* table, | ||
74 | const char* name, | ||
75 | bool nullable = false) | ||
76 | { | ||
77 | return field(object::undefined, type::boolean, name, nullable, table); | ||
78 | } | ||
79 | |||
80 | static field joinField( | ||
81 | object obj, | ||
82 | const char* name, | ||
83 | object joinWith, | ||
84 | bool nullable = false) | ||
85 | { | ||
86 | return field(obj, type::join, name, nullable, 0, joinWith); | ||
87 | } | ||
88 | |||
89 | static field joinField( | ||
90 | object obj, | ||
91 | const char* name, | ||
92 | const char* table, | ||
93 | bool nullable = false) | ||
94 | { | ||
95 | return field(obj, type::join, name, nullable, table); | ||
96 | } | ||
97 | |||
98 | static field joinThrough( | ||
99 | object obj, | ||
100 | const char* name, | ||
101 | object joinWith, | ||
102 | const char* joinTable, | ||
103 | const char* foreignColumn) | ||
104 | { | ||
105 | return field(obj, type::join_through, name, true, joinTable, joinWith, foreignColumn, name, foreignColumn); | ||
106 | } | ||
107 | |||
108 | static field joinThrough( | ||
109 | object obj, | ||
110 | const char* name, | ||
111 | object joinWith, | ||
112 | const char* joinTable, | ||
113 | const char* foreignColumn, | ||
114 | const char* joinColumn, | ||
115 | const char* foreignJoinColumn) | ||
116 | { | ||
117 | return field(obj, type::join_through, name, true, joinTable, joinWith, foreignColumn, joinColumn, foreignJoinColumn); | ||
118 | } | ||
119 | |||
120 | static field selfJoin( | ||
121 | object obj, | ||
122 | const char* name, | ||
123 | const char* joinTable, | ||
124 | const char* joinColumn, | ||
125 | const char* foreignJoinColumn) | ||
126 | { | ||
127 | return field(obj, type::join_through, name, true, joinTable, obj, name, joinColumn, foreignJoinColumn); | ||
128 | } | ||
129 | |||
130 | static field hierarchalSelfJoin( | ||
131 | object obj, | ||
132 | const char* name, | ||
133 | const char* joinTable, | ||
134 | const char* joinColumn, | ||
135 | const char* foreignJoinColumn) | ||
136 | { | ||
137 | return field(obj, type::hierarchal_join, name, true, joinTable, obj, name, joinColumn, foreignJoinColumn); | ||
138 | } | ||
139 | |||
140 | // Accessors | ||
141 | |||
142 | object getObject() const | ||
143 | { | ||
144 | return object_; | ||
145 | } | ||
146 | |||
147 | type getType() const | ||
148 | { | ||
149 | return type_; | ||
150 | } | ||
151 | |||
152 | bool isJoin() const | ||
153 | { | ||
154 | return ((type_ == type::join) || (type_ == type::join_through) || (type_ == type::hierarchal_join)); | ||
155 | } | ||
156 | |||
157 | const char* getColumn() const | ||
158 | { | ||
159 | return column_; | ||
160 | } | ||
161 | |||
162 | bool isNullable() const | ||
163 | { | ||
164 | return nullable_; | ||
165 | } | ||
166 | |||
167 | bool hasTable() const | ||
168 | { | ||
169 | return (table_ != 0); | ||
170 | } | ||
171 | |||
172 | const char* getTable() const | ||
173 | { | ||
174 | return table_; | ||
175 | } | ||
176 | |||
177 | // Joins | ||
178 | |||
179 | object getJoinObject() const | ||
180 | { | ||
181 | // We ignore hierarchal joins because they are always self joins. | ||
182 | return ((type_ == type::join) || (type_ == type::join_through)) | ||
183 | ? joinObject_ | ||
184 | : throw std::domain_error("Non-join fields don't have join objects"); | ||
185 | } | ||
186 | |||
187 | // Many-to-many joins | ||
188 | |||
189 | const char* getForeignColumn() const | ||
190 | { | ||
191 | // We ignore hierarchal joins because they are always self joins. | ||
192 | return (type_ == type::join_through) | ||
193 | ? foreignColumn_ | ||
194 | : throw std::domain_error("Only many-to-many join fields have a foreign column"); | ||
195 | } | ||
196 | |||
197 | const char* getJoinColumn() const | ||
198 | { | ||
199 | return ((type_ == type::join_through) || (type_ == type::hierarchal_join)) | ||
200 | ? joinColumn_ | ||
201 | : throw std::domain_error("Only many-to-many join fields have a join column"); | ||
202 | } | ||
203 | |||
204 | const char* getForeignJoinColumn() const | ||
205 | { | ||
206 | return ((type_ == type::join_through) || (type_ == type::hierarchal_join)) | ||
207 | ? foreignJoinColumn_ | ||
208 | : throw std::domain_error("Only many-to-many join fields have a foreign join column"); | ||
209 | } | ||
210 | |||
211 | // Ordering | ||
212 | |||
213 | bool operator<(const field& other) const | ||
214 | { | ||
215 | // For the most part, (object, column) uniquely identifies fields. | ||
216 | // However, there do exist a number of relationships from an object to | ||
217 | // itself, such as notion hypernymy/hyponymy. Hypernymy and hyponymy have | ||
218 | // the same object (notion), the same column (notion_id), and the same | ||
219 | // table (hypernymy); however, they have different join columns. | ||
220 | return std::tie(object_, column_, table_, joinColumn_) < std::tie(other.object_, other.column_, other.table_, other.joinColumn_); | ||
221 | } | ||
222 | |||
223 | // Equality | ||
224 | |||
225 | bool operator==(const field& other) const | ||
226 | { | ||
227 | // For the most part, (object, column) uniquely identifies fields. | ||
228 | // However, there do exist a number of relationships from an object to | ||
229 | // itself, such as notion hypernymy/hyponymy. Hypernymy and hyponymy have | ||
230 | // the same object (notion), the same column (notion_id), and the same | ||
231 | // table (hypernymy); however, they have different join columns. | ||
232 | return std::tie(object_, column_, table_, joinColumn_) == std::tie(other.object_, other.column_, other.table_, other.joinColumn_); | ||
233 | } | ||
234 | |||
235 | // Filter construction | ||
236 | |||
237 | filter operator==(int value) const; // Integer equality | ||
238 | filter operator!=(int value) const; // Integer inequality | ||
239 | filter operator<(int value) const; // Integer is less than | ||
240 | filter operator<=(int value) const; // Integer is at most | ||
241 | filter operator>(int value) const; // Integer is greater than | ||
242 | filter operator>=(int value) const; // Integer is at least | ||
243 | |||
244 | filter operator==(part_of_speech value) const; // Part of speech equality | ||
245 | filter operator==(positioning value) const; // Adjective positioning equality | ||
246 | filter operator==(inflection value) const; // Inflection category equality | ||
247 | |||
248 | filter operator==(bool value) const; // Boolean equality | ||
249 | |||
250 | filter operator==(std::string value) const; // String equality | ||
251 | filter operator!=(std::string value) const; // String inequality | ||
252 | filter operator%=(std::string value) const; // String matching | ||
253 | |||
254 | operator filter() const; // Non-nullity | ||
255 | filter operator!() const; // Nullity | ||
256 | |||
257 | filter operator%=(filter joinCondition) const; // Join | ||
258 | |||
259 | private: | ||
260 | |||
261 | // Constructor | ||
262 | |||
263 | field( | ||
264 | object obj, | ||
265 | type datatype, | ||
266 | const char* column, | ||
267 | bool nullable = false, | ||
268 | const char* table = 0, | ||
269 | object joinObject = object::undefined, | ||
270 | const char* foreignColumn = 0, | ||
271 | const char* joinColumn = 0, | ||
272 | const char* foreignJoinColumn = 0) : | ||
273 | object_(obj), | ||
274 | type_(datatype), | ||
275 | column_(column), | ||
276 | nullable_(nullable), | ||
277 | table_(table), | ||
278 | joinObject_(joinObject), | ||
279 | foreignColumn_(foreignColumn), | ||
280 | joinColumn_(joinColumn), | ||
281 | foreignJoinColumn_(foreignJoinColumn) | ||
282 | { | ||
283 | } | ||
284 | |||
285 | // General | ||
286 | object object_ = object::undefined; | ||
287 | type type_ = type::undefined; | ||
288 | const char* column_ = 0; | ||
289 | const char* table_ = 0; | ||
290 | |||
291 | // Non-joins and belongs-to joins | ||
292 | bool nullable_ = false; | ||
293 | |||
294 | // Joins | ||
295 | object joinObject_ = object::undefined; | ||
296 | |||
297 | // Many-to-many joins | ||
298 | const char* foreignColumn_ = 0; | ||
299 | const char* joinColumn_ = 0; | ||
300 | const char* foreignJoinColumn_ = 0; | ||
301 | |||
302 | }; | ||
303 | |||
304 | }; | ||
305 | |||
306 | #endif /* end of include guard: FIELD_H_43258321 */ | ||