Query API
Christopher Browne
cbbrowne@hex.net
Tue, 19 Dec 2000 01:10:44 -0600
On 18 Dec 2000 13:00:56 EST, the world broke into rejoicing as
Derek Atkins <warlord@MIT.EDU> said:
> Christopher Browne <cbbrowne@hex.net> writes:
> > It shouldn't be a situation of the GUI submitting database queries;
> > instead, the GUI should submit _transaction_ queries to the engine, and
> > the engine can then do what it needs.
> This is a reasonable approach, although I think we still want
> (need?) to be flexible enough to make some rather robust queries.
> For example, I can certainly see where you might want to search for
> transactions in an account between specific dates, or certain
> reports might want to make certain more extensive queries. I'm not
> sure what the best way to do this would be; I'd like to be able to
> support batch queries across an RPC, but I don't know how to make
> the request.
This is absolutely sensible; it would be logical to provide a CORBA
interface to the Query scheme, perhaps thus:
module Query {
enum SortBy { STANDARD, DATE, DATEENTERED, DATERECONCILED, NUM,
AMOUNT, MEMO, DESC, RECONCILE, NONE };
enum QueryOp { AND, OR, NAND, NOR, XOR };
enum pdtypet { DATE, AMOUNT, ACCOUNT, STRING, CLEARED, MISC };
enum acctmatcht { ACCT_MATCH_ALL, ACCT_MATCH_ANY, ACCT_MATCH_NONE }
enum amtmatcht { AMT_MATCH_ATLEAST, AMT_MATCH_ATMOST,
AMT_MATCH_EXACTLY } ;
enum amtmatchsgnt { AMT_SGN_MATCH_EITHER, AMT_SGN_MATCH_CREDIT,
AMT_SGN_MATCH_DEBIT } ;
enum clearing { CLEARED_NO, CLEARED_CLEARED, CLEARED_RECONCILED,
CLEARED_FROZEN };
enum strmatching { STRING_MATCH_CASE, STRING_MATCH_REGEXP,
STRING_MATCH_INSENSITIVE };
struct DatePredicateData {
long usestart;
Timespec start;
long useend;
Timespec end;
}
struct AmountPredicateData {
amtmatcht how;
amtmatchsgnt amt_sgn;
double amount;
};
struct AccountPredicateData {
acctmatcht how;
Accounts::AccountList accounts;
// Note that this references a type from
// module "Accounts"
}
struct StringPredicateData {
strmatching behavior; /* what kind of search? */
string matchstring;
// regex_t compiled; // Compilation isn't part of the interface
} StringPredicateData;
struct MiscPredicateData {
long how; /* Shouldn't this use one of the enums? */
long data; /* What is this? */
};
struct ClearedPredicateData {
long how;
};
union PredicateData switch (pdtypet) {
case DATE:
DatePredicateData date;
case AMOUNT:
AmountPredicateData amount;
case ACCOUNT:
AccountPredicateData acct;
case STRING:
StringPredicateData str;
case CLEARED:
ClearedPredicateData cleared;
case MISC:
MiscPredicateData misc;
}
struct QueryTerm {
Predicate p; /* What is this type supposed to be? */
PredicateData data;
long sense;
};
/* Something is wrong with the following; I am somehow not correctly
understanding what the Predicate type is... I'll punt and
pretend that a Query consists of a binary tree of QueryTerm
elements... */
struct Query {
QueryTerm qt;
QueryOp combinethus;
Query subquery;
};
// Locally, there would be the whole host of "Query Construction"
// functions to build up a complex query.
void InvokeQuery (in query q,
out Transactions::TransactionList txns);
/* Note that this references, from the "Transactions" module, the
"TransactionList" typedef, which would reflect a sequence of
transactions... */
};
A few points that should be made conspicuous:
- Note that the "enums" do not declare specific values. They CANNOT
do so; CORBA works with some languages, e.g. Lisp, that would allow
"enums" to be kept symbolic.
- Note that the only actual "function call" here, which, in CORBA, is
called an "operator," is InvokeQuery. It returns a _sequence_ that
could include arbitrarily many transactions. It is passed what
amounts to a "tree;" a potentially-very-complex query.
This is the _direct_ answer to your issue of "supporting batch
queries" across RPC. This allows passing in a complex query, and
returning a complex response.
- Frankly, this probably shouldn't return the transactions, but rather
return a list of transaction _references_ [e.g. - perhaps a sequence
of GUIDs]. That way, if the goal is not to look up the
transactions, we don't have to.
But it's easy enough to take that sequence of GUIDs, and pass them to
void PullTransactions ( in GUIDList g; out TransactionList txns );
- Note that the interface does NOT provide the whole set of functions
described in Query.h/Query.c; only the one that would be used to
request the query.
Query.h describes a bunch of functions that may be used to help
construct the query. Those should run locally; there is _NO_ point
to running them across a network.
--
(concatenate 'string "cbbrowne" "@ntlug.org")
<http://www.hex.net/~cbbrowne/>
"Never make any mistaeks." (Anonymous, in a mail discussion about to a
kernel bug report.)