2001-08-07 18:36:04 -05:00
/********************************************************************\
* Query . c : api for finding transactions *
* Copyright ( C ) 2000 Bill Gribble < grib @ billgribble . com > *
2002-01-02 15:29:00 -06:00
* Copyright ( C ) 2002 Linas Vepstas < linas @ linas . org > *
2001-08-07 18:36:04 -05:00
* *
* This program is free software ; you can redistribute it and / or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation ; either version 2 of *
* the License , or ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , contact : *
* *
* Free Software Foundation Voice : + 1 - 617 - 542 - 5942 *
2005-11-16 23:35:02 -06:00
* 51 Franklin Street , Fifth Floor Fax : + 1 - 617 - 542 - 2652 *
* Boston , MA 02110 - 1301 , USA gnu @ gnu . org *
2001-08-07 18:36:04 -05:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-10-26 04:14:21 -05:00
# include <config.h>
2001-09-07 16:51:13 -05:00
2015-05-22 21:50:25 -05:00
# include <platform.h>
# if PLATFORM(WINDOWS)
# include <windows.h>
# endif
2001-08-07 18:36:04 -05:00
# include <ctype.h>
# include <glib.h>
# include <math.h>
# include <string.h>
# include <sys/types.h>
# include <regex.h>
2010-02-25 11:42:43 -06:00
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
2001-08-07 18:36:04 -05:00
2003-09-12 08:17:26 -05:00
# include "gnc-lot.h"
2002-06-05 16:59:35 -05:00
# include "Account.h"
2001-08-07 18:36:04 -05:00
# include "Query.h"
2002-06-05 16:59:35 -05:00
# include "Transaction.h"
2024-04-25 08:15:31 -05:00
# include "TransactionP.hpp"
2001-08-07 18:36:04 -05:00
2005-11-01 21:32:36 -06:00
static QofLogModule log_module = GNC_MOD_QUERY ;
2001-08-07 18:36:04 -05:00
2002-06-05 16:59:35 -05:00
static GSList *
build_param_list_internal ( const char * first , va_list rest )
{
2024-03-17 03:41:27 -05:00
GSList * list = nullptr ;
2010-03-02 15:40:28 -06:00
char const * param ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
for ( param = first ; param ; param = va_arg ( rest , const char * ) )
list = g_slist_prepend ( list , ( gpointer ) param ) ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
return ( g_slist_reverse ( list ) ) ;
2002-06-05 16:59:35 -05:00
}
/********************************************************************
2010-03-02 15:40:28 -06:00
* xaccQueryGetSplitsUniqueTrans
2002-06-05 16:59:35 -05:00
* Get splits but no more than one from a given transaction .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
SplitList *
2010-12-14 14:22:48 -06:00
xaccQueryGetSplitsUniqueTrans ( QofQuery * q )
2002-06-05 16:59:35 -05:00
{
2010-10-13 11:16:04 -05:00
GList * splits = qof_query_run ( q ) ;
2010-03-02 15:40:28 -06:00
GList * current ;
2024-03-17 03:41:27 -05:00
GList * result = nullptr ;
2010-03-02 15:40:28 -06:00
GHashTable * trans_hash = g_hash_table_new ( g_direct_hash , g_direct_equal ) ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
for ( current = splits ; current ; current = current - > next )
2002-06-05 16:59:35 -05:00
{
2024-03-17 03:41:27 -05:00
Split * split = GNC_SPLIT ( current - > data ) ;
2010-03-02 15:40:28 -06:00
Transaction * trans = xaccSplitGetParent ( split ) ;
if ( ! g_hash_table_lookup ( trans_hash , trans ) )
{
g_hash_table_insert ( trans_hash , trans , trans ) ;
result = g_list_prepend ( result , split ) ;
}
2002-06-05 16:59:35 -05:00
}
2010-03-02 15:40:28 -06:00
g_hash_table_destroy ( trans_hash ) ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
return g_list_reverse ( result ) ;
2002-06-05 16:59:35 -05:00
}
/********************************************************************
2010-03-02 15:40:28 -06:00
* xaccQueryGetTransactions
* Get transactions matching the query terms , specifying whether
* we require some or all splits to match
2002-06-05 16:59:35 -05:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
2010-03-02 15:40:28 -06:00
query_match_all_filter_func ( gpointer key , gpointer value , gpointer user_data )
2002-06-05 16:59:35 -05:00
{
2024-03-17 03:41:27 -05:00
Transaction * t = GNC_TRANSACTION ( key ) ;
2010-03-02 15:40:28 -06:00
int num_matches = GPOINTER_TO_INT ( value ) ;
2024-03-17 03:41:27 -05:00
auto matches = static_cast < GList * * > ( user_data ) ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( num_matches = = xaccTransCountSplits ( t ) )
{
* matches = g_list_prepend ( * matches , t ) ;
}
2002-06-05 16:59:35 -05:00
}
static void
2010-03-02 15:40:28 -06:00
query_match_any_filter_func ( gpointer key , gpointer value , gpointer user_data )
2002-06-05 16:59:35 -05:00
{
2024-03-17 03:41:27 -05:00
Transaction * t = GNC_TRANSACTION ( key ) ;
auto matches = static_cast < GList * * > ( user_data ) ;
2010-03-02 15:40:28 -06:00
* matches = g_list_prepend ( * matches , t ) ;
2002-06-05 16:59:35 -05:00
}
2010-03-02 15:40:28 -06:00
TransList *
2010-12-14 14:22:48 -06:00
xaccQueryGetTransactions ( QofQuery * q , query_txn_match_t runtype )
2002-06-05 16:59:35 -05:00
{
2010-10-13 11:16:04 -05:00
GList * splits = qof_query_run ( q ) ;
2024-03-17 03:41:27 -05:00
GList * current = nullptr ;
GList * retval = nullptr ;
2010-03-02 15:40:28 -06:00
GHashTable * trans_hash = g_hash_table_new ( g_direct_hash , g_direct_equal ) ;
2024-03-17 03:41:27 -05:00
Transaction * trans = nullptr ;
gpointer val = nullptr ;
2010-03-02 15:40:28 -06:00
int count = 0 ;
/* iterate over matching splits, incrementing a match-count in
* the hash table */
for ( current = splits ; current ; current = current - > next )
{
2024-03-17 03:41:27 -05:00
trans = xaccSplitGetParent ( GNC_SPLIT ( current - > data ) ) ;
2010-03-02 15:40:28 -06:00
/* don't waste time looking up unless we need the count
* information */
if ( runtype = = QUERY_TXN_MATCH_ALL )
{
val = g_hash_table_lookup ( trans_hash , trans ) ;
count = GPOINTER_TO_INT ( val ) ;
}
g_hash_table_insert ( trans_hash , trans , GINT_TO_POINTER ( count + 1 ) ) ;
2002-06-05 16:59:35 -05:00
}
2010-03-02 15:40:28 -06:00
/* now pick out the transactions that match */
if ( runtype = = QUERY_TXN_MATCH_ALL )
{
g_hash_table_foreach ( trans_hash , query_match_all_filter_func ,
& retval ) ;
}
else
{
g_hash_table_foreach ( trans_hash , query_match_any_filter_func ,
& retval ) ;
}
g_hash_table_destroy ( trans_hash ) ;
return retval ;
2002-06-05 16:59:35 -05:00
}
2002-06-27 09:10:40 -05:00
/********************************************************************
* xaccQueryGetLots
2010-03-02 15:40:28 -06:00
* Get lots matching the query terms , specifying whether
* we require some or all splits to match
2002-06-27 09:10:40 -05:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
2010-03-02 15:40:28 -06:00
query_match_all_lot_filter_func ( gpointer key , gpointer value , gpointer user_data )
2002-06-27 09:10:40 -05:00
{
2024-03-17 03:41:27 -05:00
GNCLot * l = GNC_LOT ( key ) ;
2010-03-02 15:40:28 -06:00
int num_matches = GPOINTER_TO_INT ( value ) ;
2024-03-17 03:41:27 -05:00
auto matches = static_cast < GList * * > ( user_data ) ;
2002-06-27 09:10:40 -05:00
2010-03-02 15:40:28 -06:00
if ( num_matches = = gnc_lot_count_splits ( l ) )
{
* matches = g_list_prepend ( * matches , l ) ;
}
2002-06-27 09:10:40 -05:00
}
static void
2010-03-02 15:40:28 -06:00
query_match_any_lot_filter_func ( gpointer key , gpointer value , gpointer user_data )
2002-06-27 09:10:40 -05:00
{
2024-03-17 03:41:27 -05:00
GNCLot * t = GNC_LOT ( key ) ;
auto matches = static_cast < GList * * > ( user_data ) ;
2010-03-02 15:40:28 -06:00
* matches = g_list_prepend ( * matches , t ) ;
2002-06-27 09:10:40 -05:00
}
2010-03-02 15:40:28 -06:00
LotList *
2010-12-14 14:22:48 -06:00
xaccQueryGetLots ( QofQuery * q , query_txn_match_t runtype )
2002-06-27 09:10:40 -05:00
{
2010-10-13 11:16:04 -05:00
GList * splits = qof_query_run ( q ) ;
2024-03-17 03:41:27 -05:00
GList * current = nullptr ;
GList * retval = nullptr ;
2010-03-02 15:40:28 -06:00
GHashTable * lot_hash = g_hash_table_new ( g_direct_hash , g_direct_equal ) ;
2024-03-17 03:41:27 -05:00
GNCLot * lot = nullptr ;
gpointer val = nullptr ;
2010-03-02 15:40:28 -06:00
int count = 0 ;
/* iterate over matching splits, incrementing a match-count in
* the hash table */
for ( current = splits ; current ; current = current - > next )
{
2024-03-17 03:41:27 -05:00
lot = xaccSplitGetLot ( ( GNC_SPLIT ( current - > data ) ) ) ;
2010-03-02 15:40:28 -06:00
/* don't waste time looking up unless we need the count
* information */
if ( runtype = = QUERY_TXN_MATCH_ALL )
{
val = g_hash_table_lookup ( lot_hash , lot ) ;
count = GPOINTER_TO_INT ( val ) ;
}
g_hash_table_insert ( lot_hash , lot , GINT_TO_POINTER ( count + 1 ) ) ;
}
/* now pick out the transactions that match */
if ( runtype = = QUERY_TXN_MATCH_ALL )
{
g_hash_table_foreach ( lot_hash , query_match_all_lot_filter_func ,
& retval ) ;
}
else
{
g_hash_table_foreach ( lot_hash , query_match_any_lot_filter_func ,
& retval ) ;
2002-06-27 09:10:40 -05:00
}
2010-03-02 15:40:28 -06:00
g_hash_table_destroy ( lot_hash ) ;
return retval ;
2002-06-27 09:10:40 -05:00
}
2002-06-05 16:59:35 -05:00
/*******************************************************************
2010-03-02 15:40:28 -06:00
* match - adding API
2002-06-05 16:59:35 -05:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
2010-12-14 14:22:48 -06:00
xaccQueryAddAccountMatch ( QofQuery * q , AccountList * acct_list ,
2010-03-02 15:40:28 -06:00
QofGuidMatch how , QofQueryOp op )
2002-06-05 16:59:35 -05:00
{
2024-03-17 03:41:27 -05:00
GList * list = nullptr ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( ! q ) return ;
for ( ; acct_list ; acct_list = acct_list - > next )
{
2024-03-17 03:41:27 -05:00
Account * acc = GNC_ACCOUNT ( acct_list - > data ) ;
2010-03-27 16:01:21 -05:00
const GncGUID * guid ;
2010-03-02 15:40:28 -06:00
if ( ! acc )
{
2024-03-17 03:41:27 -05:00
PWARN ( " acct_list has nullptr account " ) ;
2010-03-02 15:40:28 -06:00
continue ;
}
guid = qof_entity_get_guid ( QOF_INSTANCE ( acc ) ) ;
if ( ! guid )
{
2024-03-17 03:41:27 -05:00
PWARN ( " acct returns nullptr GncGUID " ) ;
2010-03-02 15:40:28 -06:00
continue ;
}
list = g_list_prepend ( list , ( gpointer ) guid ) ;
2002-06-05 16:59:35 -05:00
}
2010-03-02 15:40:28 -06:00
xaccQueryAddAccountGUIDMatch ( q , list , how , op ) ;
g_list_free ( list ) ;
2002-06-05 16:59:35 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddAccountGUIDMatch ( QofQuery * q , AccountGUIDList * guid_list ,
2010-03-02 15:40:28 -06:00
QofGuidMatch how , QofQueryOp op )
2002-06-05 16:59:35 -05:00
{
2010-03-02 15:40:28 -06:00
QofQueryPredData * pred_data ;
2024-03-17 03:41:27 -05:00
GSList * param_list = nullptr ;
2010-03-02 15:40:28 -06:00
if ( ! q ) return ;
2011-02-12 09:53:51 -06:00
if ( ! guid_list & & how ! = QOF_GUID_MATCH_NULL )
{
2024-03-17 03:41:27 -05:00
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 ) ;
2011-02-12 09:53:51 -06:00
/* qof_query_guid_predicate() would trigger a g_warning as well */
return ;
}
2010-03-02 15:40:28 -06:00
pred_data = qof_query_guid_predicate ( how , guid_list ) ;
if ( ! pred_data )
return ;
switch ( how )
{
case QOF_GUID_MATCH_ANY :
case QOF_GUID_MATCH_NONE :
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( SPLIT_ACCOUNT , QOF_PARAM_GUID , nullptr ) ;
2010-03-02 15:40:28 -06:00
break ;
case QOF_GUID_MATCH_ALL :
param_list = qof_query_build_param_list ( SPLIT_TRANS , TRANS_SPLITLIST ,
2024-03-17 03:41:27 -05:00
SPLIT_ACCOUNT_GUID , nullptr ) ;
2010-03-02 15:40:28 -06:00
break ;
default :
PERR ( " Invalid match type: %d " , how ) ;
2011-12-08 11:11:21 -06:00
break ;
2010-03-02 15:40:28 -06:00
}
qof_query_add_term ( q , param_list , pred_data , op ) ;
2002-06-05 16:59:35 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddSingleAccountMatch ( QofQuery * q , Account * acc , QofQueryOp op )
2002-06-05 16:59:35 -05:00
{
2010-03-02 15:40:28 -06:00
GList * list ;
2010-03-27 16:01:21 -05:00
const GncGUID * guid ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( ! q | | ! acc )
return ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
guid = qof_entity_get_guid ( QOF_INSTANCE ( acc ) ) ;
g_return_if_fail ( guid ) ;
2002-06-05 16:59:35 -05:00
2024-03-17 03:41:27 -05:00
list = g_list_prepend ( nullptr , ( gpointer ) guid ) ;
2010-03-02 15:40:28 -06:00
xaccQueryAddAccountGUIDMatch ( q , list , QOF_GUID_MATCH_ANY , op ) ;
g_list_free ( list ) ;
2002-06-05 16:59:35 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddStringMatch ( QofQuery * q , const char * matchstring ,
2010-03-02 15:40:28 -06:00
gboolean case_sens , gboolean use_regexp ,
2015-01-19 03:52:29 -06:00
QofQueryCompare how , QofQueryOp op ,
2010-03-02 15:40:28 -06:00
const char * path , . . . )
2002-06-05 16:59:35 -05:00
{
2010-03-02 15:40:28 -06:00
QofQueryPredData * pred_data ;
GSList * param_list ;
va_list ap ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( ! path | | ! q )
return ;
2002-06-05 16:59:35 -05:00
2015-01-19 03:52:29 -06:00
pred_data = qof_query_string_predicate ( how , ( char * ) matchstring ,
2010-03-02 15:40:28 -06:00
( case_sens ? QOF_STRING_MATCH_NORMAL :
QOF_STRING_MATCH_CASEINSENSITIVE ) ,
use_regexp ) ;
if ( ! pred_data )
return ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
va_start ( ap , path ) ;
param_list = build_param_list_internal ( path , ap ) ;
va_end ( ap ) ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
qof_query_add_term ( q , param_list , pred_data , op ) ;
2002-06-05 16:59:35 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddNumericMatch ( QofQuery * q , gnc_numeric amount , QofNumericMatch sign ,
2010-03-02 15:40:28 -06:00
QofQueryCompare how , QofQueryOp op ,
const char * path , . . . )
2002-06-05 16:59:35 -05:00
{
2010-03-02 15:40:28 -06:00
QofQueryPredData * pred_data ;
GSList * param_list ;
va_list ap ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( ! q | | ! path )
return ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
pred_data = qof_query_numeric_predicate ( how , sign , amount ) ;
if ( ! pred_data )
return ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
va_start ( ap , path ) ;
param_list = build_param_list_internal ( path , ap ) ;
va_end ( ap ) ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
qof_query_add_term ( q , param_list , pred_data , op ) ;
2002-06-05 16:59:35 -05:00
}
/* The DateMatch queries match transactions whose posted date
* is in a date range . If use_start is TRUE , then a matching
2010-03-02 15:40:28 -06:00
* posted date will be greater than the start date . If
* use_end is TRUE , then a match occurs for posted dates earlier
* than the end date . If both flags are set , then * both *
* conditions must hold ( ' and ' ) . If neither flag is set , then
2002-06-05 16:59:35 -05:00
* all transactions are matched .
*/
void
2018-04-26 08:48:06 -05:00
xaccQueryAddDateMatchTT ( QofQuery * q ,
gboolean use_start , time64 stt ,
gboolean use_end , time64 ett ,
2010-03-02 15:40:28 -06:00
QofQueryOp op )
2002-06-05 16:59:35 -05:00
{
2024-03-17 03:41:27 -05:00
QofQuery * tmp_q = nullptr ;
2010-03-02 15:40:28 -06:00
QofQueryPredData * pred_data ;
GSList * param_list ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( ! q | | ( ! use_start & & ! use_end ) )
return ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
tmp_q = qof_query_create ( ) ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( use_start )
{
2018-04-26 08:48:06 -05:00
pred_data = qof_query_date_predicate ( QOF_COMPARE_GTE , QOF_DATE_MATCH_NORMAL , stt ) ;
2010-03-02 15:40:28 -06:00
if ( ! pred_data )
{
qof_query_destroy ( tmp_q ) ;
return ;
}
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( SPLIT_TRANS , TRANS_DATE_POSTED , nullptr ) ;
2010-03-02 15:40:28 -06:00
qof_query_add_term ( tmp_q , param_list , pred_data , QOF_QUERY_AND ) ;
2002-06-05 16:59:35 -05:00
}
2010-03-02 15:40:28 -06:00
if ( use_end )
{
2018-04-26 08:48:06 -05:00
pred_data = qof_query_date_predicate ( QOF_COMPARE_LTE , QOF_DATE_MATCH_NORMAL , ett ) ;
2010-03-02 15:40:28 -06:00
if ( ! pred_data )
{
qof_query_destroy ( tmp_q ) ;
return ;
}
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( SPLIT_TRANS , TRANS_DATE_POSTED , nullptr ) ;
2010-03-02 15:40:28 -06:00
qof_query_add_term ( tmp_q , param_list , pred_data , QOF_QUERY_AND ) ;
2002-06-05 16:59:35 -05:00
}
2010-03-02 15:40:28 -06:00
qof_query_merge_in_place ( q , tmp_q , op ) ;
qof_query_destroy ( tmp_q ) ;
2002-06-05 16:59:35 -05:00
}
2005-11-01 21:32:36 -06:00
void
2018-04-26 08:48:06 -05:00
xaccQueryGetDateMatchTT ( QofQuery * q ,
time64 * stt ,
time64 * ett )
2005-11-01 21:32:36 -06:00
{
2010-03-02 15:40:28 -06:00
QofQueryPredData * term_data ;
GSList * param_list ;
GSList * terms , * tmp ;
2018-04-26 08:48:06 -05:00
* stt = 0 ;
* ett = 0 ;
2010-03-02 15:40:28 -06:00
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( SPLIT_TRANS , TRANS_DATE_POSTED , nullptr ) ;
2010-03-02 15:40:28 -06:00
terms = qof_query_get_term_type ( q , param_list ) ;
g_slist_free ( param_list ) ;
for ( tmp = terms ; tmp ; tmp = g_slist_next ( tmp ) )
{
2024-03-17 03:41:27 -05:00
term_data = static_cast < QofQueryPredData * > ( tmp - > data ) ;
2010-03-02 15:40:28 -06:00
if ( term_data - > how = = QOF_COMPARE_GTE )
2018-04-26 08:48:06 -05:00
qof_query_date_predicate_get_date ( term_data , stt ) ;
2010-03-02 15:40:28 -06:00
if ( term_data - > how = = QOF_COMPARE_LTE )
2018-04-26 08:48:06 -05:00
qof_query_date_predicate_get_date ( term_data , ett ) ;
2010-03-02 15:40:28 -06:00
}
g_slist_free ( terms ) ;
2005-11-01 21:32:36 -06:00
}
2002-06-05 16:59:35 -05:00
/********************************************************************
* xaccQueryAddDateMatch
2010-03-02 15:40:28 -06:00
* Add a date filter to an existing query .
2002-06-05 16:59:35 -05:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
2010-12-14 14:22:48 -06:00
xaccQueryAddDateMatch ( QofQuery * q ,
2006-10-15 14:02:05 -05:00
gboolean use_start , int sday , int smonth , int syear ,
gboolean use_end , int eday , int emonth , int eyear ,
2010-03-02 15:40:28 -06:00
QofQueryOp op )
2002-06-05 16:59:35 -05:00
{
2010-03-02 15:40:28 -06:00
/* gcc -O3 will auto-inline this function, avoiding a call overhead */
2018-04-26 08:48:06 -05:00
xaccQueryAddDateMatchTT ( q , use_start ,
gnc_dmy2time64 ( sday , smonth , syear ) ,
2010-03-02 15:40:28 -06:00
use_end ,
2018-04-26 08:48:06 -05:00
gnc_dmy2time64_end ( eday , emonth , eyear ) ,
2010-03-02 15:40:28 -06:00
op ) ;
2002-06-05 16:59:35 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddClearedMatch ( QofQuery * q , cleared_match_t how , QofQueryOp op )
2002-06-05 16:59:35 -05:00
{
2010-03-02 15:40:28 -06:00
QofQueryPredData * pred_data ;
GSList * param_list ;
char chars [ 6 ] ;
int i = 0 ;
if ( ! q )
return ;
if ( how & CLEARED_CLEARED )
chars [ i + + ] = CREC ;
if ( how & CLEARED_RECONCILED )
chars [ i + + ] = YREC ;
if ( how & CLEARED_FROZEN )
chars [ i + + ] = FREC ;
if ( how & CLEARED_NO )
chars [ i + + ] = NREC ;
if ( how & CLEARED_VOIDED )
chars [ i + + ] = VREC ;
chars [ i ] = ' \0 ' ;
pred_data = qof_query_char_predicate ( QOF_CHAR_MATCH_ANY , chars ) ;
if ( ! pred_data )
return ;
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( SPLIT_RECONCILE , nullptr ) ;
2010-03-02 15:40:28 -06:00
qof_query_add_term ( q , param_list , pred_data , op ) ;
2002-06-05 16:59:35 -05:00
}
2024-06-17 08:31:53 -05:00
cleared_match_t
xaccQueryGetClearedMatch ( QofQuery * q )
{
QofQueryPredData * term_data ;
cleared_match_t cleared_match = CLEARED_ALL ;
GSList * param_list ;
GSList * terms , * tmp ;
char * chars = nullptr ;
param_list = qof_query_build_param_list ( SPLIT_RECONCILE , nullptr ) ;
terms = qof_query_get_term_type ( q , param_list ) ;
g_slist_free ( param_list ) ;
for ( tmp = terms ; tmp ; tmp = g_slist_next ( tmp ) )
{
term_data = static_cast < QofQueryPredData * > ( tmp - > data ) ;
if ( qof_query_char_predicate_get_char ( term_data , & chars ) )
{
cleared_match = CLEARED_NONE ;
if ( strstr ( chars , " c " ) )
cleared_match = ( cleared_match_t ) ( cleared_match | CLEARED_CLEARED ) ;
if ( strstr ( chars , " y " ) )
cleared_match = ( cleared_match_t ) ( cleared_match | CLEARED_RECONCILED ) ;
if ( strstr ( chars , " f " ) )
cleared_match = ( cleared_match_t ) ( cleared_match | CLEARED_FROZEN ) ;
if ( strstr ( chars , " n " ) )
cleared_match = ( cleared_match_t ) ( cleared_match | CLEARED_NO ) ;
if ( strstr ( chars , " v " ) )
cleared_match = ( cleared_match_t ) ( cleared_match | CLEARED_VOIDED ) ;
}
}
g_slist_free ( terms ) ;
return cleared_match ;
}
2002-06-05 16:59:35 -05:00
void
2010-12-14 14:22:48 -06:00
xaccQueryAddGUIDMatch ( QofQuery * q , const GncGUID * guid ,
2010-03-02 15:40:28 -06:00
QofIdType id_type , QofQueryOp op )
2002-06-05 16:59:35 -05:00
{
2024-03-17 03:41:27 -05:00
GSList * param_list = nullptr ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( ! q | | ! guid | | ! id_type )
return ;
2002-06-05 16:59:35 -05:00
2012-08-07 12:24:55 -05:00
if ( ! g_strcmp0 ( id_type , GNC_ID_SPLIT ) )
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( QOF_PARAM_GUID , nullptr ) ;
2012-08-07 12:24:55 -05:00
else if ( ! g_strcmp0 ( id_type , GNC_ID_TRANS ) )
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( SPLIT_TRANS , QOF_PARAM_GUID , nullptr ) ;
2012-08-07 12:24:55 -05:00
else if ( ! g_strcmp0 ( id_type , GNC_ID_ACCOUNT ) )
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( SPLIT_ACCOUNT , QOF_PARAM_GUID , nullptr ) ;
2010-03-02 15:40:28 -06:00
else
PERR ( " Invalid match type: %s " , id_type ) ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
qof_query_add_guid_match ( q , param_list , guid , op ) ;
2002-06-05 16:59:35 -05:00
}
2013-12-10 16:17:50 -06:00
/********************************************************************
* xaccQueryAddClosingTransMatch
* Add a filter that matches book closing entries to an existing query .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
xaccQueryAddClosingTransMatch ( QofQuery * q , gboolean value , QofQueryOp op )
{
2024-06-17 08:31:53 -05:00
GSList * param_list ;
2024-03-17 03:41:27 -05:00
param_list = qof_query_build_param_list ( SPLIT_TRANS , TRANS_IS_CLOSING , nullptr ) ;
2013-12-10 16:17:50 -06:00
qof_query_add_boolean_match ( q , param_list , value , op ) ;
}
2002-06-05 16:59:35 -05:00
/*******************************************************************
* xaccQueryGetEarliestDateFound
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-12-01 16:44:53 -06:00
time64
2010-12-14 14:22:48 -06:00
xaccQueryGetEarliestDateFound ( QofQuery * q )
2002-06-05 16:59:35 -05:00
{
2010-03-02 15:40:28 -06:00
GList * spl ;
Split * sp ;
2012-12-01 16:44:53 -06:00
time64 earliest ;
2010-03-02 15:40:28 -06:00
if ( ! q ) return 0 ;
spl = qof_query_last_run ( q ) ;
if ( ! spl ) return 0 ;
2012-12-01 16:44:53 -06:00
/* Safe until 2038 on archs where time64 is 32bit */
2024-03-17 03:41:27 -05:00
sp = GNC_SPLIT ( spl - > data ) ;
2017-12-31 06:37:02 -06:00
earliest = sp - > parent - > date_posted ;
2010-03-02 15:40:28 -06:00
for ( ; spl ; spl = spl - > next )
{
2024-03-17 03:41:27 -05:00
sp = GNC_SPLIT ( spl - > data ) ;
2017-12-31 06:37:02 -06:00
if ( sp - > parent - > date_posted < earliest )
2010-03-02 15:40:28 -06:00
{
2017-12-31 06:37:02 -06:00
earliest = sp - > parent - > date_posted ;
2010-03-02 15:40:28 -06:00
}
2002-06-05 16:59:35 -05:00
}
2010-03-02 15:40:28 -06:00
return earliest ;
2002-06-05 16:59:35 -05:00
}
/*******************************************************************
* xaccQueryGetLatestDateFound
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-12-01 16:44:53 -06:00
time64
2010-12-14 14:22:48 -06:00
xaccQueryGetLatestDateFound ( QofQuery * q )
2002-06-05 16:59:35 -05:00
{
2010-03-02 15:40:28 -06:00
Split * sp ;
GList * spl ;
2012-12-01 16:44:53 -06:00
time64 latest = 0 ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
if ( ! q ) return 0 ;
spl = qof_query_last_run ( q ) ;
if ( ! spl ) return 0 ;
2002-06-05 16:59:35 -05:00
2010-03-02 15:40:28 -06:00
for ( ; spl ; spl = spl - > next )
{
2024-03-17 03:41:27 -05:00
sp = GNC_SPLIT ( spl - > data ) ;
2017-12-31 06:37:02 -06:00
if ( sp - > parent - > date_posted > latest )
2010-03-02 15:40:28 -06:00
{
2017-12-31 06:37:02 -06:00
latest = sp - > parent - > date_posted ;
2010-03-02 15:40:28 -06:00
}
2002-06-05 16:59:35 -05:00
}
2010-03-02 15:40:28 -06:00
return latest ;
2002-06-05 16:59:35 -05:00
}
2006-10-15 14:02:05 -05:00
void
2010-12-14 14:22:48 -06:00
xaccQueryAddDescriptionMatch ( QofQuery * q , const char * m , gboolean c , gboolean r ,
2015-01-19 03:52:29 -06:00
QofQueryCompare h , QofQueryOp o )
2006-10-15 14:02:05 -05:00
{
2015-01-19 03:52:29 -06:00
xaccQueryAddStringMatch ( ( q ) , ( m ) , ( c ) , ( r ) , ( h ) , ( o ) , SPLIT_TRANS ,
2024-03-17 03:41:27 -05:00
TRANS_DESCRIPTION , nullptr ) ;
2006-10-15 14:02:05 -05:00
}
2015-01-19 03:52:29 -06:00
void
xaccQueryAddNotesMatch ( QofQuery * q , const char * m , gboolean c , gboolean r ,
QofQueryCompare h , QofQueryOp o )
{
xaccQueryAddStringMatch ( ( q ) , ( m ) , ( c ) , ( r ) , ( h ) , ( o ) , SPLIT_TRANS ,
2024-03-17 03:41:27 -05:00
TRANS_NOTES , nullptr ) ;
2015-01-19 03:52:29 -06:00
}
2006-10-15 14:02:05 -05:00
void
2010-12-14 14:22:48 -06:00
xaccQueryAddNumberMatch ( QofQuery * q , const char * m , gboolean c , gboolean r ,
2015-01-19 03:52:29 -06:00
QofQueryCompare h , QofQueryOp o )
2006-10-15 14:02:05 -05:00
{
2015-01-19 03:52:29 -06:00
xaccQueryAddStringMatch ( ( q ) , ( m ) , ( c ) , ( r ) , ( h ) , ( o ) , SPLIT_TRANS ,
2024-03-17 03:41:27 -05:00
TRANS_NUM , nullptr ) ;
2006-10-15 14:02:05 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddActionMatch ( QofQuery * q , const char * m , gboolean c , gboolean r ,
2015-01-19 03:52:29 -06:00
QofQueryCompare h , QofQueryOp o )
2006-10-15 14:02:05 -05:00
{
2024-03-17 03:41:27 -05:00
xaccQueryAddStringMatch ( ( q ) , ( m ) , ( c ) , ( r ) , ( h ) , ( o ) , SPLIT_ACTION , nullptr ) ;
2006-10-15 14:02:05 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddMemoMatch ( QofQuery * q , const char * m , gboolean c , gboolean r ,
2015-01-19 03:52:29 -06:00
QofQueryCompare h , QofQueryOp o )
2006-10-15 14:02:05 -05:00
{
2024-03-17 03:41:27 -05:00
xaccQueryAddStringMatch ( ( q ) , ( m ) , ( c ) , ( r ) , ( h ) , ( o ) , SPLIT_MEMO , nullptr ) ;
2006-10-15 14:02:05 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddValueMatch ( QofQuery * q , gnc_numeric amt , QofNumericMatch sgn ,
2006-10-15 14:02:05 -05:00
QofQueryCompare how , QofQueryOp op )
{
xaccQueryAddNumericMatch ( ( q ) , ( amt ) , ( sgn ) , ( how ) , ( op ) ,
2024-03-17 03:41:27 -05:00
SPLIT_VALUE , nullptr ) ;
2006-10-15 14:02:05 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddSharePriceMatch ( QofQuery * q , gnc_numeric amt , QofQueryCompare how ,
2006-10-15 14:02:05 -05:00
QofQueryOp op )
{
xaccQueryAddNumericMatch ( ( q ) , ( amt ) , QOF_NUMERIC_MATCH_ANY , ( how ) , ( op ) ,
2024-03-17 03:41:27 -05:00
SPLIT_SHARE_PRICE , nullptr ) ;
2006-10-15 14:02:05 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddSharesMatch ( QofQuery * q , gnc_numeric amt , QofQueryCompare how ,
2006-10-15 14:02:05 -05:00
QofQueryOp op )
{
xaccQueryAddNumericMatch ( ( q ) , ( amt ) , QOF_NUMERIC_MATCH_ANY , ( how ) , ( op ) ,
2024-03-17 03:41:27 -05:00
SPLIT_AMOUNT , nullptr ) ;
2006-10-15 14:02:05 -05:00
}
void
2010-12-14 14:22:48 -06:00
xaccQueryAddBalanceMatch ( QofQuery * q , QofQueryCompare bal , QofQueryOp op )
2006-10-15 14:02:05 -05:00
{
xaccQueryAddNumericMatch (
( q ) , gnc_numeric_zero ( ) , QOF_NUMERIC_MATCH_ANY ,
( ( bal ) ? QOF_COMPARE_EQUAL : QOF_COMPARE_NEQ ) , ( op ) ,
2024-03-17 03:41:27 -05:00
SPLIT_TRANS , TRANS_IMBALANCE , nullptr ) ;
2006-10-15 14:02:05 -05:00
}
2002-01-02 13:56:02 -06:00
/* ======================== END OF FILE ======================= */