summary refs log tree commit diff stats
path: root/lib/adjective_query.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/adjective_query.cpp')
-rw-r--r--lib/adjective_query.cpp1072
1 files changed, 0 insertions, 1072 deletions
diff --git a/lib/adjective_query.cpp b/lib/adjective_query.cpp deleted file mode 100644 index 90ccef4..0000000 --- a/lib/adjective_query.cpp +++ /dev/null
@@ -1,1072 +0,0 @@
1#include "verbly.h"
2
3namespace 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.get_rhymes())
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::rhymes_with(rhyme _r)
50 {
51 _rhymes.push_back(_r);
52
53 return *this;
54 }
55
56 adjective_query& adjective_query::has_pronunciation()
57 {
58 this->_has_prn = true;
59
60 return *this;
61 }
62
63 adjective_query& adjective_query::has_rhyming_noun()
64 {
65 _has_rhyming_noun = true;
66
67 return *this;
68 }
69
70 adjective_query& adjective_query::has_rhyming_adjective()
71 {
72 _has_rhyming_adjective = true;
73
74 return *this;
75 }
76
77 adjective_query& adjective_query::has_rhyming_adverb()
78 {
79 _has_rhyming_adverb = true;
80
81 return *this;
82 }
83
84 adjective_query& adjective_query::has_rhyming_verb()
85 {
86 _has_rhyming_verb = true;
87
88 return *this;
89 }
90
91 adjective_query& adjective_query::with_stress(filter<std::vector<bool>> _arg)
92 {
93 _stress = _arg;
94
95 return *this;
96 }
97
98 adjective_query& adjective_query::with_prefix(filter<std::string> _f)
99 {
100 _f.clean();
101 _with_prefix = _f;
102
103 return *this;
104 }
105
106 adjective_query& adjective_query::with_suffix(filter<std::string> _f)
107 {
108 _f.clean();
109 _with_suffix = _f;
110
111 return *this;
112 }
113
114 adjective_query& adjective_query::with_complexity(int _arg)
115 {
116 _with_complexity = _arg;
117
118 return *this;
119 }
120
121 adjective_query& adjective_query::requires_comparative_form()
122 {
123 _requires_comparative_form = true;
124
125 return *this;
126 }
127
128 adjective_query& adjective_query::requires_superlative_form()
129 {
130 _requires_superlative_form = true;
131
132 return *this;
133 }
134
135 adjective_query& adjective_query::position(adjective::positioning pos)
136 {
137 _position = pos;
138
139 return *this;
140 }
141
142 adjective_query& adjective_query::is_variant()
143 {
144 this->_is_variant = true;
145
146 return *this;
147 }
148
149 adjective_query& adjective_query::variant_of(filter<noun> _f)
150 {
151 _f.clean();
152 _variant_of = _f;
153
154 return *this;
155 }
156
157 adjective_query& adjective_query::has_antonyms()
158 {
159 this->_is_antonymic = true;
160
161 return *this;
162 }
163
164 adjective_query& adjective_query::antonym_of(filter<adjective> _f)
165 {
166 _f.clean();
167 _antonym_of = _f;
168
169 return *this;
170 }
171
172 adjective_query& adjective_query::has_synonyms()
173 {
174 this->_is_synonymic = true;
175
176 return *this;
177 }
178
179 adjective_query& adjective_query::synonym_of(filter<adjective> _f)
180 {
181 _f.clean();
182 _synonym_of = _f;
183
184 return *this;
185 }
186
187 adjective_query& adjective_query::is_generalization()
188 {
189 this->_is_generalization = true;
190
191 return *this;
192 }
193
194 adjective_query& adjective_query::generalization_of(filter<adjective> _f)
195 {
196 _f.clean();
197 _generalization_of = _f;
198
199 return *this;
200 }
201
202 adjective_query& adjective_query::is_specification()
203 {
204 this->_is_specification = true;
205
206 return *this;
207 }
208
209 adjective_query& adjective_query::specification_of(filter<adjective> _f)
210 {
211 _f.clean();
212 _specification_of = _f;
213
214 return *this;
215 }
216
217 adjective_query& adjective_query::is_pertainymic()
218 {
219 this->_is_pertainymic = true;
220
221 return *this;
222 }
223
224 adjective_query& adjective_query::pertainym_of(filter<noun> _f)
225 {
226 _f.clean();
227 _pertainym_of = _f;
228
229 return *this;
230 }
231
232 adjective_query& adjective_query::is_mannernymic()
233 {
234 this->_is_mannernymic = true;
235
236 return *this;
237 }
238
239 adjective_query& adjective_query::anti_mannernym_of(filter<adverb> _f)
240 {
241 _f.clean();
242 _anti_mannernym_of = _f;
243
244 return *this;
245 }
246 /*
247 adjective_query& adjective_query::derived_from(const word& _w)
248 {
249 if (dynamic_cast<const adjective*>(&_w) != nullptr)
250 {
251 _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
252 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
253 {
254 _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
255 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
256 {
257 _derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
258 }
259
260 return *this;
261 }
262
263 adjective_query& adjective_query::not_derived_from(const word& _w)
264 {
265 if (dynamic_cast<const adjective*>(&_w) != nullptr)
266 {
267 _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
268 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
269 {
270 _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
271 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
272 {
273 _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
274 }
275
276 return *this;
277 }
278 */
279 std::list<adjective> adjective_query::run() const
280 {
281 std::stringstream construct;
282 construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives";
283 std::list<std::string> conditions;
284 std::list<binding> bindings;
285
286 if (_has_prn)
287 {
288 conditions.push_back("adjective_id IN (SELECT adjective_id FROM adjective_pronunciations)");
289 }
290
291 if (!_rhymes.empty())
292 {
293 std::list<std::string> clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)");
294 std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
295 conditions.push_back(cond);
296
297 for (auto rhy : _rhymes)
298 {
299 bindings.emplace_back(rhy.get_prerhyme());
300 bindings.emplace_back(rhy.get_rhyme());
301 }
302 }
303
304 if (_has_rhyming_noun)
305 {
306 conditions.push_back("adjective_id IN (SELECT a.adjective_id FROM adjectives AS a INNER JOIN adjective_pronunciations AS curp ON curp.adjective_id = a.adjective_id INNER JOIN noun_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)");
307 }
308
309 if (_has_rhyming_adjective)
310 {
311 conditions.push_back("adjective_id IN (SELECT a.adjective_id FROM adjectives AS a INNER JOIN adjective_pronunciations AS curp ON curp.adjective_id = a.adjective_id INNER JOIN adjective_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme AND rhmp.adjective_id != curp.adjective_id)");
312 }
313
314 if (_has_rhyming_adverb)
315 {
316 conditions.push_back("adjective_id IN (SELECT a.adjective_id FROM adjectives AS a INNER JOIN adjective_pronunciations AS curp ON curp.adjective_id = a.adjective_id INNER JOIN adverb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)");
317 }
318
319 if (_has_rhyming_verb)
320 {
321 conditions.push_back("adjective_id IN (SELECT a.adjective_id FROM adjectives AS a INNER JOIN adjective_pronunciations AS curp ON curp.adjective_id = a.adjective_id INNER JOIN verb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)");
322 }
323
324 for (auto except : _except)
325 {
326 conditions.push_back("adjective_id != ?");
327 bindings.emplace_back(except._id);
328 }
329
330 if (_requires_comparative_form)
331 {
332 conditions.push_back("comparative IS NOT NULL");
333 }
334
335 if (_requires_superlative_form)
336 {
337 conditions.push_back("superlative IS NOT NULL");
338 }
339
340 switch (_position)
341 {
342 case adjective::positioning::predicate: conditions.push_back("position = 'p'"); break;
343 case adjective::positioning::attributive: conditions.push_back("position = 'a'"); break;
344 case adjective::positioning::postnominal: conditions.push_back("position = 'i'"); break;
345 case adjective::positioning::undefined: break;
346 }
347
348 if (!_stress.empty())
349 {
350 std::stringstream cond;
351 if (_stress.get_notlogic())
352 {
353 cond << "adjective_id NOT IN";
354 } else {
355 cond << "adjective_id IN";
356 }
357
358 cond << "(SELECT adjective_id FROM adjective_pronunciations WHERE ";
359
360 std::function<std::string (filter<std::vector<bool>>, bool)> recur = [&] (filter<std::vector<bool>> f, bool notlogic) -> std::string {
361 switch (f.get_type())
362 {
363 case filter<std::vector<bool>>::type::singleton:
364 {
365 std::ostringstream _val;
366 for (auto syl : f.get_elem())
367 {
368 if (syl)
369 {
370 _val << "1";
371 } else {
372 _val << "0";
373 }
374 }
375
376 bindings.emplace_back(_val.str());
377
378 if (notlogic == f.get_notlogic())
379 {
380 return "stress = ?";
381 } else {
382 return "stress != ?";
383 }
384 }
385
386 case filter<std::vector<bool>>::type::group:
387 {
388 bool truelogic = notlogic != f.get_notlogic();
389
390 std::list<std::string> clauses;
391 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::vector<bool>> f2) {
392 return recur(f2, truelogic);
393 });
394
395 if (truelogic == f.get_orlogic())
396 {
397 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
398 } else {
399 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
400 }
401 }
402 }
403 };
404
405 cond << recur(_stress, _stress.get_notlogic());
406 cond << ")";
407 conditions.push_back(cond.str());
408 }
409
410 if (!_with_prefix.empty())
411 {
412 std::function<std::string (filter<std::string>, bool)> recur = [&] (filter<std::string> f, bool notlogic) -> std::string {
413 switch (f.get_type())
414 {
415 case filter<std::string>::type::singleton:
416 {
417 bindings.emplace_back(f.get_elem() + "%");
418
419 if (notlogic == f.get_notlogic())
420 {
421 return "base_form LIKE ?";
422 } else {
423 return "base_form NOT LIKE ?";
424 }
425 }
426
427 case filter<std::string>::type::group:
428 {
429 bool truelogic = notlogic != f.get_notlogic();
430
431 std::list<std::string> clauses;
432 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::string> f2) {
433 return recur(f2, truelogic);
434 });
435
436 if (truelogic == f.get_orlogic())
437 {
438 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
439 } else {
440 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
441 }
442 }
443 }
444 };
445
446 conditions.push_back(recur(_with_prefix, false));
447 }
448
449 if (!_with_suffix.empty())
450 {
451 std::function<std::string (filter<std::string>, bool)> recur = [&] (filter<std::string> f, bool notlogic) -> std::string {
452 switch (f.get_type())
453 {
454 case filter<std::string>::type::singleton:
455 {
456 bindings.emplace_back("%" + f.get_elem());
457
458 if (notlogic == f.get_notlogic())
459 {
460 return "base_form LIKE ?";
461 } else {
462 return "base_form NOT LIKE ?";
463 }
464 }
465
466 case filter<std::string>::type::group:
467 {
468 bool truelogic = notlogic != f.get_notlogic();
469
470 std::list<std::string> clauses;
471 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<std::string> f2) {
472 return recur(f2, truelogic);
473 });
474
475 if (truelogic == f.get_orlogic())
476 {
477 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
478 } else {
479 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
480 }
481 }
482 }
483 };
484
485 conditions.push_back(recur(_with_suffix, false));
486 }
487
488 if (_with_complexity != unlimited)
489 {
490 conditions.push_back("complexity = ?");
491 bindings.emplace_back(_with_complexity);
492 }
493
494 if (_is_variant)
495 {
496 conditions.push_back("adjective_id IN (SELECT adjective_id FROM variation)");
497 }
498
499 if (!_variant_of.empty())
500 {
501 std::stringstream cond;
502 if (_variant_of.get_notlogic())
503 {
504 cond << "adjective_id NOT IN";
505 } else {
506 cond << "adjective_id IN";
507 }
508
509 cond << "(SELECT adjective_id FROM variation WHERE ";
510
511 std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string {
512 switch (f.get_type())
513 {
514 case filter<noun>::type::singleton:
515 {
516 bindings.emplace_back(f.get_elem()._id);
517
518 if (notlogic == f.get_notlogic())
519 {
520 return "noun_id = ?";
521 } else {
522 return "noun_id != ?";
523 }
524 }
525
526 case filter<noun>::type::group:
527 {
528 bool truelogic = notlogic != f.get_notlogic();
529
530 std::list<std::string> clauses;
531 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) {
532 return recur(f2, truelogic);
533 });
534
535 if (truelogic == f.get_orlogic())
536 {
537 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
538 } else {
539 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
540 }
541 }
542 }
543 };
544
545 cond << recur(_variant_of, _variant_of.get_notlogic());
546 cond << ")";
547 conditions.push_back(cond.str());
548 }
549
550 if (_is_antonymic)
551 {
552 conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_antonymy)");
553 }
554
555 if (!_antonym_of.empty())
556 {
557 std::stringstream cond;
558 if (_antonym_of.get_notlogic())
559 {
560 cond << "adjective_id NOT IN";
561 } else {
562 cond << "adjective_id IN";
563 }
564
565 cond << "(SELECT adjective_2_id FROM adjective_antonymy WHERE ";
566
567 std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string {
568 switch (f.get_type())
569 {
570 case filter<adjective>::type::singleton:
571 {
572 bindings.emplace_back(f.get_elem()._id);
573
574 if (notlogic == f.get_notlogic())
575 {
576 return "adjective_1_id = ?";
577 } else {
578 return "adjective_1_id != ?";
579 }
580 }
581
582 case filter<adjective>::type::group:
583 {
584 bool truelogic = notlogic != f.get_notlogic();
585
586 std::list<std::string> clauses;
587 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) {
588 return recur(f2, truelogic);
589 });
590
591 if (truelogic == f.get_orlogic())
592 {
593 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
594 } else {
595 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
596 }
597 }
598 }
599 };
600
601 cond << recur(_antonym_of, _antonym_of.get_notlogic());
602 cond << ")";
603 conditions.push_back(cond.str());
604 }
605
606 if (_is_synonymic)
607 {
608 conditions.push_back("adjective_id IN (SELECT adjective_2_id FROM adjective_synonymy)");
609 }
610
611 if (!_synonym_of.empty())
612 {
613 std::stringstream cond;
614 if (_synonym_of.get_notlogic())
615 {
616 cond << "adjective_id NOT IN";
617 } else {
618 cond << "adjective_id IN";
619 }
620
621 cond << "(SELECT adjective_2_id FROM adjective_synonymy WHERE ";
622
623 std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string {
624 switch (f.get_type())
625 {
626 case filter<adjective>::type::singleton:
627 {
628 bindings.emplace_back(f.get_elem()._id);
629
630 if (notlogic == f.get_notlogic())
631 {
632 return "adjective_1_id = ?";
633 } else {
634 return "adjective_1_id != ?";
635 }
636 }
637
638 case filter<adjective>::type::group:
639 {
640 bool truelogic = notlogic != f.get_notlogic();
641
642 std::list<std::string> clauses;
643 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) {
644 return recur(f2, truelogic);
645 });
646
647 if (truelogic == f.get_orlogic())
648 {
649 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
650 } else {
651 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
652 }
653 }
654 }
655 };
656
657 cond << recur(_synonym_of, _synonym_of.get_notlogic());
658 cond << ")";
659 conditions.push_back(cond.str());
660 }
661
662 if (_is_generalization)
663 {
664 conditions.push_back("adjective_id IN (SELECT general_id FROM specification)");
665 }
666
667 if (!_generalization_of.empty())
668 {
669 std::stringstream cond;
670 if (_generalization_of.get_notlogic())
671 {
672 cond << "adjective_id NOT IN";
673 } else {
674 cond << "adjective_id IN";
675 }
676
677 cond << "(SELECT general_id FROM specification WHERE ";
678
679 std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string {
680 switch (f.get_type())
681 {
682 case filter<adjective>::type::singleton:
683 {
684 bindings.emplace_back(f.get_elem()._id);
685
686 if (notlogic == f.get_notlogic())
687 {
688 return "specific_id = ?";
689 } else {
690 return "specific_id != ?";
691 }
692 }
693
694 case filter<adjective>::type::group:
695 {
696 bool truelogic = notlogic != f.get_notlogic();
697
698 std::list<std::string> clauses;
699 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) {
700 return recur(f2, truelogic);
701 });
702
703 if (truelogic == f.get_orlogic())
704 {
705 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
706 } else {
707 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
708 }
709 }
710 }
711 };
712
713 cond << recur(_generalization_of, _generalization_of.get_notlogic());
714 cond << ")";
715 conditions.push_back(cond.str());
716 }
717
718 if (_is_specification)
719 {
720 conditions.push_back("adjective_id IN (SELECT specific_id FROM specification)");
721 }
722
723 if (!_specification_of.empty())
724 {
725 std::stringstream cond;
726 if (_specification_of.get_notlogic())
727 {
728 cond << "adjective_id NOT IN";
729 } else {
730 cond << "adjective_id IN";
731 }
732
733 cond << "(SELECT specific_id FROM specification WHERE ";
734
735 std::function<std::string (filter<adjective>, bool)> recur = [&] (filter<adjective> f, bool notlogic) -> std::string {
736 switch (f.get_type())
737 {
738 case filter<adjective>::type::singleton:
739 {
740 bindings.emplace_back(f.get_elem()._id);
741
742 if (notlogic == f.get_notlogic())
743 {
744 return "general_id = ?";
745 } else {
746 return "general_id != ?";
747 }
748 }
749
750 case filter<adjective>::type::group:
751 {
752 bool truelogic = notlogic != f.get_notlogic();
753
754 std::list<std::string> clauses;
755 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adjective> f2) {
756 return recur(f2, truelogic);
757 });
758
759 if (truelogic == f.get_orlogic())
760 {
761 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
762 } else {
763 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
764 }
765 }
766 }
767 };
768
769 cond << recur(_specification_of, _specification_of.get_notlogic());
770 cond << ")";
771 conditions.push_back(cond.str());
772 }
773
774 if (_is_pertainymic)
775 {
776 conditions.push_back("adjective_id IN (SELECT pertainym_id FROM pertainymy)");
777 }
778
779 if (!_pertainym_of.empty())
780 {
781 std::stringstream cond;
782 if (_pertainym_of.get_notlogic())
783 {
784 cond << "adjective_id NOT IN";
785 } else {
786 cond << "adjective_id IN";
787 }
788
789 cond << "(SELECT pertainym_id FROM pertainymy WHERE ";
790
791 std::function<std::string (filter<noun>, bool)> recur = [&] (filter<noun> f, bool notlogic) -> std::string {
792 switch (f.get_type())
793 {
794 case filter<noun>::type::singleton:
795 {
796 bindings.emplace_back(f.get_elem()._id);
797
798 if (notlogic == f.get_notlogic())
799 {
800 return "noun_id = ?";
801 } else {
802 return "noun_id != ?";
803 }
804 }
805
806 case filter<noun>::type::group:
807 {
808 bool truelogic = notlogic != f.get_notlogic();
809
810 std::list<std::string> clauses;
811 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<noun> f2) {
812 return recur(f2, truelogic);
813 });
814
815 if (truelogic == f.get_orlogic())
816 {
817 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
818 } else {
819 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
820 }
821 }
822 }
823 };
824
825 cond << recur(_pertainym_of, _pertainym_of.get_notlogic());
826 cond << ")";
827 conditions.push_back(cond.str());
828 }
829
830 if (_is_mannernymic)
831 {
832 conditions.push_back("adjective_id IN (SELECT adjective_id FROM mannernymy)");
833 }
834
835 if (!_anti_mannernym_of.empty())
836 {
837 std::stringstream cond;
838 if (_anti_mannernym_of.get_notlogic())
839 {
840 cond << "adjective_id NOT IN";
841 } else {
842 cond << "adjective_id IN";
843 }
844
845 cond << "(SELECT adjective_id FROM mannernymy WHERE ";
846
847 std::function<std::string (filter<adverb>, bool)> recur = [&] (filter<adverb> f, bool notlogic) -> std::string {
848 switch (f.get_type())
849 {
850 case filter<adverb>::type::singleton:
851 {
852 bindings.emplace_back(f.get_elem()._id);
853
854 if (notlogic == f.get_notlogic())
855 {
856 return "mannernym_id = ?";
857 } else {
858 return "mannernym_id != ?";
859 }
860 }
861
862 case filter<adverb>::type::group:
863 {
864 bool truelogic = notlogic != f.get_notlogic();
865
866 std::list<std::string> clauses;
867 std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter<adverb> f2) {
868 return recur(f2, truelogic);
869 });
870
871 if (truelogic == f.get_orlogic())
872 {
873 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")";
874 } else {
875 return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
876 }
877 }
878 }
879 };
880
881 cond << recur(_anti_mannernym_of, _anti_mannernym_of.get_notlogic());
882 cond << ")";
883 conditions.push_back(cond.str());
884 }
885/*
886 if (!_derived_from_adjective.empty())
887 {
888 std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_2_id = @DERADJ");
889 std::string cond = "adjective_id IN (SELECT adjective_1_id FROM adjective_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
890 conditions.push_back(cond);
891 }
892
893 if (!_not_derived_from_adjective.empty())
894 {
895 std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_2_id = @NDERADJ");
896 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 ") + ")";
897 conditions.push_back(cond);
898 }
899
900 if (!_derived_from_adverb.empty())
901 {
902 std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_id = @DERADV");
903 std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
904 conditions.push_back(cond);
905 }
906
907 if (!_not_derived_from_adverb.empty())
908 {
909 std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_id = @NDERADV");
910 std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
911 conditions.push_back(cond);
912 }
913
914 if (!_derived_from_noun.empty())
915 {
916 std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN");
917 std::string cond = "adjective_id IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
918 conditions.push_back(cond);
919 }
920
921 if (!_not_derived_from_noun.empty())
922 {
923 std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN");
924 std::string cond = "adjective_id NOT IN (SELECT adjective_id FROM noun_adjective_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
925 conditions.push_back(cond);
926 }*/
927
928 if (!conditions.empty())
929 {
930 construct << " WHERE ";
931 construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND ");
932 }
933
934 if (_random)
935 {
936 construct << " ORDER BY RANDOM()";
937 }
938
939 if (_limit != unlimited)
940 {
941 construct << " LIMIT " << _limit;
942 }
943
944 sqlite3_stmt* ppstmt;
945 std::string query = construct.str();
946 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
947 {
948 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
949 }
950
951 int i = 1;
952 for (auto& binding : bindings)
953 {
954 switch (binding.get_type())
955 {
956 case binding::type::integer:
957 {
958 sqlite3_bind_int(ppstmt, i, binding.get_integer());
959
960 break;
961 }
962
963 case binding::type::string:
964 {
965 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT);
966
967 break;
968 }
969 }
970
971 i++;
972 }
973
974 /*
975 for (auto adj : _derived_from_adjective)
976 {
977 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id);
978 }
979
980 for (auto adj : _not_derived_from_adjective)
981 {
982 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id);
983 }
984
985 for (auto adv : _derived_from_adverb)
986 {
987 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id);
988 }
989
990 for (auto adv : _not_derived_from_adverb)
991 {
992 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id);
993 }
994
995 for (auto n : _derived_from_noun)
996 {
997 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id);
998 }
999
1000 for (auto n : _not_derived_from_noun)
1001 {
1002 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id);
1003 }
1004*/
1005 std::list<adjective> output;
1006 while (sqlite3_step(ppstmt) == SQLITE_ROW)
1007 {
1008 adjective tnc {_data, sqlite3_column_int(ppstmt, 0)};
1009 tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
1010
1011 if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)
1012 {
1013 tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
1014 }
1015
1016 if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL)
1017 {
1018 tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3)));
1019 }
1020
1021 if (sqlite3_column_type(ppstmt, 4) != SQLITE_NULL)
1022 {
1023 std::string adjpos(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 4)));
1024 if (adjpos == "p")
1025 {
1026 tnc._position = adjective::positioning::predicate;
1027 } else if (adjpos == "a")
1028 {
1029 tnc._position = adjective::positioning::attributive;
1030 } else if (adjpos == "i")
1031 {
1032 tnc._position = adjective::positioning::postnominal;
1033 }
1034 }
1035
1036 output.push_back(tnc);
1037 }
1038
1039 sqlite3_finalize(ppstmt);
1040
1041 for (auto& adjective : output)
1042 {
1043 query = "SELECT pronunciation, prerhyme, rhyme FROM adjective_pronunciations WHERE adjective_id = ?";
1044 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
1045 {
1046 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
1047 }
1048
1049 sqlite3_bind_int(ppstmt, 1, adjective._id);
1050
1051 while (sqlite3_step(ppstmt) == SQLITE_ROW)
1052 {
1053 std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0)));
1054 auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " ");
1055
1056 adjective.pronunciations.push_back(phonemes);
1057
1058 if ((sqlite3_column_type(ppstmt, 1) != SQLITE_NULL) && (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL))
1059 {
1060 std::string prerhyme(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
1061 std::string rhyming(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
1062 adjective.rhymes.emplace_back(prerhyme, rhyming);
1063 }
1064 }
1065
1066 sqlite3_finalize(ppstmt);
1067 }
1068
1069 return output;
1070 }
1071
1072};