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:
Linas Vepstas
2001-01-08 03:31:05 +00:00
parent 003419381c
commit 57533297f0
4 changed files with 356 additions and 187 deletions

View File

@@ -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);

View File

@@ -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);
/*******************************************************************

View File

@@ -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);
}

View File

@@ -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)