diff options
Diffstat (limited to 'lib/adjective_query.cpp')
-rw-r--r-- | lib/adjective_query.cpp | 207 |
1 files changed, 122 insertions, 85 deletions
diff --git a/lib/adjective_query.cpp b/lib/adjective_query.cpp index 283fdca..2bea68f 100644 --- a/lib/adjective_query.cpp +++ b/lib/adjective_query.cpp | |||
@@ -33,7 +33,7 @@ namespace verbly { | |||
33 | 33 | ||
34 | adjective_query& adjective_query::rhymes_with(const word& _word) | 34 | adjective_query& adjective_query::rhymes_with(const word& _word) |
35 | { | 35 | { |
36 | for (auto rhyme : _word.rhyme_phonemes()) | 36 | for (auto rhyme : _word.get_rhymes()) |
37 | { | 37 | { |
38 | _rhymes.push_back(rhyme); | 38 | _rhymes.push_back(rhyme); |
39 | } | 39 | } |
@@ -53,6 +53,34 @@ namespace verbly { | |||
53 | return *this; | 53 | return *this; |
54 | } | 54 | } |
55 | 55 | ||
56 | adjective_query& adjective_query::has_rhyming_noun() | ||
57 | { | ||
58 | _has_rhyming_noun = true; | ||
59 | |||
60 | return *this; | ||
61 | } | ||
62 | |||
63 | adjective_query& adjective_query::has_rhyming_adjective() | ||
64 | { | ||
65 | _has_rhyming_adjective = true; | ||
66 | |||
67 | return *this; | ||
68 | } | ||
69 | |||
70 | adjective_query& adjective_query::has_rhyming_adverb() | ||
71 | { | ||
72 | _has_rhyming_adverb = true; | ||
73 | |||
74 | return *this; | ||
75 | } | ||
76 | |||
77 | adjective_query& adjective_query::has_rhyming_verb() | ||
78 | { | ||
79 | _has_rhyming_verb = true; | ||
80 | |||
81 | return *this; | ||
82 | } | ||
83 | |||
56 | adjective_query& adjective_query::with_prefix(filter<std::string> _f) | 84 | adjective_query& adjective_query::with_prefix(filter<std::string> _f) |
57 | { | 85 | { |
58 | _f.clean(); | 86 | _f.clean(); |
@@ -218,6 +246,7 @@ namespace verbly { | |||
218 | std::stringstream construct; | 246 | std::stringstream construct; |
219 | construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; | 247 | construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; |
220 | std::list<std::string> conditions; | 248 | std::list<std::string> conditions; |
249 | std::list<binding> bindings; | ||
221 | 250 | ||
222 | if (_has_prn) | 251 | if (_has_prn) |
223 | { | 252 | { |
@@ -226,14 +255,41 @@ namespace verbly { | |||
226 | 255 | ||
227 | if (!_rhymes.empty()) | 256 | if (!_rhymes.empty()) |
228 | { | 257 | { |
229 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | 258 | std::list<std::string> clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)"); |
230 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 259 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; |
231 | conditions.push_back(cond); | 260 | conditions.push_back(cond); |
261 | |||
262 | for (auto rhy : _rhymes) | ||
263 | { | ||
264 | bindings.emplace_back(rhy.get_prerhyme()); | ||
265 | bindings.emplace_back(rhy.get_rhyme()); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | if (_has_rhyming_noun) | ||
270 | { | ||
271 | 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)"); | ||
272 | } | ||
273 | |||
274 | if (_has_rhyming_adjective) | ||
275 | { | ||
276 | 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)"); | ||
277 | } | ||
278 | |||
279 | if (_has_rhyming_adverb) | ||
280 | { | ||
281 | 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)"); | ||
282 | } | ||
283 | |||
284 | if (_has_rhyming_verb) | ||
285 | { | ||
286 | 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)"); | ||
232 | } | 287 | } |
233 | 288 | ||
234 | for (auto except : _except) | 289 | for (auto except : _except) |
235 | { | 290 | { |
236 | conditions.push_back("adjective_id != @EXCID"); | 291 | conditions.push_back("adjective_id != ?"); |
292 | bindings.emplace_back(except._id); | ||
237 | } | 293 | } |
238 | 294 | ||
239 | if (_requires_comparative_form) | 295 | if (_requires_comparative_form) |
@@ -261,11 +317,13 @@ namespace verbly { | |||
261 | { | 317 | { |
262 | case filter<std::string>::type::singleton: | 318 | case filter<std::string>::type::singleton: |
263 | { | 319 | { |
320 | bindings.emplace_back(f.get_elem() + "%"); | ||
321 | |||
264 | if (notlogic == f.get_notlogic()) | 322 | if (notlogic == f.get_notlogic()) |
265 | { | 323 | { |
266 | return "base_form LIKE @PREFIX"; | 324 | return "base_form LIKE ?"; |
267 | } else { | 325 | } else { |
268 | return "base_form NOT LIKE @PREFIX"; | 326 | return "base_form NOT LIKE ?"; |
269 | } | 327 | } |
270 | } | 328 | } |
271 | 329 | ||
@@ -298,11 +356,13 @@ namespace verbly { | |||
298 | { | 356 | { |
299 | case filter<std::string>::type::singleton: | 357 | case filter<std::string>::type::singleton: |
300 | { | 358 | { |
359 | bindings.emplace_back("%" + f.get_elem()); | ||
360 | |||
301 | if (notlogic == f.get_notlogic()) | 361 | if (notlogic == f.get_notlogic()) |
302 | { | 362 | { |
303 | return "base_form LIKE @SUFFIX"; | 363 | return "base_form LIKE ?"; |
304 | } else { | 364 | } else { |
305 | return "base_form NOT LIKE @SUFFIX"; | 365 | return "base_form NOT LIKE ?"; |
306 | } | 366 | } |
307 | } | 367 | } |
308 | 368 | ||
@@ -330,7 +390,8 @@ namespace verbly { | |||
330 | 390 | ||
331 | if (_with_complexity != unlimited) | 391 | if (_with_complexity != unlimited) |
332 | { | 392 | { |
333 | conditions.push_back("complexity = @COMPLEX"); | 393 | conditions.push_back("complexity = ?"); |
394 | bindings.emplace_back(_with_complexity); | ||
334 | } | 395 | } |
335 | 396 | ||
336 | if (_is_variant) | 397 | if (_is_variant) |
@@ -355,11 +416,13 @@ namespace verbly { | |||
355 | { | 416 | { |
356 | case filter<noun>::type::singleton: | 417 | case filter<noun>::type::singleton: |
357 | { | 418 | { |
419 | bindings.emplace_back(f.get_elem()._id); | ||
420 | |||
358 | if (notlogic == f.get_notlogic()) | 421 | if (notlogic == f.get_notlogic()) |
359 | { | 422 | { |
360 | return "noun_id = @ATTRID"; | 423 | return "noun_id = ?"; |
361 | } else { | 424 | } else { |
362 | return "noun_id != @ATTRID"; | 425 | return "noun_id != ?"; |
363 | } | 426 | } |
364 | } | 427 | } |
365 | 428 | ||
@@ -409,11 +472,13 @@ namespace verbly { | |||
409 | { | 472 | { |
410 | case filter<adjective>::type::singleton: | 473 | case filter<adjective>::type::singleton: |
411 | { | 474 | { |
475 | bindings.emplace_back(f.get_elem()._id); | ||
476 | |||
412 | if (notlogic == f.get_notlogic()) | 477 | if (notlogic == f.get_notlogic()) |
413 | { | 478 | { |
414 | return "adjective_1_id = @ANTID"; | 479 | return "adjective_1_id = ?"; |
415 | } else { | 480 | } else { |
416 | return "adjective_1_id != @ANTID"; | 481 | return "adjective_1_id != ?"; |
417 | } | 482 | } |
418 | } | 483 | } |
419 | 484 | ||
@@ -463,11 +528,13 @@ namespace verbly { | |||
463 | { | 528 | { |
464 | case filter<adjective>::type::singleton: | 529 | case filter<adjective>::type::singleton: |
465 | { | 530 | { |
531 | bindings.emplace_back(f.get_elem()._id); | ||
532 | |||
466 | if (notlogic == f.get_notlogic()) | 533 | if (notlogic == f.get_notlogic()) |
467 | { | 534 | { |
468 | return "adjective_1_id = @SYNID"; | 535 | return "adjective_1_id = ?"; |
469 | } else { | 536 | } else { |
470 | return "adjective_1_id != @SYNID"; | 537 | return "adjective_1_id != ?"; |
471 | } | 538 | } |
472 | } | 539 | } |
473 | 540 | ||
@@ -517,11 +584,13 @@ namespace verbly { | |||
517 | { | 584 | { |
518 | case filter<adjective>::type::singleton: | 585 | case filter<adjective>::type::singleton: |
519 | { | 586 | { |
587 | bindings.emplace_back(f.get_elem()._id); | ||
588 | |||
520 | if (notlogic == f.get_notlogic()) | 589 | if (notlogic == f.get_notlogic()) |
521 | { | 590 | { |
522 | return "specific_id = @SPECID"; | 591 | return "specific_id = ?"; |
523 | } else { | 592 | } else { |
524 | return "specific_id != @SPECID"; | 593 | return "specific_id != ?"; |
525 | } | 594 | } |
526 | } | 595 | } |
527 | 596 | ||
@@ -571,11 +640,13 @@ namespace verbly { | |||
571 | { | 640 | { |
572 | case filter<adjective>::type::singleton: | 641 | case filter<adjective>::type::singleton: |
573 | { | 642 | { |
643 | bindings.emplace_back(f.get_elem()._id); | ||
644 | |||
574 | if (notlogic == f.get_notlogic()) | 645 | if (notlogic == f.get_notlogic()) |
575 | { | 646 | { |
576 | return "general_id = @GENID"; | 647 | return "general_id = ?"; |
577 | } else { | 648 | } else { |
578 | return "general_id != @GENID"; | 649 | return "general_id != ?"; |
579 | } | 650 | } |
580 | } | 651 | } |
581 | 652 | ||
@@ -625,11 +696,13 @@ namespace verbly { | |||
625 | { | 696 | { |
626 | case filter<noun>::type::singleton: | 697 | case filter<noun>::type::singleton: |
627 | { | 698 | { |
699 | bindings.emplace_back(f.get_elem()._id); | ||
700 | |||
628 | if (notlogic == f.get_notlogic()) | 701 | if (notlogic == f.get_notlogic()) |
629 | { | 702 | { |
630 | return "noun_id = @APERID"; | 703 | return "noun_id = ?"; |
631 | } else { | 704 | } else { |
632 | return "noun_id != @APERID"; | 705 | return "noun_id != ?"; |
633 | } | 706 | } |
634 | } | 707 | } |
635 | 708 | ||
@@ -679,11 +752,13 @@ namespace verbly { | |||
679 | { | 752 | { |
680 | case filter<adverb>::type::singleton: | 753 | case filter<adverb>::type::singleton: |
681 | { | 754 | { |
755 | bindings.emplace_back(f.get_elem()._id); | ||
756 | |||
682 | if (notlogic == f.get_notlogic()) | 757 | if (notlogic == f.get_notlogic()) |
683 | { | 758 | { |
684 | return "mannernym_id = @MANID"; | 759 | return "mannernym_id = ?"; |
685 | } else { | 760 | } else { |
686 | return "mannernym_id != @MANID"; | 761 | return "mannernym_id != ?"; |
687 | } | 762 | } |
688 | } | 763 | } |
689 | 764 | ||
@@ -776,74 +851,29 @@ namespace verbly { | |||
776 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 851 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
777 | } | 852 | } |
778 | 853 | ||
779 | if (!_rhymes.empty()) | 854 | int i = 1; |
855 | for (auto& binding : bindings) | ||
780 | { | 856 | { |
781 | int i = 0; | 857 | switch (binding.get_type()) |
782 | for (auto rhyme : _rhymes) | ||
783 | { | 858 | { |
784 | std::string rhymer = "%" + rhyme; | 859 | case binding::type::integer: |
785 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | 860 | { |
861 | sqlite3_bind_int(ppstmt, i, binding.get_integer()); | ||
862 | |||
863 | break; | ||
864 | } | ||
786 | 865 | ||
787 | i++; | 866 | case binding::type::string: |
867 | { | ||
868 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); | ||
869 | |||
870 | break; | ||
871 | } | ||
788 | } | 872 | } |
873 | |||
874 | i++; | ||
789 | } | 875 | } |
790 | 876 | ||
791 | for (auto except : _except) | ||
792 | { | ||
793 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
794 | } | ||
795 | |||
796 | for (auto prefix : _with_prefix.inorder_flatten()) | ||
797 | { | ||
798 | std::string pfat = prefix + "%"; | ||
799 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PREFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC); | ||
800 | } | ||
801 | |||
802 | for (auto suffix : _with_suffix.inorder_flatten()) | ||
803 | { | ||
804 | std::string pfat = "%" + suffix; | ||
805 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SUFFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC); | ||
806 | } | ||
807 | |||
808 | if (_with_complexity != unlimited) | ||
809 | { | ||
810 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@COMPLEX"), _with_complexity); | ||
811 | } | ||
812 | |||
813 | for (auto attribute : _variant_of.inorder_flatten()) | ||
814 | { | ||
815 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ATTRID"), attribute._id); | ||
816 | } | ||
817 | |||
818 | for (auto antonym : _antonym_of.inorder_flatten()) | ||
819 | { | ||
820 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
821 | } | ||
822 | |||
823 | for (auto synonym : _synonym_of.inorder_flatten()) | ||
824 | { | ||
825 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
826 | } | ||
827 | |||
828 | for (auto specific : _generalization_of.inorder_flatten()) | ||
829 | { | ||
830 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SPECID"), specific._id); | ||
831 | } | ||
832 | |||
833 | for (auto general : _specification_of.inorder_flatten()) | ||
834 | { | ||
835 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GENID"), general._id); | ||
836 | } | ||
837 | |||
838 | for (auto n : _pertainym_of.inorder_flatten()) | ||
839 | { | ||
840 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@APERID"), n._id); | ||
841 | } | ||
842 | |||
843 | for (auto mannernym : _anti_mannernym_of.inorder_flatten()) | ||
844 | { | ||
845 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MANID"), mannernym._id); | ||
846 | } | ||
847 | /* | 877 | /* |
848 | for (auto adj : _derived_from_adjective) | 878 | for (auto adj : _derived_from_adjective) |
849 | { | 879 | { |
@@ -913,7 +943,7 @@ namespace verbly { | |||
913 | 943 | ||
914 | for (auto& adjective : output) | 944 | for (auto& adjective : output) |
915 | { | 945 | { |
916 | query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?"; | 946 | query = "SELECT pronunciation, prerhyme, rhyme FROM adjective_pronunciations WHERE adjective_id = ?"; |
917 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | 947 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) |
918 | { | 948 | { |
919 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 949 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
@@ -927,6 +957,13 @@ namespace verbly { | |||
927 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | 957 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); |
928 | 958 | ||
929 | adjective.pronunciations.push_back(phonemes); | 959 | adjective.pronunciations.push_back(phonemes); |
960 | |||
961 | if ((sqlite3_column_type(ppstmt, 1) != SQLITE_NULL) && (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)) | ||
962 | { | ||
963 | std::string prerhyme(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
964 | std::string rhyming(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
965 | adjective.rhymes.emplace_back(prerhyme, rhyming); | ||
966 | } | ||
930 | } | 967 | } |
931 | 968 | ||
932 | sqlite3_finalize(ppstmt); | 969 | sqlite3_finalize(ppstmt); |