diff options
-rw-r--r-- | generator/generator.cpp | 57 | ||||
-rw-r--r-- | generator/schema.sql | 4 | ||||
-rw-r--r-- | lib/adjective_query.cpp | 147 | ||||
-rw-r--r-- | lib/adverb_query.cpp | 103 | ||||
-rw-r--r-- | lib/data.cpp | 117 | ||||
-rw-r--r-- | lib/data.h | 32 | ||||
-rw-r--r-- | lib/frame_query.cpp | 30 | ||||
-rw-r--r-- | lib/noun.cpp | 17 | ||||
-rw-r--r-- | lib/noun.h | 4 | ||||
-rw-r--r-- | lib/noun_query.cpp | 274 | ||||
-rw-r--r-- | lib/noun_query.h | 6 | ||||
-rw-r--r-- | lib/preposition.cpp | 30 | ||||
-rw-r--r-- | lib/verb_query.cpp | 39 |
13 files changed, 551 insertions, 309 deletions
diff --git a/generator/generator.cpp b/generator/generator.cpp index 6fbbfb8..e67bda7 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp | |||
@@ -81,6 +81,7 @@ std::map<std::string, verb_t> verbs; | |||
81 | std::map<std::string, adjective_t> adjectives; | 81 | std::map<std::string, adjective_t> adjectives; |
82 | std::map<std::string, noun_t> nouns; | 82 | std::map<std::string, noun_t> nouns; |
83 | std::map<int, std::map<int, int>> wn; | 83 | std::map<int, std::map<int, int>> wn; |
84 | std::map<int, int> images; | ||
84 | std::map<std::string, std::set<std::string>> pronunciations; | 85 | std::map<std::string, std::set<std::string>> pronunciations; |
85 | 86 | ||
86 | void print_usage() | 87 | void print_usage() |
@@ -89,10 +90,10 @@ void print_usage() | |||
89 | std::cout << "-------------------------" << std::endl; | 90 | std::cout << "-------------------------" << std::endl; |
90 | std::cout << "Requires exactly six arguments." << std::endl; | 91 | std::cout << "Requires exactly six arguments." << std::endl; |
91 | std::cout << "1. The path to a VerbNet data directory." << std::endl; | 92 | std::cout << "1. The path to a VerbNet data directory." << std::endl; |
92 | std::cout << "2. The path to a SemLink vnpbMappings file." << std::endl; | 93 | std::cout << "2. The path to an AGID infl.txt file." << std::endl; |
93 | std::cout << "3. The path to an AGID infl.txt file." << std::endl; | 94 | std::cout << "3. The path to a WordNet prolog data directory." << std::endl; |
94 | std::cout << "4. The path to a WordNet prolog data directory." << std::endl; | 95 | std::cout << "4. The path to a CMUDICT pronunciation file." << std::endl; |
95 | std::cout << "5. The path to a CMUDICT pronunciation file." << std::endl; | 96 | std::cout << "5. The path to an ImageNet urls.txt file." << std::endl; |
96 | std::cout << "6. Datafile output path." << std::endl; | 97 | std::cout << "6. Datafile output path." << std::endl; |
97 | 98 | ||
98 | exit(1); | 99 | exit(1); |
@@ -431,10 +432,10 @@ int main(int argc, char** argv) | |||
431 | // Get verbs from AGID | 432 | // Get verbs from AGID |
432 | std::cout << "Reading inflections..." << std::endl; | 433 | std::cout << "Reading inflections..." << std::endl; |
433 | 434 | ||
434 | std::ifstream agidfile(argv[3]); | 435 | std::ifstream agidfile(argv[2]); |
435 | if (!agidfile.is_open()) | 436 | if (!agidfile.is_open()) |
436 | { | 437 | { |
437 | std::cout << "Could not open AGID file: " << argv[3] << std::endl; | 438 | std::cout << "Could not open AGID file: " << argv[2] << std::endl; |
438 | print_usage(); | 439 | print_usage(); |
439 | } | 440 | } |
440 | 441 | ||
@@ -562,10 +563,10 @@ int main(int argc, char** argv) | |||
562 | // Pronounciations | 563 | // Pronounciations |
563 | std::cout << "Reading pronunciations..." << std::endl; | 564 | std::cout << "Reading pronunciations..." << std::endl; |
564 | 565 | ||
565 | std::ifstream pronfile(argv[5]); | 566 | std::ifstream pronfile(argv[4]); |
566 | if (!pronfile.is_open()) | 567 | if (!pronfile.is_open()) |
567 | { | 568 | { |
568 | std::cout << "Could not open CMUDICT file: " << argv[5] << std::endl; | 569 | std::cout << "Could not open CMUDICT file: " << argv[4] << std::endl; |
569 | print_usage(); | 570 | print_usage(); |
570 | } | 571 | } |
571 | 572 | ||
@@ -593,6 +594,36 @@ int main(int argc, char** argv) | |||
593 | } | 594 | } |
594 | } | 595 | } |
595 | 596 | ||
597 | // Images | ||
598 | std::cout << "Reading images..." << std::endl; | ||
599 | |||
600 | std::ifstream imagefile(argv[5]); | ||
601 | if (!imagefile.is_open()) | ||
602 | { | ||
603 | std::cout << "Could not open ImageNet file: " << argv[5] << std::endl; | ||
604 | print_usage(); | ||
605 | } | ||
606 | |||
607 | for (;;) | ||
608 | { | ||
609 | std::string line; | ||
610 | if (!getline(imagefile, line)) | ||
611 | { | ||
612 | break; | ||
613 | } | ||
614 | |||
615 | if (line.back() == '\r') | ||
616 | { | ||
617 | line.pop_back(); | ||
618 | } | ||
619 | |||
620 | std::string wnid_s = line.substr(1, 8); | ||
621 | int wnid = stoi(wnid_s) + 100000000; | ||
622 | images[wnid]++; | ||
623 | } | ||
624 | |||
625 | imagefile.close(); | ||
626 | |||
596 | // Start writing output | 627 | // Start writing output |
597 | std::cout << "Writing schema..." << std::endl; | 628 | std::cout << "Writing schema..." << std::endl; |
598 | 629 | ||
@@ -972,7 +1003,7 @@ int main(int argc, char** argv) | |||
972 | // - sa: specification (e.g. inaccurate (general) can mean imprecise or incorrect (specific)) | 1003 | // - sa: specification (e.g. inaccurate (general) can mean imprecise or incorrect (specific)) |
973 | // - sim: synonymy (e.g. cheerful/happy, happy/cheerful) | 1004 | // - sim: synonymy (e.g. cheerful/happy, happy/cheerful) |
974 | // - syntax: positioning flags for some adjectives | 1005 | // - syntax: positioning flags for some adjectives |
975 | std::string wnpref {argv[4]}; | 1006 | std::string wnpref {argv[3]}; |
976 | if (wnpref.back() != '/') | 1007 | if (wnpref.back() != '/') |
977 | { | 1008 | { |
978 | wnpref += '/'; | 1009 | wnpref += '/'; |
@@ -1027,9 +1058,9 @@ int main(int argc, char** argv) | |||
1027 | { | 1058 | { |
1028 | if (nouns.count(word) == 1) | 1059 | if (nouns.count(word) == 1) |
1029 | { | 1060 | { |
1030 | query = "INSERT INTO nouns (singular, proper, complexity, plural) VALUES (?, ?, ?, ?)"; | 1061 | query = "INSERT INTO nouns (singular, proper, complexity, images, wnid, plural) VALUES (?, ?, ?, ?, ?, ?)"; |
1031 | } else { | 1062 | } else { |
1032 | query = "INSERT INTO nouns (singular, proper, complexity) VALUES (?, ?, ?)"; | 1063 | query = "INSERT INTO nouns (singular, proper, complexity, images, wnid) VALUES (?, ?, ?, ?, ?)"; |
1033 | } | 1064 | } |
1034 | 1065 | ||
1035 | break; | 1066 | break; |
@@ -1083,10 +1114,12 @@ int main(int argc, char** argv) | |||
1083 | }) ? 1 : 0)); | 1114 | }) ? 1 : 0)); |
1084 | 1115 | ||
1085 | sqlite3_bind_int(ppstmt, 3, verbly::split<std::list<std::string>>(word, " ").size()); | 1116 | sqlite3_bind_int(ppstmt, 3, verbly::split<std::list<std::string>>(word, " ").size()); |
1117 | sqlite3_bind_int(ppstmt, 4, images[synset_id]); | ||
1118 | sqlite3_bind_int(ppstmt, 5, synset_id); | ||
1086 | 1119 | ||
1087 | if (nouns.count(word) == 1) | 1120 | if (nouns.count(word) == 1) |
1088 | { | 1121 | { |
1089 | sqlite3_bind_text(ppstmt, 4, nouns[word].plural.c_str(), nouns[word].plural.length(), SQLITE_STATIC); | 1122 | sqlite3_bind_text(ppstmt, 6, nouns[word].plural.c_str(), nouns[word].plural.length(), SQLITE_STATIC); |
1090 | } | 1123 | } |
1091 | 1124 | ||
1092 | break; | 1125 | break; |
diff --git a/generator/schema.sql b/generator/schema.sql index f2445f0..9a39944 100644 --- a/generator/schema.sql +++ b/generator/schema.sql | |||
@@ -55,7 +55,9 @@ CREATE TABLE `nouns` ( | |||
55 | `singular` VARCHAR(32) NOT NULL, | 55 | `singular` VARCHAR(32) NOT NULL, |
56 | `plural` VARCHAR(32), | 56 | `plural` VARCHAR(32), |
57 | `proper` INTEGER(1) NOT NULL, | 57 | `proper` INTEGER(1) NOT NULL, |
58 | `complexity` INTEGER NOT NULL | 58 | `complexity` INTEGER NOT NULL, |
59 | `images` INTEGER NOT NULL, | ||
60 | `wnid` INTEGER NOT NULL | ||
59 | ); | 61 | ); |
60 | 62 | ||
61 | DROP TABLE IF EXISTS `hypernymy`; | 63 | DROP TABLE IF EXISTS `hypernymy`; |
diff --git a/lib/adjective_query.cpp b/lib/adjective_query.cpp index 283fdca..a7f915c 100644 --- a/lib/adjective_query.cpp +++ b/lib/adjective_query.cpp | |||
@@ -218,6 +218,7 @@ namespace verbly { | |||
218 | std::stringstream construct; | 218 | std::stringstream construct; |
219 | construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; | 219 | construct << "SELECT adjective_id, base_form, comparative, superlative, position FROM adjectives"; |
220 | std::list<std::string> conditions; | 220 | std::list<std::string> conditions; |
221 | std::list<binding> bindings; | ||
221 | 222 | ||
222 | if (_has_prn) | 223 | if (_has_prn) |
223 | { | 224 | { |
@@ -226,14 +227,20 @@ namespace verbly { | |||
226 | 227 | ||
227 | if (!_rhymes.empty()) | 228 | if (!_rhymes.empty()) |
228 | { | 229 | { |
229 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | 230 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?"); |
230 | std::string cond = "adjective_id IN (SELECT adjective_id FROM adjective_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 231 | 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); | 232 | conditions.push_back(cond); |
233 | |||
234 | for (auto rhyme : _rhymes) | ||
235 | { | ||
236 | bindings.emplace_back("%" + rhyme); | ||
237 | } | ||
232 | } | 238 | } |
233 | 239 | ||
234 | for (auto except : _except) | 240 | for (auto except : _except) |
235 | { | 241 | { |
236 | conditions.push_back("adjective_id != @EXCID"); | 242 | conditions.push_back("adjective_id != ?"); |
243 | bindings.emplace_back(except._id); | ||
237 | } | 244 | } |
238 | 245 | ||
239 | if (_requires_comparative_form) | 246 | if (_requires_comparative_form) |
@@ -261,11 +268,13 @@ namespace verbly { | |||
261 | { | 268 | { |
262 | case filter<std::string>::type::singleton: | 269 | case filter<std::string>::type::singleton: |
263 | { | 270 | { |
271 | bindings.emplace_back(f.get_elem() + "%"); | ||
272 | |||
264 | if (notlogic == f.get_notlogic()) | 273 | if (notlogic == f.get_notlogic()) |
265 | { | 274 | { |
266 | return "base_form LIKE @PREFIX"; | 275 | return "base_form LIKE ?"; |
267 | } else { | 276 | } else { |
268 | return "base_form NOT LIKE @PREFIX"; | 277 | return "base_form NOT LIKE ?"; |
269 | } | 278 | } |
270 | } | 279 | } |
271 | 280 | ||
@@ -298,11 +307,13 @@ namespace verbly { | |||
298 | { | 307 | { |
299 | case filter<std::string>::type::singleton: | 308 | case filter<std::string>::type::singleton: |
300 | { | 309 | { |
310 | bindings.emplace_back("%" + f.get_elem()); | ||
311 | |||
301 | if (notlogic == f.get_notlogic()) | 312 | if (notlogic == f.get_notlogic()) |
302 | { | 313 | { |
303 | return "base_form LIKE @SUFFIX"; | 314 | return "base_form LIKE ?"; |
304 | } else { | 315 | } else { |
305 | return "base_form NOT LIKE @SUFFIX"; | 316 | return "base_form NOT LIKE ?"; |
306 | } | 317 | } |
307 | } | 318 | } |
308 | 319 | ||
@@ -330,7 +341,8 @@ namespace verbly { | |||
330 | 341 | ||
331 | if (_with_complexity != unlimited) | 342 | if (_with_complexity != unlimited) |
332 | { | 343 | { |
333 | conditions.push_back("complexity = @COMPLEX"); | 344 | conditions.push_back("complexity = ?"); |
345 | bindings.emplace_back(_with_complexity); | ||
334 | } | 346 | } |
335 | 347 | ||
336 | if (_is_variant) | 348 | if (_is_variant) |
@@ -355,11 +367,13 @@ namespace verbly { | |||
355 | { | 367 | { |
356 | case filter<noun>::type::singleton: | 368 | case filter<noun>::type::singleton: |
357 | { | 369 | { |
370 | bindings.emplace_back(f.get_elem()._id); | ||
371 | |||
358 | if (notlogic == f.get_notlogic()) | 372 | if (notlogic == f.get_notlogic()) |
359 | { | 373 | { |
360 | return "noun_id = @ATTRID"; | 374 | return "noun_id = ?"; |
361 | } else { | 375 | } else { |
362 | return "noun_id != @ATTRID"; | 376 | return "noun_id != ?"; |
363 | } | 377 | } |
364 | } | 378 | } |
365 | 379 | ||
@@ -409,11 +423,13 @@ namespace verbly { | |||
409 | { | 423 | { |
410 | case filter<adjective>::type::singleton: | 424 | case filter<adjective>::type::singleton: |
411 | { | 425 | { |
426 | bindings.emplace_back(f.get_elem()._id); | ||
427 | |||
412 | if (notlogic == f.get_notlogic()) | 428 | if (notlogic == f.get_notlogic()) |
413 | { | 429 | { |
414 | return "adjective_1_id = @ANTID"; | 430 | return "adjective_1_id = ?"; |
415 | } else { | 431 | } else { |
416 | return "adjective_1_id != @ANTID"; | 432 | return "adjective_1_id != ?"; |
417 | } | 433 | } |
418 | } | 434 | } |
419 | 435 | ||
@@ -463,11 +479,13 @@ namespace verbly { | |||
463 | { | 479 | { |
464 | case filter<adjective>::type::singleton: | 480 | case filter<adjective>::type::singleton: |
465 | { | 481 | { |
482 | bindings.emplace_back(f.get_elem()._id); | ||
483 | |||
466 | if (notlogic == f.get_notlogic()) | 484 | if (notlogic == f.get_notlogic()) |
467 | { | 485 | { |
468 | return "adjective_1_id = @SYNID"; | 486 | return "adjective_1_id = ?"; |
469 | } else { | 487 | } else { |
470 | return "adjective_1_id != @SYNID"; | 488 | return "adjective_1_id != ?"; |
471 | } | 489 | } |
472 | } | 490 | } |
473 | 491 | ||
@@ -517,11 +535,13 @@ namespace verbly { | |||
517 | { | 535 | { |
518 | case filter<adjective>::type::singleton: | 536 | case filter<adjective>::type::singleton: |
519 | { | 537 | { |
538 | bindings.emplace_back(f.get_elem()._id); | ||
539 | |||
520 | if (notlogic == f.get_notlogic()) | 540 | if (notlogic == f.get_notlogic()) |
521 | { | 541 | { |
522 | return "specific_id = @SPECID"; | 542 | return "specific_id = ?"; |
523 | } else { | 543 | } else { |
524 | return "specific_id != @SPECID"; | 544 | return "specific_id != ?"; |
525 | } | 545 | } |
526 | } | 546 | } |
527 | 547 | ||
@@ -571,11 +591,13 @@ namespace verbly { | |||
571 | { | 591 | { |
572 | case filter<adjective>::type::singleton: | 592 | case filter<adjective>::type::singleton: |
573 | { | 593 | { |
594 | bindings.emplace_back(f.get_elem()._id); | ||
595 | |||
574 | if (notlogic == f.get_notlogic()) | 596 | if (notlogic == f.get_notlogic()) |
575 | { | 597 | { |
576 | return "general_id = @GENID"; | 598 | return "general_id = ?"; |
577 | } else { | 599 | } else { |
578 | return "general_id != @GENID"; | 600 | return "general_id != ?"; |
579 | } | 601 | } |
580 | } | 602 | } |
581 | 603 | ||
@@ -625,11 +647,13 @@ namespace verbly { | |||
625 | { | 647 | { |
626 | case filter<noun>::type::singleton: | 648 | case filter<noun>::type::singleton: |
627 | { | 649 | { |
650 | bindings.emplace_back(f.get_elem()._id); | ||
651 | |||
628 | if (notlogic == f.get_notlogic()) | 652 | if (notlogic == f.get_notlogic()) |
629 | { | 653 | { |
630 | return "noun_id = @APERID"; | 654 | return "noun_id = ?"; |
631 | } else { | 655 | } else { |
632 | return "noun_id != @APERID"; | 656 | return "noun_id != ?"; |
633 | } | 657 | } |
634 | } | 658 | } |
635 | 659 | ||
@@ -679,11 +703,13 @@ namespace verbly { | |||
679 | { | 703 | { |
680 | case filter<adverb>::type::singleton: | 704 | case filter<adverb>::type::singleton: |
681 | { | 705 | { |
706 | bindings.emplace_back(f.get_elem()._id); | ||
707 | |||
682 | if (notlogic == f.get_notlogic()) | 708 | if (notlogic == f.get_notlogic()) |
683 | { | 709 | { |
684 | return "mannernym_id = @MANID"; | 710 | return "mannernym_id = ?"; |
685 | } else { | 711 | } else { |
686 | return "mannernym_id != @MANID"; | 712 | return "mannernym_id != ?"; |
687 | } | 713 | } |
688 | } | 714 | } |
689 | 715 | ||
@@ -776,74 +802,29 @@ namespace verbly { | |||
776 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 802 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
777 | } | 803 | } |
778 | 804 | ||
779 | if (!_rhymes.empty()) | 805 | int i = 1; |
806 | for (auto& binding : bindings) | ||
780 | { | 807 | { |
781 | int i = 0; | 808 | switch (binding.get_type()) |
782 | for (auto rhyme : _rhymes) | ||
783 | { | 809 | { |
784 | std::string rhymer = "%" + rhyme; | 810 | case binding::type::integer: |
785 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | 811 | { |
812 | sqlite3_bind_int(ppstmt, i, binding.get_integer()); | ||
813 | |||
814 | break; | ||
815 | } | ||
786 | 816 | ||
787 | i++; | 817 | case binding::type::string: |
818 | { | ||
819 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | ||
820 | |||
821 | break; | ||
822 | } | ||
788 | } | 823 | } |
824 | |||
825 | i++; | ||
789 | } | 826 | } |
790 | 827 | ||
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 | /* | 828 | /* |
848 | for (auto adj : _derived_from_adjective) | 829 | for (auto adj : _derived_from_adjective) |
849 | { | 830 | { |
diff --git a/lib/adverb_query.cpp b/lib/adverb_query.cpp index c9d0d09..30ba92b 100644 --- a/lib/adverb_query.cpp +++ b/lib/adverb_query.cpp | |||
@@ -172,6 +172,7 @@ namespace verbly { | |||
172 | std::stringstream construct; | 172 | std::stringstream construct; |
173 | construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; | 173 | construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; |
174 | std::list<std::string> conditions; | 174 | std::list<std::string> conditions; |
175 | std::list<binding> bindings; | ||
175 | 176 | ||
176 | if (_has_prn) | 177 | if (_has_prn) |
177 | { | 178 | { |
@@ -180,14 +181,20 @@ namespace verbly { | |||
180 | 181 | ||
181 | if (!_rhymes.empty()) | 182 | if (!_rhymes.empty()) |
182 | { | 183 | { |
183 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | 184 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?"); |
184 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 185 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; |
185 | conditions.push_back(cond); | 186 | conditions.push_back(cond); |
187 | |||
188 | for (auto rhyme : _rhymes) | ||
189 | { | ||
190 | bindings.emplace_back("%" + rhyme); | ||
191 | } | ||
186 | } | 192 | } |
187 | 193 | ||
188 | for (auto except : _except) | 194 | for (auto except : _except) |
189 | { | 195 | { |
190 | conditions.push_back("adverb_id != @EXCID"); | 196 | conditions.push_back("adverb_id != ?"); |
197 | bindings.emplace_back(except._id); | ||
191 | } | 198 | } |
192 | 199 | ||
193 | if (_requires_comparative_form) | 200 | if (_requires_comparative_form) |
@@ -207,11 +214,13 @@ namespace verbly { | |||
207 | { | 214 | { |
208 | case filter<std::string>::type::singleton: | 215 | case filter<std::string>::type::singleton: |
209 | { | 216 | { |
217 | bindings.emplace_back(f.get_elem() + "%"); | ||
218 | |||
210 | if (notlogic == f.get_notlogic()) | 219 | if (notlogic == f.get_notlogic()) |
211 | { | 220 | { |
212 | return "base_form LIKE @PREFIX"; | 221 | return "base_form LIKE ?"; |
213 | } else { | 222 | } else { |
214 | return "base_form NOT LIKE @PREFIX"; | 223 | return "base_form NOT LIKE ?"; |
215 | } | 224 | } |
216 | } | 225 | } |
217 | 226 | ||
@@ -244,11 +253,13 @@ namespace verbly { | |||
244 | { | 253 | { |
245 | case filter<std::string>::type::singleton: | 254 | case filter<std::string>::type::singleton: |
246 | { | 255 | { |
256 | bindings.emplace_back("%" + f.get_elem()); | ||
257 | |||
247 | if (notlogic == f.get_notlogic()) | 258 | if (notlogic == f.get_notlogic()) |
248 | { | 259 | { |
249 | return "base_form LIKE @SUFFIX"; | 260 | return "base_form LIKE ?"; |
250 | } else { | 261 | } else { |
251 | return "base_form NOT LIKE @SUFFIX"; | 262 | return "base_form NOT LIKE ?"; |
252 | } | 263 | } |
253 | } | 264 | } |
254 | 265 | ||
@@ -276,7 +287,8 @@ namespace verbly { | |||
276 | 287 | ||
277 | if (_with_complexity != unlimited) | 288 | if (_with_complexity != unlimited) |
278 | { | 289 | { |
279 | conditions.push_back("complexity = @COMPLEX"); | 290 | conditions.push_back("complexity = ?"); |
291 | bindings.emplace_back(_with_complexity); | ||
280 | } | 292 | } |
281 | 293 | ||
282 | if (_has_antonyms) | 294 | if (_has_antonyms) |
@@ -301,11 +313,13 @@ namespace verbly { | |||
301 | { | 313 | { |
302 | case filter<adverb>::type::singleton: | 314 | case filter<adverb>::type::singleton: |
303 | { | 315 | { |
316 | bindings.emplace_back(f.get_elem()._id); | ||
317 | |||
304 | if (notlogic == f.get_notlogic()) | 318 | if (notlogic == f.get_notlogic()) |
305 | { | 319 | { |
306 | return "adverb_1_id = @ANTID"; | 320 | return "adverb_1_id = ?"; |
307 | } else { | 321 | } else { |
308 | return "adverb_1_id != @ANTID"; | 322 | return "adverb_1_id != ?"; |
309 | } | 323 | } |
310 | } | 324 | } |
311 | 325 | ||
@@ -355,11 +369,13 @@ namespace verbly { | |||
355 | { | 369 | { |
356 | case filter<adverb>::type::singleton: | 370 | case filter<adverb>::type::singleton: |
357 | { | 371 | { |
372 | bindings.emplace_back(f.get_elem()._id); | ||
373 | |||
358 | if (notlogic == f.get_notlogic()) | 374 | if (notlogic == f.get_notlogic()) |
359 | { | 375 | { |
360 | return "adverb_1_id = @SYNID"; | 376 | return "adverb_1_id = ?"; |
361 | } else { | 377 | } else { |
362 | return "adverb_1_id != @SYNID"; | 378 | return "adverb_1_id != ?"; |
363 | } | 379 | } |
364 | } | 380 | } |
365 | 381 | ||
@@ -409,11 +425,13 @@ namespace verbly { | |||
409 | { | 425 | { |
410 | case filter<adjective>::type::singleton: | 426 | case filter<adjective>::type::singleton: |
411 | { | 427 | { |
428 | bindings.emplace_back(f.get_elem()._id); | ||
429 | |||
412 | if (notlogic == f.get_notlogic()) | 430 | if (notlogic == f.get_notlogic()) |
413 | { | 431 | { |
414 | return "adjective_id = @AMANID"; | 432 | return "adjective_id = ?"; |
415 | } else { | 433 | } else { |
416 | return "adjective_id != @AMANID"; | 434 | return "adjective_id != ?"; |
417 | } | 435 | } |
418 | } | 436 | } |
419 | 437 | ||
@@ -506,54 +524,29 @@ namespace verbly { | |||
506 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 524 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
507 | } | 525 | } |
508 | 526 | ||
509 | if (!_rhymes.empty()) | 527 | int i = 1; |
528 | for (auto& binding : bindings) | ||
510 | { | 529 | { |
511 | int i = 0; | 530 | switch (binding.get_type()) |
512 | for (auto rhyme : _rhymes) | ||
513 | { | 531 | { |
514 | std::string rhymer = "%" + rhyme; | 532 | case binding::type::integer: |
515 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | 533 | { |
534 | sqlite3_bind_int(ppstmt, i, binding.get_integer()); | ||
535 | |||
536 | break; | ||
537 | } | ||
516 | 538 | ||
517 | i++; | 539 | case binding::type::string: |
540 | { | ||
541 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | ||
542 | |||
543 | break; | ||
544 | } | ||
518 | } | 545 | } |
546 | |||
547 | i++; | ||
519 | } | 548 | } |
520 | 549 | ||
521 | for (auto except : _except) | ||
522 | { | ||
523 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
524 | } | ||
525 | |||
526 | for (auto prefix : _with_prefix.inorder_flatten()) | ||
527 | { | ||
528 | std::string pfat = prefix + "%"; | ||
529 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PREFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC); | ||
530 | } | ||
531 | |||
532 | for (auto suffix : _with_suffix.inorder_flatten()) | ||
533 | { | ||
534 | std::string pfat = "%" + suffix; | ||
535 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SUFFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC); | ||
536 | } | ||
537 | |||
538 | if (_with_complexity != unlimited) | ||
539 | { | ||
540 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@COMPLEX"), _with_complexity); | ||
541 | } | ||
542 | |||
543 | for (auto antonym : _antonym_of.inorder_flatten()) | ||
544 | { | ||
545 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
546 | } | ||
547 | |||
548 | for (auto synonym : _synonym_of.inorder_flatten()) | ||
549 | { | ||
550 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
551 | } | ||
552 | |||
553 | for (auto adj : _mannernym_of.inorder_flatten()) | ||
554 | { | ||
555 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id); | ||
556 | } | ||
557 | /* | 550 | /* |
558 | for (auto adj : _derived_from_adjective) | 551 | for (auto adj : _derived_from_adjective) |
559 | { | 552 | { |
diff --git a/lib/data.cpp b/lib/data.cpp index 5a9397b..c14956f 100644 --- a/lib/data.cpp +++ b/lib/data.cpp | |||
@@ -57,4 +57,121 @@ namespace verbly { | |||
57 | return preposition_query(*this); | 57 | return preposition_query(*this); |
58 | } | 58 | } |
59 | 59 | ||
60 | binding::type binding::get_type() const | ||
61 | { | ||
62 | return _type; | ||
63 | } | ||
64 | |||
65 | binding::binding(const binding& other) | ||
66 | { | ||
67 | _type = other._type; | ||
68 | |||
69 | switch (_type) | ||
70 | { | ||
71 | case type::integer: | ||
72 | { | ||
73 | _integer = other._integer; | ||
74 | |||
75 | break; | ||
76 | } | ||
77 | |||
78 | case type::string: | ||
79 | { | ||
80 | new(&_string) std::string(other._string); | ||
81 | |||
82 | break; | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | |||
87 | binding::~binding() | ||
88 | { | ||
89 | switch (_type) | ||
90 | { | ||
91 | case type::string: | ||
92 | { | ||
93 | using string_type = std::string; | ||
94 | _string.~string_type(); | ||
95 | |||
96 | break; | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | |||
101 | binding& binding::operator=(const binding& other) | ||
102 | { | ||
103 | this->~binding(); | ||
104 | |||
105 | _type = other._type; | ||
106 | |||
107 | switch (_type) | ||
108 | { | ||
109 | case type::integer: | ||
110 | { | ||
111 | _integer = other._integer; | ||
112 | |||
113 | break; | ||
114 | } | ||
115 | |||
116 | case type::string: | ||
117 | { | ||
118 | new(&_string) std::string(other._string); | ||
119 | |||
120 | break; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | return *this; | ||
125 | } | ||
126 | |||
127 | binding::binding(int _arg) | ||
128 | { | ||
129 | _type = type::integer; | ||
130 | _integer = _arg; | ||
131 | } | ||
132 | |||
133 | int binding::get_integer() const | ||
134 | { | ||
135 | assert(_type == type::integer); | ||
136 | |||
137 | return _integer; | ||
138 | } | ||
139 | |||
140 | void binding::set_integer(int _arg) | ||
141 | { | ||
142 | *this = binding(_arg); | ||
143 | } | ||
144 | |||
145 | binding& binding::operator=(int _arg) | ||
146 | { | ||
147 | *this = binding(_arg); | ||
148 | |||
149 | return *this; | ||
150 | } | ||
151 | |||
152 | binding::binding(std::string _arg) | ||
153 | { | ||
154 | _type = type::string; | ||
155 | new(&_string) std::string(_arg); | ||
156 | } | ||
157 | |||
158 | std::string binding::get_string() const | ||
159 | { | ||
160 | assert(_type == type::string); | ||
161 | |||
162 | return _string; | ||
163 | } | ||
164 | |||
165 | void binding::set_string(std::string _arg) | ||
166 | { | ||
167 | *this = binding(_arg); | ||
168 | } | ||
169 | |||
170 | binding& binding::operator=(std::string _arg) | ||
171 | { | ||
172 | *this = binding(_arg); | ||
173 | |||
174 | return *this; | ||
175 | } | ||
176 | |||
60 | }; | 177 | }; |
diff --git a/lib/data.h b/lib/data.h index 0d599c4..b8b12b9 100644 --- a/lib/data.h +++ b/lib/data.h | |||
@@ -343,6 +343,38 @@ namespace verbly { | |||
343 | }; | 343 | }; |
344 | }; | 344 | }; |
345 | 345 | ||
346 | class binding { | ||
347 | public: | ||
348 | enum class type { | ||
349 | integer, | ||
350 | string | ||
351 | }; | ||
352 | |||
353 | type get_type() const; | ||
354 | binding(const binding& other); | ||
355 | ~binding(); | ||
356 | binding& operator=(const binding& other); | ||
357 | |||
358 | // Integer | ||
359 | binding(int _arg); | ||
360 | int get_integer() const; | ||
361 | void set_integer(int _arg); | ||
362 | binding& operator=(int _arg); | ||
363 | |||
364 | // String | ||
365 | binding(std::string _arg); | ||
366 | std::string get_string() const; | ||
367 | void set_string(std::string _arg); | ||
368 | binding& operator=(std::string _arg); | ||
369 | |||
370 | private: | ||
371 | union { | ||
372 | int _integer; | ||
373 | std::string _string; | ||
374 | }; | ||
375 | type _type; | ||
376 | }; | ||
377 | |||
346 | }; | 378 | }; |
347 | 379 | ||
348 | #endif /* end of include guard: DATA_H_C4AEC3DD */ | 380 | #endif /* end of include guard: DATA_H_C4AEC3DD */ |
diff --git a/lib/frame_query.cpp b/lib/frame_query.cpp index 6583da4..3c4a3e8 100644 --- a/lib/frame_query.cpp +++ b/lib/frame_query.cpp | |||
@@ -37,13 +37,19 @@ namespace verbly { | |||
37 | { | 37 | { |
38 | std::stringstream construct; | 38 | std::stringstream construct; |
39 | construct << "SELECT frames.data, groups.data FROM frames INNER JOIN groups ON frames.group_id = groups.group_id"; | 39 | construct << "SELECT frames.data, groups.data FROM frames INNER JOIN groups ON frames.group_id = groups.group_id"; |
40 | std::list<binding> bindings; | ||
40 | 41 | ||
41 | if (!_for_verb.empty()) | 42 | if (!_for_verb.empty()) |
42 | { | 43 | { |
43 | std::list<std::string> clauses(_for_verb.size(), "verb_id = @VERID"); | 44 | std::list<std::string> clauses(_for_verb.size(), "verb_id = ?"); |
44 | construct << " WHERE frames.group_id IN (SELECT group_id FROM verb_groups WHERE "; | 45 | construct << " WHERE frames.group_id IN (SELECT group_id FROM verb_groups WHERE "; |
45 | construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR "); | 46 | construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR "); |
46 | construct << ")"; | 47 | construct << ")"; |
48 | |||
49 | for (auto v : _for_verb) | ||
50 | { | ||
51 | bindings.emplace_back(v._id); | ||
52 | } | ||
47 | } | 53 | } |
48 | 54 | ||
49 | sqlite3_stmt* ppstmt; | 55 | sqlite3_stmt* ppstmt; |
@@ -53,9 +59,27 @@ namespace verbly { | |||
53 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 59 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
54 | } | 60 | } |
55 | 61 | ||
56 | for (auto verb : _for_verb) | 62 | int i = 1; |
63 | for (auto& binding : bindings) | ||
57 | { | 64 | { |
58 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VERID"), verb._id); | 65 | switch (binding.get_type()) |
66 | { | ||
67 | case binding::type::integer: | ||
68 | { | ||
69 | sqlite3_bind_int(ppstmt, i, binding.get_integer()); | ||
70 | |||
71 | break; | ||
72 | } | ||
73 | |||
74 | case binding::type::string: | ||
75 | { | ||
76 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | ||
77 | |||
78 | break; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | i++; | ||
59 | } | 83 | } |
60 | 84 | ||
61 | std::list<frame> output; | 85 | std::list<frame> output; |
diff --git a/lib/noun.cpp b/lib/noun.cpp index 71c9af0..d8b34c9 100644 --- a/lib/noun.cpp +++ b/lib/noun.cpp | |||
@@ -34,6 +34,13 @@ namespace verbly { | |||
34 | 34 | ||
35 | return _plural; | 35 | return _plural; |
36 | } | 36 | } |
37 | |||
38 | int noun::wnid() const | ||
39 | { | ||
40 | assert(_valid == true); | ||
41 | |||
42 | return _wnid; | ||
43 | } | ||
37 | 44 | ||
38 | bool noun::has_plural_form() const | 45 | bool noun::has_plural_form() const |
39 | { | 46 | { |
@@ -196,6 +203,16 @@ namespace verbly { | |||
196 | return _data->adjectives().variant_of(*this); | 203 | return _data->adjectives().variant_of(*this); |
197 | } | 204 | } |
198 | 205 | ||
206 | std::string noun::imagenet_url() const | ||
207 | { | ||
208 | std::stringstream url; | ||
209 | url << "http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n"; | ||
210 | url.width(8); | ||
211 | url.fill('0'); | ||
212 | url << (_wnid % 100000000); | ||
213 | return url.str(); | ||
214 | } | ||
215 | |||
199 | bool noun::operator<(const noun& other) const | 216 | bool noun::operator<(const noun& other) const |
200 | { | 217 | { |
201 | return _id < other._id; | 218 | return _id < other._id; |
diff --git a/lib/noun.h b/lib/noun.h index 969d2c8..bd71e57 100644 --- a/lib/noun.h +++ b/lib/noun.h | |||
@@ -7,6 +7,7 @@ namespace verbly { | |||
7 | private: | 7 | private: |
8 | std::string _singular; | 8 | std::string _singular; |
9 | std::string _plural; | 9 | std::string _plural; |
10 | int _wnid; | ||
10 | 11 | ||
11 | friend class noun_query; | 12 | friend class noun_query; |
12 | 13 | ||
@@ -17,6 +18,7 @@ namespace verbly { | |||
17 | std::string base_form() const; | 18 | std::string base_form() const; |
18 | std::string singular_form() const; | 19 | std::string singular_form() const; |
19 | std::string plural_form() const; | 20 | std::string plural_form() const; |
21 | int wnid() const; | ||
20 | 22 | ||
21 | bool has_plural_form() const; | 23 | bool has_plural_form() const; |
22 | 24 | ||
@@ -43,6 +45,8 @@ namespace verbly { | |||
43 | adjective_query pertainyms() const; | 45 | adjective_query pertainyms() const; |
44 | adjective_query variations() const; | 46 | adjective_query variations() const; |
45 | 47 | ||
48 | std::string imagenet_url() const; | ||
49 | |||
46 | bool operator<(const noun& other) const; | 50 | bool operator<(const noun& other) const; |
47 | }; | 51 | }; |
48 | 52 | ||
diff --git a/lib/noun_query.cpp b/lib/noun_query.cpp index 83bb47d..19a1297 100644 --- a/lib/noun_query.cpp +++ b/lib/noun_query.cpp | |||
@@ -370,6 +370,21 @@ namespace verbly { | |||
370 | 370 | ||
371 | return *this; | 371 | return *this; |
372 | } | 372 | } |
373 | |||
374 | noun_query& noun_query::at_least_n_images(int _arg) | ||
375 | { | ||
376 | _at_least_n_images = _arg; | ||
377 | |||
378 | return *this; | ||
379 | } | ||
380 | |||
381 | noun_query& noun_query::with_wnid(int _arg) | ||
382 | { | ||
383 | _with_wnid.insert(_arg); | ||
384 | |||
385 | return *this; | ||
386 | } | ||
387 | |||
373 | /* | 388 | /* |
374 | noun_query& noun_query::derived_from(const word& _w) | 389 | noun_query& noun_query::derived_from(const word& _w) |
375 | { | 390 | { |
@@ -457,8 +472,9 @@ namespace verbly { | |||
457 | construct << " "; | 472 | construct << " "; |
458 | } | 473 | } |
459 | 474 | ||
460 | construct << "SELECT noun_id, singular, plural FROM nouns"; | 475 | construct << "SELECT noun_id, singular, plural, wnid FROM nouns"; |
461 | std::list<std::string> conditions; | 476 | std::list<std::string> conditions; |
477 | std::list<binding> bindings; | ||
462 | 478 | ||
463 | if (_has_prn) | 479 | if (_has_prn) |
464 | { | 480 | { |
@@ -467,21 +483,32 @@ namespace verbly { | |||
467 | 483 | ||
468 | if (!_rhymes.empty()) | 484 | if (!_rhymes.empty()) |
469 | { | 485 | { |
470 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | 486 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?"); |
471 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 487 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; |
472 | conditions.push_back(cond); | 488 | conditions.push_back(cond); |
489 | |||
490 | for (auto rhyme : _rhymes) | ||
491 | { | ||
492 | bindings.emplace_back("%" + rhyme); | ||
493 | } | ||
473 | } | 494 | } |
474 | 495 | ||
475 | for (auto except : _except) | 496 | for (auto except : _except) |
476 | { | 497 | { |
477 | conditions.push_back("noun_id != @EXCID"); | 498 | conditions.push_back("noun_id != ?"); |
499 | bindings.emplace_back(except._id); | ||
478 | } | 500 | } |
479 | 501 | ||
480 | if (!_with_singular_form.empty()) | 502 | if (!_with_singular_form.empty()) |
481 | { | 503 | { |
482 | std::list<std::string> clauses(_with_singular_form.size(), "singular = @SFORM"); | 504 | std::list<std::string> clauses(_with_singular_form.size(), "singular = ?"); |
483 | std::string cond = "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 505 | std::string cond = "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; |
484 | conditions.push_back(cond); | 506 | conditions.push_back(cond); |
507 | |||
508 | for (auto form : _with_singular_form) | ||
509 | { | ||
510 | bindings.emplace_back(form); | ||
511 | } | ||
485 | } | 512 | } |
486 | 513 | ||
487 | if (!_with_prefix.empty()) | 514 | if (!_with_prefix.empty()) |
@@ -491,11 +518,13 @@ namespace verbly { | |||
491 | { | 518 | { |
492 | case filter<std::string>::type::singleton: | 519 | case filter<std::string>::type::singleton: |
493 | { | 520 | { |
521 | bindings.emplace_back(f.get_elem() + "%"); | ||
522 | |||
494 | if (notlogic == f.get_notlogic()) | 523 | if (notlogic == f.get_notlogic()) |
495 | { | 524 | { |
496 | return "singular LIKE @PREFIX"; | 525 | return "singular LIKE ?"; |
497 | } else { | 526 | } else { |
498 | return "singular NOT LIKE @PREFIX"; | 527 | return "singular NOT LIKE ?"; |
499 | } | 528 | } |
500 | } | 529 | } |
501 | 530 | ||
@@ -528,11 +557,13 @@ namespace verbly { | |||
528 | { | 557 | { |
529 | case filter<std::string>::type::singleton: | 558 | case filter<std::string>::type::singleton: |
530 | { | 559 | { |
560 | bindings.emplace_back("%" + f.get_elem()); | ||
561 | |||
531 | if (notlogic == f.get_notlogic()) | 562 | if (notlogic == f.get_notlogic()) |
532 | { | 563 | { |
533 | return "singular LIKE @SUFFIX"; | 564 | return "singular LIKE ?"; |
534 | } else { | 565 | } else { |
535 | return "singular NOT LIKE @SUFFIX"; | 566 | return "singular NOT LIKE ?"; |
536 | } | 567 | } |
537 | } | 568 | } |
538 | 569 | ||
@@ -560,7 +591,8 @@ namespace verbly { | |||
560 | 591 | ||
561 | if (_with_complexity != unlimited) | 592 | if (_with_complexity != unlimited) |
562 | { | 593 | { |
563 | conditions.push_back("complexity = @COMPLEX"); | 594 | conditions.push_back("complexity = ?"); |
595 | bindings.emplace_back(_with_complexity); | ||
564 | } | 596 | } |
565 | 597 | ||
566 | if (_is_hypernym) | 598 | if (_is_hypernym) |
@@ -585,11 +617,13 @@ namespace verbly { | |||
585 | { | 617 | { |
586 | case filter<noun>::type::singleton: | 618 | case filter<noun>::type::singleton: |
587 | { | 619 | { |
620 | bindings.emplace_back(f.get_elem()._id); | ||
621 | |||
588 | if (notlogic == f.get_notlogic()) | 622 | if (notlogic == f.get_notlogic()) |
589 | { | 623 | { |
590 | return "hyponym_id = @HYPO"; | 624 | return "hyponym_id = ?"; |
591 | } else { | 625 | } else { |
592 | return "hyponym_id != @HYPO"; | 626 | return "hyponym_id != ?"; |
593 | } | 627 | } |
594 | } | 628 | } |
595 | 629 | ||
@@ -713,11 +747,13 @@ namespace verbly { | |||
713 | { | 747 | { |
714 | case filter<noun>::type::singleton: | 748 | case filter<noun>::type::singleton: |
715 | { | 749 | { |
750 | bindings.emplace_back(f.get_elem()._id); | ||
751 | |||
716 | if (notlogic == f.get_notlogic()) | 752 | if (notlogic == f.get_notlogic()) |
717 | { | 753 | { |
718 | return "hypernym_id = @HYPER"; | 754 | return "hypernym_id = ?"; |
719 | } else { | 755 | } else { |
720 | return "hypernym_id != @HYPER"; | 756 | return "hypernym_id != ?"; |
721 | } | 757 | } |
722 | } | 758 | } |
723 | 759 | ||
@@ -767,11 +803,13 @@ namespace verbly { | |||
767 | { | 803 | { |
768 | case filter<noun>::type::singleton: | 804 | case filter<noun>::type::singleton: |
769 | { | 805 | { |
806 | bindings.emplace_back(f.get_elem()._id); | ||
807 | |||
770 | if (notlogic == f.get_notlogic()) | 808 | if (notlogic == f.get_notlogic()) |
771 | { | 809 | { |
772 | return "holonym_id = @PHOLO"; | 810 | return "holonym_id = ?"; |
773 | } else { | 811 | } else { |
774 | return "holonym_id != @PHOLO"; | 812 | return "holonym_id != ?"; |
775 | } | 813 | } |
776 | } | 814 | } |
777 | 815 | ||
@@ -858,11 +896,13 @@ namespace verbly { | |||
858 | { | 896 | { |
859 | case filter<noun>::type::singleton: | 897 | case filter<noun>::type::singleton: |
860 | { | 898 | { |
899 | bindings.emplace_back(f.get_elem()._id); | ||
900 | |||
861 | if (notlogic == f.get_notlogic()) | 901 | if (notlogic == f.get_notlogic()) |
862 | { | 902 | { |
863 | return "meronym_id = @PMERO"; | 903 | return "meronym_id = ?"; |
864 | } else { | 904 | } else { |
865 | return "meronym_id != @PMERO"; | 905 | return "meronym_id != ?"; |
866 | } | 906 | } |
867 | } | 907 | } |
868 | 908 | ||
@@ -949,11 +989,13 @@ namespace verbly { | |||
949 | { | 989 | { |
950 | case filter<noun>::type::singleton: | 990 | case filter<noun>::type::singleton: |
951 | { | 991 | { |
992 | bindings.emplace_back(f.get_elem()._id); | ||
993 | |||
952 | if (notlogic == f.get_notlogic()) | 994 | if (notlogic == f.get_notlogic()) |
953 | { | 995 | { |
954 | return "holonym_id = @SHOLO"; | 996 | return "holonym_id = ?"; |
955 | } else { | 997 | } else { |
956 | return "holonym_id != @SHOLO"; | 998 | return "holonym_id != ?"; |
957 | } | 999 | } |
958 | } | 1000 | } |
959 | 1001 | ||
@@ -1040,11 +1082,13 @@ namespace verbly { | |||
1040 | { | 1082 | { |
1041 | case filter<noun>::type::singleton: | 1083 | case filter<noun>::type::singleton: |
1042 | { | 1084 | { |
1085 | bindings.emplace_back(f.get_elem()._id); | ||
1086 | |||
1043 | if (notlogic == f.get_notlogic()) | 1087 | if (notlogic == f.get_notlogic()) |
1044 | { | 1088 | { |
1045 | return "meronym_id = @SMERO"; | 1089 | return "meronym_id = ?"; |
1046 | } else { | 1090 | } else { |
1047 | return "meronym_id != @SMERO"; | 1091 | return "meronym_id != ?"; |
1048 | } | 1092 | } |
1049 | } | 1093 | } |
1050 | 1094 | ||
@@ -1131,11 +1175,13 @@ namespace verbly { | |||
1131 | { | 1175 | { |
1132 | case filter<noun>::type::singleton: | 1176 | case filter<noun>::type::singleton: |
1133 | { | 1177 | { |
1178 | bindings.emplace_back(f.get_elem()._id); | ||
1179 | |||
1134 | if (notlogic == f.get_notlogic()) | 1180 | if (notlogic == f.get_notlogic()) |
1135 | { | 1181 | { |
1136 | return "holonym_id = @MHOLO"; | 1182 | return "holonym_id = ?"; |
1137 | } else { | 1183 | } else { |
1138 | return "holonym_id != @MHOLO"; | 1184 | return "holonym_id != ?"; |
1139 | } | 1185 | } |
1140 | } | 1186 | } |
1141 | 1187 | ||
@@ -1222,11 +1268,13 @@ namespace verbly { | |||
1222 | { | 1268 | { |
1223 | case filter<noun>::type::singleton: | 1269 | case filter<noun>::type::singleton: |
1224 | { | 1270 | { |
1271 | bindings.emplace_back(f.get_elem()._id); | ||
1272 | |||
1225 | if (notlogic == f.get_notlogic()) | 1273 | if (notlogic == f.get_notlogic()) |
1226 | { | 1274 | { |
1227 | return "meronym_id = @MMERO"; | 1275 | return "meronym_id = ?"; |
1228 | } else { | 1276 | } else { |
1229 | return "meronym_id != @MMERO"; | 1277 | return "meronym_id != ?"; |
1230 | } | 1278 | } |
1231 | } | 1279 | } |
1232 | 1280 | ||
@@ -1323,11 +1371,13 @@ namespace verbly { | |||
1323 | { | 1371 | { |
1324 | case filter<noun>::type::singleton: | 1372 | case filter<noun>::type::singleton: |
1325 | { | 1373 | { |
1374 | bindings.emplace_back(f.get_elem()._id); | ||
1375 | |||
1326 | if (notlogic == f.get_notlogic()) | 1376 | if (notlogic == f.get_notlogic()) |
1327 | { | 1377 | { |
1328 | return "class_id = @CLSID"; | 1378 | return "class_id = ?"; |
1329 | } else { | 1379 | } else { |
1330 | return "class_id != @CLSID"; | 1380 | return "class_id != ?"; |
1331 | } | 1381 | } |
1332 | } | 1382 | } |
1333 | 1383 | ||
@@ -1377,11 +1427,13 @@ namespace verbly { | |||
1377 | { | 1427 | { |
1378 | case filter<noun>::type::singleton: | 1428 | case filter<noun>::type::singleton: |
1379 | { | 1429 | { |
1430 | bindings.emplace_back(f.get_elem()._id); | ||
1431 | |||
1380 | if (notlogic == f.get_notlogic()) | 1432 | if (notlogic == f.get_notlogic()) |
1381 | { | 1433 | { |
1382 | return "instance_id = @INSID"; | 1434 | return "instance_id = ?"; |
1383 | } else { | 1435 | } else { |
1384 | return "instance_id != @INSID"; | 1436 | return "instance_id != ?"; |
1385 | } | 1437 | } |
1386 | } | 1438 | } |
1387 | 1439 | ||
@@ -1431,11 +1483,13 @@ namespace verbly { | |||
1431 | { | 1483 | { |
1432 | case filter<noun>::type::singleton: | 1484 | case filter<noun>::type::singleton: |
1433 | { | 1485 | { |
1486 | bindings.emplace_back(f.get_elem()._id); | ||
1487 | |||
1434 | if (notlogic == f.get_notlogic()) | 1488 | if (notlogic == f.get_notlogic()) |
1435 | { | 1489 | { |
1436 | return "noun_1_id = @SYNID"; | 1490 | return "noun_1_id = ?"; |
1437 | } else { | 1491 | } else { |
1438 | return "noun_1_id != @SYNID"; | 1492 | return "noun_1_id != ?"; |
1439 | } | 1493 | } |
1440 | } | 1494 | } |
1441 | 1495 | ||
@@ -1485,11 +1539,13 @@ namespace verbly { | |||
1485 | { | 1539 | { |
1486 | case filter<noun>::type::singleton: | 1540 | case filter<noun>::type::singleton: |
1487 | { | 1541 | { |
1542 | bindings.emplace_back(f.get_elem()._id); | ||
1543 | |||
1488 | if (notlogic == f.get_notlogic()) | 1544 | if (notlogic == f.get_notlogic()) |
1489 | { | 1545 | { |
1490 | return "noun_1_id = @ANTID"; | 1546 | return "noun_1_id = ?"; |
1491 | } else { | 1547 | } else { |
1492 | return "noun_1_id != @ANTID"; | 1548 | return "noun_1_id != ?"; |
1493 | } | 1549 | } |
1494 | } | 1550 | } |
1495 | 1551 | ||
@@ -1539,11 +1595,13 @@ namespace verbly { | |||
1539 | { | 1595 | { |
1540 | case filter<adjective>::type::singleton: | 1596 | case filter<adjective>::type::singleton: |
1541 | { | 1597 | { |
1598 | bindings.emplace_back(f.get_elem()._id); | ||
1599 | |||
1542 | if (notlogic == f.get_notlogic()) | 1600 | if (notlogic == f.get_notlogic()) |
1543 | { | 1601 | { |
1544 | return "pertainym_id = @PERID"; | 1602 | return "pertainym_id = ?"; |
1545 | } else { | 1603 | } else { |
1546 | return "pertainym_id != @PERID"; | 1604 | return "pertainym_id != ?"; |
1547 | } | 1605 | } |
1548 | } | 1606 | } |
1549 | 1607 | ||
@@ -1593,11 +1651,13 @@ namespace verbly { | |||
1593 | { | 1651 | { |
1594 | case filter<adjective>::type::singleton: | 1652 | case filter<adjective>::type::singleton: |
1595 | { | 1653 | { |
1654 | bindings.emplace_back(f.get_elem()._id); | ||
1655 | |||
1596 | if (notlogic == f.get_notlogic()) | 1656 | if (notlogic == f.get_notlogic()) |
1597 | { | 1657 | { |
1598 | return "adjective_id = @VALID"; | 1658 | return "adjective_id = ?"; |
1599 | } else { | 1659 | } else { |
1600 | return "adjective_id != @VALID"; | 1660 | return "adjective_id != ?"; |
1601 | } | 1661 | } |
1602 | } | 1662 | } |
1603 | 1663 | ||
@@ -1624,6 +1684,25 @@ namespace verbly { | |||
1624 | cond << ")"; | 1684 | cond << ")"; |
1625 | conditions.push_back(cond.str()); | 1685 | conditions.push_back(cond.str()); |
1626 | } | 1686 | } |
1687 | |||
1688 | if (_at_least_n_images != unlimited) | ||
1689 | { | ||
1690 | conditions.push_back("images >= ?"); | ||
1691 | bindings.emplace_back(_at_least_n_images); | ||
1692 | } | ||
1693 | |||
1694 | if (!_with_wnid.empty()) | ||
1695 | { | ||
1696 | std::vector<std::string> clauses(_with_wnid.size(), "wnid = ?"); | ||
1697 | std::string cond = verbly::implode(std::begin(clauses), std::end(clauses), " OR "); | ||
1698 | conditions.push_back("(" + cond + ")"); | ||
1699 | |||
1700 | for (auto wnid : _with_wnid) | ||
1701 | { | ||
1702 | bindings.emplace_back(wnid); | ||
1703 | } | ||
1704 | } | ||
1705 | |||
1627 | /* | 1706 | /* |
1628 | if (!_derived_from_adjective.empty()) | 1707 | if (!_derived_from_adjective.empty()) |
1629 | { | 1708 | { |
@@ -1690,114 +1769,29 @@ namespace verbly { | |||
1690 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 1769 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
1691 | } | 1770 | } |
1692 | 1771 | ||
1693 | if (!_rhymes.empty()) | 1772 | int i = 1; |
1773 | for (auto& binding : bindings) | ||
1694 | { | 1774 | { |
1695 | int i = 0; | 1775 | switch (binding.get_type()) |
1696 | for (auto rhyme : _rhymes) | ||
1697 | { | 1776 | { |
1698 | std::string rhymer = "%" + rhyme; | 1777 | case binding::type::integer: |
1699 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | 1778 | { |
1779 | sqlite3_bind_int(ppstmt, i, binding.get_integer()); | ||
1780 | |||
1781 | break; | ||
1782 | } | ||
1700 | 1783 | ||
1701 | i++; | 1784 | case binding::type::string: |
1785 | { | ||
1786 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | ||
1787 | |||
1788 | break; | ||
1789 | } | ||
1702 | } | 1790 | } |
1791 | |||
1792 | i++; | ||
1703 | } | 1793 | } |
1704 | 1794 | ||
1705 | for (auto except : _except) | ||
1706 | { | ||
1707 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
1708 | } | ||
1709 | |||
1710 | for (auto sform : _with_singular_form) | ||
1711 | { | ||
1712 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SFORM"), sform.c_str(), sform.size(), SQLITE_STATIC); | ||
1713 | } | ||
1714 | |||
1715 | for (auto prefix : _with_prefix.inorder_flatten()) | ||
1716 | { | ||
1717 | std::string pfat = prefix + "%"; | ||
1718 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PREFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC); | ||
1719 | } | ||
1720 | |||
1721 | for (auto suffix : _with_suffix.inorder_flatten()) | ||
1722 | { | ||
1723 | std::string pfat = "%" + suffix; | ||
1724 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SUFFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC); | ||
1725 | } | ||
1726 | |||
1727 | if (_with_complexity != unlimited) | ||
1728 | { | ||
1729 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@COMPLEX"), _with_complexity); | ||
1730 | } | ||
1731 | |||
1732 | for (auto hyponym : _hypernym_of.inorder_flatten()) | ||
1733 | { | ||
1734 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id); | ||
1735 | } | ||
1736 | |||
1737 | for (auto hypernym : _hyponym_of.inorder_flatten()) | ||
1738 | { | ||
1739 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id); | ||
1740 | } | ||
1741 | |||
1742 | for (auto holonym : _part_meronym_of.inorder_flatten()) | ||
1743 | { | ||
1744 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id); | ||
1745 | } | ||
1746 | |||
1747 | for (auto meronym : _part_holonym_of.inorder_flatten()) | ||
1748 | { | ||
1749 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id); | ||
1750 | } | ||
1751 | |||
1752 | for (auto holonym : _substance_meronym_of.inorder_flatten()) | ||
1753 | { | ||
1754 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id); | ||
1755 | } | ||
1756 | |||
1757 | for (auto meronym : _substance_holonym_of.inorder_flatten()) | ||
1758 | { | ||
1759 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id); | ||
1760 | } | ||
1761 | |||
1762 | for (auto holonym : _member_meronym_of.inorder_flatten()) | ||
1763 | { | ||
1764 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id); | ||
1765 | } | ||
1766 | |||
1767 | for (auto meronym : _member_holonym_of.inorder_flatten()) | ||
1768 | { | ||
1769 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id); | ||
1770 | } | ||
1771 | |||
1772 | for (auto cls : _instance_of.inorder_flatten()) | ||
1773 | { | ||
1774 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id); | ||
1775 | } | ||
1776 | |||
1777 | for (auto inst : _class_of.inorder_flatten()) | ||
1778 | { | ||
1779 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id); | ||
1780 | } | ||
1781 | |||
1782 | for (auto synonym : _synonym_of.inorder_flatten()) | ||
1783 | { | ||
1784 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
1785 | } | ||
1786 | |||
1787 | for (auto antonym : _antonym_of.inorder_flatten()) | ||
1788 | { | ||
1789 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
1790 | } | ||
1791 | |||
1792 | for (auto pertainym : _anti_pertainym_of.inorder_flatten()) | ||
1793 | { | ||
1794 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id); | ||
1795 | } | ||
1796 | |||
1797 | for (auto value : _attribute_of.inorder_flatten()) | ||
1798 | { | ||
1799 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id); | ||
1800 | } | ||
1801 | /* | 1795 | /* |
1802 | for (auto adj : _derived_from_adjective) | 1796 | for (auto adj : _derived_from_adjective) |
1803 | { | 1797 | { |
@@ -1839,6 +1833,8 @@ namespace verbly { | |||
1839 | { | 1833 | { |
1840 | tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | 1834 | tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); |
1841 | } | 1835 | } |
1836 | |||
1837 | tnc._wnid = sqlite3_column_int(ppstmt, 3); | ||
1842 | 1838 | ||
1843 | output.push_back(tnc); | 1839 | output.push_back(tnc); |
1844 | } | 1840 | } |
diff --git a/lib/noun_query.h b/lib/noun_query.h index 5b73f8d..8768f5d 100644 --- a/lib/noun_query.h +++ b/lib/noun_query.h | |||
@@ -72,6 +72,9 @@ namespace verbly { | |||
72 | noun_query& is_attribute(); | 72 | noun_query& is_attribute(); |
73 | noun_query& attribute_of(filter<adjective> _f); | 73 | noun_query& attribute_of(filter<adjective> _f); |
74 | 74 | ||
75 | noun_query& at_least_n_images(int _arg); | ||
76 | noun_query& with_wnid(int _arg); | ||
77 | |||
75 | /* noun_query& derived_from(const word& _w); | 78 | /* noun_query& derived_from(const word& _w); |
76 | noun_query& not_derived_from(const word& _w);*/ | 79 | noun_query& not_derived_from(const word& _w);*/ |
77 | 80 | ||
@@ -146,6 +149,9 @@ namespace verbly { | |||
146 | bool _is_attribute = false; | 149 | bool _is_attribute = false; |
147 | filter<adjective> _attribute_of; | 150 | filter<adjective> _attribute_of; |
148 | 151 | ||
152 | int _at_least_n_images = unlimited; | ||
153 | std::set<int> _with_wnid; | ||
154 | |||
149 | /* std::list<adjective> _derived_from_adjective; | 155 | /* std::list<adjective> _derived_from_adjective; |
150 | std::list<adjective> _not_derived_from_adjective; | 156 | std::list<adjective> _not_derived_from_adjective; |
151 | std::list<adverb> _derived_from_adverb; | 157 | std::list<adverb> _derived_from_adverb; |
diff --git a/lib/preposition.cpp b/lib/preposition.cpp index c619bbf..8df13aa 100644 --- a/lib/preposition.cpp +++ b/lib/preposition.cpp | |||
@@ -37,13 +37,19 @@ namespace verbly { | |||
37 | { | 37 | { |
38 | std::stringstream construct; | 38 | std::stringstream construct; |
39 | construct << "SELECT form FROM prepositions"; | 39 | construct << "SELECT form FROM prepositions"; |
40 | std::list<binding> bindings; | ||
40 | 41 | ||
41 | if (!_in_group.empty()) | 42 | if (!_in_group.empty()) |
42 | { | 43 | { |
43 | std::list<std::string> clauses(_in_group.size(), "groupname = @GNAME"); | 44 | std::list<std::string> clauses(_in_group.size(), "groupname = ?"); |
44 | construct << " WHERE preposition_id IN (SELECT preposition_id FROM preposition_groups WHERE "; | 45 | construct << " WHERE preposition_id IN (SELECT preposition_id FROM preposition_groups WHERE "; |
45 | construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR "); | 46 | construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR "); |
46 | construct << ")"; | 47 | construct << ")"; |
48 | |||
49 | for (auto g : _in_group) | ||
50 | { | ||
51 | bindings.emplace_back(g); | ||
52 | } | ||
47 | } | 53 | } |
48 | 54 | ||
49 | if (_random) | 55 | if (_random) |
@@ -63,9 +69,27 @@ namespace verbly { | |||
63 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 69 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
64 | } | 70 | } |
65 | 71 | ||
66 | for (auto& group : _in_group) | 72 | int i = 1; |
73 | for (auto& binding : bindings) | ||
67 | { | 74 | { |
68 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@GNAME"), group.c_str(), group.length(), SQLITE_STATIC); | 75 | switch (binding.get_type()) |
76 | { | ||
77 | case binding::type::integer: | ||
78 | { | ||
79 | sqlite3_bind_int(ppstmt, i, binding.get_integer()); | ||
80 | |||
81 | break; | ||
82 | } | ||
83 | |||
84 | case binding::type::string: | ||
85 | { | ||
86 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | ||
87 | |||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | i++; | ||
69 | } | 93 | } |
70 | 94 | ||
71 | std::list<preposition> output; | 95 | std::list<preposition> output; |
diff --git a/lib/verb_query.cpp b/lib/verb_query.cpp index 173a04e..929ecc7 100644 --- a/lib/verb_query.cpp +++ b/lib/verb_query.cpp | |||
@@ -65,6 +65,7 @@ namespace verbly { | |||
65 | std::stringstream construct; | 65 | std::stringstream construct; |
66 | construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; | 66 | construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; |
67 | std::list<std::string> conditions; | 67 | std::list<std::string> conditions; |
68 | std::list<binding> bindings; | ||
68 | 69 | ||
69 | if (_has_prn) | 70 | if (_has_prn) |
70 | { | 71 | { |
@@ -73,14 +74,20 @@ namespace verbly { | |||
73 | 74 | ||
74 | if (!_rhymes.empty()) | 75 | if (!_rhymes.empty()) |
75 | { | 76 | { |
76 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | 77 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?"); |
77 | std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 78 | std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; |
78 | conditions.push_back(cond); | 79 | conditions.push_back(cond); |
80 | |||
81 | for (auto rhyme : _rhymes) | ||
82 | { | ||
83 | bindings.emplace_back("%" + rhyme); | ||
84 | } | ||
79 | } | 85 | } |
80 | 86 | ||
81 | for (auto except : _except) | 87 | for (auto except : _except) |
82 | { | 88 | { |
83 | conditions.push_back("verb_id != @EXCID"); | 89 | conditions.push_back("verb_id != ?"); |
90 | bindings.emplace_back(except._id); | ||
84 | } | 91 | } |
85 | 92 | ||
86 | if (!_has_frames) | 93 | if (!_has_frames) |
@@ -111,21 +118,27 @@ namespace verbly { | |||
111 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 118 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
112 | } | 119 | } |
113 | 120 | ||
114 | if (!_rhymes.empty()) | 121 | int i = 1; |
122 | for (auto& binding : bindings) | ||
115 | { | 123 | { |
116 | int i = 0; | 124 | switch (binding.get_type()) |
117 | for (auto rhyme : _rhymes) | ||
118 | { | 125 | { |
119 | std::string rhymer = "%" + rhyme; | 126 | case binding::type::integer: |
120 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | 127 | { |
128 | sqlite3_bind_int(ppstmt, i, binding.get_integer()); | ||
129 | |||
130 | break; | ||
131 | } | ||
121 | 132 | ||
122 | i++; | 133 | case binding::type::string: |
134 | { | ||
135 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | ||
136 | |||
137 | break; | ||
138 | } | ||
123 | } | 139 | } |
124 | } | 140 | |
125 | 141 | i++; | |
126 | for (auto except : _except) | ||
127 | { | ||
128 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
129 | } | 142 | } |
130 | 143 | ||
131 | std::list<verb> output; | 144 | std::list<verb> output; |