summary refs log tree commit diff stats
path: root/lib/part.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-01-28 12:59:42 -0500
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-01-28 12:59:42 -0500
commita7645346293ed6a912c26d0c50b6f7943f1f3072 (patch)
treed4d144e03a5e2dfcebbad2692fa71e790719d8fd /lib/part.cpp
parent6ba8989bbbd497f949a3e8b17abed1d0bd048347 (diff)
downloadverbly-a7645346293ed6a912c26d0c50b6f7943f1f3072.tar.gz
verbly-a7645346293ed6a912c26d0c50b6f7943f1f3072.tar.bz2
verbly-a7645346293ed6a912c26d0c50b6f7943f1f3072.zip
Restructured verb frame schema to be more queryable
Groups are much less significant now, and they no longer have a database
table, nor are they considered a top level object anymore. Instead of
containing their own role data, that data is folded into the frames so
that it's easier to query; as a result, each group has its own copy of
the frames that it contains. Additionally, parts are considered top
level objects now, and you can query for frames based on attributes of
their indexed parts. Synrestrs are also contained in their own table
now, so that parts can be filtered against their synrestrs; they are
however not considered top level objects.

Created a new type of field, the "join where" or "condition join" field,
which is a normal join field that has a built in condition on a
specified field. This is used to allow creating multiple distinct join
fields from one object to another. This is required for the lemma::form
and frame::part joins, because filters for forms of separate inflections
should not be coalesced; similarly, filters on differently indexed frame
parts should not be coalesced.

Queries can now be ordered, ascending or descending, by a field, in
addition to randomly as before. This is necessary for accessing the
parts of a verb frame in the correct order, but may be useful to an end
user as well.

Fixed a bug with statement generation in that condition groups were not
being surrounded in parentheses, which made mixing OR groups and AND
groups generate inaccurate statements. This has been fixed;
additionally, parentheses are not placed around the top level condition,
and nested condition groups with the same logic type are coalesced, to
make query strings as easy to read as possible.

Also simplified the form::lemma field; it no longer conditions on the
inflection of the form like the lemma::form field does.

Also added a debug flag to statement::getQueryString that makes it
return a query string with all of the bindings filled in, for debug use
only.
Diffstat (limited to 'lib/part.cpp')
-rw-r--r--lib/part.cpp128
1 files changed, 100 insertions, 28 deletions
diff --git a/lib/part.cpp b/lib/part.cpp index e66d151..1fbb24d 100644 --- a/lib/part.cpp +++ b/lib/part.cpp
@@ -1,12 +1,30 @@
1#include "part.h" 1#include "part.h"
2#include <stdexcept> 2#include <stdexcept>
3#include <sqlite3.h>
3#include "selrestr.h" 4#include "selrestr.h"
5#include "database.h"
4 6
5namespace verbly { 7namespace verbly {
6 8
9 const object part::objectType = object::part;
10
11 const std::list<std::string> part::select = {"part_id", "frame_id", "part_index", "type", "role", "selrestrs", "prepositions", "preposition_literality", "literal_value"};
12
13 const field part::index = field::integerField(object::part, "part_index");
14 const field part::type = field::integerField(object::part, "type");
15
16 const field part::role = field::stringField(object::part, "role", true);
17
18 const field part::frame = field::joinField(object::part, "frame_id", object::frame);
19
20 const field part::synrestr_field::synrestrJoin = field::joinField(object::part, "part_id", "synrestrs");
21 const field part::synrestr_field::synrestrField = field::stringField("synrestrs", "synrestr");
22
23 const part::synrestr_field part::synrestr = {};
24
7 part part::createNounPhrase(std::string role, selrestr selrestrs, std::set<std::string> synrestrs) 25 part part::createNounPhrase(std::string role, selrestr selrestrs, std::set<std::string> synrestrs)
8 { 26 {
9 part p(type::noun_phrase); 27 part p(part_type::noun_phrase);
10 28
11 new(&p.noun_phrase_.role) std::string(std::move(role)); 29 new(&p.noun_phrase_.role) std::string(std::move(role));
12 new(&p.noun_phrase_.selrestrs) selrestr(std::move(selrestrs)); 30 new(&p.noun_phrase_.selrestrs) selrestr(std::move(selrestrs));
@@ -17,12 +35,12 @@ namespace verbly {
17 35
18 part part::createVerb() 36 part part::createVerb()
19 { 37 {
20 return part(type::verb); 38 return part(part_type::verb);
21 } 39 }
22 40
23 part part::createPreposition(std::vector<std::string> choices, bool literal) 41 part part::createPreposition(std::vector<std::string> choices, bool literal)
24 { 42 {
25 part p(type::preposition); 43 part p(part_type::preposition);
26 44
27 new(&p.preposition_.choices) std::vector<std::string>(std::move(choices)); 45 new(&p.preposition_.choices) std::vector<std::string>(std::move(choices));
28 p.preposition_.literal = literal; 46 p.preposition_.literal = literal;
@@ -32,30 +50,79 @@ namespace verbly {
32 50
33 part part::createAdjective() 51 part part::createAdjective()
34 { 52 {
35 return part(type::adjective); 53 return part(part_type::adjective);
36 } 54 }
37 55
38 part part::createAdverb() 56 part part::createAdverb()
39 { 57 {
40 return part(type::adverb); 58 return part(part_type::adverb);
41 } 59 }
42 60
43 part part::createLiteral(std::string value) 61 part part::createLiteral(std::string value)
44 { 62 {
45 part p(type::literal); 63 part p(part_type::literal);
46 64
47 new(&p.literal_) std::string(std::move(value)); 65 new(&p.literal_) std::string(std::move(value));
48 66
49 return p; 67 return p;
50 } 68 }
51 69
70 part::part(const database& db, sqlite3_stmt* row)
71 {
72 int id = sqlite3_column_int(row, 0);
73
74 type_ = static_cast<part_type>(sqlite3_column_int(row, 3));
75
76 switch (type_)
77 {
78 case part_type::noun_phrase:
79 {
80 new(&noun_phrase_.role) std::string(reinterpret_cast<const char*>(sqlite3_column_blob(row, 4)));
81 new(&noun_phrase_.selrestrs) selrestr(nlohmann::json::parse(reinterpret_cast<const char*>(sqlite3_column_blob(row, 5))));
82 new(&noun_phrase_.synrestrs) std::set<std::string>(db.synrestrs(id));
83
84 break;
85 }
86
87 case part_type::preposition:
88 {
89 new(&preposition_.choices) std::vector<std::string>();
90 preposition_.literal = (sqlite3_column_int(row, 7) == 1);
91
92 std::string choicesJsonStr(reinterpret_cast<const char*>(sqlite3_column_blob(row, 6)));
93 nlohmann::json choicesJson = nlohmann::json::parse(std::move(choicesJsonStr));
94 for (const nlohmann::json& choiceJson : choicesJson)
95 {
96 preposition_.choices.push_back(choiceJson.get<std::string>());
97 }
98
99 break;
100 }
101
102 case part_type::literal:
103 {
104 new(&literal_) std::string(reinterpret_cast<const char*>(sqlite3_column_blob(row, 8)));
105
106 break;
107 }
108
109 case part_type::verb:
110 case part_type::adjective:
111 case part_type::adverb:
112 case part_type::invalid:
113 {
114 break;
115 }
116 }
117 }
118
52 part::part(const part& other) 119 part::part(const part& other)
53 { 120 {
54 type_ = other.type_; 121 type_ = other.type_;
55 122
56 switch (type_) 123 switch (type_)
57 { 124 {
58 case type::noun_phrase: 125 case part_type::noun_phrase:
59 { 126 {
60 new(&noun_phrase_.role) std::string(other.noun_phrase_.role); 127 new(&noun_phrase_.role) std::string(other.noun_phrase_.role);
61 new(&noun_phrase_.selrestrs) selrestr(other.noun_phrase_.selrestrs); 128 new(&noun_phrase_.selrestrs) selrestr(other.noun_phrase_.selrestrs);
@@ -64,7 +131,7 @@ namespace verbly {
64 break; 131 break;
65 } 132 }
66 133
67 case type::preposition: 134 case part_type::preposition:
68 { 135 {
69 new(&preposition_.choices) std::vector<std::string>(other.preposition_.choices); 136 new(&preposition_.choices) std::vector<std::string>(other.preposition_.choices);
70 preposition_.literal = other.preposition_.literal; 137 preposition_.literal = other.preposition_.literal;
@@ -72,17 +139,17 @@ namespace verbly {
72 break; 139 break;
73 } 140 }
74 141
75 case type::literal: 142 case part_type::literal:
76 { 143 {
77 new(&literal_) std::string(other.literal_); 144 new(&literal_) std::string(other.literal_);
78 145
79 break; 146 break;
80 } 147 }
81 148
82 case type::verb: 149 case part_type::verb:
83 case type::adjective: 150 case part_type::adjective:
84 case type::adverb: 151 case part_type::adverb:
85 case type::invalid: 152 case part_type::invalid:
86 { 153 {
87 break; 154 break;
88 } 155 }
@@ -103,7 +170,7 @@ namespace verbly {
103 170
104 void swap(part& first, part& second) 171 void swap(part& first, part& second)
105 { 172 {
106 using type = part::type; 173 using type = part_type;
107 174
108 type tempType = first.type_; 175 type tempType = first.type_;
109 std::string tempRole; 176 std::string tempRole;
@@ -231,7 +298,7 @@ namespace verbly {
231 { 298 {
232 switch (type_) 299 switch (type_)
233 { 300 {
234 case type::noun_phrase: 301 case part_type::noun_phrase:
235 { 302 {
236 using string_type = std::string; 303 using string_type = std::string;
237 using set_type = std::set<std::string>; 304 using set_type = std::set<std::string>;
@@ -243,7 +310,7 @@ namespace verbly {
243 break; 310 break;
244 } 311 }
245 312
246 case type::preposition: 313 case part_type::preposition:
247 { 314 {
248 using vector_type = std::vector<std::string>; 315 using vector_type = std::vector<std::string>;
249 316
@@ -252,7 +319,7 @@ namespace verbly {
252 break; 319 break;
253 } 320 }
254 321
255 case type::literal: 322 case part_type::literal:
256 { 323 {
257 using string_type = std::string; 324 using string_type = std::string;
258 325
@@ -261,10 +328,10 @@ namespace verbly {
261 break; 328 break;
262 } 329 }
263 330
264 case type::verb: 331 case part_type::verb:
265 case type::adjective: 332 case part_type::adjective:
266 case type::adverb: 333 case part_type::adverb:
267 case type::invalid: 334 case part_type::invalid:
268 { 335 {
269 break; 336 break;
270 } 337 }
@@ -273,7 +340,7 @@ namespace verbly {
273 340
274 std::string part::getNounRole() const 341 std::string part::getNounRole() const
275 { 342 {
276 if (type_ == type::noun_phrase) 343 if (type_ == part_type::noun_phrase)
277 { 344 {
278 return noun_phrase_.role; 345 return noun_phrase_.role;
279 } else { 346 } else {
@@ -283,7 +350,7 @@ namespace verbly {
283 350
284 selrestr part::getNounSelrestrs() const 351 selrestr part::getNounSelrestrs() const
285 { 352 {
286 if (type_ == type::noun_phrase) 353 if (type_ == part_type::noun_phrase)
287 { 354 {
288 return noun_phrase_.selrestrs; 355 return noun_phrase_.selrestrs;
289 } else { 356 } else {
@@ -293,7 +360,7 @@ namespace verbly {
293 360
294 std::set<std::string> part::getNounSynrestrs() const 361 std::set<std::string> part::getNounSynrestrs() const
295 { 362 {
296 if (type_ == type::noun_phrase) 363 if (type_ == part_type::noun_phrase)
297 { 364 {
298 return noun_phrase_.synrestrs; 365 return noun_phrase_.synrestrs;
299 } else { 366 } else {
@@ -303,7 +370,7 @@ namespace verbly {
303 370
304 bool part::nounHasSynrestr(std::string synrestr) const 371 bool part::nounHasSynrestr(std::string synrestr) const
305 { 372 {
306 if (type_ != type::noun_phrase) 373 if (type_ != part_type::noun_phrase)
307 { 374 {
308 throw std::domain_error("part::nounHasSynrestr is only valid for noun phrase parts"); 375 throw std::domain_error("part::nounHasSynrestr is only valid for noun phrase parts");
309 } 376 }
@@ -313,7 +380,7 @@ namespace verbly {
313 380
314 std::vector<std::string> part::getPrepositionChoices() const 381 std::vector<std::string> part::getPrepositionChoices() const
315 { 382 {
316 if (type_ == type::preposition) 383 if (type_ == part_type::preposition)
317 { 384 {
318 return preposition_.choices; 385 return preposition_.choices;
319 } else { 386 } else {
@@ -323,7 +390,7 @@ namespace verbly {
323 390
324 bool part::isPrepositionLiteral() const 391 bool part::isPrepositionLiteral() const
325 { 392 {
326 if (type_ == type::preposition) 393 if (type_ == part_type::preposition)
327 { 394 {
328 return preposition_.literal; 395 return preposition_.literal;
329 } else { 396 } else {
@@ -333,7 +400,7 @@ namespace verbly {
333 400
334 std::string part::getLiteralValue() const 401 std::string part::getLiteralValue() const
335 { 402 {
336 if (type_ == type::literal) 403 if (type_ == part_type::literal)
337 { 404 {
338 return literal_; 405 return literal_;
339 } else { 406 } else {
@@ -341,4 +408,9 @@ namespace verbly {
341 } 408 }
342 } 409 }
343 410
411 filter part::synrestr_field::operator%=(std::string synrestr) const
412 {
413 return (synrestrJoin %= (synrestrField == synrestr));
414 }
415
344}; 416};