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