diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/adjective_query.cpp | 68 | ||||
-rw-r--r-- | lib/adjective_query.h | 10 | ||||
-rw-r--r-- | lib/adverb_query.cpp | 68 | ||||
-rw-r--r-- | lib/adverb_query.h | 10 | ||||
-rw-r--r-- | lib/data.cpp | 2 | ||||
-rw-r--r-- | lib/frame_query.cpp | 2 | ||||
-rw-r--r-- | lib/noun_query.cpp | 73 | ||||
-rw-r--r-- | lib/noun_query.h | 10 | ||||
-rw-r--r-- | lib/preposition.cpp | 2 | ||||
-rw-r--r-- | lib/verb_query.cpp | 68 | ||||
-rw-r--r-- | lib/verb_query.h | 10 | ||||
-rw-r--r-- | lib/word.cpp | 41 | ||||
-rw-r--r-- | lib/word.h | 17 |
13 files changed, 328 insertions, 53 deletions
diff --git a/lib/adjective_query.cpp b/lib/adjective_query.cpp index a7f915c..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(); |
@@ -227,16 +255,37 @@ namespace verbly { | |||
227 | 255 | ||
228 | if (!_rhymes.empty()) | 256 | if (!_rhymes.empty()) |
229 | { | 257 | { |
230 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?"); | 258 | std::list<std::string> clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)"); |
231 | 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 ") + ")"; |
232 | conditions.push_back(cond); | 260 | conditions.push_back(cond); |
233 | 261 | ||
234 | for (auto rhyme : _rhymes) | 262 | for (auto rhy : _rhymes) |
235 | { | 263 | { |
236 | bindings.emplace_back("%" + rhyme); | 264 | bindings.emplace_back(rhy.get_prerhyme()); |
265 | bindings.emplace_back(rhy.get_rhyme()); | ||
237 | } | 266 | } |
238 | } | 267 | } |
239 | 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)"); | ||
287 | } | ||
288 | |||
240 | for (auto except : _except) | 289 | for (auto except : _except) |
241 | { | 290 | { |
242 | conditions.push_back("adjective_id != ?"); | 291 | conditions.push_back("adjective_id != ?"); |
@@ -816,7 +865,7 @@ namespace verbly { | |||
816 | 865 | ||
817 | case binding::type::string: | 866 | case binding::type::string: |
818 | { | 867 | { |
819 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | 868 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); |
820 | 869 | ||
821 | break; | 870 | break; |
822 | } | 871 | } |
@@ -894,7 +943,7 @@ namespace verbly { | |||
894 | 943 | ||
895 | for (auto& adjective : output) | 944 | for (auto& adjective : output) |
896 | { | 945 | { |
897 | query = "SELECT pronunciation FROM adjective_pronunciations WHERE adjective_id = ?"; | 946 | query = "SELECT pronunciation, prerhyme, rhyme FROM adjective_pronunciations WHERE adjective_id = ?"; |
898 | 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) |
899 | { | 948 | { |
900 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 949 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
@@ -908,6 +957,13 @@ namespace verbly { | |||
908 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | 957 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); |
909 | 958 | ||
910 | 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 | } | ||
911 | } | 967 | } |
912 | 968 | ||
913 | sqlite3_finalize(ppstmt); | 969 | sqlite3_finalize(ppstmt); |
diff --git a/lib/adjective_query.h b/lib/adjective_query.h index b2859dc..030a494 100644 --- a/lib/adjective_query.h +++ b/lib/adjective_query.h | |||
@@ -12,6 +12,10 @@ namespace verbly { | |||
12 | adjective_query& except(const adjective& _word); | 12 | adjective_query& except(const adjective& _word); |
13 | adjective_query& rhymes_with(const word& _word); | 13 | adjective_query& rhymes_with(const word& _word); |
14 | adjective_query& has_pronunciation(); | 14 | adjective_query& has_pronunciation(); |
15 | adjective_query& has_rhyming_noun(); | ||
16 | adjective_query& has_rhyming_adjective(); | ||
17 | adjective_query& has_rhyming_adverb(); | ||
18 | adjective_query& has_rhyming_verb(); | ||
15 | 19 | ||
16 | adjective_query& requires_comparative_form(); | 20 | adjective_query& requires_comparative_form(); |
17 | adjective_query& requires_superlative_form(); | 21 | adjective_query& requires_superlative_form(); |
@@ -54,9 +58,13 @@ namespace verbly { | |||
54 | const data& _data; | 58 | const data& _data; |
55 | int _limit = unlimited; | 59 | int _limit = unlimited; |
56 | bool _random = false; | 60 | bool _random = false; |
57 | std::list<std::string> _rhymes; | 61 | std::list<rhyme> _rhymes; |
58 | std::list<adjective> _except; | 62 | std::list<adjective> _except; |
59 | bool _has_prn = false; | 63 | bool _has_prn = false; |
64 | bool _has_rhyming_noun = false; | ||
65 | bool _has_rhyming_adjective = false; | ||
66 | bool _has_rhyming_adverb = false; | ||
67 | bool _has_rhyming_verb = false; | ||
60 | 68 | ||
61 | bool _requires_comparative_form = false; | 69 | bool _requires_comparative_form = false; |
62 | bool _requires_superlative_form = false; | 70 | bool _requires_superlative_form = false; |
diff --git a/lib/adverb_query.cpp b/lib/adverb_query.cpp index 30ba92b..797e6a6 100644 --- a/lib/adverb_query.cpp +++ b/lib/adverb_query.cpp | |||
@@ -33,7 +33,7 @@ namespace verbly { | |||
33 | 33 | ||
34 | adverb_query& adverb_query::rhymes_with(const word& _word) | 34 | adverb_query& adverb_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 | adverb_query& adverb_query::has_rhyming_noun() | ||
57 | { | ||
58 | _has_rhyming_noun = true; | ||
59 | |||
60 | return *this; | ||
61 | } | ||
62 | |||
63 | adverb_query& adverb_query::has_rhyming_adjective() | ||
64 | { | ||
65 | _has_rhyming_adjective = true; | ||
66 | |||
67 | return *this; | ||
68 | } | ||
69 | |||
70 | adverb_query& adverb_query::has_rhyming_adverb() | ||
71 | { | ||
72 | _has_rhyming_adverb = true; | ||
73 | |||
74 | return *this; | ||
75 | } | ||
76 | |||
77 | adverb_query& adverb_query::has_rhyming_verb() | ||
78 | { | ||
79 | _has_rhyming_verb = true; | ||
80 | |||
81 | return *this; | ||
82 | } | ||
83 | |||
56 | adverb_query& adverb_query::requires_comparative_form() | 84 | adverb_query& adverb_query::requires_comparative_form() |
57 | { | 85 | { |
58 | _requires_comparative_form = true; | 86 | _requires_comparative_form = true; |
@@ -181,16 +209,37 @@ namespace verbly { | |||
181 | 209 | ||
182 | if (!_rhymes.empty()) | 210 | if (!_rhymes.empty()) |
183 | { | 211 | { |
184 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?"); | 212 | std::list<std::string> clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)"); |
185 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 213 | std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; |
186 | conditions.push_back(cond); | 214 | conditions.push_back(cond); |
187 | 215 | ||
188 | for (auto rhyme : _rhymes) | 216 | for (auto rhy : _rhymes) |
189 | { | 217 | { |
190 | bindings.emplace_back("%" + rhyme); | 218 | bindings.emplace_back(rhy.get_prerhyme()); |
219 | bindings.emplace_back(rhy.get_rhyme()); | ||
191 | } | 220 | } |
192 | } | 221 | } |
193 | 222 | ||
223 | if (_has_rhyming_noun) | ||
224 | { | ||
225 | conditions.push_back("adverb_id IN (SELECT a.adverb_id FROM adverbs AS a INNER JOIN adverb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN noun_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
226 | } | ||
227 | |||
228 | if (_has_rhyming_adjective) | ||
229 | { | ||
230 | conditions.push_back("adverb_id IN (SELECT a.adverb_id FROM adverbs AS a INNER JOIN adverb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN adjective_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
231 | } | ||
232 | |||
233 | if (_has_rhyming_adverb) | ||
234 | { | ||
235 | conditions.push_back("adverb_id IN (SELECT a.adverb_id FROM adverbs AS a INNER JOIN adverb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN adverb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme AND rhmp.adverb_id != curp.adverb_id)"); | ||
236 | } | ||
237 | |||
238 | if (_has_rhyming_verb) | ||
239 | { | ||
240 | conditions.push_back("adverb_id IN (SELECT a.adverb_id FROM adverbs AS a INNER JOIN adverb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN verb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
241 | } | ||
242 | |||
194 | for (auto except : _except) | 243 | for (auto except : _except) |
195 | { | 244 | { |
196 | conditions.push_back("adverb_id != ?"); | 245 | conditions.push_back("adverb_id != ?"); |
@@ -538,7 +587,7 @@ namespace verbly { | |||
538 | 587 | ||
539 | case binding::type::string: | 588 | case binding::type::string: |
540 | { | 589 | { |
541 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | 590 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); |
542 | 591 | ||
543 | break; | 592 | break; |
544 | } | 593 | } |
@@ -601,7 +650,7 @@ namespace verbly { | |||
601 | 650 | ||
602 | for (auto& adverb : output) | 651 | for (auto& adverb : output) |
603 | { | 652 | { |
604 | query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?"; | 653 | query = "SELECT pronunciation, prerhyme, rhyme FROM adverb_pronunciations WHERE adverb_id = ?"; |
605 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | 654 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) |
606 | { | 655 | { |
607 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 656 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
@@ -615,6 +664,13 @@ namespace verbly { | |||
615 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | 664 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); |
616 | 665 | ||
617 | adverb.pronunciations.push_back(phonemes); | 666 | adverb.pronunciations.push_back(phonemes); |
667 | |||
668 | if ((sqlite3_column_type(ppstmt, 1) != SQLITE_NULL) && (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)) | ||
669 | { | ||
670 | std::string prerhyme(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
671 | std::string rhyming(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
672 | adverb.rhymes.emplace_back(prerhyme, rhyming); | ||
673 | } | ||
618 | } | 674 | } |
619 | 675 | ||
620 | sqlite3_finalize(ppstmt); | 676 | sqlite3_finalize(ppstmt); |
diff --git a/lib/adverb_query.h b/lib/adverb_query.h index e9354bb..403a616 100644 --- a/lib/adverb_query.h +++ b/lib/adverb_query.h | |||
@@ -12,6 +12,10 @@ namespace verbly { | |||
12 | adverb_query& except(const adverb& _word); | 12 | adverb_query& except(const adverb& _word); |
13 | adverb_query& rhymes_with(const word& _word); | 13 | adverb_query& rhymes_with(const word& _word); |
14 | adverb_query& has_pronunciation(); | 14 | adverb_query& has_pronunciation(); |
15 | adverb_query& has_rhyming_noun(); | ||
16 | adverb_query& has_rhyming_adjective(); | ||
17 | adverb_query& has_rhyming_adverb(); | ||
18 | adverb_query& has_rhyming_verb(); | ||
15 | 19 | ||
16 | adverb_query& requires_comparative_form(); | 20 | adverb_query& requires_comparative_form(); |
17 | adverb_query& requires_superlative_form(); | 21 | adverb_query& requires_superlative_form(); |
@@ -41,9 +45,13 @@ namespace verbly { | |||
41 | const data& _data; | 45 | const data& _data; |
42 | int _limit = unlimited; | 46 | int _limit = unlimited; |
43 | bool _random = false; | 47 | bool _random = false; |
44 | std::list<std::string> _rhymes; | 48 | std::list<rhyme> _rhymes; |
45 | std::list<adverb> _except; | 49 | std::list<adverb> _except; |
46 | bool _has_prn = false; | 50 | bool _has_prn = false; |
51 | bool _has_rhyming_noun = false; | ||
52 | bool _has_rhyming_adjective = false; | ||
53 | bool _has_rhyming_adverb = false; | ||
54 | bool _has_rhyming_verb = false; | ||
47 | 55 | ||
48 | bool _requires_comparative_form = false; | 56 | bool _requires_comparative_form = false; |
49 | bool _requires_superlative_form = false; | 57 | bool _requires_superlative_form = false; |
diff --git a/lib/data.cpp b/lib/data.cpp index c14956f..db42487 100644 --- a/lib/data.cpp +++ b/lib/data.cpp | |||
@@ -1,7 +1,7 @@ | |||
1 | #include "verbly.h" | 1 | #include "verbly.h" |
2 | 2 | ||
3 | namespace verbly { | 3 | namespace verbly { |
4 | 4 | ||
5 | data::data(std::string datafile) | 5 | data::data(std::string datafile) |
6 | { | 6 | { |
7 | if (sqlite3_open_v2(datafile.c_str(), &ppdb, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) | 7 | if (sqlite3_open_v2(datafile.c_str(), &ppdb, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) |
diff --git a/lib/frame_query.cpp b/lib/frame_query.cpp index 3c4a3e8..11f0432 100644 --- a/lib/frame_query.cpp +++ b/lib/frame_query.cpp | |||
@@ -73,7 +73,7 @@ namespace verbly { | |||
73 | 73 | ||
74 | case binding::type::string: | 74 | case binding::type::string: |
75 | { | 75 | { |
76 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | 76 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); |
77 | 77 | ||
78 | break; | 78 | break; |
79 | } | 79 | } |
diff --git a/lib/noun_query.cpp b/lib/noun_query.cpp index 19a1297..b4336b6 100644 --- a/lib/noun_query.cpp +++ b/lib/noun_query.cpp | |||
@@ -33,7 +33,7 @@ namespace verbly { | |||
33 | 33 | ||
34 | noun_query& noun_query::rhymes_with(const word& _word) | 34 | noun_query& noun_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 | noun_query& noun_query::has_rhyming_noun() | ||
57 | { | ||
58 | _has_rhyming_noun = true; | ||
59 | |||
60 | return *this; | ||
61 | } | ||
62 | |||
63 | noun_query& noun_query::has_rhyming_adjective() | ||
64 | { | ||
65 | _has_rhyming_adjective = true; | ||
66 | |||
67 | return *this; | ||
68 | } | ||
69 | |||
70 | noun_query& noun_query::has_rhyming_adverb() | ||
71 | { | ||
72 | _has_rhyming_adverb = true; | ||
73 | |||
74 | return *this; | ||
75 | } | ||
76 | |||
77 | noun_query& noun_query::has_rhyming_verb() | ||
78 | { | ||
79 | _has_rhyming_verb = true; | ||
80 | |||
81 | return *this; | ||
82 | } | ||
83 | |||
56 | noun_query& noun_query::with_singular_form(std::string _arg) | 84 | noun_query& noun_query::with_singular_form(std::string _arg) |
57 | { | 85 | { |
58 | _with_singular_form.push_back(_arg); | 86 | _with_singular_form.push_back(_arg); |
@@ -483,16 +511,37 @@ namespace verbly { | |||
483 | 511 | ||
484 | if (!_rhymes.empty()) | 512 | if (!_rhymes.empty()) |
485 | { | 513 | { |
486 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?"); | 514 | std::list<std::string> clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)"); |
487 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 515 | std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; |
488 | conditions.push_back(cond); | 516 | conditions.push_back(cond); |
489 | 517 | ||
490 | for (auto rhyme : _rhymes) | 518 | for (auto rhy : _rhymes) |
491 | { | 519 | { |
492 | bindings.emplace_back("%" + rhyme); | 520 | bindings.emplace_back(rhy.get_prerhyme()); |
521 | bindings.emplace_back(rhy.get_rhyme()); | ||
493 | } | 522 | } |
494 | } | 523 | } |
495 | 524 | ||
525 | if (_has_rhyming_noun) | ||
526 | { | ||
527 | conditions.push_back("noun_id IN (SELECT a.noun_id FROM nouns AS a INNER JOIN noun_pronunciations AS curp ON curp.noun_id = a.noun_id INNER JOIN noun_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme AND rhmp.noun_id != curp.noun_id)"); | ||
528 | } | ||
529 | |||
530 | if (_has_rhyming_adjective) | ||
531 | { | ||
532 | conditions.push_back("noun_id IN (SELECT a.noun_id FROM nouns AS a INNER JOIN noun_pronunciations AS curp ON curp.noun_id = a.noun_id INNER JOIN adjective_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
533 | } | ||
534 | |||
535 | if (_has_rhyming_adverb) | ||
536 | { | ||
537 | conditions.push_back("noun_id IN (SELECT a.noun_id FROM nouns AS a INNER JOIN noun_pronunciations AS curp ON curp.noun_id = a.noun_id INNER JOIN adverb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
538 | } | ||
539 | |||
540 | if (_has_rhyming_verb) | ||
541 | { | ||
542 | conditions.push_back("noun_id IN (SELECT a.noun_id FROM nouns AS a INNER JOIN noun_pronunciations AS curp ON curp.noun_id = a.noun_id INNER JOIN verb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
543 | } | ||
544 | |||
496 | for (auto except : _except) | 545 | for (auto except : _except) |
497 | { | 546 | { |
498 | conditions.push_back("noun_id != ?"); | 547 | conditions.push_back("noun_id != ?"); |
@@ -1768,7 +1817,7 @@ namespace verbly { | |||
1768 | { | 1817 | { |
1769 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 1818 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
1770 | } | 1819 | } |
1771 | 1820 | ||
1772 | int i = 1; | 1821 | int i = 1; |
1773 | for (auto& binding : bindings) | 1822 | for (auto& binding : bindings) |
1774 | { | 1823 | { |
@@ -1783,7 +1832,7 @@ namespace verbly { | |||
1783 | 1832 | ||
1784 | case binding::type::string: | 1833 | case binding::type::string: |
1785 | { | 1834 | { |
1786 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | 1835 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); |
1787 | 1836 | ||
1788 | break; | 1837 | break; |
1789 | } | 1838 | } |
@@ -1791,7 +1840,7 @@ namespace verbly { | |||
1791 | 1840 | ||
1792 | i++; | 1841 | i++; |
1793 | } | 1842 | } |
1794 | 1843 | ||
1795 | /* | 1844 | /* |
1796 | for (auto adj : _derived_from_adjective) | 1845 | for (auto adj : _derived_from_adjective) |
1797 | { | 1846 | { |
@@ -1843,7 +1892,7 @@ namespace verbly { | |||
1843 | 1892 | ||
1844 | for (auto& noun : output) | 1893 | for (auto& noun : output) |
1845 | { | 1894 | { |
1846 | query = "SELECT pronunciation FROM noun_pronunciations WHERE noun_id = ?"; | 1895 | query = "SELECT pronunciation, prerhyme, rhyme FROM noun_pronunciations WHERE noun_id = ?"; |
1847 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | 1896 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) |
1848 | { | 1897 | { |
1849 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 1898 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
@@ -1857,6 +1906,14 @@ namespace verbly { | |||
1857 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | 1906 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); |
1858 | 1907 | ||
1859 | noun.pronunciations.push_back(phonemes); | 1908 | noun.pronunciations.push_back(phonemes); |
1909 | |||
1910 | if ((sqlite3_column_type(ppstmt, 1) != SQLITE_NULL) && (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)) | ||
1911 | { | ||
1912 | std::string prerhyme(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
1913 | std::string rhyming(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
1914 | |||
1915 | noun.rhymes.emplace_back(prerhyme, rhyming); | ||
1916 | } | ||
1860 | } | 1917 | } |
1861 | 1918 | ||
1862 | sqlite3_finalize(ppstmt); | 1919 | sqlite3_finalize(ppstmt); |
diff --git a/lib/noun_query.h b/lib/noun_query.h index 8768f5d..6b5733f 100644 --- a/lib/noun_query.h +++ b/lib/noun_query.h | |||
@@ -12,6 +12,10 @@ namespace verbly { | |||
12 | noun_query& except(const noun& _word); | 12 | noun_query& except(const noun& _word); |
13 | noun_query& rhymes_with(const word& _word); | 13 | noun_query& rhymes_with(const word& _word); |
14 | noun_query& has_pronunciation(); | 14 | noun_query& has_pronunciation(); |
15 | noun_query& has_rhyming_noun(); | ||
16 | noun_query& has_rhyming_adjective(); | ||
17 | noun_query& has_rhyming_adverb(); | ||
18 | noun_query& has_rhyming_verb(); | ||
15 | 19 | ||
16 | noun_query& with_singular_form(std::string _arg); | 20 | noun_query& with_singular_form(std::string _arg); |
17 | noun_query& with_prefix(filter<std::string> _f); | 21 | noun_query& with_prefix(filter<std::string> _f); |
@@ -86,9 +90,13 @@ namespace verbly { | |||
86 | const data& _data; | 90 | const data& _data; |
87 | int _limit = unlimited; | 91 | int _limit = unlimited; |
88 | bool _random = false; | 92 | bool _random = false; |
89 | std::list<std::string> _rhymes; | 93 | std::list<rhyme> _rhymes; |
90 | std::list<noun> _except; | 94 | std::list<noun> _except; |
91 | bool _has_prn = false; | 95 | bool _has_prn = false; |
96 | bool _has_rhyming_noun = false; | ||
97 | bool _has_rhyming_adjective = false; | ||
98 | bool _has_rhyming_adverb = false; | ||
99 | bool _has_rhyming_verb = false; | ||
92 | 100 | ||
93 | std::list<std::string> _with_singular_form; | 101 | std::list<std::string> _with_singular_form; |
94 | filter<std::string> _with_prefix; | 102 | filter<std::string> _with_prefix; |
diff --git a/lib/preposition.cpp b/lib/preposition.cpp index 8df13aa..cea9165 100644 --- a/lib/preposition.cpp +++ b/lib/preposition.cpp | |||
@@ -83,7 +83,7 @@ namespace verbly { | |||
83 | 83 | ||
84 | case binding::type::string: | 84 | case binding::type::string: |
85 | { | 85 | { |
86 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | 86 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); |
87 | 87 | ||
88 | break; | 88 | break; |
89 | } | 89 | } |
diff --git a/lib/verb_query.cpp b/lib/verb_query.cpp index 929ecc7..654bc33 100644 --- a/lib/verb_query.cpp +++ b/lib/verb_query.cpp | |||
@@ -33,7 +33,7 @@ namespace verbly { | |||
33 | 33 | ||
34 | verb_query& verb_query::rhymes_with(const word& _word) | 34 | verb_query& verb_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 | verb_query& verb_query::has_rhyming_noun() | ||
57 | { | ||
58 | _has_rhyming_noun = true; | ||
59 | |||
60 | return *this; | ||
61 | } | ||
62 | |||
63 | verb_query& verb_query::has_rhyming_adjective() | ||
64 | { | ||
65 | _has_rhyming_adjective = true; | ||
66 | |||
67 | return *this; | ||
68 | } | ||
69 | |||
70 | verb_query& verb_query::has_rhyming_adverb() | ||
71 | { | ||
72 | _has_rhyming_adverb = true; | ||
73 | |||
74 | return *this; | ||
75 | } | ||
76 | |||
77 | verb_query& verb_query::has_rhyming_verb() | ||
78 | { | ||
79 | _has_rhyming_verb = true; | ||
80 | |||
81 | return *this; | ||
82 | } | ||
83 | |||
56 | verb_query& verb_query::has_frames() | 84 | verb_query& verb_query::has_frames() |
57 | { | 85 | { |
58 | this->_has_frames = true; | 86 | this->_has_frames = true; |
@@ -74,16 +102,37 @@ namespace verbly { | |||
74 | 102 | ||
75 | if (!_rhymes.empty()) | 103 | if (!_rhymes.empty()) |
76 | { | 104 | { |
77 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?"); | 105 | std::list<std::string> clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)"); |
78 | std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | 106 | std::string cond = "verb_id IN (SELECT verb_id FROM verb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; |
79 | conditions.push_back(cond); | 107 | conditions.push_back(cond); |
80 | 108 | ||
81 | for (auto rhyme : _rhymes) | 109 | for (auto rhy : _rhymes) |
82 | { | 110 | { |
83 | bindings.emplace_back("%" + rhyme); | 111 | bindings.emplace_back(rhy.get_prerhyme()); |
112 | bindings.emplace_back(rhy.get_rhyme()); | ||
84 | } | 113 | } |
85 | } | 114 | } |
86 | 115 | ||
116 | if (_has_rhyming_noun) | ||
117 | { | ||
118 | conditions.push_back("verb_id IN (SELECT a.verb_id FROM verbs AS a INNER JOIN verb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN noun_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
119 | } | ||
120 | |||
121 | if (_has_rhyming_adjective) | ||
122 | { | ||
123 | conditions.push_back("verb_id IN (SELECT a.verb_id FROM verbs AS a INNER JOIN verb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN adjective_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
124 | } | ||
125 | |||
126 | if (_has_rhyming_adverb) | ||
127 | { | ||
128 | conditions.push_back("verb_id IN (SELECT a.verb_id FROM verbs AS a INNER JOIN verb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN adverb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); | ||
129 | } | ||
130 | |||
131 | if (_has_rhyming_verb) | ||
132 | { | ||
133 | conditions.push_back("verb_id IN (SELECT a.verb_id FROM verbs AS a INNER JOIN verb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN verb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme AND rhmp.verb_id != curp.verb_id)"); | ||
134 | } | ||
135 | |||
87 | for (auto except : _except) | 136 | for (auto except : _except) |
88 | { | 137 | { |
89 | conditions.push_back("verb_id != ?"); | 138 | conditions.push_back("verb_id != ?"); |
@@ -132,7 +181,7 @@ namespace verbly { | |||
132 | 181 | ||
133 | case binding::type::string: | 182 | case binding::type::string: |
134 | { | 183 | { |
135 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); | 184 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); |
136 | 185 | ||
137 | break; | 186 | break; |
138 | } | 187 | } |
@@ -158,7 +207,7 @@ namespace verbly { | |||
158 | 207 | ||
159 | for (auto& verb : output) | 208 | for (auto& verb : output) |
160 | { | 209 | { |
161 | query = "SELECT pronunciation FROM verb_pronunciations WHERE verb_id = ?"; | 210 | query = "SELECT pronunciation, prerhyme, rhyme FROM verb_pronunciations WHERE verb_id = ?"; |
162 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | 211 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) |
163 | { | 212 | { |
164 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 213 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
@@ -172,6 +221,13 @@ namespace verbly { | |||
172 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | 221 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); |
173 | 222 | ||
174 | verb.pronunciations.push_back(phonemes); | 223 | verb.pronunciations.push_back(phonemes); |
224 | |||
225 | if ((sqlite3_column_type(ppstmt, 1) != SQLITE_NULL) && (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)) | ||
226 | { | ||
227 | std::string prerhyme(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
228 | std::string rhyming(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
229 | verb.rhymes.emplace_back(prerhyme, rhyming); | ||
230 | } | ||
175 | } | 231 | } |
176 | 232 | ||
177 | sqlite3_finalize(ppstmt); | 233 | sqlite3_finalize(ppstmt); |
diff --git a/lib/verb_query.h b/lib/verb_query.h index 24f5732..a07dc18 100644 --- a/lib/verb_query.h +++ b/lib/verb_query.h | |||
@@ -12,6 +12,10 @@ namespace verbly { | |||
12 | verb_query& except(const verb& _word); | 12 | verb_query& except(const verb& _word); |
13 | verb_query& rhymes_with(const word& _word); | 13 | verb_query& rhymes_with(const word& _word); |
14 | verb_query& has_pronunciation(); | 14 | verb_query& has_pronunciation(); |
15 | verb_query& has_rhyming_noun(); | ||
16 | verb_query& has_rhyming_adjective(); | ||
17 | verb_query& has_rhyming_adverb(); | ||
18 | verb_query& has_rhyming_verb(); | ||
15 | 19 | ||
16 | verb_query& has_frames(); | 20 | verb_query& has_frames(); |
17 | 21 | ||
@@ -23,10 +27,14 @@ namespace verbly { | |||
23 | const data& _data; | 27 | const data& _data; |
24 | int _limit = unlimited; | 28 | int _limit = unlimited; |
25 | bool _random = false; | 29 | bool _random = false; |
26 | std::list<std::string> _rhymes; | 30 | std::list<rhyme> _rhymes; |
27 | std::list<verb> _except; | 31 | std::list<verb> _except; |
28 | bool _has_prn = false; | 32 | bool _has_prn = false; |
29 | bool _has_frames = false; | 33 | bool _has_frames = false; |
34 | bool _has_rhyming_noun = false; | ||
35 | bool _has_rhyming_adjective = false; | ||
36 | bool _has_rhyming_adverb = false; | ||
37 | bool _has_rhyming_verb = false; | ||
30 | }; | 38 | }; |
31 | 39 | ||
32 | }; | 40 | }; |
diff --git a/lib/word.cpp b/lib/word.cpp index 13c611f..49e34a1 100644 --- a/lib/word.cpp +++ b/lib/word.cpp | |||
@@ -3,6 +3,26 @@ | |||
3 | 3 | ||
4 | namespace verbly { | 4 | namespace verbly { |
5 | 5 | ||
6 | rhyme::rhyme(std::string prerhyme, std::string phonemes) : _prerhyme(prerhyme), _rhyme(phonemes) | ||
7 | { | ||
8 | |||
9 | } | ||
10 | |||
11 | std::string rhyme::get_prerhyme() const | ||
12 | { | ||
13 | return _prerhyme; | ||
14 | } | ||
15 | |||
16 | std::string rhyme::get_rhyme() const | ||
17 | { | ||
18 | return _rhyme; | ||
19 | } | ||
20 | |||
21 | bool rhyme::operator==(const rhyme& other) const | ||
22 | { | ||
23 | return std::tie(_prerhyme, _rhyme) == std::tie(other._prerhyme, other._rhyme); | ||
24 | } | ||
25 | |||
6 | word::word() | 26 | word::word() |
7 | { | 27 | { |
8 | 28 | ||
@@ -13,28 +33,11 @@ namespace verbly { | |||
13 | 33 | ||
14 | } | 34 | } |
15 | 35 | ||
16 | std::list<std::string> word::rhyme_phonemes() const | 36 | std::list<rhyme> word::get_rhymes() const |
17 | { | 37 | { |
18 | assert(_valid == true); | 38 | assert(_valid == true); |
19 | 39 | ||
20 | std::list<std::string> result; | 40 | return rhymes; |
21 | |||
22 | for (auto pronunciation : pronunciations) | ||
23 | { | ||
24 | auto phemstrt = std::find_if(std::begin(pronunciation), std::end(pronunciation), [] (std::string phoneme) { | ||
25 | return phoneme.find("1") != std::string::npos; | ||
26 | }); | ||
27 | |||
28 | std::stringstream rhymer; | ||
29 | for (auto it = phemstrt; it != std::end(pronunciation); it++) | ||
30 | { | ||
31 | rhymer << " " << *it; | ||
32 | } | ||
33 | |||
34 | result.push_back(rhymer.str()); | ||
35 | } | ||
36 | |||
37 | return result; | ||
38 | } | 41 | } |
39 | 42 | ||
40 | bool word::starts_with_vowel_sound() const | 43 | bool word::starts_with_vowel_sound() const |
diff --git a/lib/word.h b/lib/word.h index dc6fac8..08797a3 100644 --- a/lib/word.h +++ b/lib/word.h | |||
@@ -3,6 +3,20 @@ | |||
3 | 3 | ||
4 | namespace verbly { | 4 | namespace verbly { |
5 | 5 | ||
6 | class rhyme { | ||
7 | public: | ||
8 | rhyme(std::string prerhyme, std::string phonemes); | ||
9 | |||
10 | std::string get_prerhyme() const; | ||
11 | std::string get_rhyme() const; | ||
12 | |||
13 | bool operator==(const rhyme& other) const; | ||
14 | |||
15 | private: | ||
16 | std::string _prerhyme; | ||
17 | std::string _rhyme; | ||
18 | }; | ||
19 | |||
6 | class word { | 20 | class word { |
7 | protected: | 21 | protected: |
8 | const data* _data; | 22 | const data* _data; |
@@ -10,6 +24,7 @@ namespace verbly { | |||
10 | bool _valid = false; | 24 | bool _valid = false; |
11 | 25 | ||
12 | std::list<std::list<std::string>> pronunciations; | 26 | std::list<std::list<std::string>> pronunciations; |
27 | std::list<rhyme> rhymes; | ||
13 | 28 | ||
14 | word(); | 29 | word(); |
15 | word(const data& _data, int _id); | 30 | word(const data& _data, int _id); |
@@ -24,7 +39,7 @@ namespace verbly { | |||
24 | public: | 39 | public: |
25 | virtual std::string base_form() const = 0; | 40 | virtual std::string base_form() const = 0; |
26 | 41 | ||
27 | std::list<std::string> rhyme_phonemes() const; | 42 | std::list<rhyme> get_rhymes() const; |
28 | bool starts_with_vowel_sound() const; | 43 | bool starts_with_vowel_sound() const; |
29 | }; | 44 | }; |
30 | 45 | ||