summary refs log tree commit diff stats
path: root/lib/adverb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/adverb.cpp')
-rw-r--r--lib/adverb.cpp468
1 files changed, 468 insertions, 0 deletions
diff --git a/lib/adverb.cpp b/lib/adverb.cpp new file mode 100644 index 0000000..8fcddad --- /dev/null +++ b/lib/adverb.cpp
@@ -0,0 +1,468 @@
1#include "verbly.h"
2
3namespace 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 adverb_query& adverb_query::derived_from(const word& _w)
172 {
173 if (dynamic_cast<const adjective*>(&_w) != nullptr)
174 {
175 _derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
176 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
177 {
178 _derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
179 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
180 {
181 _derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
182 }
183
184 return *this;
185 }
186
187 adverb_query& adverb_query::not_derived_from(const word& _w)
188 {
189 if (dynamic_cast<const adjective*>(&_w) != nullptr)
190 {
191 _not_derived_from_adjective.push_back(dynamic_cast<const adjective&>(_w));
192 } else if (dynamic_cast<const adverb*>(&_w) != nullptr)
193 {
194 _not_derived_from_adverb.push_back(dynamic_cast<const adverb&>(_w));
195 } else if (dynamic_cast<const noun*>(&_w) != nullptr)
196 {
197 _not_derived_from_noun.push_back(dynamic_cast<const noun&>(_w));
198 }
199
200 return *this;
201 }
202
203 std::list<adverb> adverb_query::run() const
204 {
205 std::stringstream construct;
206 construct << "SELECT adverb_id, base_form, comparative, superlative FROM adverbs";
207 std::list<std::string> conditions;
208
209 if (_has_prn)
210 {
211 conditions.push_back("adverb_id IN (SELECT adverb_id FROM adverb_pronunciations)");
212 }
213
214 if (!_rhymes.empty())
215 {
216 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN");
217 std::string cond = "adverb_id IN (SELECT adverb_id FROM adverb_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
218 conditions.push_back(cond);
219 }
220
221 for (auto except : _except)
222 {
223 conditions.push_back("adverb_id != @EXCID");
224 }
225
226 if (_requires_comparative_form)
227 {
228 conditions.push_back("comparative IS NOT NULL");
229 }
230
231 if (_requires_superlative_form)
232 {
233 conditions.push_back("superlative IS NOT NULL");
234 }
235
236 if (_has_antonyms)
237 {
238 conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy)");
239 }
240
241 if (!_antonym_of.empty())
242 {
243 std::list<std::string> clauses(_antonym_of.size(), "adverb_1_id = @ANTID");
244 std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
245 conditions.push_back(cond);
246 }
247
248 if (!_not_antonym_of.empty())
249 {
250 std::list<std::string> clauses(_not_antonym_of.size(), "adverb_1_id = @NANTID");
251 std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_antonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
252 conditions.push_back(cond);
253 }
254
255 if (_has_synonyms)
256 {
257 conditions.push_back("adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy)");
258 }
259
260 if (!_synonym_of.empty())
261 {
262 std::list<std::string> clauses(_synonym_of.size(), "adverb_1_id = @SYNID");
263 std::string cond = "adverb_id IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
264 conditions.push_back(cond);
265 }
266
267 if (!_not_synonym_of.empty())
268 {
269 std::list<std::string> clauses(_not_synonym_of.size(), "adverb_1_id = @NSYNID");
270 std::string cond = "adverb_id NOT IN (SELECT adverb_2_id FROM adverb_synonymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
271 conditions.push_back(cond);
272 }
273
274 if (_is_mannernymic)
275 {
276 conditions.push_back("adverb_id IN (SELECT mannernym_id FROM mannernymy)");
277 }
278
279 if (!_mannernym_of.empty())
280 {
281 std::list<std::string> clauses(_mannernym_of.size(), "adjective_id = @AMANID");
282 std::string cond = "adverb_id IN (SELECT mannernym_id FROM mannernymy WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
283 conditions.push_back(cond);
284 }
285
286 if (!_derived_from_adjective.empty())
287 {
288 std::list<std::string> clauses(_derived_from_adjective.size(), "adjective_id = @DERADJ");
289 std::string cond = "adverb_id IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
290 conditions.push_back(cond);
291 }
292
293 if (!_not_derived_from_adjective.empty())
294 {
295 std::list<std::string> clauses(_not_derived_from_adjective.size(), "adjective_id = @NDERADJ");
296 std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM adjective_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
297 conditions.push_back(cond);
298 }
299
300 if (!_derived_from_adverb.empty())
301 {
302 std::list<std::string> clauses(_derived_from_adverb.size(), "adverb_2_id = @DERADV");
303 std::string cond = "adverb_id IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
304 conditions.push_back(cond);
305 }
306
307 if (!_not_derived_from_adverb.empty())
308 {
309 std::list<std::string> clauses(_not_derived_from_adverb.size(), "adverb_2_id = @NDERADV");
310 std::string cond = "adverb_id NOT IN (SELECT adverb_1_id FROM adverb_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
311 conditions.push_back(cond);
312 }
313
314 if (!_derived_from_noun.empty())
315 {
316 std::list<std::string> clauses(_derived_from_noun.size(), "noun_id = @DERN");
317 std::string cond = "adverb_id IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
318 conditions.push_back(cond);
319 }
320
321 if (!_not_derived_from_noun.empty())
322 {
323 std::list<std::string> clauses(_not_derived_from_noun.size(), "noun_id = @NDERN");
324 std::string cond = "adverb_id NOT IN (SELECT adverb_id FROM noun_adverb_derivation WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
325 conditions.push_back(cond);
326 }
327
328 if (!conditions.empty())
329 {
330 construct << " WHERE ";
331 construct << verbly::implode(std::begin(conditions), std::end(conditions), " AND ");
332 }
333
334 if (_random)
335 {
336 construct << " ORDER BY RANDOM()";
337 }
338
339 if (_limit != unlimited)
340 {
341 construct << " LIMIT " << _limit;
342 }
343
344 sqlite3_stmt* ppstmt;
345 std::string query = construct.str();
346 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
347 {
348 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
349 }
350
351 if (!_rhymes.empty())
352 {
353 int i = 0;
354 for (auto rhyme : _rhymes)
355 {
356 std::string rhymer = "%" + rhyme;
357 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC);
358
359 i++;
360 }
361 }
362
363 for (auto except : _except)
364 {
365 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
366 }
367
368 for (auto antonym : _antonym_of)
369 {
370 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
371 }
372
373 for (auto antonym : _not_antonym_of)
374 {
375 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NANTID"), antonym._id);
376 }
377
378 for (auto synonym : _synonym_of)
379 {
380 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
381 }
382
383 for (auto synonym : _not_synonym_of)
384 {
385 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NSYNID"), synonym._id);
386 }
387
388 for (auto adj : _mannernym_of)
389 {
390 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@AMANID"), adj._id);
391 }
392
393 for (auto adj : _derived_from_adjective)
394 {
395 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADJ"), adj._id);
396 }
397
398 for (auto adj : _not_derived_from_adjective)
399 {
400 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADJ"), adj._id);
401 }
402
403 for (auto adv : _derived_from_adverb)
404 {
405 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERADV"), adv._id);
406 }
407
408 for (auto adv : _not_derived_from_adverb)
409 {
410 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERADV"), adv._id);
411 }
412
413 for (auto n : _derived_from_noun)
414 {
415 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@DERN"), n._id);
416 }
417
418 for (auto n : _not_derived_from_noun)
419 {
420 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@NDERN"), n._id);
421 }
422
423 std::list<adverb> output;
424 while (sqlite3_step(ppstmt) == SQLITE_ROW)
425 {
426 adverb tnc {_data, sqlite3_column_int(ppstmt, 0)};
427 tnc._base_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 1)));
428
429 if (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)
430 {
431 tnc._comparative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
432 }
433
434 if (sqlite3_column_type(ppstmt, 3) != SQLITE_NULL)
435 {
436 tnc._superlative_form = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 3)));
437 }
438
439 output.push_back(tnc);
440 }
441
442 sqlite3_finalize(ppstmt);
443
444 for (auto& adverb : output)
445 {
446 query = "SELECT pronunciation FROM adverb_pronunciations WHERE adverb_id = ?";
447 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
448 {
449 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
450 }
451
452 sqlite3_bind_int(ppstmt, 1, adverb._id);
453
454 while (sqlite3_step(ppstmt) == SQLITE_ROW)
455 {
456 std::string pronunciation(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 0)));
457 auto phonemes = verbly::split<std::list<std::string>>(pronunciation, " ");
458
459 adverb.pronunciations.push_back(phonemes);
460 }
461
462 sqlite3_finalize(ppstmt);
463 }
464
465 return output;
466 }
467
468};