diff options
Diffstat (limited to 'lib/adjective_query.cpp')
-rw-r--r-- | lib/adjective_query.cpp | 1072 |
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 | |||
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.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 | }; | ||