diff --git a/src/engine/Makefile.in b/src/engine/Makefile.in index b372327a63..1cbe9a5e53 100644 --- a/src/engine/Makefile.in +++ b/src/engine/Makefile.in @@ -35,7 +35,7 @@ CFLAGS = @CFLAGS@ ${INCLPATH} ###################################################################### # See Makefile.common for information about these variables. INDEP_SRCS := AccInfo.c Account.c DateUtils.c FileIO.c Group.c LedgerUtils.c \ - QIFIO.c Transaction.c TransLog.c date.c util.c + QIFIO.c Query.c Transaction.c TransLog.c date.c util.c ###################################################################### all: default diff --git a/src/engine/Query.c b/src/engine/Query.c new file mode 100644 index 0000000000..bae6cbbdfa --- /dev/null +++ b/src/engine/Query.c @@ -0,0 +1,188 @@ +/* + * FILE: + * Query.c + * + * DESCRIPTION: + * Provide a simple query engine interface. + * + * HISTORY: + * created by Linas Vepstas Sept 1998 + * Copyright (c) 1998 Linas Vepstas + */ + +#include "config.h" +#include "Query.h" +#include "util.h" + +struct _Query { + Account ** acc_list; + + /* maximum number of splits to return */ + int max_num_splits; + + char changed; /* flag, has the query changed? */ + Split **split_list; +}; + +/* ================================================== */ + +Query * +xaccMallocQuery (void) +{ + Query * ret; + ret = (Query *) _malloc (sizeof (Query)); + xaccInitQuery (ret); + return ret; +} + +/* ================================================== */ + +void +xaccInitQuery (Query *q) +{ + if (!q) return; + + q->acc_list = NULL; + q->split_list = NULL; + q->changed = 0; + q->max_num_splits = 2<<30; +} + +/* ================================================== */ + +void +xaccFreeQuery (Query *q) +{ + if (!q) return; + + if (q->acc_list) _free (q->acc_list); + q->acc_list = 0x0; + + if (q->split_list) _free (q->split_list); + q->split_list = 0x0; + + _free (q); +} + +/* ================================================== */ + +void +xaccQuerySetAccounts (Query *q, Account **list) +{ + int i=0; + Account *acc; + + if (!q || !list) return; + q->changed = 1; + + i=0; acc = list[0]; + while (acc) { + i++; acc = list[i]; + } + + if (q->acc_list) free (q->acc_list); + + q->acc_list = (Account **) _malloc ( (i+1) * sizeof (Account *)); + + i=0; acc = list[0]; + while (acc) { + q->acc_list[i] = acc; + i++; acc = list[i]; + } + q->acc_list[i] = NULL; +} + +/* ================================================== */ + +void +xaccQueryAddAccount (Query *q, Account *addme) +{ + int i=0; + Account *acc; + Account **oldlist; + + if (!q || !addme) return; + q->changed = 1; + + oldlist = q->acc_list; + i = 0; + if (oldlist) { + i=0; acc = oldlist[0]; + while (acc) { + i++; acc = oldlist[i]; + } + } + + q->acc_list = (Account **) _malloc ( (i+2) * sizeof (Account *)); + + i=0; acc = oldlist[0]; + while (acc) { + q->acc_list[i] = acc; + i++; acc = oldlist[i]; + } + q->acc_list[i] = addme; + i++; + q->acc_list[i] = NULL; + + if (oldlist) free (oldlist); +} + +/* ================================================== */ + +void +xaccQuerySetMaxSplits (Query *q, int max) +{ + if (!q) return; + q->max_num_splits = max; +} + +/* ================================================== */ + +Split ** +xaccQueryGetSplits (Query *q) +{ + int i=0, j=0; + int nlist, nstart, nret; + Split *s, **slist; + + if (!q) return NULL; + + /* if not changed then don't recompute cache */ + if (!(q->changed)) return q->split_list; + q->changed = 0; + + if (q->split_list) _free (q->split_list); + q->split_list = NULL; + + /* hack alert */ + slist = xaccAccountGetSplitList (q->acc_list[0]); + if (!slist) return NULL; + + i=0; s = slist[0]; + while (s) { i++; s = slist [i]; } + nlist = i; + + /* make sure we don't return too many splits */ + nret = nlist; + if (nret > q->max_num_splits) nret = q->max_num_splits; + q->split_list = (Split **) malloc ((nret+1) * sizeof (Split *)); + + /* return only the last few splits */ + nstart = nlist - nret; + if (0 > nstart) nstart = 0; + + /* copy over */ + i=nstart; s = slist[i]; + j = 0; + while (s) { + q->split_list [j] = s; + j++; i++; s = slist [i]; + } + q->split_list [j] = NULL; + + return q->split_list; +} + +/* ================================================== */ + + diff --git a/src/engine/Query.h b/src/engine/Query.h new file mode 100644 index 0000000000..06ae65d195 --- /dev/null +++ b/src/engine/Query.h @@ -0,0 +1,48 @@ +/* + * FILE: + * Query.h + * + * DESCRIPTION: + * Provide a simple query engine interface. + * + * HISTORY: + * created by Linas Vepstas Sept 1998 + * Copyright (c) 1998 Linas Vepstas + */ + +#ifndef __GNUCASH_QUERY_H__ +#define __GNUCASH_QUERY_H__ + +#include "Account.h" +#include "Transaction.h" + +typedef struct _Query Query; + +/* sorting orders */ +enum { + BY_DATE, + BY_NUM, + BY_AMOUNT +}; + +Query * xaccMallocQuery (void); +void xaccInitQuery (Query *); +void xaccFreeQuery (Query *); + +/* The xaccSetAccountList() method is used to define the set + * of accounts the should be queried. + */ +void xaccQuerySetAccounts (Query *, Account **list); +void xaccQueryAddAccount (Query *, Account *acc); + +/* The xaccQuerySetMaxSplits() method sets the maximum number + * of splits to return as a result of a query. + */ +void xaccQuerySetMaxSplits (Query *, int); + +/* The xaccQueryGetSplits() method returns a list of splits + * matching the query and sorting criteria previously set up. + */ +Split ** xaccQueryGetSplits (Query *); + +#endif /* __GNUCASH_QUERY_H__ */