diff options
Diffstat (limited to 'verbly/adverb.cpp')
| -rw-r--r-- | verbly/adverb.cpp | 364 |
1 files changed, 364 insertions, 0 deletions
| diff --git a/verbly/adverb.cpp b/verbly/adverb.cpp new file mode 100644 index 0000000..9bb5a0d --- /dev/null +++ b/verbly/adverb.cpp | |||
| @@ -0,0 +1,364 @@ | |||
| 1 | #include "verbly.h" | ||
| 2 | |||
| 3 | namespace verbly { | ||
| 4 | |||
| 5 | adverb::adverb(const data& _data, int _id) : word(_data, _id) | ||
| 6 | { | ||
| 7 | |||
| 8 | } | ||
| 9 | |||
| 10 | std::string adverb::base_form() const | ||
| 11 | { | ||
| 12 | return _base_form; | ||
| 13 | } | ||
| 14 | |||
| 15 | std::string adverb::comparative_form() const | ||
| 16 | { | ||
| 17 | return _comparative_form; | ||
| 18 | } | ||
| 19 | |||
| 20 | std::string adverb::superlative_form() const | ||
| 21 | { | ||
| 22 | return _superlative_form; | ||
| 23 | } | ||
| 24 | |||
| 25 | bool adverb::has_comparative_form() const | ||
| 26 | { | ||
| 27 | return !_comparative_form.empty(); | ||
| 28 | } | ||
| 29 | |||
| 30 | bool adverb::has_superlative_form() const | ||
| 31 | { | ||
| 32 | return !_superlative_form.empty(); | ||
| 33 | } | ||
| 34 | |||
| 35 | adverb_query adverb::antonyms() const | ||
| 36 | { | ||
| 37 | return _data.adverbs().antonym_of(*this); | ||
| 38 | } | ||
| 39 | |||
| 40 | adverb_query adverb::synonyms() const | ||
| 41 | { | ||
| 42 | return _data.adverbs().synonym_of(*this); | ||
| 43 | } | ||
| 44 | |||
| 45 | adjective_query adverb::anti_mannernyms() const | ||
| 46 | { | ||
| 47 | return _data.adjectives().anti_mannernym_of(*this); | ||
| 48 | } | ||
| 49 | |||
| 50 | adverb_query::adverb_query(const data& _data) : _data(_data) | ||
| 51 | { | ||
| 52 | |||
| 53 | } | ||
| 54 | |||
| 55 | adverb_query& adverb_query::limit(int _limit) | ||
| 56 | { | ||
| 57 | if ((_limit > 0) || (_limit == unlimited)) | ||
| 58 | { | ||
| 59 | this->_limit = _limit; | ||
| 60 | } | ||
| 61 | |||
| 62 | return *this; | ||
| 63 | } | ||
| 64 | |||
| 65 | adverb_query& adverb_query::random(bool _random) | ||
| 66 | { | ||
| 67 | this->_random = _random; | ||
| 68 | |||
| 69 | return *this; | ||
| 70 | } | ||
| 71 | |||
| 72 | adverb_query& adverb_query::except(const adverb& _word) | ||
| 73 | { | ||
| 74 | _except.push_back(_word); | ||
| 75 | |||
| 76 | return *this; | ||
| 77 | } | ||
| 78 | |||
| 79 | adverb_query& adverb_query::rhymes_with(const word& _word) | ||
| 80 | { | ||
| 81 | for (auto rhyme : _word.rhyme_phonemes()) | ||
| 82 | { | ||
| 83 | _rhymes.push_back(rhyme); | ||
| 84 | } | ||
| 85 | |||
| 86 | if (dynamic_cast<const adverb*>(&_word) != nullptr) | ||
| 87 | { | ||
| 88 | _except.push_back(dynamic_cast<const adverb&>(_word)); | ||
| 89 | } | ||
| 90 | |||
| 91 | return *this; | ||
| 92 | } | ||
| 93 | |||
| 94 | adverb_query& adverb_query::has_pronunciation(bool _has_prn) | ||
| 95 | { | ||
| 96 | this->_has_prn = _has_prn; | ||
| 97 | |||
| 98 | return *this; | ||
| 99 | } | ||
| 100 | |||
| 101 | adverb_query& adverb_query::requires_comparative_form(bool _arg) | ||
| 102 | { | ||
| 103 | _requires_comparative_form = _arg; | ||
| 104 | |||
| 105 | return *this; | ||
| 106 | } | ||
| 107 | |||
| 108 | adverb_query& adverb_query::requires_superlative_form(bool _arg) | ||
| 109 | { | ||
| 110 | _requires_superlative_form = _arg; | ||
| 111 | |||
| 112 | return *this; | ||
| 113 | } | ||
| 114 | |||
| 115 | adverb_query& adverb_query::has_antonyms(bool _arg) | ||
| 116 | { | ||
| 117 | _has_antonyms = _arg; | ||
| 118 | |||
| 119 | return *this; | ||
| 120 | } | ||
| 121 | |||
| 122 | adverb_query& adverb_query::antonym_of(const adverb& _adv) | ||
| 123 | { | ||
| 124 | _antonym_of.push_back(_adv); | ||
| 125 | |||
| 126 | return *this; | ||
| 127 | } | ||
| 128 | |||
| 129 | adverb_query& adverb_query::not_antonym_of(const adverb& _adv) | ||
| 130 | { | ||
| 131 | _not_antonym_of.push_back(_adv); | ||
| 132 | |||
| 133 | return *this; | ||
| 134 | } | ||
| 135 | |||
| 136 | adverb_query& adverb_query::has_synonyms(bool _arg) | ||
| 137 | { | ||
| 138 | _has_synonyms = _arg; | ||
| 139 | |||
| 140 | return *this; | ||
| 141 | } | ||
| 142 | |||
| 143 | adverb_query& adverb_query::synonym_of(const adverb& _adv) | ||
| 144 | { | ||
| 145 | _synonym_of.push_back(_adv); | ||
| 146 | |||
| 147 | return *this; | ||
| 148 | } | ||
| 149 | |||
| 150 | adverb_query& adverb_query::not_synonym_of(const adverb& _adv) | ||
| 151 | { | ||
| 152 | _not_synonym_of.push_back(_adv); | ||
| 153 | |||
| 154 | return *this; | ||
| 155 | } | ||
| 156 | |||
| 157 | adverb_query& adverb_query::is_mannernymic(bool _arg) | ||
| 158 | { | ||
| 159 | _is_mannernymic = _arg; | ||
| 160 | |||
| 161 | return *this; | ||
| 162 | } | ||
| 163 | |||
| 164 | adverb_query& adverb_query::mannernym_of(const adjective& _adj) | ||
| 165 | { | ||
| 166 | _mannernym_of.push_back(_adj); | ||
| 167 | |||
| 168 | return *this; | ||
| 169 | } | ||
| 170 | |||
| 171 | std::list<adverb> adverb_query::run() const | ||
| 172 | { | ||
| 173 | std::stringstream construct; | ||
| 174 | construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs"; | ||
| 175 | std::list<std::string> conditions; | ||
| 176 | |||
| 177 | if (_has_prn) | ||
| 178 | { | ||
| 179 | conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)"); | ||
| 180 | } | ||
| 181 | |||
| 182 | if (!_rhymes.empty()) | ||
| 183 | { | ||
| 184 | std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); | ||
| 185 | 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); | ||
| 187 | } | ||
| 188 | |||
| 189 | for (auto except : _except) | ||
| 190 | { | ||
| 191 | conditions.push_back("adverb_id != @EXCID"); | ||
| 192 | } | ||
| 193 | |||
| 194 | if (_requires_comparative_form) | ||
| 195 | { | ||
| 196 | conditions.push_back("comparative IS NOT NULL"); | ||
| 197 | } | ||
| 198 | |||
| 199 | if (_requires_superlative_form) | ||
| 200 | { | ||
| 201 | conditions.push_back("superlative IS NOT NULL"); | ||
| 202 | } | ||
| 203 | |||
| 204 | if (_has_antonyms) | ||
| 205 | { | ||
| 206 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)"); | ||
| 207 | } | ||
| 208 | |||
| 209 | if (!_antonym_of.empty()) | ||
| 210 | { | ||
| 211 | std::list<std::string> clauses(_antonym_of.size(), "adverb_1_id = @ANTID"); | ||
| 212 | std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 213 | conditions.push_back(cond); | ||
| 214 | } | ||
| 215 | |||
| 216 | if (!_not_antonym_of.empty()) | ||
| 217 | { | ||
| 218 | std::list<std::string> clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID"); | ||
| 219 | std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 220 | conditions.push_back(cond); | ||
| 221 | } | ||
| 222 | |||
| 223 | if (_has_synonyms) | ||
| 224 | { | ||
| 225 | conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)"); | ||
| 226 | } | ||
| 227 | |||
| 228 | if (!_synonym_of.empty()) | ||
| 229 | { | ||
| 230 | std::list<std::string> clauses(_synonym_of.size(), "adverb_1_id = @SYNID"); | ||
| 231 | std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 232 | conditions.push_back(cond); | ||
| 233 | } | ||
| 234 | |||
| 235 | if (!_not_synonym_of.empty()) | ||
| 236 | { | ||
| 237 | std::list<std::string> clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID"); | ||
| 238 | std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 239 | conditions.push_back(cond); | ||
| 240 | } | ||
| 241 | |||
| 242 | if (_is_mannernymic) | ||
| 243 | { | ||
| 244 | conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)"); | ||
| 245 | } | ||
| 246 | |||
| 247 | if (!_mannernym_of.empty()) | ||
| 248 | { | ||
| 249 | std::list<std::string> clauses(_mannernym_of.size(), "adjective_id = @AMANID"); | ||
| 250 | std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; | ||
| 251 | conditions.push_back(cond); | ||
| 252 | } | ||
| 253 | |||
| 254 | if (!conditions.empty()) | ||
| 255 | { | ||
| 256 | construct << " WHERE "; | ||
| 257 | construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND "); | ||
| 258 | } | ||
| 259 | |||
| 260 | if (_random) | ||
| 261 | { | ||
| 262 | construct << " ORDER BY RANDOM()"; | ||
| 263 | } | ||
| 264 | |||
| 265 | if (_limit != unlimited) | ||
| 266 | { | ||
| 267 | construct << " LIMIT " << _limit; | ||
| 268 | } | ||
| 269 | |||
| 270 | sqlite3_stmt* ppstmt; | ||
| 271 | std::string query = construct.str(); | ||
| 272 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 273 | { | ||
| 274 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 275 | } | ||
| 276 | |||
| 277 | if (!_rhymes.empty()) | ||
| 278 | { | ||
| 279 | int i = 0; | ||
| 280 | for (auto rhyme : _rhymes) | ||
| 281 | { | ||
| 282 | std::string rhymer = "%" + rhyme; | ||
| 283 | sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); | ||
| 284 | |||
| 285 | i++; | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | for (auto except : _except) | ||
| 290 | { | ||
| 291 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id); | ||
| 292 | } | ||
| 293 | |||
| 294 | for (auto antonym : _antonym_of) | ||
| 295 | { | ||
| 296 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id); | ||
| 297 | } | ||
| 298 | |||
| 299 | for (auto antonym : _not_antonym_of) | ||
| 300 | { | ||
| 301 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id); | ||
| 302 | } | ||
| 303 | |||
| 304 | for (auto synonym : _synonym_of) | ||
| 305 | { | ||
| 306 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id); | ||
| 307 | } | ||
| 308 | |||
| 309 | for (auto synonym : _not_synonym_of) | ||
| 310 | { | ||
| 311 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id); | ||
| 312 | } | ||
| 313 | |||
| 314 | for (auto adj : _mannernym_of) | ||
| 315 | { | ||
| 316 | sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id); | ||
| 317 | } | ||
| 318 | |||
| 319 | std::list<adverb> output; | ||
| 320 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 321 | { | ||
| 322 | adverb tnc {_data, sqlite3_column_int(ppstmt, 0)}; | ||
| 323 | tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1))); | ||
| 324 | |||
| 325 | if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL) | ||
| 326 | { | ||
| 327 | tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); | ||
| 328 | } | ||
| 329 | |||
| 330 | if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL) | ||
| 331 | { | ||
| 332 | tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3))); | ||
| 333 | } | ||
| 334 | |||
| 335 | output.push_back(tnc); | ||
| 336 | } | ||
| 337 | |||
| 338 | sqlite3_finalize(ppstmt); | ||
| 339 | |||
| 340 | for (auto& adverb : output) | ||
| 341 | { | ||
| 342 | query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?"; | ||
| 343 | if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) | ||
| 344 | { | ||
| 345 | throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); | ||
| 346 | } | ||
| 347 | |||
| 348 | sqlite3_bind_int(ppstmt, 1, adverb._id); | ||
| 349 | |||
| 350 | while (sqlite3_step(ppstmt) == SQLITE_ROW) | ||
| 351 | { | ||
| 352 | std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0))); | ||
| 353 | auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " "); | ||
| 354 | |||
| 355 | adverb.pronunciations.push_back(phonemes); | ||
| 356 | } | ||
| 357 | |||
| 358 | sqlite3_finalize(ppstmt); | ||
| 359 | } | ||
| 360 | |||
| 361 | return output; | ||
| 362 | } | ||
| 363 | |||
| 364 | }; | ||
