Line data Source code
1 : /********************************************************************\
2 : * Query.c : api for finding transactions *
3 : * Copyright (C) 2000 Bill Gribble <grib@billgribble.com> *
4 : * Copyright (C) 2002 Linas Vepstas <linas@linas.org> *
5 : * *
6 : * This program is free software; you can redistribute it and/or *
7 : * modify it under the terms of the GNU General Public License as *
8 : * published by the Free Software Foundation; either version 2 of *
9 : * the License, or (at your option) any later version. *
10 : * *
11 : * This program is distributed in the hope that it will be useful, *
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 : * GNU General Public License for more details. *
15 : * *
16 : * You should have received a copy of the GNU General Public License*
17 : * along with this program; if not, contact: *
18 : * *
19 : * Free Software Foundation Voice: +1-617-542-5942 *
20 : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21 : * Boston, MA 02110-1301, USA gnu@gnu.org *
22 : \********************************************************************/
23 :
24 : #include <config.h>
25 :
26 : #include <platform.h>
27 : #if PLATFORM(WINDOWS)
28 : #include <windows.h>
29 : #endif
30 :
31 : #include <ctype.h>
32 : #include <glib.h>
33 : #include <math.h>
34 : #include <string.h>
35 : #include <sys/types.h>
36 :
37 : #include <regex.h>
38 : #ifdef HAVE_UNISTD_H
39 : # include <unistd.h>
40 : #endif
41 :
42 : #include "gnc-lot.h"
43 : #include "Account.h"
44 : #include "Query.h"
45 : #include "Transaction.h"
46 : #include "TransactionP.hpp"
47 :
48 : static QofLogModule log_module = GNC_MOD_QUERY;
49 :
50 : static GSList *
51 2321 : build_param_list_internal (const char *first, va_list rest)
52 : {
53 2321 : GSList *list = nullptr;
54 : char const *param;
55 :
56 5351 : for (param = first; param; param = va_arg (rest, const char *))
57 3030 : list = g_slist_prepend (list, (gpointer)param);
58 :
59 2321 : return (g_slist_reverse (list));
60 : }
61 :
62 : /********************************************************************
63 : * xaccQueryGetSplitsUniqueTrans
64 : * Get splits but no more than one from a given transaction.
65 : ********************************************************************/
66 :
67 : SplitList *
68 19 : xaccQueryGetSplitsUniqueTrans(QofQuery *q)
69 : {
70 19 : GList * splits = qof_query_run(q);
71 : GList * current;
72 19 : GList * result = nullptr;
73 19 : GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
74 :
75 270 : for (current = splits; current; current = current->next)
76 : {
77 251 : Split *split = GNC_SPLIT (current->data);
78 251 : Transaction *trans = xaccSplitGetParent (split);
79 :
80 251 : if (!g_hash_table_lookup (trans_hash, trans))
81 : {
82 232 : g_hash_table_insert (trans_hash, trans, trans);
83 232 : result = g_list_prepend (result, split);
84 : }
85 : }
86 :
87 19 : g_hash_table_destroy (trans_hash);
88 :
89 19 : return g_list_reverse (result);
90 : }
91 :
92 : /********************************************************************
93 : * xaccQueryGetTransactions
94 : * Get transactions matching the query terms, specifying whether
95 : * we require some or all splits to match
96 : ********************************************************************/
97 :
98 : static void
99 59 : query_match_all_filter_func(gpointer key, gpointer value, gpointer user_data)
100 : {
101 59 : Transaction * t = GNC_TRANSACTION(key);
102 59 : int num_matches = GPOINTER_TO_INT(value);
103 59 : auto matches = static_cast<GList**>(user_data);
104 :
105 59 : if (num_matches == xaccTransCountSplits(t))
106 : {
107 59 : *matches = g_list_prepend(*matches, t);
108 : }
109 59 : }
110 :
111 : static void
112 200 : query_match_any_filter_func(gpointer key, gpointer value, gpointer user_data)
113 : {
114 200 : Transaction * t = GNC_TRANSACTION(key);
115 200 : auto matches = static_cast<GList**>(user_data);
116 200 : *matches = g_list_prepend(*matches, t);
117 200 : }
118 :
119 : TransList *
120 201 : xaccQueryGetTransactions (QofQuery * q, query_txn_match_t runtype)
121 : {
122 201 : GList * splits = qof_query_run(q);
123 201 : GList * current = nullptr;
124 201 : GList * retval = nullptr;
125 201 : GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
126 201 : Transaction * trans = nullptr;
127 201 : gpointer val = nullptr;
128 201 : int count = 0;
129 :
130 : /* iterate over matching splits, incrementing a match-count in
131 : * the hash table */
132 520 : for (current = splits; current; current = current->next)
133 : {
134 319 : trans = xaccSplitGetParent(GNC_SPLIT(current->data));
135 :
136 : /* don't waste time looking up unless we need the count
137 : * information */
138 319 : if (runtype == QUERY_TXN_MATCH_ALL)
139 : {
140 119 : val = g_hash_table_lookup(trans_hash, trans);
141 119 : count = GPOINTER_TO_INT(val);
142 : }
143 319 : g_hash_table_insert(trans_hash, trans, GINT_TO_POINTER(count + 1));
144 : }
145 :
146 : /* now pick out the transactions that match */
147 201 : if (runtype == QUERY_TXN_MATCH_ALL)
148 : {
149 1 : g_hash_table_foreach(trans_hash, query_match_all_filter_func,
150 : &retval);
151 : }
152 : else
153 : {
154 200 : g_hash_table_foreach(trans_hash, query_match_any_filter_func,
155 : &retval);
156 : }
157 :
158 201 : g_hash_table_destroy(trans_hash);
159 :
160 201 : return retval;
161 : }
162 :
163 : /********************************************************************
164 : * xaccQueryGetLots
165 : * Get lots matching the query terms, specifying whether
166 : * we require some or all splits to match
167 : ********************************************************************/
168 :
169 : static void
170 0 : query_match_all_lot_filter_func(gpointer key, gpointer value, gpointer user_data)
171 : {
172 0 : GNCLot * l = GNC_LOT(key);
173 0 : int num_matches = GPOINTER_TO_INT(value);
174 0 : auto matches = static_cast<GList**>(user_data);
175 :
176 0 : if (num_matches == gnc_lot_count_splits(l))
177 : {
178 0 : *matches = g_list_prepend(*matches, l);
179 : }
180 0 : }
181 :
182 : static void
183 0 : query_match_any_lot_filter_func(gpointer key, gpointer value, gpointer user_data)
184 : {
185 0 : GNCLot * t = GNC_LOT(key);
186 0 : auto matches = static_cast<GList**>(user_data);
187 0 : *matches = g_list_prepend(*matches, t);
188 0 : }
189 :
190 : LotList *
191 0 : xaccQueryGetLots (QofQuery * q, query_txn_match_t runtype)
192 : {
193 0 : GList * splits = qof_query_run(q);
194 0 : GList * current = nullptr;
195 0 : GList * retval = nullptr;
196 0 : GHashTable * lot_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
197 0 : GNCLot * lot = nullptr;
198 0 : gpointer val = nullptr;
199 0 : int count = 0;
200 :
201 : /* iterate over matching splits, incrementing a match-count in
202 : * the hash table */
203 0 : for (current = splits; current; current = current->next)
204 : {
205 0 : lot = xaccSplitGetLot((GNC_SPLIT (current->data)));
206 :
207 : /* don't waste time looking up unless we need the count
208 : * information */
209 0 : if (runtype == QUERY_TXN_MATCH_ALL)
210 : {
211 0 : val = g_hash_table_lookup(lot_hash, lot);
212 0 : count = GPOINTER_TO_INT(val);
213 : }
214 0 : g_hash_table_insert(lot_hash, lot, GINT_TO_POINTER(count + 1));
215 : }
216 :
217 : /* now pick out the transactions that match */
218 0 : if (runtype == QUERY_TXN_MATCH_ALL)
219 : {
220 0 : g_hash_table_foreach(lot_hash, query_match_all_lot_filter_func,
221 : &retval);
222 : }
223 : else
224 : {
225 0 : g_hash_table_foreach(lot_hash, query_match_any_lot_filter_func,
226 : &retval);
227 : }
228 :
229 0 : g_hash_table_destroy(lot_hash);
230 :
231 0 : return retval;
232 : }
233 :
234 : /*******************************************************************
235 : * match-adding API
236 : *******************************************************************/
237 :
238 : void
239 368 : xaccQueryAddAccountMatch(QofQuery *q, AccountList *acct_list,
240 : QofGuidMatch how, QofQueryOp op)
241 : {
242 368 : GList *list = nullptr;
243 :
244 368 : if (!q) return;
245 1242 : for (; acct_list; acct_list = acct_list->next)
246 : {
247 874 : Account *acc = GNC_ACCOUNT (acct_list->data);
248 : const GncGUID *guid;
249 :
250 874 : if (!acc)
251 : {
252 0 : PWARN ("acct_list has nullptr account");
253 0 : continue;
254 : }
255 :
256 874 : guid = qof_entity_get_guid (QOF_INSTANCE(acc));
257 874 : if (!guid)
258 : {
259 0 : PWARN ("acct returns nullptr GncGUID");
260 0 : continue;
261 : }
262 :
263 874 : list = g_list_prepend (list, (gpointer)guid);
264 : }
265 368 : xaccQueryAddAccountGUIDMatch (q, list, how, op);
266 368 : g_list_free (list);
267 : }
268 :
269 : void
270 1170 : xaccQueryAddAccountGUIDMatch(QofQuery *q, AccountGUIDList *guid_list,
271 : QofGuidMatch how, QofQueryOp op)
272 : {
273 : QofQueryPredData *pred_data;
274 1170 : GSList *param_list = nullptr;
275 :
276 1170 : if (!q) return;
277 :
278 1170 : if (!guid_list && how != QOF_GUID_MATCH_NULL)
279 : {
280 0 : g_warning("Got a nullptr guid_list but the QofGuidMatch is not MATCH_nullptr (but instead %d). In other words, the list of GUID matches is empty but it must contain something non-empty.", how);
281 : /* qof_query_guid_predicate() would trigger a g_warning as well */
282 0 : return;
283 : }
284 1170 : pred_data = qof_query_guid_predicate (how, guid_list);
285 1170 : if (!pred_data)
286 0 : return;
287 :
288 1170 : switch (how)
289 : {
290 970 : case QOF_GUID_MATCH_ANY:
291 : case QOF_GUID_MATCH_NONE:
292 970 : param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID, nullptr);
293 970 : break;
294 200 : case QOF_GUID_MATCH_ALL:
295 200 : param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_SPLITLIST,
296 : SPLIT_ACCOUNT_GUID, nullptr);
297 200 : break;
298 0 : default:
299 0 : PERR ("Invalid match type: %d", how);
300 0 : break;
301 : }
302 :
303 1170 : qof_query_add_term (q, param_list, pred_data, op);
304 : }
305 :
306 : void
307 201 : xaccQueryAddSingleAccountMatch(QofQuery *q, Account *acc, QofQueryOp op)
308 : {
309 : GList *list;
310 : const GncGUID *guid;
311 :
312 201 : if (!q || !acc)
313 0 : return;
314 :
315 201 : guid = qof_entity_get_guid (QOF_INSTANCE(acc));
316 201 : g_return_if_fail (guid);
317 :
318 201 : list = g_list_prepend (nullptr, (gpointer)guid);
319 201 : xaccQueryAddAccountGUIDMatch (q, list, QOF_GUID_MATCH_ANY, op);
320 201 : g_list_free (list);
321 : }
322 :
323 : void
324 1471 : xaccQueryAddStringMatch (QofQuery* q, const char *matchstring,
325 : gboolean case_sens, gboolean use_regexp,
326 : QofQueryCompare how, QofQueryOp op,
327 : const char * path, ...)
328 : {
329 : QofQueryPredData *pred_data;
330 : GSList *param_list;
331 : va_list ap;
332 :
333 1471 : if (!path || !q)
334 0 : return;
335 :
336 1471 : pred_data = qof_query_string_predicate (how, (char *)matchstring,
337 : (case_sens ? QOF_STRING_MATCH_NORMAL :
338 : QOF_STRING_MATCH_CASEINSENSITIVE),
339 : use_regexp);
340 1471 : if (!pred_data)
341 419 : return;
342 :
343 1052 : va_start (ap, path);
344 1052 : param_list = build_param_list_internal (path, ap);
345 1052 : va_end (ap);
346 :
347 1052 : qof_query_add_term (q, param_list, pred_data, op);
348 : }
349 :
350 : void
351 1269 : xaccQueryAddNumericMatch (QofQuery *q, gnc_numeric amount, QofNumericMatch sign,
352 : QofQueryCompare how, QofQueryOp op,
353 : const char * path, ...)
354 : {
355 : QofQueryPredData *pred_data;
356 : GSList *param_list;
357 : va_list ap;
358 :
359 1269 : if (!q || !path)
360 0 : return;
361 :
362 1269 : pred_data = qof_query_numeric_predicate (how, sign, amount);
363 1269 : if (!pred_data)
364 0 : return;
365 :
366 1269 : va_start (ap, path);
367 1269 : param_list = build_param_list_internal (path, ap);
368 1269 : va_end (ap);
369 :
370 1269 : qof_query_add_term (q, param_list, pred_data, op);
371 : }
372 :
373 : /* The DateMatch queries match transactions whose posted date
374 : * is in a date range. If use_start is TRUE, then a matching
375 : * posted date will be greater than the start date. If
376 : * use_end is TRUE, then a match occurs for posted dates earlier
377 : * than the end date. If both flags are set, then *both*
378 : * conditions must hold ('and'). If neither flag is set, then
379 : * all transactions are matched.
380 : */
381 :
382 : void
383 560 : xaccQueryAddDateMatchTT (QofQuery * q,
384 : gboolean use_start, time64 stt,
385 : gboolean use_end, time64 ett,
386 : QofQueryOp op)
387 : {
388 560 : QofQuery *tmp_q = nullptr;
389 : QofQueryPredData *pred_data;
390 : GSList *param_list;
391 :
392 560 : if (!q || (!use_start && !use_end))
393 56 : return;
394 :
395 504 : tmp_q = qof_query_create ();
396 :
397 504 : if (use_start)
398 : {
399 438 : pred_data = qof_query_date_predicate (QOF_COMPARE_GTE, QOF_DATE_MATCH_NORMAL, stt);
400 438 : if (!pred_data)
401 : {
402 0 : qof_query_destroy (tmp_q);
403 0 : return;
404 : }
405 :
406 438 : param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, nullptr);
407 438 : qof_query_add_term (tmp_q, param_list, pred_data, QOF_QUERY_AND);
408 : }
409 :
410 504 : if (use_end)
411 : {
412 465 : pred_data = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, ett);
413 465 : if (!pred_data)
414 : {
415 0 : qof_query_destroy (tmp_q);
416 0 : return;
417 : }
418 :
419 465 : param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, nullptr);
420 465 : qof_query_add_term (tmp_q, param_list, pred_data, QOF_QUERY_AND);
421 : }
422 :
423 504 : qof_query_merge_in_place (q, tmp_q, op);
424 504 : qof_query_destroy (tmp_q);
425 : }
426 :
427 : void
428 0 : xaccQueryGetDateMatchTT (QofQuery * q,
429 : time64 * stt,
430 : time64 * ett)
431 : {
432 : QofQueryPredData *term_data;
433 : GSList *param_list;
434 : GSList *terms, *tmp;
435 :
436 0 : *stt = 0;
437 0 : *ett = 0;
438 :
439 0 : param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, nullptr);
440 0 : terms = qof_query_get_term_type (q, param_list);
441 0 : g_slist_free(param_list);
442 :
443 0 : for (tmp = terms; tmp; tmp = g_slist_next(tmp))
444 : {
445 0 : term_data = static_cast<QofQueryPredData*>(tmp->data);
446 0 : if (term_data->how == QOF_COMPARE_GTE)
447 0 : qof_query_date_predicate_get_date(term_data, stt);
448 0 : if (term_data->how == QOF_COMPARE_LTE)
449 0 : qof_query_date_predicate_get_date(term_data, ett);
450 : }
451 0 : g_slist_free(terms);
452 0 : }
453 :
454 : /********************************************************************
455 : * xaccQueryAddDateMatch
456 : * Add a date filter to an existing query.
457 : ********************************************************************/
458 :
459 : void
460 0 : xaccQueryAddDateMatch(QofQuery * q,
461 : gboolean use_start, int sday, int smonth, int syear,
462 : gboolean use_end, int eday, int emonth, int eyear,
463 : QofQueryOp op)
464 : {
465 : /* gcc -O3 will auto-inline this function, avoiding a call overhead */
466 0 : xaccQueryAddDateMatchTT (q, use_start,
467 : gnc_dmy2time64(sday, smonth, syear),
468 : use_end,
469 : gnc_dmy2time64_end(eday, emonth, eyear),
470 : op);
471 0 : }
472 :
473 : void
474 530 : xaccQueryAddClearedMatch(QofQuery * q, cleared_match_t how, QofQueryOp op)
475 : {
476 : QofQueryPredData *pred_data;
477 : GSList *param_list;
478 : char chars[6];
479 530 : int i = 0;
480 :
481 530 : if (!q)
482 0 : return;
483 :
484 530 : if (how & CLEARED_CLEARED)
485 311 : chars[i++] = CREC;
486 530 : if (how & CLEARED_RECONCILED)
487 284 : chars[i++] = YREC;
488 530 : if (how & CLEARED_FROZEN)
489 297 : chars[i++] = FREC;
490 530 : if (how & CLEARED_NO)
491 279 : chars[i++] = NREC;
492 530 : if (how & CLEARED_VOIDED)
493 132 : chars[i++] = VREC;
494 530 : chars[i] = '\0';
495 :
496 530 : pred_data = qof_query_char_predicate (QOF_CHAR_MATCH_ANY, chars);
497 530 : if (!pred_data)
498 0 : return;
499 :
500 530 : param_list = qof_query_build_param_list (SPLIT_RECONCILE, nullptr);
501 :
502 530 : qof_query_add_term (q, param_list, pred_data, op);
503 : }
504 :
505 : cleared_match_t
506 0 : xaccQueryGetClearedMatch(QofQuery * q)
507 : {
508 : QofQueryPredData *term_data;
509 0 : cleared_match_t cleared_match = CLEARED_ALL;
510 : GSList *param_list;
511 : GSList *terms, *tmp;
512 0 : char *chars = nullptr;
513 :
514 0 : param_list = qof_query_build_param_list (SPLIT_RECONCILE, nullptr);
515 0 : terms = qof_query_get_term_type (q, param_list);
516 0 : g_slist_free (param_list);
517 :
518 0 : for (tmp = terms; tmp; tmp = g_slist_next (tmp))
519 : {
520 0 : term_data = static_cast<QofQueryPredData*>(tmp->data);
521 :
522 0 : if (qof_query_char_predicate_get_char (term_data, &chars))
523 : {
524 0 : cleared_match = CLEARED_NONE;
525 :
526 0 : if (strstr (chars, "c"))
527 0 : cleared_match = (cleared_match_t)(cleared_match | CLEARED_CLEARED);
528 0 : if (strstr (chars, "y"))
529 0 : cleared_match = (cleared_match_t)(cleared_match | CLEARED_RECONCILED);
530 0 : if (strstr (chars, "f"))
531 0 : cleared_match = (cleared_match_t)(cleared_match | CLEARED_FROZEN);
532 0 : if (strstr (chars, "n"))
533 0 : cleared_match = (cleared_match_t)(cleared_match | CLEARED_NO);
534 0 : if (strstr (chars, "v"))
535 0 : cleared_match = (cleared_match_t)(cleared_match | CLEARED_VOIDED);
536 : }
537 : }
538 0 : g_slist_free (terms);
539 :
540 0 : return cleared_match;
541 : }
542 :
543 : void
544 762 : xaccQueryAddGUIDMatch(QofQuery * q, const GncGUID *guid,
545 : QofIdType id_type, QofQueryOp op)
546 : {
547 762 : GSList *param_list = nullptr;
548 :
549 762 : if (!q || !guid || !id_type)
550 0 : return;
551 :
552 762 : if (!g_strcmp0 (id_type, GNC_ID_SPLIT))
553 256 : param_list = qof_query_build_param_list (QOF_PARAM_GUID, nullptr);
554 506 : else if (!g_strcmp0 (id_type, GNC_ID_TRANS))
555 251 : param_list = qof_query_build_param_list (SPLIT_TRANS, QOF_PARAM_GUID, nullptr);
556 255 : else if (!g_strcmp0 (id_type, GNC_ID_ACCOUNT))
557 255 : param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID, nullptr);
558 : else
559 0 : PERR ("Invalid match type: %s", id_type);
560 :
561 762 : qof_query_add_guid_match (q, param_list, guid, op);
562 : }
563 :
564 :
565 : /********************************************************************
566 : * xaccQueryAddClosingTransMatch
567 : * Add a filter that matches book closing entries to an existing query.
568 : ********************************************************************/
569 :
570 : void
571 97 : xaccQueryAddClosingTransMatch(QofQuery *q, gboolean value, QofQueryOp op)
572 : {
573 : GSList *param_list;
574 :
575 97 : param_list = qof_query_build_param_list(SPLIT_TRANS, TRANS_IS_CLOSING, nullptr);
576 97 : qof_query_add_boolean_match(q, param_list, value, op);
577 97 : }
578 :
579 : /*******************************************************************
580 : * xaccQueryGetEarliestDateFound
581 : *******************************************************************/
582 :
583 : time64
584 0 : xaccQueryGetEarliestDateFound(QofQuery * q)
585 : {
586 : GList * spl;
587 : Split * sp;
588 : time64 earliest;
589 :
590 0 : if (!q) return 0;
591 0 : spl = qof_query_last_run (q);
592 0 : if (!spl) return 0;
593 :
594 : /* Safe until 2038 on archs where time64 is 32bit */
595 0 : sp = GNC_SPLIT (spl->data);
596 0 : earliest = sp->parent->date_posted;
597 0 : for (; spl; spl = spl->next)
598 : {
599 0 : sp = GNC_SPLIT (spl->data);
600 0 : if (sp->parent->date_posted < earliest)
601 : {
602 0 : earliest = sp->parent->date_posted;
603 : }
604 : }
605 0 : return earliest;
606 : }
607 :
608 : /*******************************************************************
609 : * xaccQueryGetLatestDateFound
610 : *******************************************************************/
611 :
612 : time64
613 0 : xaccQueryGetLatestDateFound(QofQuery * q)
614 : {
615 : Split * sp;
616 : GList * spl;
617 0 : time64 latest = 0;
618 :
619 0 : if (!q) return 0;
620 0 : spl = qof_query_last_run (q);
621 0 : if (!spl) return 0;
622 :
623 0 : for (; spl; spl = spl->next)
624 : {
625 0 : sp = GNC_SPLIT (spl->data);
626 0 : if (sp->parent->date_posted > latest)
627 : {
628 0 : latest = sp->parent->date_posted;
629 : }
630 : }
631 0 : return latest;
632 : }
633 :
634 : void
635 371 : xaccQueryAddDescriptionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
636 : QofQueryCompare h, QofQueryOp o)
637 : {
638 371 : xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
639 : TRANS_DESCRIPTION, nullptr);
640 371 : }
641 :
642 : void
643 0 : xaccQueryAddNotesMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
644 : QofQueryCompare h, QofQueryOp o)
645 : {
646 0 : xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
647 : TRANS_NOTES, nullptr);
648 0 : }
649 :
650 : void
651 344 : xaccQueryAddNumberMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
652 : QofQueryCompare h, QofQueryOp o)
653 : {
654 344 : xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
655 : TRANS_NUM, nullptr);
656 344 : }
657 :
658 : void
659 382 : xaccQueryAddActionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
660 : QofQueryCompare h, QofQueryOp o)
661 : {
662 382 : xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_ACTION, nullptr);
663 382 : }
664 :
665 : void
666 374 : xaccQueryAddMemoMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
667 : QofQueryCompare h, QofQueryOp o)
668 : {
669 374 : xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_MEMO, nullptr);
670 374 : }
671 :
672 : void
673 356 : xaccQueryAddValueMatch(QofQuery *q, gnc_numeric amt, QofNumericMatch sgn,
674 : QofQueryCompare how, QofQueryOp op)
675 : {
676 356 : xaccQueryAddNumericMatch ((q), (amt), (sgn), (how), (op),
677 : SPLIT_VALUE, nullptr);
678 356 : }
679 :
680 : void
681 358 : xaccQueryAddSharePriceMatch(QofQuery *q, gnc_numeric amt, QofQueryCompare how,
682 : QofQueryOp op)
683 : {
684 358 : xaccQueryAddNumericMatch ((q), (amt), QOF_NUMERIC_MATCH_ANY, (how), (op),
685 : SPLIT_SHARE_PRICE, nullptr);
686 358 : }
687 :
688 : void
689 366 : xaccQueryAddSharesMatch(QofQuery *q, gnc_numeric amt, QofQueryCompare how,
690 : QofQueryOp op)
691 : {
692 366 : xaccQueryAddNumericMatch ((q), (amt), QOF_NUMERIC_MATCH_ANY, (how), (op),
693 : SPLIT_AMOUNT, nullptr);
694 366 : }
695 :
696 : void
697 189 : xaccQueryAddBalanceMatch(QofQuery *q, QofQueryCompare bal, QofQueryOp op)
698 : {
699 189 : xaccQueryAddNumericMatch(
700 : (q), gnc_numeric_zero(), QOF_NUMERIC_MATCH_ANY,
701 : ((bal) ? QOF_COMPARE_EQUAL : QOF_COMPARE_NEQ), (op),
702 : SPLIT_TRANS, TRANS_IMBALANCE, nullptr);
703 189 : }
704 :
705 :
706 : /* ======================== END OF FILE ======================= */
|