diff options
Diffstat (limited to 'lib/verb_query.cpp')
| -rw-r--r-- | lib/verb_query.cpp | 99 |
1 files changed, 84 insertions, 15 deletions
| diff --git a/lib/verb_query.cpp b/lib/verb_query.cpp index 173a04e..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; |
| @@ -65,6 +93,7 @@ namespace verbly { | |||
| 65 | std::stringstream construct; | 93 | std::stringstream construct; |
| 66 | construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; | 94 | construct << "SELECT verb_id, infinitive, past_tense, past_participle, ing_form, s_form FROM verbs"; |
| 67 | std::list<std::string> conditions; | 95 | std::list<std::string> conditions; |
| 96 | std::list<binding> bindings; | ||
| 68 | 97 | ||
| 69 | if (_has_prn) | 98 | if (_has_prn) |
| 70 | { | 99 | { |
| @@ -73,14 +102,41 @@ namespace verbly { | |||
| 73 | 102 | ||
| 74 | if (!_rhymes.empty()) | 103 | if (!_rhymes.empty()) |
| 75 | { | 104 | { |
| 76 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | 105 | std::list<std::string> clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)"); |
| 77 | 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 ") + ")"; |
| 78 | conditions.push_back(cond); | 107 | conditions.push_back(cond); |
| 108 | |||
| 109 | for (auto rhy : _rhymes) | ||
| 110 | { | ||
| 111 | bindings.emplace_back(rhy.get_prerhyme()); | ||
| 112 | bindings.emplace_back(rhy.get_rhyme()); | ||
| 113 | } | ||
| 114 | } | ||
| 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)"); | ||
| 79 | } | 134 | } |
| 80 | 135 | ||
| 81 | for (auto except : _except) | 136 | for (auto except : _except) |
| 82 | { | 137 | { |
| 83 | conditions.push_back("verb_id != @EXCID"); | 138 | conditions.push_back("verb_id != ?"); |
| 139 | bindings.emplace_back(except._id); | ||
| 84 | } | 140 | } |
| 85 | 141 | ||
| 86 | if (!_has_frames) | 142 | if (!_has_frames) |
| @@ -111,21 +167,27 @@ namespace verbly { | |||
| 111 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 167 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
| 112 | } | 168 | } |
| 113 | 169 | ||
| 114 | if (!_rhymes.empty()) | 170 | int i = 1; |
| 171 | for (auto& binding : bindings) | ||
| 115 | { | 172 | { |
| 116 | int i = 0; | 173 | switch (binding.get_type()) |
| 117 | for (auto rhyme : _rhymes) | ||
| 118 | { | 174 | { |
| 119 | std::string rhymer = "%" + rhyme; | 175 | case binding::type::integer: |
| 120 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | 176 | { |
| 177 | sqlite3_bind_int(ppstmt, i, binding.get_integer()); | ||
| 178 | |||
| 179 | break; | ||
| 180 | } | ||
| 121 | 181 | ||
| 122 | i++; | 182 | case binding::type::string: |
| 183 | { | ||
| 184 | sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); | ||
| 185 | |||
| 186 | break; | ||
| 187 | } | ||
| 123 | } | 188 | } |
| 124 | } | 189 | |
| 125 | 190 | i++; | |
| 126 | for (auto except : _except) | ||
| 127 | { | ||
| 128 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 129 | } | 191 | } |
| 130 | 192 | ||
| 131 | std::list<verb> output; | 193 | std::list<verb> output; |
| @@ -145,7 +207,7 @@ namespace verbly { | |||
| 145 | 207 | ||
| 146 | for (auto& verb : output) | 208 | for (auto& verb : output) |
| 147 | { | 209 | { |
| 148 | query = "SELECT pronunciation FROM verb_pronunciations WHERE verb_id = ?"; | 210 | query = "SELECT pronunciation, prerhyme, rhyme FROM verb_pronunciations WHERE verb_id = ?"; |
| 149 | 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) |
| 150 | { | 212 | { |
| 151 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | 213 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); |
| @@ -159,6 +221,13 @@ namespace verbly { | |||
| 159 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | 221 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); |
| 160 | 222 | ||
| 161 | 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 | } | ||
| 162 | } | 231 | } |
| 163 | 232 | ||
| 164 | sqlite3_finalize(ppstmt); | 233 | sqlite3_finalize(ppstmt); |
