mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
OK, with this patch, the save & restore of the date query works.
What remains is to implement the other query terms, and sort order. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3408 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
#include "Group.h"
|
||||
#include "Query.h"
|
||||
|
||||
/* static short module = MOD_QUERY; */
|
||||
static short module = MOD_QUERY;
|
||||
|
||||
/* the Query makes a subset of all splits based on 3 things:
|
||||
* - an AND-OR tree of predicates which combine to make a
|
||||
@@ -73,16 +73,16 @@ struct _querystruct {
|
||||
*******************************************************************/
|
||||
|
||||
static int xaccAccountMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccDescriptionMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccActionMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccNumberMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccAmountMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccBalanceMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccClearedMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccDateMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccDescriptionMatchPredicate(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);
|
||||
static int xaccSharesMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccClearedMatchPredicate(Split * s, PredicateData * pd);
|
||||
static int xaccBalanceMatchPredicate(Split * s, PredicateData * pd);
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
@@ -95,12 +95,14 @@ xaccQueryPrint(Query * q)
|
||||
QueryTerm * qt;
|
||||
|
||||
printf("Query: max splits = %d\n", q->max_splits);
|
||||
|
||||
/* print and & or terms */
|
||||
for(i=q->terms; i; i=i->next) {
|
||||
aterms = i->data;
|
||||
printf("(");
|
||||
for(j=aterms; j; j=j->next) {
|
||||
qt = (QueryTerm *)j->data;
|
||||
if(!qt->sense) printf("~");
|
||||
if(!qt->data.base.sense) printf("~");
|
||||
printf("%d ", qt->data.type);
|
||||
}
|
||||
printf(")");
|
||||
@@ -109,6 +111,31 @@ xaccQueryPrint(Query * q)
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* print the node contents */
|
||||
for(i=q->terms; i; i=i->next) {
|
||||
aterms = i->data;
|
||||
printf("aterm=%p\n", aterms);
|
||||
for(j=aterms; j; j=j->next) {
|
||||
qt = (QueryTerm *)j->data;
|
||||
switch (qt->data.base.term_type)
|
||||
{
|
||||
case PR_DATE:
|
||||
printf ("date sense=%d use_start=%d use_end=%d\n",
|
||||
qt->data.base.sense,
|
||||
qt->data.date.use_start,
|
||||
qt->data.date.use_end
|
||||
);
|
||||
break;
|
||||
default:
|
||||
printf ("other\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
if(i->next) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -424,7 +451,7 @@ xaccQueryInvert(Query * q) {
|
||||
new_oterm = NULL;
|
||||
for(cur=aterms; cur; cur=cur->next) {
|
||||
qt = copy_query_term(cur->data);
|
||||
qt->sense = !(qt->sense);
|
||||
qt->data.base.sense = !(qt->data.base.sense);
|
||||
new_oterm = g_list_append(NULL, qt);
|
||||
retval->terms = g_list_append(retval->terms, new_oterm);
|
||||
}
|
||||
@@ -830,7 +857,7 @@ xaccQueryCheckSplit(Query * q, Split * s) {
|
||||
and_terms_ok = 1;
|
||||
for(and_ptr = or_ptr->data; and_ptr; and_ptr = and_ptr->next) {
|
||||
qt = (QueryTerm *)(and_ptr->data);
|
||||
if(((qt->p)(s, &(qt->data))) != qt->sense) {
|
||||
if(((qt->p)(s, &(qt->data))) != qt->data.base.sense) {
|
||||
and_terms_ok = 0;
|
||||
break;
|
||||
}
|
||||
@@ -1055,10 +1082,8 @@ xaccQueryGetSplits(Query * q) {
|
||||
* Add a predicate an existing query.
|
||||
********************************************************************/
|
||||
|
||||
/* hack alert -- this is atemproray API */
|
||||
void
|
||||
xaccQueryAddPredicate (Query * q,
|
||||
int snes,
|
||||
PredicateData *pred,
|
||||
QueryOp op)
|
||||
{
|
||||
@@ -1066,37 +1091,50 @@ xaccQueryAddPredicate (Query * q,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->sense = snes;
|
||||
qt->data = *pred;
|
||||
|
||||
/* hack alert this switch stement is clearly wrong !!!!! */
|
||||
switch (pred->type) {
|
||||
case PD_DATE:
|
||||
qt->p = & xaccDateMatchPredicate;
|
||||
break;
|
||||
case PD_AMOUNT:
|
||||
qt->p = & xaccAmountMatchPredicate;
|
||||
qt->p = & xaccSharePriceMatchPredicate;
|
||||
qt->p = & xaccSharesMatchPredicate;
|
||||
break;
|
||||
case PD_ACCOUNT:
|
||||
/* the predicates are only known in the local
|
||||
* address space, which is why we have to set them
|
||||
* from the abstract type here.
|
||||
*/
|
||||
switch (pred->base.term_type)
|
||||
{
|
||||
case PR_ACCOUNT:
|
||||
qt->p = & xaccAccountMatchPredicate;
|
||||
break;
|
||||
case PD_STRING:
|
||||
qt->p = & xaccDescriptionMatchPredicate;
|
||||
qt->p = & xaccMemoMatchPredicate;
|
||||
qt->p = & xaccNumberMatchPredicate;
|
||||
case PR_ACTION:
|
||||
qt->p = & xaccActionMatchPredicate;
|
||||
break;
|
||||
case PD_CLEARED:
|
||||
qt->p = & xaccClearedMatchPredicate;
|
||||
case PR_AMOUNT:
|
||||
qt->p = & xaccAmountMatchPredicate;
|
||||
break;
|
||||
case PD_BALANCE:
|
||||
case PR_BALANCE:
|
||||
qt->p = & xaccBalanceMatchPredicate;
|
||||
break;
|
||||
case PD_MISC:
|
||||
case PR_CLEARED:
|
||||
qt->p = & xaccClearedMatchPredicate;
|
||||
break;
|
||||
case PR_DATE:
|
||||
qt->p = & xaccDateMatchPredicate;
|
||||
break;
|
||||
case PR_DESC:
|
||||
qt->p = & xaccDescriptionMatchPredicate;
|
||||
break;
|
||||
case PR_MEMO:
|
||||
qt->p = & xaccMemoMatchPredicate;
|
||||
break;
|
||||
case PR_NUM:
|
||||
qt->p = & xaccNumberMatchPredicate;
|
||||
break;
|
||||
case PR_PRICE:
|
||||
qt->p = & xaccSharePriceMatchPredicate;
|
||||
break;
|
||||
case PR_SHRS:
|
||||
qt->p = & xaccSharesMatchPredicate;
|
||||
break;
|
||||
case PR_MISC:
|
||||
PERR ("misc term must not appear");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
xaccInitQuery(qs, qt);
|
||||
@@ -1125,9 +1163,10 @@ xaccQueryAddAccountMatch(Query * q, GList * accounts, acct_match_t how,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = & xaccAccountMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccAccountMatchPredicate;
|
||||
qt->data.type = PD_ACCOUNT;
|
||||
qt->data.base.term_type = PR_ACCOUNT;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.acct.how = how;
|
||||
qt->data.acct.accounts = NULL;
|
||||
qt->data.acct.account_guids = account_list_to_guid_list (accounts);
|
||||
@@ -1160,9 +1199,10 @@ xaccQueryAddSingleAccountMatch(Query * q, Account * acct,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = & xaccAccountMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccAccountMatchPredicate;
|
||||
qt->data.type = PD_ACCOUNT;
|
||||
qt->data.base.term_type = PR_ACCOUNT;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.acct.how = ACCT_MATCH_ANY;
|
||||
qt->data.acct.accounts = g_list_prepend(NULL, acct);
|
||||
qt->data.acct.account_guids
|
||||
@@ -1197,9 +1237,10 @@ xaccQueryAddDescriptionMatch(Query * q, const char * matchstring,
|
||||
Query * qr;
|
||||
int flags = REG_EXTENDED;
|
||||
|
||||
qt->p = & xaccDescriptionMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccDescriptionMatchPredicate;
|
||||
qt->data.type = PD_STRING;
|
||||
qt->data.base.term_type = PR_DESC;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.str.case_sens = case_sens;
|
||||
qt->data.str.use_regexp = use_regexp;
|
||||
qt->data.str.matchstring = g_strdup(matchstring);
|
||||
@@ -1249,9 +1290,10 @@ xaccQueryAddMemoMatch(Query * q, const char * matchstring,
|
||||
Query * qr;
|
||||
int flags = REG_EXTENDED;
|
||||
|
||||
qt->p = & xaccMemoMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccMemoMatchPredicate;
|
||||
qt->data.type = PD_STRING;
|
||||
qt->data.base.term_type = PR_MEMO;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.str.case_sens = case_sens;
|
||||
qt->data.str.use_regexp = use_regexp;
|
||||
qt->data.str.matchstring = g_strdup(matchstring);
|
||||
@@ -1303,9 +1345,10 @@ xaccQueryAddDateMatchTS(Query * q,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = & xaccDateMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccDateMatchPredicate;
|
||||
qt->data.type = PD_DATE;
|
||||
qt->data.base.term_type = PR_DATE;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.date.use_start = use_start;
|
||||
qt->data.date.use_end = use_end;
|
||||
qt->data.date.start = sts;
|
||||
@@ -1385,9 +1428,10 @@ xaccQueryAddNumberMatch(Query * q, const char * matchstring, int case_sens,
|
||||
Query * qr;
|
||||
int flags = REG_EXTENDED;
|
||||
|
||||
qt->p = & xaccNumberMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccNumberMatchPredicate;
|
||||
qt->data.type = PD_STRING;
|
||||
qt->data.base.term_type = PR_NUM;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.str.case_sens = case_sens;
|
||||
qt->data.str.use_regexp = use_regexp;
|
||||
qt->data.str.matchstring = g_strdup(matchstring);
|
||||
@@ -1436,9 +1480,10 @@ xaccQueryAddActionMatch(Query * q, const char * matchstring, int case_sens,
|
||||
Query * qr;
|
||||
int flags = REG_EXTENDED;
|
||||
|
||||
qt->p = & xaccActionMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccActionMatchPredicate;
|
||||
qt->data.type = PD_STRING;
|
||||
qt->data.base.term_type = PR_ACTION;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.str.case_sens = case_sens;
|
||||
qt->data.str.use_regexp = use_regexp;
|
||||
qt->data.str.matchstring = g_strdup(matchstring);
|
||||
@@ -1490,9 +1535,10 @@ DxaccQueryAddAmountMatch(Query * q, double amt,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = & xaccAmountMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccAmountMatchPredicate;
|
||||
qt->data.type = PD_AMOUNT;
|
||||
qt->data.base.term_type = PR_AMOUNT;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.amount.how = how;
|
||||
qt->data.amount.amt_sgn = amt_sgn;
|
||||
qt->data.amount.amount = amt;
|
||||
@@ -1526,9 +1572,10 @@ DxaccQueryAddSharePriceMatch(Query * q, double amt,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = & xaccSharePriceMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccSharePriceMatchPredicate;
|
||||
qt->data.type = PD_AMOUNT;
|
||||
qt->data.base.term_type = PR_PRICE;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.amount.how = how;
|
||||
qt->data.amount.amt_sgn = 0;
|
||||
qt->data.amount.amount = amt;
|
||||
@@ -1562,9 +1609,10 @@ DxaccQueryAddSharesMatch(Query * q, double amt,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = & xaccSharesMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->p = & xaccSharesMatchPredicate;
|
||||
qt->data.type = PD_AMOUNT;
|
||||
qt->data.base.term_type = PR_SHRS;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.amount.how = how;
|
||||
qt->data.amount.amt_sgn = 0;
|
||||
qt->data.amount.amount = amt;
|
||||
@@ -1597,9 +1645,10 @@ xaccQueryAddMiscMatch(Query * q, Predicate p, int how, int data,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = p;
|
||||
qt->sense = 1;
|
||||
qt->p = p;
|
||||
qt->data.type = PD_MISC;
|
||||
qt->data.base.term_type = PR_MISC;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.misc.how = how;
|
||||
qt->data.misc.data = data;
|
||||
|
||||
@@ -1630,10 +1679,11 @@ xaccQueryAddClearedMatch(Query * q, cleared_match_t how,
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = & xaccClearedMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->data.type = PD_CLEARED;
|
||||
qt->data.cleared.how = how;
|
||||
qt->p = & xaccClearedMatchPredicate;
|
||||
qt->data.type = PD_CLEARED;
|
||||
qt->data.base.term_type = PR_CLEARED;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.cleared.how = how;
|
||||
|
||||
xaccInitQuery(qs, qt);
|
||||
xaccQuerySetGroup(qs, q->acct_group);
|
||||
@@ -1661,10 +1711,11 @@ xaccQueryAddBalanceMatch(Query * q, balance_match_t how, QueryOp op)
|
||||
QueryTerm * qt = g_new0(QueryTerm, 1);
|
||||
Query * qr;
|
||||
|
||||
qt->p = & xaccBalanceMatchPredicate;
|
||||
qt->sense = 1;
|
||||
qt->data.type = PD_BALANCE;
|
||||
qt->data.balance.how = how;
|
||||
qt->p = & xaccBalanceMatchPredicate;
|
||||
qt->data.type = PD_BALANCE;
|
||||
qt->data.base.term_type = PR_BALANCE;
|
||||
qt->data.base.sense = 1;
|
||||
qt->data.balance.how = how;
|
||||
|
||||
xaccInitQuery(qs, qt);
|
||||
xaccQuerySetGroup(qs, q->acct_group);
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "Transaction.h"
|
||||
|
||||
typedef enum {
|
||||
QUERY_AND,
|
||||
QUERY_AND=1,
|
||||
QUERY_OR,
|
||||
QUERY_NAND,
|
||||
QUERY_NOR,
|
||||
@@ -41,7 +41,7 @@ typedef enum {
|
||||
} QueryOp;
|
||||
|
||||
typedef enum {
|
||||
BY_STANDARD,
|
||||
BY_STANDARD=1,
|
||||
BY_DATE,
|
||||
BY_DATE_ENTERED,
|
||||
BY_DATE_RECONCILED,
|
||||
@@ -54,7 +54,7 @@ typedef enum {
|
||||
} sort_type_t;
|
||||
|
||||
typedef enum {
|
||||
PD_DATE,
|
||||
PD_DATE=1,
|
||||
PD_AMOUNT,
|
||||
PD_ACCOUNT,
|
||||
PD_STRING,
|
||||
@@ -64,20 +64,35 @@ typedef enum {
|
||||
} pd_type_t;
|
||||
|
||||
typedef enum {
|
||||
ACCT_MATCH_ALL,
|
||||
PR_ACCOUNT=1,
|
||||
PR_ACTION,
|
||||
PR_AMOUNT,
|
||||
PR_BALANCE,
|
||||
PR_CLEARED,
|
||||
PR_DATE,
|
||||
PR_DESC,
|
||||
PR_MEMO,
|
||||
PR_MISC,
|
||||
PR_NUM,
|
||||
PR_PRICE,
|
||||
PR_SHRS
|
||||
} pr_type_t;
|
||||
|
||||
typedef enum {
|
||||
ACCT_MATCH_ALL=1,
|
||||
ACCT_MATCH_ANY,
|
||||
ACCT_MATCH_NONE
|
||||
} acct_match_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AMT_MATCH_ATLEAST,
|
||||
AMT_MATCH_ATLEAST=1,
|
||||
AMT_MATCH_ATMOST,
|
||||
AMT_MATCH_EXACTLY
|
||||
} amt_match_t;
|
||||
|
||||
typedef enum {
|
||||
AMT_SGN_MATCH_EITHER,
|
||||
AMT_SGN_MATCH_EITHER=1,
|
||||
AMT_SGN_MATCH_CREDIT,
|
||||
AMT_SGN_MATCH_DEBIT
|
||||
} amt_match_sgn_t;
|
||||
@@ -102,53 +117,74 @@ typedef enum {
|
||||
typedef struct _querystruct Query;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
int use_start;
|
||||
Timespec start;
|
||||
int use_end;
|
||||
Timespec end;
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
} BasePredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int use_start;
|
||||
Timespec start;
|
||||
int use_end;
|
||||
Timespec end;
|
||||
} DatePredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
amt_match_t how;
|
||||
amt_match_sgn_t amt_sgn;
|
||||
double amount;
|
||||
} AmountPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
acct_match_t how;
|
||||
GList * accounts;
|
||||
GList * account_guids;
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
acct_match_t how;
|
||||
GList *accounts;
|
||||
GList *account_guids;
|
||||
} AccountPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
int case_sens;
|
||||
int use_regexp;
|
||||
char * matchstring;
|
||||
regex_t compiled;
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int case_sens;
|
||||
int use_regexp;
|
||||
char *matchstring;
|
||||
regex_t compiled;
|
||||
} StringPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
cleared_match_t how;
|
||||
} ClearedPredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
balance_match_t how;
|
||||
} BalancePredicateData;
|
||||
|
||||
typedef struct {
|
||||
pd_type_t type;
|
||||
int how;
|
||||
int data;
|
||||
pd_type_t type;
|
||||
pr_type_t term_type;
|
||||
int sense;
|
||||
int how;
|
||||
int data;
|
||||
} MiscPredicateData;
|
||||
|
||||
typedef union {
|
||||
pd_type_t type;
|
||||
BasePredicateData base;
|
||||
DatePredicateData date;
|
||||
AmountPredicateData amount;
|
||||
AccountPredicateData acct;
|
||||
@@ -161,9 +197,8 @@ typedef union {
|
||||
typedef int (* Predicate)(Split * to_test, PredicateData * test_data);
|
||||
|
||||
typedef struct {
|
||||
Predicate p;
|
||||
PredicateData data;
|
||||
int sense;
|
||||
Predicate p;
|
||||
} QueryTerm;
|
||||
|
||||
|
||||
@@ -230,8 +265,7 @@ void xaccQueryAddBalanceMatch(Query * q, balance_match_t how, QueryOp op);
|
||||
void xaccQueryAddMiscMatch(Query * q, Predicate p, int how, int data,
|
||||
QueryOp op);
|
||||
|
||||
void xaccQueryAddPredicate (Query * q, int sense, PredicateData *pred,
|
||||
QueryOp op);
|
||||
void xaccQueryAddPredicate (Query * q, PredicateData *pred, QueryOp op);
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
@@ -4011,9 +4011,35 @@ START_HANDLER(query_restore)
|
||||
|
||||
END_HANDLER(query_restore)
|
||||
{
|
||||
sixtp_child_result *cr;
|
||||
Query *qand, *qret;
|
||||
Query *q = (Query *) data_for_children;
|
||||
g_return_val_if_fail(q, FALSE);
|
||||
*result = q;
|
||||
|
||||
g_return_val_if_fail(data_from_children, FALSE);
|
||||
cr = (sixtp_child_result *) data_from_children->data;
|
||||
g_return_val_if_fail(cr, FALSE);
|
||||
|
||||
qand = (Query *) (cr->data);
|
||||
g_return_val_if_fail(qand, FALSE);
|
||||
|
||||
/* append the and terms by or'ing them in ... */
|
||||
qret = xaccQueryMerge (q, qand, QUERY_OR);
|
||||
if (!qret) {
|
||||
xaccFreeQuery(qand);
|
||||
*result = q;
|
||||
g_return_val_if_fail(qret, FALSE);
|
||||
}
|
||||
|
||||
xaccFreeQuery(q);
|
||||
xaccFreeQuery(qand);
|
||||
|
||||
*result = qret;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
AFTER_CHILD(query_restore)
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
@@ -4023,21 +4049,53 @@ FAIL_HANDLER(query_restore)
|
||||
if (q) xaccFreeQuery(q);
|
||||
}
|
||||
|
||||
RESULT_CLEANUP(query_restore)
|
||||
{
|
||||
Query *q = (Query *) cr->data;
|
||||
if (q) xaccFreeQuery(q);
|
||||
/* ================================================================= */
|
||||
/* <and-terms> (lineage <restore> <query> <query-server>)
|
||||
|
||||
restores a given query. We allocate the new query in the
|
||||
start block, the children modify it, and in the end block, we see
|
||||
if the resultant query is OK, and if so, we're done.
|
||||
|
||||
input: Query*
|
||||
to-children-via-*result: new Query*
|
||||
returns: NA
|
||||
start: create new Query*, and leave in for children.
|
||||
characters: NA
|
||||
end: clear *result
|
||||
cleanup-result: NA
|
||||
cleanup-chars: NA
|
||||
fail: delete Query*
|
||||
result-fail: NA
|
||||
chars-fail: NA
|
||||
|
||||
*/
|
||||
|
||||
START_HANDLER(query_and)
|
||||
{
|
||||
Query *q;
|
||||
|
||||
/* note this malloc freed in the node higher up (query_restore_end_handler) */
|
||||
q = xaccMallocQuery();
|
||||
g_return_val_if_fail(q, FALSE);
|
||||
*data_for_children = q;
|
||||
*result = q;
|
||||
return(q != NULL);
|
||||
}
|
||||
|
||||
|
||||
AFTER_CHILD(query_restore)
|
||||
END_HANDLER(query_and)
|
||||
{
|
||||
g_return_val_if_fail(data_for_children, FALSE);
|
||||
if(!child_result) return(TRUE);
|
||||
if(child_result->type != SIXTP_CHILD_RESULT_NODE) return(TRUE);
|
||||
Query *q = (Query *) data_for_children;
|
||||
g_return_val_if_fail(q, FALSE);
|
||||
*result = q;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
FAIL_HANDLER(query_and)
|
||||
{
|
||||
Query *q = (Query *) data_for_children;
|
||||
if (q) xaccFreeQuery(q);
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
#define CVT_INT(to) { \
|
||||
@@ -4067,6 +4125,21 @@ AFTER_CHILD(query_restore)
|
||||
g_free(info); \
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
END_HANDLER(qrestore_genericpred)
|
||||
{
|
||||
Query *q = (Query *) parent_data;
|
||||
PredicateData *dp = (PredicateData *) data_for_children;
|
||||
|
||||
g_return_val_if_fail(q, FALSE);
|
||||
g_return_val_if_fail(dp, FALSE);
|
||||
|
||||
xaccQueryAddPredicate (q, dp, QUERY_AND);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
/* <datepred> (lineage <and-terms> <restore> <query> <query-server>)
|
||||
Restores a given date predicate.
|
||||
@@ -4091,51 +4164,14 @@ START_HANDLER(qrestore_datepred)
|
||||
g_return_val_if_fail(dp, FALSE);
|
||||
bzero (dp, sizeof (DatePredicateData));
|
||||
dp->type = PD_DATE;
|
||||
dp->term_type = PR_DATE;
|
||||
*data_for_children = dp;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
END_HANDLER(qrestore_datepred)
|
||||
{
|
||||
Query *q = (Query *) parent_data;
|
||||
PredicateData *dp = (PredicateData *) data_for_children;
|
||||
|
||||
g_return_val_if_fail(q, FALSE);
|
||||
g_return_val_if_fail(dp, FALSE);
|
||||
|
||||
xaccQueryAddPredicate (q, 1, dp, QUERY_OR);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
AFTER_CHILD(qrestore_datepred)
|
||||
{
|
||||
#if 0
|
||||
Split *s = (Split *) data_for_children;
|
||||
g_return_val_if_fail(s, FALSE);
|
||||
if(!child_result) return(TRUE);
|
||||
if(child_result->type != SIXTP_CHILD_RESULT_NODE) return(TRUE);
|
||||
|
||||
if(strcmp(child_result->tag, "quantity") == 0) {
|
||||
gnc_numeric *n = (gnc_numeric *) child_result->data;
|
||||
g_return_val_if_fail(n, FALSE);
|
||||
xaccSplitSetShareAmount(s, *n);
|
||||
/* let the normal child_result handler clean up n */
|
||||
}
|
||||
else if(strcmp(child_result->tag, "value") == 0) {
|
||||
gnc_numeric *n = (gnc_numeric *) child_result->data;
|
||||
g_return_val_if_fail(n, FALSE);
|
||||
xaccSplitSetValue(s, *n);
|
||||
/* let the normal child_result handler clean up n */
|
||||
}
|
||||
#endif
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
FAIL_HANDLER(qrestore_datepred)
|
||||
{
|
||||
g_free (data_for_children);
|
||||
// g_free (data_for_children);
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
@@ -4175,8 +4211,8 @@ END_HANDLER(datepred_end_date)
|
||||
|
||||
END_HANDLER(generic_pred_sense)
|
||||
{
|
||||
DatePredicateData *dp = (DatePredicateData *) parent_data;
|
||||
// CVT_INT(dp->sense);
|
||||
PredicateData *dp = (PredicateData *) parent_data;
|
||||
CVT_INT(dp->base.sense);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
@@ -4202,11 +4238,11 @@ qrestore_datepred_parser_new(void)
|
||||
sixtp *restore_pr = top_level;
|
||||
g_return_val_if_fail(top_level, NULL);
|
||||
|
||||
PRED_PARSE(generic_pred, sense, "sense");
|
||||
PRED_PARSE(datepred, use_start, "use-start");
|
||||
PRED_PARSE(datepred, use_end, "use-end");
|
||||
RESTORE_DATE (datepred, start_date, "start-date");
|
||||
RESTORE_DATE (datepred, end_date, "end-date");
|
||||
PRED_PARSE(generic_pred, sense, "sense");
|
||||
|
||||
return(top_level);
|
||||
}
|
||||
@@ -4222,10 +4258,10 @@ qrestore_datepred_parser_new(void)
|
||||
} \
|
||||
sixtp_set_start(tmp_pr, REST##_##NAME##_start_handler); \
|
||||
sixtp_set_chars(top_level, allow_and_ignore_only_whitespace); \
|
||||
sixtp_set_end(tmp_pr, REST##_##NAME##_end_handler); \
|
||||
sixtp_set_after_child(tmp_pr, REST##_##NAME##_after_child_handler); \
|
||||
sixtp_set_end(tmp_pr, qrestore_genericpred_end_handler); \
|
||||
/* sixtp_set_after_child(tmp_pr, REST##_##NAME##_after_child_handler); */ \
|
||||
sixtp_set_fail(tmp_pr, REST##_##NAME##_fail_handler); \
|
||||
sixtp_add_sub_parser(restore_pr, TOK, tmp_pr); \
|
||||
sixtp_add_sub_parser(and_pr, TOK, tmp_pr); \
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
@@ -4236,6 +4272,7 @@ query_server_parser_new (void)
|
||||
sixtp *top_level;
|
||||
sixtp *query_pr;
|
||||
sixtp *restore_pr;
|
||||
sixtp *and_pr;
|
||||
|
||||
/* <query_server> */
|
||||
top_level = sixtp_new();
|
||||
@@ -4258,21 +4295,19 @@ query_server_parser_new (void)
|
||||
/* <query> <restore> */
|
||||
SETUP_RESTORE (query, query_pr);
|
||||
|
||||
RESTORE_PRED(datepred, "date-pred", qrestore);
|
||||
|
||||
#ifdef LATER
|
||||
|
||||
/* <transaction> */
|
||||
{
|
||||
sixtp *transaction_pr = gnc_transaction_parser_new();
|
||||
if(!transaction_pr) {
|
||||
/* FIXME: need more cleanup here... */
|
||||
return(NULL);
|
||||
}
|
||||
sixtp_add_sub_parser(ledger_data_pr, "transaction", transaction_pr);
|
||||
/* <query> <restore> <and-terms> */
|
||||
and_pr = sixtp_new();
|
||||
if (!and_pr) {
|
||||
sixtp_destroy(top_level);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
sixtp_set_start(and_pr, query_and_start_handler);
|
||||
sixtp_set_chars(and_pr, allow_and_ignore_only_whitespace);
|
||||
sixtp_set_end(and_pr, query_and_end_handler);
|
||||
sixtp_set_fail(and_pr, query_and_fail_handler);
|
||||
sixtp_add_sub_parser(restore_pr, "and-terms", and_pr);
|
||||
|
||||
RESTORE_PRED(datepred, "date-pred", qrestore);
|
||||
|
||||
return(top_level);
|
||||
}
|
||||
|
||||
@@ -879,9 +879,83 @@ xml_add_qterm_restorer(xmlNodePtr qxml, QueryTerm *qt)
|
||||
g_return_val_if_fail(qxml, FALSE);
|
||||
g_return_val_if_fail(qt, FALSE);
|
||||
|
||||
switch (qt->data.type) {
|
||||
case PD_DATE:
|
||||
/* we set the predicates names based on the info they record */
|
||||
switch (qt->data.base.term_type) {
|
||||
case PR_ACCOUNT:
|
||||
p = xmlNewTextChild(qxml, NULL, "account-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_ACTION:
|
||||
p = xmlNewTextChild(qxml, NULL, "action-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_AMOUNT:
|
||||
p = xmlNewTextChild(qxml, NULL, "amount-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_BALANCE:
|
||||
p = xmlNewTextChild(qxml, NULL, "balance-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_CLEARED:
|
||||
p = xmlNewTextChild(qxml, NULL, "cleared-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_DATE:
|
||||
p = xmlNewTextChild(qxml, NULL, "date-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_DESC:
|
||||
p = xmlNewTextChild(qxml, NULL, "description-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_MEMO:
|
||||
p = xmlNewTextChild(qxml, NULL, "memo-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_NUM:
|
||||
p = xmlNewTextChild(qxml, NULL, "num-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_PRICE:
|
||||
p = xmlNewTextChild(qxml, NULL, "price-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_SHRS:
|
||||
p = xmlNewTextChild(qxml, NULL, "shares-pred", NULL);
|
||||
break;
|
||||
|
||||
case PR_MISC:
|
||||
PERR ("Misc terms are not transmittable");
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
if (!p) return (FALSE);
|
||||
|
||||
rc = xml_add_gint32(p, "sense", qt->data.base.sense);
|
||||
if (!rc) return(FALSE);
|
||||
|
||||
|
||||
/* however, many of the types share a generic structure. */
|
||||
switch (qt->data.type) {
|
||||
case PD_ACCOUNT:
|
||||
PERR ("unimplemented");
|
||||
break;
|
||||
|
||||
case PD_AMOUNT:
|
||||
PERR ("unimplemented");
|
||||
break;
|
||||
|
||||
case PD_BALANCE:
|
||||
PERR ("unimplemented");
|
||||
break;
|
||||
|
||||
case PD_CLEARED:
|
||||
PERR ("unimplemented");
|
||||
break;
|
||||
|
||||
case PD_DATE:
|
||||
xml_add_gint32(p, "use-start", qt->data.date.use_start);
|
||||
xml_add_gint32(p, "use-end", qt->data.date.use_end);
|
||||
if (qt->data.date.use_start) {
|
||||
@@ -894,51 +968,26 @@ xml_add_qterm_restorer(xmlNodePtr qxml, QueryTerm *qt)
|
||||
}
|
||||
break;
|
||||
|
||||
case PD_AMOUNT:
|
||||
p = xmlNewTextChild(qxml, NULL, "amount-pred", NULL);
|
||||
PERR ("unimplemented");
|
||||
break;
|
||||
|
||||
case PD_ACCOUNT:
|
||||
p = xmlNewTextChild(qxml, NULL, "account-pred", NULL);
|
||||
PERR ("unimplemented");
|
||||
break;
|
||||
|
||||
case PD_STRING:
|
||||
p = xmlNewTextChild(qxml, NULL, "string-pred", NULL);
|
||||
xml_add_gint32(p, "case-sens", qt->data.str.case_sens);
|
||||
xml_add_gint32(p, "use-regexp", qt->data.str.use_regexp);
|
||||
xml_add_str(p, "matchstring", qt->data.str.matchstring, TRUE);
|
||||
break;
|
||||
|
||||
case PD_CLEARED:
|
||||
p = xmlNewTextChild(qxml, NULL, "cleared-pred", NULL);
|
||||
PERR ("unimplemented");
|
||||
break;
|
||||
|
||||
case PD_BALANCE:
|
||||
p = xmlNewTextChild(qxml, NULL, "balance-pred", NULL);
|
||||
PERR ("unimplemented");
|
||||
break;
|
||||
|
||||
case PD_MISC:
|
||||
p = xmlNewTextChild(qxml, NULL, "misc-pred", NULL);
|
||||
PERR ("unimplemented");
|
||||
PERR ("Must not happen");
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
|
||||
if (!p) return (FALSE);
|
||||
|
||||
rc = xml_add_gint32(p, "sense", qt->sense);
|
||||
if (!rc) return(FALSE);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
/* loop over all terms in the query */
|
||||
/* XXX hack alert -- need to also send max-terms, sort-order,
|
||||
* and other mis query elements */
|
||||
|
||||
static gboolean
|
||||
xml_add_query_restorers(xmlNodePtr p, Query *q)
|
||||
|
||||
Reference in New Issue
Block a user