LCOV - code coverage report
Current view: top level - libgnucash/engine - Query.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 60.5 % 286 173
Test Date: 2025-02-07 16:25:45 Functions: 71.0 % 31 22
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     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                 :        2413 : build_param_list_internal (const char *first, va_list rest)
      52                 :             : {
      53                 :        2413 :     GSList *list = nullptr;
      54                 :             :     char const *param;
      55                 :             : 
      56                 :        5627 :     for (param = first; param; param = va_arg (rest, const char *))
      57                 :        3214 :         list = g_slist_prepend (list, (gpointer)param);
      58                 :             : 
      59                 :        2413 :     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                 :          32 : xaccQueryGetSplitsUniqueTrans(QofQuery *q)
      69                 :             : {
      70                 :          32 :     GList       * splits = qof_query_run(q);
      71                 :             :     GList       * current;
      72                 :          32 :     GList       * result = nullptr;
      73                 :          32 :     GHashTable  * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
      74                 :             : 
      75                 :         658 :     for (current = splits; current; current = current->next)
      76                 :             :     {
      77                 :         626 :         Split *split = GNC_SPLIT (current->data);
      78                 :         626 :         Transaction *trans = xaccSplitGetParent (split);
      79                 :             : 
      80                 :         626 :         if (!g_hash_table_lookup (trans_hash, trans))
      81                 :             :         {
      82                 :         459 :             g_hash_table_insert (trans_hash, trans, trans);
      83                 :         459 :             result = g_list_prepend (result, split);
      84                 :             :         }
      85                 :             :     }
      86                 :             : 
      87                 :          32 :     g_hash_table_destroy (trans_hash);
      88                 :             : 
      89                 :          32 :     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                 :        2082 : xaccQueryAddAccountMatch(QofQuery *q, AccountList *acct_list,
     240                 :             :                          QofGuidMatch how, QofQueryOp op)
     241                 :             : {
     242                 :        2082 :     GList *list = nullptr;
     243                 :             : 
     244                 :        2082 :     if (!q) return;
     245                 :       15169 :     for (; acct_list; acct_list = acct_list->next)
     246                 :             :     {
     247                 :       13087 :         Account *acc = GNC_ACCOUNT (acct_list->data);
     248                 :             :         const GncGUID *guid;
     249                 :             : 
     250                 :       13087 :         if (!acc)
     251                 :             :         {
     252                 :           0 :             PWARN ("acct_list has nullptr account");
     253                 :           0 :             continue;
     254                 :             :         }
     255                 :             : 
     256                 :       13087 :         guid = qof_entity_get_guid (QOF_INSTANCE(acc));
     257                 :       13087 :         if (!guid)
     258                 :             :         {
     259                 :           0 :             PWARN ("acct returns nullptr GncGUID");
     260                 :           0 :             continue;
     261                 :             :         }
     262                 :             : 
     263                 :       13087 :         list = g_list_prepend (list, (gpointer)guid);
     264                 :             :     }
     265                 :        2082 :     xaccQueryAddAccountGUIDMatch (q, list, how, op);
     266                 :        2082 :     g_list_free (list);
     267                 :             : }
     268                 :             : 
     269                 :             : void
     270                 :        2888 : xaccQueryAddAccountGUIDMatch(QofQuery *q, AccountGUIDList *guid_list,
     271                 :             :                              QofGuidMatch how, QofQueryOp op)
     272                 :             : {
     273                 :             :     QofQueryPredData *pred_data;
     274                 :        2888 :     GSList *param_list = nullptr;
     275                 :             : 
     276                 :        2888 :     if (!q) return;
     277                 :             : 
     278                 :        2888 :     if (!guid_list && how != QOF_GUID_MATCH_NULL)
     279                 :             :     {
     280                 :           3 :         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                 :           3 :         return;
     283                 :             :     }
     284                 :        2885 :     pred_data = qof_query_guid_predicate (how, guid_list);
     285                 :        2885 :     if (!pred_data)
     286                 :           0 :         return;
     287                 :             : 
     288                 :        2885 :     switch (how)
     289                 :             :     {
     290                 :        2685 :     case QOF_GUID_MATCH_ANY:
     291                 :             :     case QOF_GUID_MATCH_NONE:
     292                 :        2685 :         param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID, nullptr);
     293                 :        2685 :         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                 :        2885 :     qof_query_add_term (q, param_list, pred_data, op);
     304                 :             : }
     305                 :             : 
     306                 :             : void
     307                 :         207 : xaccQueryAddSingleAccountMatch(QofQuery *q, Account *acc, QofQueryOp op)
     308                 :             : {
     309                 :             :     GList *list;
     310                 :             :     const GncGUID *guid;
     311                 :             : 
     312                 :         207 :     if (!q || !acc)
     313                 :           2 :         return;
     314                 :             : 
     315                 :         205 :     guid = qof_entity_get_guid (QOF_INSTANCE(acc));
     316                 :         205 :     g_return_if_fail (guid);
     317                 :             : 
     318                 :         205 :     list = g_list_prepend (nullptr, (gpointer)guid);
     319                 :         205 :     xaccQueryAddAccountGUIDMatch (q, list, QOF_GUID_MATCH_ANY, op);
     320                 :         205 :     g_list_free (list);
     321                 :             : }
     322                 :             : 
     323                 :             : void
     324                 :        1563 : 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                 :        1563 :     if (!path || !q)
     334                 :           0 :         return;
     335                 :             : 
     336                 :        1563 :     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                 :        1563 :     if (!pred_data)
     341                 :         419 :         return;
     342                 :             : 
     343                 :        1144 :     va_start (ap, path);
     344                 :        1144 :     param_list = build_param_list_internal (path, ap);
     345                 :        1144 :     va_end (ap);
     346                 :             : 
     347                 :        1144 :     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                 :        2267 : xaccQueryAddDateMatchTT (QofQuery * q,
     384                 :             :                          gboolean use_start, time64 stt,
     385                 :             :                          gboolean use_end, time64 ett,
     386                 :             :                          QofQueryOp op)
     387                 :             : {
     388                 :        2267 :     QofQuery *tmp_q = nullptr;
     389                 :             :     QofQueryPredData *pred_data;
     390                 :             :     GSList *param_list;
     391                 :             : 
     392                 :        2267 :     if (!q || (!use_start && !use_end))
     393                 :          56 :         return;
     394                 :             : 
     395                 :        2211 :     tmp_q = qof_query_create ();
     396                 :             : 
     397                 :        2211 :     if (use_start)
     398                 :             :     {
     399                 :        1642 :         pred_data = qof_query_date_predicate (QOF_COMPARE_GTE, QOF_DATE_MATCH_NORMAL, stt);
     400                 :        1642 :         if (!pred_data)
     401                 :             :         {
     402                 :           0 :             qof_query_destroy (tmp_q);
     403                 :           0 :             return;
     404                 :             :         }
     405                 :             : 
     406                 :        1642 :         param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, nullptr);
     407                 :        1642 :         qof_query_add_term (tmp_q, param_list, pred_data, QOF_QUERY_AND);
     408                 :             :     }
     409                 :             : 
     410                 :        2211 :     if (use_end)
     411                 :             :     {
     412                 :        2172 :         pred_data = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, ett);
     413                 :        2172 :         if (!pred_data)
     414                 :             :         {
     415                 :           0 :             qof_query_destroy (tmp_q);
     416                 :           0 :             return;
     417                 :             :         }
     418                 :             : 
     419                 :        2172 :         param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, nullptr);
     420                 :        2172 :         qof_query_add_term (tmp_q, param_list, pred_data, QOF_QUERY_AND);
     421                 :             :     }
     422                 :             : 
     423                 :        2211 :     qof_query_merge_in_place (q, tmp_q, op);
     424                 :        2211 :     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                 :        1828 : xaccQueryAddClearedMatch(QofQuery * q, cleared_match_t how, QofQueryOp op)
     475                 :             : {
     476                 :             :     QofQueryPredData *pred_data;
     477                 :             :     GSList *param_list;
     478                 :             :     char chars[6];
     479                 :        1828 :     int i = 0;
     480                 :             : 
     481                 :        1828 :     if (!q)
     482                 :           0 :         return;
     483                 :             : 
     484                 :        1828 :     if (how & CLEARED_CLEARED)
     485                 :        1600 :         chars[i++] = CREC;
     486                 :        1828 :     if (how & CLEARED_RECONCILED)
     487                 :        1572 :         chars[i++] = YREC;
     488                 :        1828 :     if (how & CLEARED_FROZEN)
     489                 :        1583 :         chars[i++] = FREC;
     490                 :        1828 :     if (how & CLEARED_NO)
     491                 :        1567 :         chars[i++] = NREC;
     492                 :        1828 :     if (how & CLEARED_VOIDED)
     493                 :         134 :         chars[i++] = VREC;
     494                 :        1828 :     chars[i] = '\0';
     495                 :             : 
     496                 :        1828 :     pred_data = qof_query_char_predicate (QOF_CHAR_MATCH_ANY, chars);
     497                 :        1828 :     if (!pred_data)
     498                 :           0 :         return;
     499                 :             : 
     500                 :        1828 :     param_list = qof_query_build_param_list (SPLIT_RECONCILE, nullptr);
     501                 :             : 
     502                 :        1828 :     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                 :         208 : xaccQueryAddClosingTransMatch(QofQuery *q, gboolean value, QofQueryOp op)
     572                 :             : {
     573                 :             :     GSList *param_list;
     574                 :             : 
     575                 :         208 :     param_list = qof_query_build_param_list(SPLIT_TRANS, TRANS_IS_CLOSING, nullptr);
     576                 :         208 :     qof_query_add_boolean_match(q, param_list, value, op);
     577                 :         208 : }
     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                 :         463 : xaccQueryAddDescriptionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
     636                 :             :                              QofQueryCompare h, QofQueryOp o)
     637                 :             : {
     638                 :         463 :     xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
     639                 :             :                              TRANS_DESCRIPTION, nullptr);
     640                 :         463 : }
     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