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 *
|
|
|
|
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
|
|
|
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
|
|
|
\********************************************************************/
|
|
|
|
|
2001-09-07 16:51:13 -05:00
|
|
|
#include "config.h"
|
|
|
|
|
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>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "gnc-engine-util.h"
|
|
|
|
#include "gnc-numeric.h"
|
2003-09-12 08:17:26 -05:00
|
|
|
#include "gnc-lot.h"
|
|
|
|
#include "gnc-trace.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"
|
2001-08-07 18:36:04 -05:00
|
|
|
#include "TransactionP.h"
|
|
|
|
|
|
|
|
static short module = MOD_QUERY;
|
|
|
|
|
2002-06-05 16:59:35 -05:00
|
|
|
static GSList *
|
|
|
|
build_param_list_internal (const char *first, va_list rest)
|
|
|
|
{
|
|
|
|
GSList *list = NULL;
|
|
|
|
char const *param;
|
|
|
|
|
|
|
|
for (param = first; param; param = va_arg (rest, const char *))
|
|
|
|
list = g_slist_prepend (list, (gpointer)param);
|
|
|
|
|
|
|
|
return (g_slist_reverse (list));
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* xaccQueryGetSplitsUniqueTrans
|
|
|
|
* Get splits but no more than one from a given transaction.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
SplitList *
|
|
|
|
xaccQueryGetSplitsUniqueTrans(Query *q)
|
|
|
|
{
|
|
|
|
GList * splits = xaccQueryGetSplits(q);
|
|
|
|
GList * current;
|
|
|
|
GList * result = NULL;
|
|
|
|
GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
|
|
|
|
|
|
|
|
for (current = splits; current; current = current->next)
|
|
|
|
{
|
|
|
|
Split *split = current->data;
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_destroy (trans_hash);
|
|
|
|
|
|
|
|
return g_list_reverse (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* xaccQueryGetTransactions
|
|
|
|
* Get transactions matching the query terms, specifying whether
|
|
|
|
* we require some or all splits to match
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
static void
|
|
|
|
query_match_all_filter_func(gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
Transaction * t = key;
|
|
|
|
int num_matches = GPOINTER_TO_INT(value);
|
|
|
|
GList ** matches = user_data;
|
|
|
|
|
|
|
|
if(num_matches == xaccTransCountSplits(t)) {
|
|
|
|
*matches = g_list_prepend(*matches, t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
query_match_any_filter_func(gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
Transaction * t = key;
|
|
|
|
GList ** matches = user_data;
|
|
|
|
*matches = g_list_prepend(*matches, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
TransList *
|
|
|
|
xaccQueryGetTransactions (Query * q, query_txn_match_t runtype)
|
|
|
|
{
|
|
|
|
GList * splits = xaccQueryGetSplits(q);
|
|
|
|
GList * current = NULL;
|
|
|
|
GList * retval = NULL;
|
|
|
|
GHashTable * trans_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
|
|
|
|
Transaction * trans = NULL;
|
|
|
|
gpointer val = NULL;
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
/* iterate over matching splits, incrementing a match-count in
|
|
|
|
* the hash table */
|
|
|
|
for(current = splits; current; current=current->next) {
|
|
|
|
trans = xaccSplitGetParent((Split *)(current->data));
|
|
|
|
|
|
|
|
/* 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));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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-27 09:10:40 -05:00
|
|
|
/********************************************************************
|
|
|
|
* xaccQueryGetLots
|
|
|
|
* Get lots matching the query terms, specifying whether
|
|
|
|
* we require some or all splits to match
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
static void
|
|
|
|
query_match_all_lot_filter_func(gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
GNCLot * l = key;
|
|
|
|
int num_matches = GPOINTER_TO_INT(value);
|
|
|
|
GList ** matches = user_data;
|
|
|
|
|
|
|
|
if(num_matches == gnc_lot_count_splits(l)) {
|
|
|
|
*matches = g_list_prepend(*matches, l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
query_match_any_lot_filter_func(gpointer key, gpointer value, gpointer user_data)
|
|
|
|
{
|
|
|
|
GNCLot * t = key;
|
|
|
|
GList ** matches = user_data;
|
|
|
|
*matches = g_list_prepend(*matches, t);
|
|
|
|
}
|
|
|
|
|
|
|
|
LotList *
|
|
|
|
xaccQueryGetLots (Query * q, query_txn_match_t runtype)
|
|
|
|
{
|
|
|
|
GList * splits = xaccQueryGetSplits(q);
|
|
|
|
GList * current = NULL;
|
|
|
|
GList * retval = NULL;
|
|
|
|
GHashTable * lot_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
|
|
|
|
GNCLot * lot = NULL;
|
|
|
|
gpointer val = NULL;
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
/* iterate over matching splits, incrementing a match-count in
|
|
|
|
* the hash table */
|
|
|
|
for(current = splits; current; current=current->next) {
|
|
|
|
lot = xaccSplitGetLot((Split *)(current->data));
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_destroy(lot_hash);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2002-06-05 16:59:35 -05:00
|
|
|
/*******************************************************************
|
|
|
|
* match-adding API
|
|
|
|
*******************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
xaccQueryAddAccountMatch(Query *q, AccountList *acct_list,
|
2003-06-25 02:38:15 -05:00
|
|
|
QofGuidMatch how, QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
|
|
|
GList *list = NULL;
|
|
|
|
|
|
|
|
if (!q) return;
|
|
|
|
for (; acct_list; acct_list = acct_list->next) {
|
|
|
|
Account *acc = acct_list->data;
|
|
|
|
const GUID *guid;
|
|
|
|
|
|
|
|
if (!acc) {
|
|
|
|
PWARN ("acct_list has NULL account");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
guid = xaccAccountGetGUID (acc);
|
|
|
|
if (!guid) {
|
|
|
|
PWARN ("acct returns NULL GUID");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
list = g_list_prepend (list, (gpointer)guid);
|
|
|
|
}
|
|
|
|
xaccQueryAddAccountGUIDMatch (q, list, how, op);
|
|
|
|
g_list_free (list);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
xaccQueryAddAccountGUIDMatch(Query *q, AccountGUIDList *guid_list,
|
2003-06-25 02:38:15 -05:00
|
|
|
QofGuidMatch how, QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
2003-06-25 00:14:10 -05:00
|
|
|
QofQueryPredData *pred_data;
|
2002-06-05 16:59:35 -05:00
|
|
|
GSList *param_list = NULL;
|
|
|
|
|
|
|
|
if (!q) return;
|
|
|
|
|
2003-06-25 00:14:10 -05:00
|
|
|
pred_data = qof_query_guid_predicate (how, guid_list);
|
2002-06-05 16:59:35 -05:00
|
|
|
if (!pred_data)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (how) {
|
2003-06-25 00:14:10 -05:00
|
|
|
case QOF_GUID_MATCH_ANY:
|
|
|
|
case QOF_GUID_MATCH_NONE:
|
2004-05-23 12:31:40 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
break;
|
2003-06-25 00:14:10 -05:00
|
|
|
case QOF_GUID_MATCH_ALL:
|
2003-06-25 02:38:15 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_SPLITLIST,
|
2002-12-15 17:25:01 -06:00
|
|
|
SPLIT_ACCOUNT_GUID, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
PERR ("Invalid match type: %d", how);
|
|
|
|
}
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_add_term (q, param_list, pred_data, op);
|
2002-06-05 16:59:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-25 02:38:15 -05:00
|
|
|
xaccQueryAddSingleAccountMatch(Query *q, Account *acc, QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
|
|
|
GList *list;
|
|
|
|
const GUID *guid;
|
|
|
|
|
|
|
|
if (!q || !acc)
|
|
|
|
return;
|
|
|
|
|
|
|
|
guid = xaccAccountGetGUID (acc);
|
|
|
|
g_return_if_fail (guid);
|
|
|
|
|
|
|
|
list = g_list_prepend (NULL, (gpointer)guid);
|
2003-06-25 00:14:10 -05:00
|
|
|
xaccQueryAddAccountGUIDMatch (q, list, QOF_GUID_MATCH_ANY, op);
|
2002-06-05 16:59:35 -05:00
|
|
|
g_list_free (list);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
xaccQueryAddStringMatch (Query* q, const char *matchstring,
|
2003-06-25 02:38:15 -05:00
|
|
|
int case_sens, int use_regexp, QofQueryOp op,
|
2002-06-05 16:59:35 -05:00
|
|
|
const char * path, ...)
|
|
|
|
{
|
2003-06-25 00:14:10 -05:00
|
|
|
QofQueryPredData *pred_data;
|
2002-06-05 16:59:35 -05:00
|
|
|
GSList *param_list;
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
if (!path || !q)
|
|
|
|
return;
|
|
|
|
|
2003-06-25 00:14:10 -05:00
|
|
|
pred_data = qof_query_string_predicate (QOF_COMPARE_EQUAL, (char *)matchstring,
|
|
|
|
(case_sens ? QOF_STRING_MATCH_NORMAL :
|
|
|
|
QOF_STRING_MATCH_CASEINSENSITIVE),
|
2002-06-05 16:59:35 -05:00
|
|
|
use_regexp);
|
|
|
|
if (!pred_data)
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_start (ap, path);
|
|
|
|
param_list = build_param_list_internal (path, ap);
|
|
|
|
va_end (ap);
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_add_term (q, param_list, pred_data, op);
|
2002-06-05 16:59:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-25 00:14:10 -05:00
|
|
|
xaccQueryAddNumericMatch (Query *q, gnc_numeric amount, QofNumericMatch sign,
|
2003-06-25 02:38:15 -05:00
|
|
|
QofQueryCompare how, QofQueryOp op,
|
2002-06-05 16:59:35 -05:00
|
|
|
const char * path, ...)
|
|
|
|
{
|
2003-06-25 00:14:10 -05:00
|
|
|
QofQueryPredData *pred_data;
|
2002-06-05 16:59:35 -05:00
|
|
|
GSList *param_list;
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
if (!q || !path)
|
|
|
|
return;
|
|
|
|
|
2003-06-25 00:14:10 -05:00
|
|
|
pred_data = qof_query_numeric_predicate (how, sign, amount);
|
2002-06-05 16:59:35 -05:00
|
|
|
if (!pred_data)
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_start (ap, path);
|
|
|
|
param_list = build_param_list_internal (path, ap);
|
|
|
|
va_end (ap);
|
|
|
|
|
2003-06-25 02:38:15 -05: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
|
|
|
|
* 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
|
|
|
|
* all transactions are matched.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
xaccQueryAddDateMatchTS (Query * q,
|
|
|
|
int use_start, Timespec sts,
|
|
|
|
int use_end, Timespec ets,
|
2003-06-25 02:38:15 -05:00
|
|
|
QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
|
|
|
Query *tmp_q = NULL;
|
2003-06-25 00:14:10 -05:00
|
|
|
QofQueryPredData *pred_data;
|
2002-06-05 16:59:35 -05:00
|
|
|
GSList *param_list;
|
|
|
|
|
|
|
|
if (!q || (!use_start && !use_end))
|
|
|
|
return;
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
tmp_q = qof_query_create ();
|
2002-06-05 16:59:35 -05:00
|
|
|
|
|
|
|
if (use_start) {
|
2003-06-25 00:41:38 -05:00
|
|
|
pred_data = qof_query_date_predicate (QOF_COMPARE_GTE, QOF_DATE_MATCH_NORMAL, sts);
|
2002-06-05 16:59:35 -05:00
|
|
|
if (!pred_data) {
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_destroy (tmp_q);
|
2002-06-05 16:59:35 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, NULL);
|
|
|
|
qof_query_add_term (tmp_q, param_list, pred_data, QOF_QUERY_AND);
|
2002-06-05 16:59:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (use_end) {
|
2003-06-25 00:41:38 -05:00
|
|
|
pred_data = qof_query_date_predicate (QOF_COMPARE_LTE, QOF_DATE_MATCH_NORMAL, ets);
|
2002-06-05 16:59:35 -05:00
|
|
|
if (!pred_data) {
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_destroy (tmp_q);
|
2002-06-05 16:59:35 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_DATE_POSTED, NULL);
|
|
|
|
qof_query_add_term (tmp_q, param_list, pred_data, QOF_QUERY_AND);
|
2002-06-05 16:59:35 -05:00
|
|
|
}
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_merge_in_place (q, tmp_q, op);
|
|
|
|
qof_query_destroy (tmp_q);
|
2002-06-05 16:59:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* xaccQueryAddDateMatch
|
|
|
|
* Add a date filter to an existing query.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
xaccQueryAddDateMatch(Query * q,
|
|
|
|
int use_start, int sday, int smonth, int syear,
|
|
|
|
int use_end, int eday, int emonth, int eyear,
|
2003-06-25 02:38:15 -05:00
|
|
|
QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
|
|
|
/* gcc -O3 will auto-inline this function, avoiding a call overhead */
|
|
|
|
xaccQueryAddDateMatchTS (q, use_start,
|
|
|
|
gnc_dmy2timespec(sday, smonth, syear),
|
|
|
|
use_end,
|
|
|
|
gnc_dmy2timespec_end(eday, emonth, eyear),
|
|
|
|
op);
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
* xaccQueryAddDateMatchTT
|
|
|
|
* Add a date filter to an existing query.
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
|
|
|
xaccQueryAddDateMatchTT(Query * q,
|
|
|
|
int use_start,
|
|
|
|
time_t stt,
|
|
|
|
int use_end,
|
|
|
|
time_t ett,
|
2003-06-25 02:38:15 -05:00
|
|
|
QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
|
|
|
Timespec sts;
|
|
|
|
Timespec ets;
|
|
|
|
|
|
|
|
sts.tv_sec = (long long)stt;
|
|
|
|
sts.tv_nsec = 0;
|
|
|
|
|
|
|
|
ets.tv_sec = (long long)ett;
|
|
|
|
ets.tv_nsec = 0;
|
|
|
|
|
|
|
|
/* gcc -O3 will auto-inline this function, avoiding a call overhead */
|
|
|
|
xaccQueryAddDateMatchTS (q, use_start, sts,
|
|
|
|
use_end, ets, op);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-06-25 02:38:15 -05:00
|
|
|
xaccQueryAddClearedMatch(Query * q, cleared_match_t how, QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
2003-06-25 00:14:10 -05:00
|
|
|
QofQueryPredData *pred_data;
|
2002-06-05 16:59:35 -05:00
|
|
|
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';
|
|
|
|
|
2003-06-25 00:14:10 -05:00
|
|
|
pred_data = qof_query_char_predicate (QOF_CHAR_MATCH_ANY, chars);
|
2002-06-05 16:59:35 -05:00
|
|
|
if (!pred_data)
|
|
|
|
return;
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_RECONCILE, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_add_term (q, param_list, pred_data, op);
|
2002-06-05 16:59:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
xaccQueryAddGUIDMatch(Query * q, const GUID *guid,
|
2003-06-26 02:30:48 -05:00
|
|
|
QofIdType id_type, QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
|
|
|
GSList *param_list = NULL;
|
|
|
|
|
|
|
|
if (!q || !guid || !id_type)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!safe_strcmp (id_type, GNC_ID_SPLIT))
|
2004-05-23 12:31:40 -05:00
|
|
|
param_list = qof_query_build_param_list (QOF_PARAM_GUID, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
else if (!safe_strcmp (id_type, GNC_ID_TRANS))
|
2004-05-23 12:31:40 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_TRANS, QOF_PARAM_GUID, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
else if (!safe_strcmp (id_type, GNC_ID_ACCOUNT))
|
2004-05-23 12:31:40 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_ACCOUNT, QOF_PARAM_GUID, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
else
|
|
|
|
PERR ("Invalid match type: %s", id_type);
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_add_guid_match (q, param_list, guid, op);
|
2002-06-05 16:59:35 -05:00
|
|
|
}
|
|
|
|
|
2002-06-27 23:20:46 -05:00
|
|
|
void
|
2003-06-25 02:38:15 -05:00
|
|
|
xaccQueryAddGUIDMatchGL (QofQuery *q, GList *param_list,
|
|
|
|
GUID guid, QofQueryOp op)
|
2002-06-27 23:20:46 -05:00
|
|
|
{
|
|
|
|
GSList *params = NULL;
|
|
|
|
GList *node;
|
|
|
|
|
|
|
|
for (node = param_list; node; node = node->next)
|
|
|
|
params = g_slist_prepend (params, node->data);
|
|
|
|
|
|
|
|
params = g_slist_reverse (params);
|
|
|
|
g_list_free (param_list);
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_add_guid_match (q, params, &guid, op);
|
2002-06-27 23:20:46 -05:00
|
|
|
}
|
|
|
|
|
2002-06-05 16:59:35 -05:00
|
|
|
void
|
2003-06-27 18:33:00 -05:00
|
|
|
xaccQueryAddKVPMatch(QofQuery *q, GSList *path, const KvpValue *value,
|
2003-06-26 02:30:48 -05:00
|
|
|
QofQueryCompare how, QofIdType id_type,
|
2003-06-25 02:38:15 -05:00
|
|
|
QofQueryOp op)
|
2002-06-05 16:59:35 -05:00
|
|
|
{
|
|
|
|
GSList *param_list = NULL;
|
2003-06-25 00:14:10 -05:00
|
|
|
QofQueryPredData *pred_data;
|
2002-06-05 16:59:35 -05:00
|
|
|
|
|
|
|
if (!q || !path || !value || !id_type)
|
|
|
|
return;
|
|
|
|
|
2003-06-25 00:14:10 -05:00
|
|
|
pred_data = qof_query_kvp_predicate (how, path, value);
|
2002-06-05 16:59:35 -05:00
|
|
|
if (!pred_data)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!safe_strcmp (id_type, GNC_ID_SPLIT))
|
2003-06-25 02:38:15 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_KVP, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
else if (!safe_strcmp (id_type, GNC_ID_TRANS))
|
2003-06-25 02:38:15 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_KVP, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
else if (!safe_strcmp (id_type, GNC_ID_ACCOUNT))
|
2003-06-25 02:38:15 -05:00
|
|
|
param_list = qof_query_build_param_list (SPLIT_ACCOUNT, ACCOUNT_KVP, NULL);
|
2002-06-05 16:59:35 -05:00
|
|
|
else
|
|
|
|
PERR ("Invalid match type: %s", id_type);
|
|
|
|
|
2003-06-25 02:38:15 -05:00
|
|
|
qof_query_add_term (q, param_list, pred_data, op);
|
2002-06-05 16:59:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
* xaccQueryGetEarliestDateFound
|
|
|
|
*******************************************************************/
|
|
|
|
|
|
|
|
time_t
|
|
|
|
xaccQueryGetEarliestDateFound(Query * q)
|
|
|
|
{
|
|
|
|
GList * spl;
|
|
|
|
Split * sp;
|
2005-08-15 20:55:25 -05:00
|
|
|
time_t earliest;
|
2002-06-05 16:59:35 -05:00
|
|
|
|
|
|
|
if (!q) return 0;
|
2003-06-25 02:38:15 -05:00
|
|
|
spl = qof_query_last_run (q);
|
2002-06-05 16:59:35 -05:00
|
|
|
if (!spl) return 0;
|
|
|
|
|
2005-08-15 20:55:25 -05:00
|
|
|
/* Safe until 2038 on archs where time_t is 32bit */
|
|
|
|
sp = spl->data;
|
|
|
|
earliest = (time_t) sp->parent->date_posted.tv_sec;
|
2002-06-05 16:59:35 -05:00
|
|
|
for(; spl; spl=spl->next) {
|
|
|
|
sp = spl->data;
|
|
|
|
if(sp->parent->date_posted.tv_sec < earliest) {
|
|
|
|
earliest = (time_t) sp->parent->date_posted.tv_sec;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return earliest;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
* xaccQueryGetLatestDateFound
|
|
|
|
*******************************************************************/
|
|
|
|
|
|
|
|
time_t
|
|
|
|
xaccQueryGetLatestDateFound(Query * q)
|
|
|
|
{
|
|
|
|
Split * sp;
|
|
|
|
GList * spl;
|
|
|
|
time_t latest = 0;
|
|
|
|
|
|
|
|
if(!q) return 0;
|
2003-06-25 02:38:15 -05:00
|
|
|
spl = qof_query_last_run (q);
|
2002-06-05 16:59:35 -05:00
|
|
|
if(!spl) return 0;
|
|
|
|
|
|
|
|
for(; spl; spl=spl->next) {
|
|
|
|
sp = spl->data;
|
|
|
|
if(sp->parent->date_posted.tv_sec > latest) {
|
|
|
|
latest = (time_t) sp->parent->date_posted.tv_sec;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return latest;
|
|
|
|
}
|
|
|
|
|
2002-01-02 13:56:02 -06:00
|
|
|
/* ======================== END OF FILE ======================= */
|