LCOV - code coverage report
Current view: top level - libgnucash/engine - Query.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 59.4 % 286 170
Test Date: 2026-11-02 18:19:43 Functions: 71.0 % 31 22
Legend: Lines:     hit not hit

            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 ======================= */
        

Generated by: LCOV version 2.0-1