GncBusiness v. GNCSession

Bill Gribble grib@linuxdevel.com
26 Nov 2001 11:59:45 -0600


On Thu, 2001-11-22 at 20:24, Derek Atkins wrote:
> Well, as I said in another message, the query() method looks more
> like:
> 	char * (*query) (GNCSession *, QueryTerm *, char *);
> 
> The 'user' would generate a GNCQuery that fits the bill, and
> then would call gncQueryExecute() which would basically do
> the following (note that this is pseudocode, not C):
> 
> 	char *query_str = NULL;	
> 
> 	for (term = QueryTerms(query); term; term = term->next) {
> 		obj = object_type(term);
> 		query_str = obj->query (session, term, query_str);
> 		if (term->next)
> 			query_str = g_strdup_printf ("%s AND ", query_str);
> 	}
> 
> We would obviously need a recursive loop to deal with nested ANDs and
> ORs.

FWIW, this is the reason the current Query object is designed the way it
is.  I was trying to make it easy to mechanically translate the Query
object into any kind of backend query, including SQL, even tho at the
time we didn't have an SQL backend.  It's just stored as an and-or tree
of terms.  You could write a simple tree walker following your example
to convert it to SQL directly.

As I understand it, this is not the way the current SQL backend works. 
It sucks all the splits into memory, and then uses the in-memory Query
to find matching splits.  IMO, the brains for running the queries should
be moved into the backends, with the Query type modified as needed to
make it more of an abstract query function specifier (i.e. no function
pointers allowed, just an enumeration of types) and each backend knowing
how to translate it into a smart query. 

IOW, don't look at the way the SQL backend handles queries as
representative of how it should be done or is done in
Gnucash-as-a-whole.  Look at the engine's Query.{c,h} and work out from
there how to modify the backend query infrastructure.  

BTW, Query.{c,h} uses fixed enums for a bunch of things, which look like
obvious candidates for replacement by a hash table that's extensible by
other modules.  
 
> I think we're talking past each other again.  Yes, user's need to be
> able to specify arbitrarily-complicated queries, including joins
> across objects.  On the other hand, I do not want to require a single
> piece of code to know about all the data structures.
> 
> Currently the backends need to know about all objects.  The Postgres
> backend needs to know about everything.  The XML/file backend needs to
> know about everything.

I agree with this, to the extent that it's possible.  However, if the
backend doesn't know about all the types, then the types have to know
about all the backends; somehow or other, each backend has to be able to
generate query instructions for each object type, so they have to at
least have "behavior tables" that routines can be poked into when the
relevant module is loaded.

> I want to change that.  I don't want ANY part of Gnucash to have a
> built-in registry of all data objects/structures.  I want to be able
> to dynamically add new data-types to the engine, but at the same time
> I want to be able to query on those new objects too.  And queries
> should be able to join across existing objects.

I think I agree with this... except that I would have phrased it that
Gnucash *does* have the registry of data types and structures, and the
various providers of data types and structures use a standard API to
modify the registry.  I think that's what you mean to say. 

(I'm just back from TG and catching up, so sorry if this has already
been mentioned)

b.g.