diff options
Diffstat (limited to 'lib/adjective_query.cpp')
-rw-r--r-- | lib/adjective_query.cpp | 819 |
1 files changed, 819 insertions, 0 deletions
diff --git a/lib/adjective_query.cpp b/lib/adjective_query.cpp new file mode 100644 index 0000000..ec100e3 --- /dev/null +++ b/lib/adjective_query.cpp | |||
@@ -0,0 +1,819 @@ | |||
1 | #include "verbly.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | adjective_query::adjective_query(const data& _data) : _data(_data) | ||
6 | { | ||
7 | |||
8 | } | ||
9 | |||
10 | adjective_query& adjective_query::limit(int _limit) | ||
11 | { | ||
12 | if ((_limit > 0) || (_limit == unlimited)) | ||
13 | { | ||
14 | this->_limit = _limit; | ||
15 | } | ||
16 | |||
17 | return *this; | ||
18 | } | ||
19 | |||
20 | adjective_query& adjective_query::random() | ||
21 | { | ||
22 | this->_random = true; | ||
23 | |||
24 | return *this; | ||
25 | } | ||
26 | |||
27 | adjective_query& adjective_query::except(const adjective& _word) | ||
28 | { | ||
29 | _except.push_back(_word); | ||
30 | |||
31 | return *this; | ||
32 | } | ||
33 | |||
34 | adjective_query& adjective_query::rhymes_with(const word& _word) | ||
35 | { | ||
36 | for (auto rhyme : _word.rhyme_phonemes()) | ||
37 | { | ||
38 | _rhymes.push_back(rhyme); | ||
39 | } | ||
40 | |||
41 | if (dynamic_cast<const adjective*>(&_word) != nullptr) | ||
42 | { | ||
43 | _except.push_back(dynamic_cast<const adjective&>(_word)); | ||
44 | } | ||
45 | |||
46 | return *this; | ||
47 | } | ||
48 | |||
49 | adjective_query& adjective_query::has_pronunciation() | ||
50 | { | ||
51 | this->_has_prn = true; | ||
52 | |||
53 | return *this; | ||
54 | } | ||
55 | |||
56 | adjective_query& adjective_query::is_variant() | ||
57 | { | ||
58 | this->_is_variant = true; | ||
59 | |||
60 | return *this; | ||
61 | } | ||
62 | |||
63 | adjective_query& adjective_query::variant_of(filter<noun> _f) | ||
64 | { | ||
65 | _f.clean(); | ||
66 | _variant_of = _f; | ||
67 | |||
68 | return *this; | ||
69 | } | ||
70 | |||
71 | adjective_query& adjective_query::has_antonyms() | ||
72 | { | ||
73 | this->_is_antonymic = true; | ||
74 | |||
75 | return *this; | ||
76 | } | ||
77 | |||
78 | adjective_query& adjective_query::antonym_of(filter<adjective> _f) | ||
79 | { | ||
80 | _f.clean(); | ||
81 | _antonym_of = _f; | ||
82 | |||
83 | return *this; | ||
84 | } | ||
85 | |||
86 | adjective_query& adjective_query::has_synonyms() | ||
87 | { | ||
88 | this->_is_synonymic = true; | ||
89 | |||
90 | return *this; | ||
91 | } | ||
92 | |||
93 | adjective_query& adjective_query::synonym_of(filter<adjective> _f) | ||
94 | { | ||
95 | _f.clean(); | ||
96 | _synonym_of = _f; | ||
97 | |||
98 | return *this; | ||
99 | } | ||
100 | |||
101 | adjective_query& adjective_query::is_generalization() | ||
102 | { | ||
103 | this->_is_generalization = true; | ||
104 | |||
105 | return *this; | ||
106 | } | ||
107 | |||
108 | adjective_query& adjective_query::generalization_of(filter<adjective> _f) | ||
109 | { | ||
110 | _f.clean(); | ||
111 | _generalization_of = _f; | ||
112 | |||
113 | return *this; | ||
114 | } | ||
115 | |||
116 | adjective_query& adjective_query::is_specification() | ||
117 | { | ||
118 | this->_is_specification = true; | ||
119 | |||
120 | return *this; | ||
121 | } | ||
122 | |||
123 | adjective_query& adjective_query::specification_of(filter<adjective> _f) | ||
124 | { | ||
125 | _f.clean(); | ||
126 | _specification_of = _f; | ||
127 | |||
128 | return *this; | ||
129 | } | ||
130 | |||
131 | adjective_query& adjective_query::is_pertainymic() | ||
132 | { | ||
133 | this->_is_pertainymic = true; | ||
134 | |||
135 | return *this; | ||
136 | } | ||
137 | |||
138 | adjective_query& adjective_query::pertainym_of(filter<noun> _f) | ||
139 | { | ||
140 | _f.clean(); | ||
141 | _pertainym_of = _f; | ||
142 | |||
143 | return *this; | ||
144 | } | ||
145 | |||
146 | adjective_query& adjective_query::is_mannernymic() | ||
147 | { | ||
148 | this->_is_mannernymic = true; | ||
149 | |||
150 | return *this; | ||
151 | } | ||
152 | |||
153 | adjective_query& adjective_query::anti_mannernym_of(filter<adverb> _f) | ||
154 | { | ||
155 | _f.clean(); | ||
156 | _anti_mannernym_of = _f; | ||
157 | |||
158 | return *this; | ||
159 | } | ||
160 | /* | ||
161 | adjective_query& adjective_query::derived_from(const word& _w) | ||
162 | { | ||
163 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
164 | { | ||
165 | _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
166 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
167 | { | ||
168 | _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
169 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
170 | { | ||
171 | _derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
172 | } | ||
173 | |||
174 | return *this; | ||
175 | } | ||
176 | |||
177 | adjective_query& adjective_query::not_derived_from(const word& _w) | ||
178 | { | ||
179 | if (dynamic_cast<const adjective*>(&_w) != nullptr) | ||
180 | { | ||
181 | _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w)); | ||
182 | } else if (dynamic_cast<const adverb*>(&_w) != nullptr) | ||
183 | { | ||
184 | _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w)); | ||
185 | } else if (dynamic_cast<const noun*>(&_w) != nullptr) | ||
186 | { | ||
187 | _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w)); | ||
188 | } | ||
189 | |||
190 | return *this; | ||
191 | } | ||
192 | */ | ||
193 | std::list<adjective> adjective_query::run() const | ||
194 | { | ||
195 | std::stringstream construct; | ||
196 | construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; | ||
197 | std::list<std::string> conditions; | ||
198 | |||
199 | if (_has_prn) | ||
200 | { | ||
201 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)"); | ||
202 | } | ||
203 | |||
204 | if (!_rhymes.empty()) | ||
205 | { | ||
206 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
207 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
208 | conditions.push_back(cond); | ||
209 | } | ||
210 | |||
211 | for (auto except : _except) | ||
212 | { | ||
213 | conditions.push_back("adjective_id != @EXCID"); | ||
214 | } | ||
215 | |||
216 | if (_requires_comparative_form) | ||
217 | { | ||
218 | conditions.push_back("comparative IS NOT NULL"); | ||
219 | } | ||
220 | |||
221 | if (_requires_superlative_form) | ||
222 | { | ||
223 | conditions.push_back("superlative IS NOT NULL"); | ||
224 | } | ||
225 | |||
226 | switch (_position) | ||
227 | { | ||
228 | case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break; | ||
229 | case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break; | ||
230 | case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break; | ||
231 | case adjective::positioning::undefined: break; | ||
232 | } | ||
233 | |||
234 | if (_is_variant) | ||
235 | { | ||
236 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)"); | ||
237 | } | ||
238 | |||
239 | if (!_variant_of.empty()) | ||
240 | { | ||
241 | std::stringstream cond; | ||
242 | if (_variant_of.get_notlogic()) | ||
243 | { | ||
244 | cond << "adjective_id NOT IN"; | ||
245 | } else { | ||
246 | cond << "adjective_id IN"; | ||
247 | } | ||
248 | |||
249 | cond << "(SELECT adjective_id FROM variation WHERE "; | ||
250 | |||
251 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
252 | switch (f.get_type()) | ||
253 | { | ||
254 | case filter<noun>::type::singleton: | ||
255 | { | ||
256 | if (notlogic == f.get_notlogic()) | ||
257 | { | ||
258 | return "noun_id = @ATTRID"; | ||
259 | } else { | ||
260 | return "noun_id != @ATTRID"; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | case filter<noun>::type::group: | ||
265 | { | ||
266 | bool truelogic = notlogic != f.get_notlogic(); | ||
267 | |||
268 | std::list<std::string> clauses; | ||
269 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
270 | return recur(f2, truelogic); | ||
271 | }); | ||
272 | |||
273 | if (truelogic == f.get_orlogic()) | ||
274 | { | ||
275 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
276 | } else { | ||
277 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
278 | } | ||
279 | } | ||
280 | } | ||
281 | }; | ||
282 | |||
283 | cond << recur(_variant_of, _variant_of.get_notlogic()); | ||
284 | cond << ")"; | ||
285 | conditions.push_back(cond.str()); | ||
286 | } | ||
287 | |||
288 | if (_is_antonymic) | ||
289 | { | ||
290 | conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)"); | ||
291 | } | ||
292 | |||
293 | if (!_antonym_of.empty()) | ||
294 | { | ||
295 | std::stringstream cond; | ||
296 | if (_antonym_of.get_notlogic()) | ||
297 | { | ||
298 | cond << "adjective_id NOT IN"; | ||
299 | } else { | ||
300 | cond << "adjective_id IN"; | ||
301 | } | ||
302 | |||
303 | cond << "(SELECT adjective_2_id FROM adjective_antonymy WHERE "; | ||
304 | |||
305 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
306 | switch (f.get_type()) | ||
307 | { | ||
308 | case filter<adjective>::type::singleton: | ||
309 | { | ||
310 | if (notlogic == f.get_notlogic()) | ||
311 | { | ||
312 | return "adjective_1_id = @ANTID"; | ||
313 | } else { | ||
314 | return "adjective_1_id != @ANTID"; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | case filter<adjective>::type::group: | ||
319 | { | ||
320 | bool truelogic = notlogic != f.get_notlogic(); | ||
321 | |||
322 | std::list<std::string> clauses; | ||
323 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
324 | return recur(f2, truelogic); | ||
325 | }); | ||
326 | |||
327 | if (truelogic == f.get_orlogic()) | ||
328 | { | ||
329 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
330 | } else { | ||
331 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
332 | } | ||
333 | } | ||
334 | } | ||
335 | }; | ||
336 | |||
337 | cond << recur(_antonym_of, _antonym_of.get_notlogic()); | ||
338 | cond << ")"; | ||
339 | conditions.push_back(cond.str()); | ||
340 | } | ||
341 | |||
342 | if (_is_synonymic) | ||
343 | { | ||
344 | conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)"); | ||
345 | } | ||
346 | |||
347 | if (!_synonym_of.empty()) | ||
348 | { | ||
349 | std::stringstream cond; | ||
350 | if (_synonym_of.get_notlogic()) | ||
351 | { | ||
352 | cond << "adjective_id NOT IN"; | ||
353 | } else { | ||
354 | cond << "adjective_id IN"; | ||
355 | } | ||
356 | |||
357 | cond << "(SELECT adjective_2_id FROM adjective_synonymy WHERE "; | ||
358 | |||
359 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
360 | switch (f.get_type()) | ||
361 | { | ||
362 | case filter<adjective>::type::singleton: | ||
363 | { | ||
364 | if (notlogic == f.get_notlogic()) | ||
365 | { | ||
366 | return "adjective_1_id = @SYNID"; | ||
367 | } else { | ||
368 | return "adjective_1_id != @SYNID"; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | case filter<adjective>::type::group: | ||
373 | { | ||
374 | bool truelogic = notlogic != f.get_notlogic(); | ||
375 | |||
376 | std::list<std::string> clauses; | ||
377 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
378 | return recur(f2, truelogic); | ||
379 | }); | ||
380 | |||
381 | if (truelogic == f.get_orlogic()) | ||
382 | { | ||
383 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
384 | } else { | ||
385 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | }; | ||
390 | |||
391 | cond << recur(_synonym_of, _synonym_of.get_notlogic()); | ||
392 | cond << ")"; | ||
393 | conditions.push_back(cond.str()); | ||
394 | } | ||
395 | |||
396 | if (_is_generalization) | ||
397 | { | ||
398 | conditions.push_back("adjective_id IN (SELECT general_id FROM specification)"); | ||
399 | } | ||
400 | |||
401 | if (!_generalization_of.empty()) | ||
402 | { | ||
403 | std::stringstream cond; | ||
404 | if (_generalization_of.get_notlogic()) | ||
405 | { | ||
406 | cond << "adjective_id NOT IN"; | ||
407 | } else { | ||
408 | cond << "adjective_id IN"; | ||
409 | } | ||
410 | |||
411 | cond << "(SELECT general_id FROM specification WHERE "; | ||
412 | |||
413 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
414 | switch (f.get_type()) | ||
415 | { | ||
416 | case filter<adjective>::type::singleton: | ||
417 | { | ||
418 | if (notlogic == f.get_notlogic()) | ||
419 | { | ||
420 | return "specific_id = @SPECID"; | ||
421 | } else { | ||
422 | return "specific_id != @SPECID"; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | case filter<adjective>::type::group: | ||
427 | { | ||
428 | bool truelogic = notlogic != f.get_notlogic(); | ||
429 | |||
430 | std::list<std::string> clauses; | ||
431 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
432 | return recur(f2, truelogic); | ||
433 | }); | ||
434 | |||
435 | if (truelogic == f.get_orlogic()) | ||
436 | { | ||
437 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
438 | } else { | ||
439 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | }; | ||
444 | |||
445 | cond << recur(_generalization_of, _generalization_of.get_notlogic()); | ||
446 | cond << ")"; | ||
447 | conditions.push_back(cond.str()); | ||
448 | } | ||
449 | |||
450 | if (_is_specification) | ||
451 | { | ||
452 | conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)"); | ||
453 | } | ||
454 | |||
455 | if (!_specification_of.empty()) | ||
456 | { | ||
457 | std::stringstream cond; | ||
458 | if (_specification_of.get_notlogic()) | ||
459 | { | ||
460 | cond << "adjective_id NOT IN"; | ||
461 | } else { | ||
462 | cond << "adjective_id IN"; | ||
463 | } | ||
464 | |||
465 | cond << "(SELECT specific_id FROM specification WHERE "; | ||
466 | |||
467 | std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string { | ||
468 | switch (f.get_type()) | ||
469 | { | ||
470 | case filter<adjective>::type::singleton: | ||
471 | { | ||
472 | if (notlogic == f.get_notlogic()) | ||
473 | { | ||
474 | return "general_id = @GENID"; | ||
475 | } else { | ||
476 | return "general_id != @GENID"; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | case filter<adjective>::type::group: | ||
481 | { | ||
482 | bool truelogic = notlogic != f.get_notlogic(); | ||
483 | |||
484 | std::list<std::string> clauses; | ||
485 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) { | ||
486 | return recur(f2, truelogic); | ||
487 | }); | ||
488 | |||
489 | if (truelogic == f.get_orlogic()) | ||
490 | { | ||
491 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
492 | } else { | ||
493 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | }; | ||
498 | |||
499 | cond << recur(_specification_of, _specification_of.get_notlogic()); | ||
500 | cond << ")"; | ||
501 | conditions.push_back(cond.str()); | ||
502 | } | ||
503 | |||
504 | if (_is_pertainymic) | ||
505 | { | ||
506 | conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)"); | ||
507 | } | ||
508 | |||
509 | if (!_pertainym_of.empty()) | ||
510 | { | ||
511 | std::stringstream cond; | ||
512 | if (_pertainym_of.get_notlogic()) | ||
513 | { | ||
514 | cond << "adjective_id NOT IN"; | ||
515 | } else { | ||
516 | cond << "adjective_id IN"; | ||
517 | } | ||
518 | |||
519 | cond << "(SELECT pertainym_id FROM pertainymy WHERE "; | ||
520 | |||
521 | std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string { | ||
522 | switch (f.get_type()) | ||
523 | { | ||
524 | case filter<noun>::type::singleton: | ||
525 | { | ||
526 | if (notlogic == f.get_notlogic()) | ||
527 | { | ||
528 | return "noun_id = @APERID"; | ||
529 | } else { | ||
530 | return "noun_id != @APERID"; | ||
531 | } | ||
532 | } | ||
533 | |||
534 | case filter<noun>::type::group: | ||
535 | { | ||
536 | bool truelogic = notlogic != f.get_notlogic(); | ||
537 | |||
538 | std::list<std::string> clauses; | ||
539 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) { | ||
540 | return recur(f2, truelogic); | ||
541 | }); | ||
542 | |||
543 | if (truelogic == f.get_orlogic()) | ||
544 | { | ||
545 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
546 | } else { | ||
547 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | }; | ||
552 | |||
553 | cond << recur(_pertainym_of, _pertainym_of.get_notlogic()); | ||
554 | cond << ")"; | ||
555 | conditions.push_back(cond.str()); | ||
556 | } | ||
557 | |||
558 | if (_is_mannernymic) | ||
559 | { | ||
560 | conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)"); | ||
561 | } | ||
562 | |||
563 | if (!_anti_mannernym_of.empty()) | ||
564 | { | ||
565 | std::stringstream cond; | ||
566 | if (_anti_mannernym_of.get_notlogic()) | ||
567 | { | ||
568 | cond << "adjective_id NOT IN"; | ||
569 | } else { | ||
570 | cond << "adjective_id IN"; | ||
571 | } | ||
572 | |||
573 | cond << "(SELECT adjective_id FROM mannernymy WHERE "; | ||
574 | |||
575 | std::function<std::string (filter<adverb>, bool)> recur = [&] (filter<adverb> f, bool notlogic) -> std::string { | ||
576 | switch (f.get_type()) | ||
577 | { | ||
578 | case filter<adverb>::type::singleton: | ||
579 | { | ||
580 | if (notlogic == f.get_notlogic()) | ||
581 | { | ||
582 | return "mannernym_id = @MANID"; | ||
583 | } else { | ||
584 | return "mannernym_id != @MANID"; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | case filter<adverb>::type::group: | ||
589 | { | ||
590 | bool truelogic = notlogic != f.get_notlogic(); | ||
591 | |||
592 | std::list<std::string> clauses; | ||
593 | std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adverb> f2) { | ||
594 | return recur(f2, truelogic); | ||
595 | }); | ||
596 | |||
597 | if (truelogic == f.get_orlogic()) | ||
598 | { | ||
599 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; | ||
600 | } else { | ||
601 | return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | }; | ||
606 | |||
607 | cond << recur(_anti_mannernym_of, _anti_mannernym_of.get_notlogic()); | ||
608 | cond << ")"; | ||
609 | conditions.push_back(cond.str()); | ||
610 | } | ||
611 | /* | ||
612 | if (!_derived_from_adjective.empty()) | ||
613 | { | ||
614 | std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_2_id = @DERADJ"); | ||
615 | std::string cond = "adjective_id IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
616 | conditions.push_back(cond); | ||
617 | } | ||
618 | |||
619 | if (!_not_derived_from_adjective.empty()) | ||
620 | { | ||
621 | std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_2_id = @NDERADJ"); | ||
622 | std::string cond = "adjective_id NOT IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
623 | conditions.push_back(cond); | ||
624 | } | ||
625 | |||
626 | if (!_derived_from_adverb.empty()) | ||
627 | { | ||
628 | std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV"); | ||
629 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
630 | conditions.push_back(cond); | ||
631 | } | ||
632 | |||
633 | if (!_not_derived_from_adverb.empty()) | ||
634 | { | ||
635 | std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV"); | ||
636 | std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
637 | conditions.push_back(cond); | ||
638 | } | ||
639 | |||
640 | if (!_derived_from_noun.empty()) | ||
641 | { | ||
642 | std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN"); | ||
643 | std::string cond = "adjective_id IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
644 | conditions.push_back(cond); | ||
645 | } | ||
646 | |||
647 | if (!_not_derived_from_noun.empty()) | ||
648 | { | ||
649 | std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN"); | ||
650 | std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
651 | conditions.push_back(cond); | ||
652 | }*/ | ||
653 | |||
654 | if (!conditions.empty()) | ||
655 | { | ||
656 | construct << " WHERE "; | ||
657 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
658 | } | ||
659 | |||
660 | if (_random) | ||
661 | { | ||
662 | construct << " ORDER BY RANDOM()"; | ||
663 | } | ||
664 | |||
665 | if (_limit != unlimited) | ||
666 | { | ||
667 | construct << " LIMIT " << _limit; | ||
668 | } | ||
669 | |||
670 | sqlite3_stmt* ppstmt; | ||
671 | std::string query = construct.str(); | ||
672 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
673 | { | ||
674 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
675 | } | ||
676 | |||
677 | if (!_rhymes.empty()) | ||
678 | { | ||
679 | int i = 0; | ||
680 | for (auto rhyme : _rhymes) | ||
681 | { | ||
682 | std::string rhymer = "%" + rhyme; | ||
683 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
684 | |||
685 | i++; | ||
686 | } | ||
687 | } | ||
688 | |||
689 | for (auto except : _except) | ||
690 | { | ||
691 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
692 | } | ||
693 | |||
694 | for (auto attribute : _variant_of.inorder_flatten()) | ||
695 | { | ||
696 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id); | ||
697 | } | ||
698 | |||
699 | for (auto antonym : _antonym_of.inorder_flatten()) | ||
700 | { | ||
701 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
702 | } | ||
703 | |||
704 | for (auto synonym : _synonym_of.inorder_flatten()) | ||
705 | { | ||
706 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
707 | } | ||
708 | |||
709 | for (auto specific : _generalization_of.inorder_flatten()) | ||
710 | { | ||
711 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id); | ||
712 | } | ||
713 | |||
714 | for (auto general : _specification_of.inorder_flatten()) | ||
715 | { | ||
716 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id); | ||
717 | } | ||
718 | |||
719 | for (auto n : _pertainym_of.inorder_flatten()) | ||
720 | { | ||
721 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id); | ||
722 | } | ||
723 | |||
724 | for (auto mannernym : _anti_mannernym_of.inorder_flatten()) | ||
725 | { | ||
726 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id); | ||
727 | } | ||
728 | /* | ||
729 | for (auto adj : _derived_from_adjective) | ||
730 | { | ||
731 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id); | ||
732 | } | ||
733 | |||
734 | for (auto adj : _not_derived_from_adjective) | ||
735 | { | ||
736 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id); | ||
737 | } | ||
738 | |||
739 | for (auto adv : _derived_from_adverb) | ||
740 | { | ||
741 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id); | ||
742 | } | ||
743 | |||
744 | for (auto adv : _not_derived_from_adverb) | ||
745 | { | ||
746 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id); | ||
747 | } | ||
748 | |||
749 | for (auto n : _derived_from_noun) | ||
750 | { | ||
751 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id); | ||
752 | } | ||
753 | |||
754 | for (auto n : _not_derived_from_noun) | ||
755 | { | ||
756 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id); | ||
757 | } | ||
758 | */ | ||
759 | std::list<adjective> output; | ||
760 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
761 | { | ||
762 | adjective tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
763 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
764 | |||
765 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
766 | { | ||
767 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
768 | } | ||
769 | |||
770 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
771 | { | ||
772 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
773 | } | ||
774 | |||
775 | if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL) | ||
776 | { | ||
777 | std::string adjpos(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4))); | ||
778 | if (adjpos == "p") | ||
779 | { | ||
780 | tnc._position = adjective::positioning::predicate; | ||
781 | } else if (adjpos == "a") | ||
782 | { | ||
783 | tnc._position = adjective::positioning::attributive; | ||
784 | } else if (adjpos == "i") | ||
785 | { | ||
786 | tnc._position = adjective::positioning::postnominal; | ||
787 | } | ||
788 | } | ||
789 | |||
790 | output.push_back(tnc); | ||
791 | } | ||
792 | |||
793 | sqlite3_finalize(ppstmt); | ||
794 | |||
795 | for (auto& adjective : output) | ||
796 | { | ||
797 | query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?"; | ||
798 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
799 | { | ||
800 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
801 | } | ||
802 | |||
803 | sqlite3_bind_int(ppstmt, 1, adjective._id); | ||
804 | |||
805 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
806 | { | ||
807 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
808 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
809 | |||
810 | adjective.pronunciations.push_back(phonemes); | ||
811 | } | ||
812 | |||
813 | sqlite3_finalize(ppstmt); | ||
814 | } | ||
815 | |||
816 | return output; | ||
817 | } | ||
818 | |||
819 | }; | ||