summary refs log tree commit diff stats
path: root/lib/field.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/field.h')
-rw-r--r--lib/field.h306
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
8namespace 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 */