about summary refs log tree commit diff stats
path: root/verbly/adverb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'verbly/adverb.cpp')
-rw-r--r--verbly/adverb.cpp364
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
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 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};