mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Work on adding kvp queries.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@5770 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -86,6 +86,7 @@ static int xaccClearedMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccDateMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccDescriptionMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccGUIDMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccKVPMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccMemoMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccNumberMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccSharePriceMatchPredicate(Split * s, PredicateData * pd);
|
||||
@@ -150,18 +151,23 @@ xaccQueryPrint(Query * q)
|
||||
break;
|
||||
}
|
||||
case PR_ACTION:
|
||||
printf ("action sense=%d case sensitive=%d\n", qt->data.str.sense, qt->data.str.case_sens);
|
||||
printf ("action sense=%d case sensitive=%d\n", qt->data.str.sense,
|
||||
qt->data.str.case_sens);
|
||||
printf ("\tmatch string=%s \n", qt->data.str.matchstring);
|
||||
break;
|
||||
case PR_AMOUNT:
|
||||
printf ("amount sense=%d how=%d\n", qt->data.amount.sense, qt->data.amount.how);
|
||||
printf ("\tsign=%d amount=%f\n", qt->data.amount.amt_sgn, qt->data.amount.amount);
|
||||
printf ("amount sense=%d how=%d\n", qt->data.amount.sense,
|
||||
qt->data.amount.how);
|
||||
printf ("\tsign=%d amount=%f\n", qt->data.amount.amt_sgn,
|
||||
qt->data.amount.amount);
|
||||
break;
|
||||
case PR_BALANCE:
|
||||
printf ("balance sense=%d how=%d\n", qt->data.balance.sense, qt->data.balance.how);
|
||||
printf ("balance sense=%d how=%d\n", qt->data.balance.sense,
|
||||
qt->data.balance.how);
|
||||
break;
|
||||
case PR_CLEARED:
|
||||
printf ("cleared sense=%d how=%d\n", qt->data.cleared.sense, qt->data.cleared.how);
|
||||
printf ("cleared sense=%d how=%d\n", qt->data.cleared.sense,
|
||||
qt->data.cleared.how);
|
||||
break;
|
||||
case PR_DATE: {
|
||||
char buff[40];
|
||||
@@ -181,7 +187,8 @@ xaccQueryPrint(Query * q)
|
||||
break;
|
||||
}
|
||||
case PR_DESC:
|
||||
printf ("desc sense=%d case sensitive=%d\n", qt->data.str.sense, qt->data.str.case_sens);
|
||||
printf ("desc sense=%d case sensitive=%d\n", qt->data.str.sense,
|
||||
qt->data.str.case_sens);
|
||||
printf ("\tmatch string=%s \n", qt->data.str.matchstring);
|
||||
break;
|
||||
|
||||
@@ -192,24 +199,48 @@ xaccQueryPrint(Query * q)
|
||||
printf ("\tguid %s\n", buff);
|
||||
break;
|
||||
}
|
||||
case PR_KVP: {
|
||||
GSList *node;
|
||||
char *str;
|
||||
printf ("kvp sense=%d how=%d where=%d\n", qt->data.kvp.sense,
|
||||
qt->data.kvp.how, qt->data.kvp.where);
|
||||
printf ("path:");
|
||||
for (node = qt->data.kvp.path; node; node = node->next)
|
||||
{
|
||||
printf (node->data);
|
||||
if (node->next)
|
||||
printf ("/");
|
||||
}
|
||||
printf ("\n");
|
||||
str = kvp_value_to_string (qt->data.kvp.value);
|
||||
printf ("value: %s\n", str);
|
||||
g_free (str);
|
||||
break;
|
||||
}
|
||||
case PR_MEMO:
|
||||
printf ("memo sense=%d case sensitive=%d\n", qt->data.str.sense, qt->data.str.case_sens);
|
||||
printf ("memo sense=%d case sensitive=%d\n", qt->data.str.sense,
|
||||
qt->data.str.case_sens);
|
||||
printf ("\tmatch string=%s \n", qt->data.str.matchstring);
|
||||
break;
|
||||
case PR_MISC:
|
||||
printf ("misc\n");
|
||||
break;
|
||||
case PR_NUM:
|
||||
printf ("num sense=%d case sensitive=%d\n", qt->data.str.sense, qt->data.str.case_sens);
|
||||
printf ("num sense=%d case sensitive=%d\n", qt->data.str.sense,
|
||||
qt->data.str.case_sens);
|
||||
printf ("\tmatch string=%s \n", qt->data.str.matchstring);
|
||||
break;
|
||||
case PR_PRICE:
|
||||
printf ("price sense=%d how=%d\n", qt->data.amount.sense, qt->data.amount.how);
|
||||
printf ("\tsign=%d amount=%f\n", qt->data.amount.amt_sgn, qt->data.amount.amount);
|
||||
printf ("price sense=%d how=%d\n", qt->data.amount.sense,
|
||||
qt->data.amount.how);
|
||||
printf ("\tsign=%d amount=%f\n", qt->data.amount.amt_sgn,
|
||||
qt->data.amount.amount);
|
||||
break;
|
||||
case PR_SHRS:
|
||||
printf ("shrs sense=%d how=%d\n", qt->data.amount.sense, qt->data.amount.how);
|
||||
printf ("\tsign=%d amount=%f\n", qt->data.amount.amt_sgn, qt->data.amount.amount);
|
||||
printf ("shrs sense=%d how=%d\n", qt->data.amount.sense,
|
||||
qt->data.amount.how);
|
||||
printf ("\tsign=%d amount=%f\n", qt->data.amount.amt_sgn,
|
||||
qt->data.amount.amount);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -376,6 +407,13 @@ free_query_term(QueryTerm *qt)
|
||||
qt->data.acct.account_guids = NULL;
|
||||
break;
|
||||
|
||||
case PD_KVP:
|
||||
g_slist_free (qt->data.kvp.path);
|
||||
qt->data.kvp.path = NULL;
|
||||
kvp_value_delete (qt->data.kvp.value);
|
||||
qt->data.kvp.value = NULL;
|
||||
break;
|
||||
|
||||
case PD_STRING:
|
||||
g_free(qt->data.str.matchstring);
|
||||
qt->data.str.matchstring = NULL;
|
||||
@@ -416,6 +454,18 @@ copy_query_term(QueryTerm * qt) {
|
||||
}
|
||||
break;
|
||||
|
||||
case PD_KVP: {
|
||||
GSList *node;
|
||||
|
||||
nqt->data.kvp.path = g_slist_copy (nqt->data.kvp.path);
|
||||
nqt->data.kvp.value = kvp_value_copy (nqt->data.kvp.value);
|
||||
|
||||
for (node = nqt->data.kvp.path; node; node = node->next)
|
||||
node->data = g_strdup (node->data);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PD_STRING:
|
||||
nqt->data.str.matchstring = g_strdup(nqt->data.str.matchstring);
|
||||
break;
|
||||
@@ -1377,6 +1427,25 @@ xaccQueryTermEqual (QueryTerm *qt1, QueryTerm *qt2)
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case PD_KVP: {
|
||||
GSList *n1, *n2;
|
||||
|
||||
n1 = qt1->data.kvp.path;
|
||||
n2 = qt2->data.kvp.path;
|
||||
|
||||
for ( ; n1 && n2; n1 = n1->next, n2 = n2->next)
|
||||
if (!safe_strcmp (n1->data, n2->data))
|
||||
return FALSE;
|
||||
|
||||
if (n1 || n2)
|
||||
return FALSE;
|
||||
|
||||
if (kvp_value_compare (qt1->data.kvp.value, qt2->data.kvp.value) != 0)
|
||||
return FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PD_MISC:
|
||||
if (qt1->data.misc.how != qt2->data.misc.how) return FALSE;
|
||||
if (qt1->data.misc.data != qt2->data.misc.data) return FALSE;
|
||||
@@ -1463,6 +1532,9 @@ xaccQueryGetPredicate (pr_type_t term_type)
|
||||
case PR_GUID:
|
||||
p = & xaccGUIDMatchPredicate;
|
||||
break;
|
||||
case PR_KVP:
|
||||
p = & xaccKVPMatchPredicate;
|
||||
break;
|
||||
case PR_MEMO:
|
||||
p = & xaccMemoMatchPredicate;
|
||||
break;
|
||||
@@ -2160,6 +2232,46 @@ xaccQueryAddGUIDMatch(Query * q, const GUID *guid, QueryOp op)
|
||||
xaccFreeQuery(qr);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* xaccQueryAddKVPMatch
|
||||
* Add a 'kvp' filter to an existing query.
|
||||
********************************************************************/
|
||||
|
||||
void
|
||||
xaccQueryAddKVPMatch(Query *q, GSList *path, const kvp_value *value,
|
||||
kvp_match_t how, kvp_match_where_t where, QueryOp op)
|
||||
{
|
||||
Query * qs = xaccMallocQuery();
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
GSList * node;
|
||||
|
||||
qt->p = &xaccKVPMatchPredicate;
|
||||
qt->data.type = PD_KVP;
|
||||
qt->data.base.term_type = PR_KVP;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.kvp.how = how;
|
||||
qt->data.kvp.where = where;
|
||||
qt->data.kvp.path = g_slist_copy (path);
|
||||
qt->data.kvp.value = kvp_value_copy (value);
|
||||
|
||||
for (node = qt->data.kvp.path; node; node = node->next)
|
||||
node->data = g_strdup (node->data);
|
||||
|
||||
xaccInitQuery(qs, qt);
|
||||
xaccQuerySetGroup(qs, q->acct_group);
|
||||
|
||||
if(xaccQueryHasTerms(q)) {
|
||||
qr = xaccQueryMerge(q, qs, op);
|
||||
}
|
||||
else {
|
||||
qr = xaccQueryMerge(q, qs, QUERY_OR);
|
||||
}
|
||||
xaccQuerySwapTerms(q, qr);
|
||||
xaccFreeQuery(qs);
|
||||
xaccFreeQuery(qr);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* xaccQueryPurgeTerms
|
||||
* delete any terms of a particular type
|
||||
@@ -2353,7 +2465,6 @@ xaccDescriptionMatchPredicate(Split * s, PredicateData * pd) {
|
||||
static int
|
||||
xaccGUIDMatchPredicate(Split * s, PredicateData * pd)
|
||||
{
|
||||
GUIDPredicateData *gpd;
|
||||
GUID *guid;
|
||||
|
||||
g_return_val_if_fail (s, 0);
|
||||
@@ -2382,6 +2493,85 @@ xaccGUIDMatchPredicate(Split * s, PredicateData * pd)
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* xaccKVPMatchPredicate
|
||||
*******************************************************************/
|
||||
static int
|
||||
kvp_match_helper (GSList *path, kvp_value *value, kvp_match_t how,
|
||||
kvp_frame *frame)
|
||||
{
|
||||
kvp_value *value_2;
|
||||
int compare;
|
||||
|
||||
if (!path || !value || !frame || !how) return 0;
|
||||
|
||||
value_2 = kvp_frame_get_slot_path_gslist (frame, path);
|
||||
if (!value_2)
|
||||
return 0;
|
||||
|
||||
if (kvp_value_get_type (value) != kvp_value_get_type (value_2))
|
||||
return 0;
|
||||
|
||||
compare = kvp_value_compare (value_2, value);
|
||||
|
||||
switch (how)
|
||||
{
|
||||
case KVP_MATCH_LT:
|
||||
return (compare < 0);
|
||||
case KVP_MATCH_LTE:
|
||||
return (compare <= 0);
|
||||
case KVP_MATCH_EQ:
|
||||
return (compare == 0);
|
||||
case KVP_MATCH_GTE:
|
||||
return (compare >= 0);
|
||||
case KVP_MATCH_GT:
|
||||
return (compare > 0);
|
||||
default:
|
||||
PWARN ("bad match type: %d", how);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
xaccKVPMatchPredicate(Split * s, PredicateData * pd)
|
||||
{
|
||||
KVPPredicateData *kpd;
|
||||
|
||||
g_return_val_if_fail (s, FALSE);
|
||||
g_return_val_if_fail (pd, FALSE);
|
||||
g_return_val_if_fail (pd->type == PD_KVP, FALSE);
|
||||
|
||||
kpd = &pd->kvp;
|
||||
|
||||
if (kpd->where && KVP_MATCH_SPLIT)
|
||||
{
|
||||
kvp_frame *frame = xaccSplitGetSlots (s);
|
||||
|
||||
if (kvp_match_helper (kpd->path, kpd->value, kpd->how, frame))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (kpd->where && KVP_MATCH_TRANS)
|
||||
{
|
||||
Transaction *trans = xaccSplitGetParent (s);
|
||||
kvp_frame *frame = xaccTransGetSlots (trans);
|
||||
|
||||
if (kvp_match_helper (kpd->path, kpd->value, kpd->how, frame))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (kpd->where && KVP_MATCH_ACCOUNT)
|
||||
{
|
||||
Account *account = xaccSplitGetAccount (s);
|
||||
kvp_frame *frame = xaccAccountGetSlots (account);
|
||||
|
||||
if (kvp_match_helper (kpd->path, kpd->value, kpd->how, frame))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* xaccNumberMatchPredicate
|
||||
*******************************************************************/
|
||||
@@ -2471,9 +2661,6 @@ xaccSharePriceMatchPredicate(Split * s, PredicateData * pd) {
|
||||
acct = xaccSplitGetAccount(s);
|
||||
type = xaccAccountGetType(acct);
|
||||
|
||||
if((type != STOCK) && (type != MUTUAL)) {
|
||||
return 0;
|
||||
}
|
||||
splitamt = DxaccSplitGetSharePrice(s);
|
||||
|
||||
return value_match_predicate(splitamt, pd);
|
||||
@@ -2495,10 +2682,6 @@ xaccSharesMatchPredicate(Split * s, PredicateData * pd) {
|
||||
acct = xaccSplitGetAccount(s);
|
||||
type = xaccAccountGetType(acct);
|
||||
|
||||
if((type != STOCK) && (type != MUTUAL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
splitamt = DxaccSplitGetShareAmount(s);
|
||||
|
||||
return value_match_predicate(splitamt, pd);
|
||||
|
||||
@@ -67,6 +67,7 @@ typedef enum {
|
||||
PD_CLEARED,
|
||||
PD_BALANCE,
|
||||
PD_GUID,
|
||||
PD_KVP,
|
||||
PD_MISC
|
||||
} pd_type_t;
|
||||
|
||||
@@ -79,6 +80,7 @@ typedef enum {
|
||||
PR_DATE,
|
||||
PR_DESC,
|
||||
PR_GUID,
|
||||
PR_KVP,
|
||||
PR_MEMO,
|
||||
PR_MISC,
|
||||
PR_NUM,
|
||||
@@ -123,6 +125,20 @@ typedef enum {
|
||||
BALANCE_UNBALANCED = 1 << 1
|
||||
} balance_match_t;
|
||||
|
||||
typedef enum {
|
||||
KVP_MATCH_LT=1,
|
||||
KVP_MATCH_LTE,
|
||||
KVP_MATCH_EQ,
|
||||
KVP_MATCH_GTE,
|
||||
KVP_MATCH_GT
|
||||
} kvp_match_t;
|
||||
|
||||
typedef enum {
|
||||
KVP_MATCH_SPLIT = 1 << 0,
|
||||
KVP_MATCH_TRANS = 1 << 1,
|
||||
KVP_MATCH_ACCOUNT = 1 << 2
|
||||
} kvp_match_where_t;
|
||||
|
||||
/* query_run_t describes whether to require all splits or
|
||||
* any to match for a transaction to be returned by
|
||||
* xaccQueryGetTransactions */
|
||||
@@ -199,6 +215,16 @@ typedef struct {
|
||||
GUID guid;
|
||||
} GUIDPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
kvp_match_t how;
|
||||
kvp_match_where_t where;
|
||||
GSList *path;
|
||||
kvp_value *value;
|
||||
} KVPPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
@@ -217,6 +243,7 @@ typedef union {
|
||||
ClearedPredicateData cleared;
|
||||
BalancePredicateData balance;
|
||||
GUIDPredicateData guid;
|
||||
KVPPredicateData kvp;
|
||||
MiscPredicateData misc;
|
||||
} PredicateData;
|
||||
|
||||
@@ -307,6 +334,10 @@ void xaccQueryAddMemoMatch(Query * q, const char * matchstring,
|
||||
void xaccQueryAddClearedMatch(Query * q, cleared_match_t how, QueryOp op);
|
||||
void xaccQueryAddBalanceMatch(Query * q, balance_match_t how, QueryOp op);
|
||||
void xaccQueryAddGUIDMatch(Query * q, const GUID *guid, QueryOp op);
|
||||
/* given kvp value is on right side of comparison */
|
||||
void xaccQueryAddKVPMatch(Query *q, GSList *path, const kvp_value *value,
|
||||
kvp_match_t how, kvp_match_where_t where,
|
||||
QueryOp op);
|
||||
void xaccQueryAddMiscMatch(Query * q, Predicate p, int how, int data,
|
||||
QueryOp op);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ TESTS = \
|
||||
test-commodities \
|
||||
test-freq-spec \
|
||||
test-group-vs-book \
|
||||
test-query \
|
||||
test-resolve-file-path \
|
||||
test-scm-query \
|
||||
test-split-vs-account \
|
||||
@@ -39,6 +40,7 @@ noinst_PROGRAMS = \
|
||||
test-freq-spec \
|
||||
test-group-vs-book \
|
||||
test-load-engine \
|
||||
test-query \
|
||||
test-resolve-file-path \
|
||||
test-scm-query \
|
||||
test-split-vs-account \
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <guile/gh.h>
|
||||
|
||||
#include "GNCIdP.h"
|
||||
#include "TransLog.h"
|
||||
#include "gnc-book.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-module.h"
|
||||
@@ -145,6 +146,8 @@ main_helper (int argc, char **argv)
|
||||
|
||||
gnc_module_load("gnucash/engine", 0);
|
||||
|
||||
xaccLogDisable ();
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
run_test ();
|
||||
|
||||
|
||||
202
src/engine/test/test-query.c
Normal file
202
src/engine/test/test-query.c
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <guile/gh.h>
|
||||
|
||||
#include "TransLog.h"
|
||||
#include "Transaction.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-module.h"
|
||||
#include "gnc-session.h"
|
||||
#include "test-engine-stuff.h"
|
||||
#include "test-stuff.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
kvp_match_where_t where;
|
||||
GSList *path;
|
||||
Query *q;
|
||||
} KVPQueryData;
|
||||
|
||||
static void
|
||||
add_kvp_value_query (const char *key, kvp_value *value, gpointer data)
|
||||
{
|
||||
KVPQueryData *kqd = data;
|
||||
GSList *node;
|
||||
|
||||
kqd->path = g_slist_append (kqd->path, (gpointer) key);
|
||||
|
||||
if (kvp_value_get_type (value) == KVP_TYPE_FRAME)
|
||||
kvp_frame_for_each_slot (kvp_value_get_frame (value),
|
||||
add_kvp_value_query, data);
|
||||
else
|
||||
xaccQueryAddKVPMatch (kqd->q, kqd->path, value,
|
||||
KVP_MATCH_EQ, kqd->where,
|
||||
QUERY_AND);
|
||||
|
||||
node = g_slist_last (kqd->path);
|
||||
kqd->path = g_slist_remove_link (kqd->path, node);
|
||||
g_slist_free_1 (node);
|
||||
}
|
||||
|
||||
static void
|
||||
add_kvp_query (Query *q, kvp_frame *frame, kvp_match_where_t where)
|
||||
{
|
||||
KVPQueryData kqd;
|
||||
|
||||
kqd.where = where;
|
||||
kqd.path = NULL;
|
||||
kqd.q = q;
|
||||
|
||||
kvp_frame_for_each_slot (frame, add_kvp_value_query, &kqd);
|
||||
}
|
||||
|
||||
static Query *
|
||||
make_trans_query (Transaction *trans)
|
||||
{
|
||||
Account *a;
|
||||
double d;
|
||||
Query *q;
|
||||
Split *s;
|
||||
|
||||
q = xaccMallocQuery ();
|
||||
|
||||
s = xaccTransGetSplit (trans, 0);
|
||||
a = xaccSplitGetAccount (s);
|
||||
|
||||
xaccQueryAddSingleAccountMatch (q, xaccSplitGetAccount (s), QUERY_AND);
|
||||
|
||||
xaccQueryAddDescriptionMatch (q, xaccTransGetDescription (trans),
|
||||
TRUE, FALSE, QUERY_AND);
|
||||
|
||||
xaccQueryAddNumberMatch (q, xaccTransGetNum (trans), TRUE, FALSE, QUERY_AND);
|
||||
|
||||
xaccQueryAddActionMatch (q, xaccSplitGetAction (s), TRUE, FALSE, QUERY_AND);
|
||||
|
||||
d = gnc_numeric_to_double (xaccSplitGetValue (s));
|
||||
DxaccQueryAddAmountMatch (q, d, AMT_SGN_MATCH_EITHER,
|
||||
AMT_MATCH_EXACTLY, QUERY_AND);
|
||||
|
||||
d = gnc_numeric_to_double (xaccSplitGetSharePrice (s));
|
||||
DxaccQueryAddSharePriceMatch (q, d, AMT_MATCH_EXACTLY, QUERY_AND);
|
||||
|
||||
d = gnc_numeric_to_double (xaccSplitGetAmount (s));
|
||||
DxaccQueryAddSharesMatch (q, d, AMT_MATCH_EXACTLY, QUERY_AND);
|
||||
|
||||
{
|
||||
Timespec ts;
|
||||
|
||||
xaccTransGetDatePostedTS (trans, &ts);
|
||||
xaccQueryAddDateMatchTS (q, TRUE, ts, TRUE, ts, QUERY_AND);
|
||||
}
|
||||
|
||||
xaccQueryAddMemoMatch (q, xaccSplitGetMemo (s), TRUE, FALSE, QUERY_AND);
|
||||
|
||||
{
|
||||
cleared_match_t how;
|
||||
|
||||
switch (xaccSplitGetReconcile (s))
|
||||
{
|
||||
case NREC:
|
||||
how = CLEARED_NO;
|
||||
break;
|
||||
case CREC:
|
||||
how = CLEARED_CLEARED;
|
||||
break;
|
||||
case YREC:
|
||||
how = CLEARED_RECONCILED;
|
||||
break;
|
||||
case FREC:
|
||||
how = CLEARED_FROZEN;
|
||||
break;
|
||||
case VREC:
|
||||
how = CLEARED_VOIDED;
|
||||
break;
|
||||
default:
|
||||
failure ("bad reconcile flag");
|
||||
xaccFreeQuery (q);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xaccQueryAddClearedMatch (q, how, QUERY_AND);
|
||||
}
|
||||
|
||||
add_kvp_query (q, xaccSplitGetSlots (s), KVP_MATCH_SPLIT);
|
||||
add_kvp_query (q, xaccTransGetSlots (trans), KVP_MATCH_TRANS);
|
||||
add_kvp_query (q, xaccAccountGetSlots (a), KVP_MATCH_ACCOUNT);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_trans_query (Transaction *trans, gpointer data)
|
||||
{
|
||||
GNCSession *session = data;
|
||||
AccountGroup *group;
|
||||
GNCBook *book;
|
||||
GList *list;
|
||||
Query *q;
|
||||
|
||||
book = gnc_session_get_book (session);
|
||||
group = gnc_book_get_group (book);
|
||||
|
||||
q = make_trans_query (trans);
|
||||
xaccQuerySetGroup (q, group);
|
||||
|
||||
list = xaccQueryGetTransactions (q, QUERY_MATCH_ANY);
|
||||
if (g_list_length (list) != 1)
|
||||
{
|
||||
failure ("number of matching transactions not 1");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (list->data != trans)
|
||||
{
|
||||
failure ("matching transaction is wrong");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
success ("found right transaction");
|
||||
xaccFreeQuery (q);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
GNCSession *session;
|
||||
AccountGroup *group;
|
||||
GNCBook *book;
|
||||
|
||||
session = get_random_session ();
|
||||
book = gnc_session_get_book (session);
|
||||
group = gnc_book_get_group (book);
|
||||
|
||||
add_random_transactions_to_session (session, 20);
|
||||
|
||||
xaccGroupForEachTransaction (group, test_trans_query, session);
|
||||
|
||||
gnc_session_destroy (session);
|
||||
}
|
||||
|
||||
static void
|
||||
main_helper (int argc, char **argv)
|
||||
{
|
||||
gnc_module_load("gnucash/engine", 0);
|
||||
|
||||
xaccLogDisable ();
|
||||
|
||||
run_test ();
|
||||
|
||||
success("queries seem to work");
|
||||
|
||||
print_test_results();
|
||||
exit(get_rv());
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gh_enter (argc, argv, main_helper);
|
||||
return 0;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "test-engine-stuff.h"
|
||||
#include "test-stuff.h"
|
||||
#include "Query.h"
|
||||
#include "TransLog.h"
|
||||
|
||||
|
||||
static void
|
||||
@@ -59,6 +60,9 @@ static void
|
||||
main_helper (int argc, char **argv)
|
||||
{
|
||||
gnc_module_load("gnucash/engine", 0);
|
||||
|
||||
xaccLogDisable ();
|
||||
|
||||
run_tests ();
|
||||
|
||||
print_test_results ();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "GNCIdP.h"
|
||||
|
||||
#include "Account.h"
|
||||
#include "TransLog.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-module.h"
|
||||
#include "gnc-session.h"
|
||||
@@ -106,6 +107,8 @@ main_helper (int argc, char **argv)
|
||||
{
|
||||
gnc_module_load("gnucash/engine", 0);
|
||||
|
||||
xaccLogDisable ();
|
||||
|
||||
run_test ();
|
||||
|
||||
success("split account crap seems to work");
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "GNCIdP.h"
|
||||
|
||||
#include "Account.h"
|
||||
#include "TransLog.h"
|
||||
#include "Transaction.h"
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-module.h"
|
||||
@@ -124,6 +125,8 @@ main_helper (int argc, char **argv)
|
||||
{
|
||||
gnc_module_load("gnucash/engine", 0);
|
||||
|
||||
xaccLogDisable ();
|
||||
|
||||
run_test ();
|
||||
|
||||
success("transaction voiding seems OK");
|
||||
|
||||
Reference in New Issue
Block a user