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.cpp819
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
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.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};