35 #include <sys/types.h> 46 #include "TransactionP.hpp" 48 static QofLogModule log_module = GNC_MOD_QUERY;
51 build_param_list_internal (
const char *first, va_list rest)
53 GSList *list =
nullptr;
56 for (param = first; param; param = va_arg (rest,
const char *))
57 list = g_slist_prepend (list, (gpointer)param);
59 return (g_slist_reverse (list));
68 xaccQueryGetSplitsUniqueTrans(
QofQuery *q)
72 GList * result =
nullptr;
73 GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
75 for (current = splits; current; current = current->next)
77 Split *split = GNC_SPLIT (current->data);
80 if (!g_hash_table_lookup (trans_hash, trans))
82 g_hash_table_insert (trans_hash, trans, trans);
83 result = g_list_prepend (result, split);
87 g_hash_table_destroy (trans_hash);
89 return g_list_reverse (result);
99 query_match_all_filter_func(gpointer key, gpointer value, gpointer user_data)
101 Transaction * t = GNC_TRANSACTION(key);
102 int num_matches = GPOINTER_TO_INT(value);
103 auto matches =
static_cast<GList**
>(user_data);
107 *matches = g_list_prepend(*matches, t);
112 query_match_any_filter_func(gpointer key, gpointer value, gpointer user_data)
114 Transaction * t = GNC_TRANSACTION(key);
115 auto matches =
static_cast<GList**
>(user_data);
116 *matches = g_list_prepend(*matches, t);
120 xaccQueryGetTransactions (
QofQuery * q, query_txn_match_t runtype)
123 GList * current =
nullptr;
124 GList * retval =
nullptr;
125 GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
126 Transaction * trans =
nullptr;
127 gpointer val =
nullptr;
132 for (current = splits; current; current = current->next)
138 if (runtype == QUERY_TXN_MATCH_ALL)
140 val = g_hash_table_lookup(trans_hash, trans);
141 count = GPOINTER_TO_INT(val);
143 g_hash_table_insert(trans_hash, trans, GINT_TO_POINTER(count + 1));
147 if (runtype == QUERY_TXN_MATCH_ALL)
149 g_hash_table_foreach(trans_hash, query_match_all_filter_func,
154 g_hash_table_foreach(trans_hash, query_match_any_filter_func,
158 g_hash_table_destroy(trans_hash);
170 query_match_all_lot_filter_func(gpointer key, gpointer value, gpointer user_data)
172 GNCLot * l = GNC_LOT(key);
173 int num_matches = GPOINTER_TO_INT(value);
174 auto matches =
static_cast<GList**
>(user_data);
176 if (num_matches == gnc_lot_count_splits(l))
178 *matches = g_list_prepend(*matches, l);
183 query_match_any_lot_filter_func(gpointer key, gpointer value, gpointer user_data)
185 GNCLot * t = GNC_LOT(key);
186 auto matches =
static_cast<GList**
>(user_data);
187 *matches = g_list_prepend(*matches, t);
191 xaccQueryGetLots (
QofQuery * q, query_txn_match_t runtype)
194 GList * current =
nullptr;
195 GList * retval =
nullptr;
196 GHashTable * lot_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
197 GNCLot * lot =
nullptr;
198 gpointer val =
nullptr;
203 for (current = splits; current; current = current->next)
209 if (runtype == QUERY_TXN_MATCH_ALL)
211 val = g_hash_table_lookup(lot_hash, lot);
212 count = GPOINTER_TO_INT(val);
214 g_hash_table_insert(lot_hash, lot, GINT_TO_POINTER(count + 1));
218 if (runtype == QUERY_TXN_MATCH_ALL)
220 g_hash_table_foreach(lot_hash, query_match_all_lot_filter_func,
225 g_hash_table_foreach(lot_hash, query_match_any_lot_filter_func,
229 g_hash_table_destroy(lot_hash);
242 GList *list =
nullptr;
245 for (; acct_list; acct_list = acct_list->next)
247 Account *acc = GNC_ACCOUNT (acct_list->data);
252 PWARN (
"acct_list has nullptr account");
259 PWARN (
"acct returns nullptr GncGUID");
263 list = g_list_prepend (list, (gpointer)guid);
265 xaccQueryAddAccountGUIDMatch (q, list, how, op);
273 QofQueryPredData *pred_data;
274 GSList *param_list =
nullptr;
278 if (!guid_list && how != QOF_GUID_MATCH_NULL)
280 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);
284 pred_data = qof_query_guid_predicate (how, guid_list);
291 case QOF_GUID_MATCH_NONE:
292 param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID,
nullptr);
295 param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_SPLITLIST,
299 PERR (
"Invalid match type: %d", how);
316 g_return_if_fail (guid);
318 list = g_list_prepend (
nullptr, (gpointer)guid);
324 xaccQueryAddStringMatch (
QofQuery* q,
const char *matchstring,
325 gboolean case_sens, gboolean use_regexp,
327 const char * path, ...)
329 QofQueryPredData *pred_data;
336 pred_data = qof_query_string_predicate (how, (
char *)matchstring,
337 (case_sens ? QOF_STRING_MATCH_NORMAL :
338 QOF_STRING_MATCH_CASEINSENSITIVE),
344 param_list = build_param_list_internal (path, ap);
353 const char * path, ...)
355 QofQueryPredData *pred_data;
362 pred_data = qof_query_numeric_predicate (how, sign, amount);
367 param_list = build_param_list_internal (path, ap);
383 xaccQueryAddDateMatchTT (
QofQuery * q,
384 gboolean use_start,
time64 stt,
385 gboolean use_end,
time64 ett,
389 QofQueryPredData *pred_data;
392 if (!q || (!use_start && !use_end))
399 pred_data = qof_query_date_predicate (QOF_COMPARE_GTE, QOF_DATE_MATCH_NORMAL, stt);
406 param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED,
nullptr);
412 pred_data = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, ett);
419 param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED,
nullptr);
428 xaccQueryGetDateMatchTT (
QofQuery * q,
432 QofQueryPredData *term_data;
439 param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED,
nullptr);
440 terms = qof_query_get_term_type (q, param_list);
441 g_slist_free(param_list);
443 for (tmp = terms; tmp; tmp = g_slist_next(tmp))
445 term_data =
static_cast<QofQueryPredData*
>(tmp->data);
446 if (term_data->how == QOF_COMPARE_GTE)
448 if (term_data->how == QOF_COMPARE_LTE)
461 gboolean use_start,
int sday,
int smonth,
int syear,
462 gboolean use_end,
int eday,
int emonth,
int eyear,
466 xaccQueryAddDateMatchTT (q, use_start,
476 QofQueryPredData *pred_data;
484 if (how & CLEARED_CLEARED)
486 if (how & CLEARED_RECONCILED)
488 if (how & CLEARED_FROZEN)
490 if (how & CLEARED_NO)
492 if (how & CLEARED_VOIDED)
496 pred_data = qof_query_char_predicate (QOF_CHAR_MATCH_ANY, chars);
500 param_list = qof_query_build_param_list (SPLIT_RECONCILE,
nullptr);
506 xaccQueryGetClearedMatch(
QofQuery * q)
508 QofQueryPredData *term_data;
509 cleared_match_t cleared_match = CLEARED_ALL;
512 char *chars =
nullptr;
514 param_list = qof_query_build_param_list (SPLIT_RECONCILE,
nullptr);
515 terms = qof_query_get_term_type (q, param_list);
516 g_slist_free (param_list);
518 for (tmp = terms; tmp; tmp = g_slist_next (tmp))
520 term_data =
static_cast<QofQueryPredData*
>(tmp->data);
522 if (qof_query_char_predicate_get_char (term_data, &chars))
524 cleared_match = CLEARED_NONE;
526 if (strstr (chars,
"c"))
527 cleared_match = (cleared_match_t)(cleared_match | CLEARED_CLEARED);
528 if (strstr (chars,
"y"))
529 cleared_match = (cleared_match_t)(cleared_match | CLEARED_RECONCILED);
530 if (strstr (chars,
"f"))
531 cleared_match = (cleared_match_t)(cleared_match | CLEARED_FROZEN);
532 if (strstr (chars,
"n"))
533 cleared_match = (cleared_match_t)(cleared_match | CLEARED_NO);
534 if (strstr (chars,
"v"))
535 cleared_match = (cleared_match_t)(cleared_match | CLEARED_VOIDED);
538 g_slist_free (terms);
540 return cleared_match;
547 GSList *param_list =
nullptr;
549 if (!q || !guid || !id_type)
552 if (!g_strcmp0 (id_type, GNC_ID_SPLIT))
553 param_list = qof_query_build_param_list (QOF_PARAM_GUID,
nullptr);
554 else if (!g_strcmp0 (id_type, GNC_ID_TRANS))
555 param_list = qof_query_build_param_list (SPLIT_TRANS, QOF_PARAM_GUID,
nullptr);
556 else if (!g_strcmp0 (id_type, GNC_ID_ACCOUNT))
557 param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID,
nullptr);
559 PERR (
"Invalid match type: %s", id_type);
575 param_list = qof_query_build_param_list(SPLIT_TRANS, TRANS_IS_CLOSING,
nullptr);
584 xaccQueryGetEarliestDateFound(
QofQuery * q)
595 sp = GNC_SPLIT (spl->data);
596 earliest = sp->parent->date_posted;
597 for (; spl; spl = spl->next)
599 sp = GNC_SPLIT (spl->data);
600 if (sp->parent->date_posted < earliest)
602 earliest = sp->parent->date_posted;
613 xaccQueryGetLatestDateFound(
QofQuery * q)
623 for (; spl; spl = spl->next)
625 sp = GNC_SPLIT (spl->data);
626 if (sp->parent->date_posted > latest)
628 latest = sp->parent->date_posted;
635 xaccQueryAddDescriptionMatch(
QofQuery *q,
const char *m, gboolean c, gboolean r,
638 xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
639 TRANS_DESCRIPTION,
nullptr);
643 xaccQueryAddNotesMatch(
QofQuery *q,
const char *m, gboolean c, gboolean r,
646 xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
647 TRANS_NOTES,
nullptr);
651 xaccQueryAddNumberMatch(
QofQuery *q,
const char *m, gboolean c, gboolean r,
654 xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
659 xaccQueryAddActionMatch(
QofQuery *q,
const char *m, gboolean c, gboolean r,
662 xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_ACTION,
nullptr);
666 xaccQueryAddMemoMatch(
QofQuery *q,
const char *m, gboolean c, gboolean r,
669 xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_MEMO,
nullptr);
676 xaccQueryAddNumericMatch ((q), (amt), (sgn), (how), (op),
677 SPLIT_VALUE,
nullptr);
684 xaccQueryAddNumericMatch ((q), (amt), QOF_NUMERIC_MATCH_ANY, (how), (op),
685 SPLIT_SHARE_PRICE,
nullptr);
692 xaccQueryAddNumericMatch ((q), (amt), QOF_NUMERIC_MATCH_ANY, (how), (op),
693 SPLIT_AMOUNT,
nullptr);
699 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);
GList TransList
GList of Transaction.
void qof_query_add_term(QofQuery *q, QofQueryParamList *param_list, QofQueryPredData *pred_data, QofQueryOp op)
This is the general function that adds a new Query Term to a query.
GList LotList
GList of GNCLots.
time64 gnc_dmy2time64(gint day, gint month, gint year)
Convert a day, month, and year to a time64, returning the first second of the day.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
These expect a single object and expect the QofAccessFunc returns GncGUID*.
#define PERR(format, args...)
Log a serious error.
#define VREC
split is void
gboolean qof_query_date_predicate_get_date(const QofQueryPredData *pd, time64 *date)
Retrieve a predicate.
#define PWARN(format, args...)
Log a warning.
const gchar * QofIdType
QofIdType declaration.
int xaccTransCountSplits(const Transaction *trans)
Returns the number of splits in this transaction.
GList SplitList
GList of Split.
Account handling public routines.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
#define YREC
The Split has been reconciled.
#define FREC
frozen into accounting period
#define SPLIT_ACCOUNT_GUID
for guid_match_all
QofQueryCompare
Standard Query comparators, for how to compare objects in a predicate.
const GncGUID * qof_entity_get_guid(gconstpointer ent)
These expect a GList* of objects and calls the QofAccessFunc routine on each item in the list to obta...
#define CREC
The Split has been cleared.
void qof_query_add_guid_match(QofQuery *q, QofQueryParamList *param_list, const GncGUID *guid, QofQueryOp op)
DOCUMENT ME !!
GList * qof_query_last_run(QofQuery *query)
Return the results of the last query, without causing the query to be re-run.
QofQueryOp
Query Term Operators, for combining Query Terms.
GList * qof_query_run(QofQuery *query)
Perform the query, return the results.
GList AccountList
GList of Account.
time64 gnc_dmy2time64_end(gint day, gint month, gint year)
Same as gnc_dmy2time64, but last second of the day.
GList AccountGUIDList
GList of GUIDs of a Account.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
void qof_query_add_boolean_match(QofQuery *q, QofQueryParamList *param_list, gboolean value, QofQueryOp op)
Handy-dandy convenience routines, avoids having to create a separate predicate for boolean matches...
API for Transactions and Splits (journal entries)
The type used to store guids in C.
QofNumericMatch
Comparisons for QOF_TYPE_NUMERIC, QOF_TYPE_DEBCRED.
QofQuery * qof_query_create(void)
Create a new query.
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn't be...
#define NREC
not reconciled or cleared
void qof_query_merge_in_place(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Like qof_query_merge, but this will merge a copy of q2 into q1.