Derek Atkins warlord at MIT.EDU
Wed Jul 6 17:11:47 EDT 2005

Quoting Neil Williams <linux at>:

> Derek Atkins wrote:
> > See, this is why I've said all along that an Owner is _NOT_ a 
> > collection.. It's a CHOICE.
> OK, I was hoping that as it is a choice between one entity from a
> collection of types (and that it merely happened in this case to be a
> single entity at a time) that it could be handled in the same way as a
> collection (like Entries) of the same type. The root of the problem is
> one-to-many linkage. One parameter containing a predictable collection
> of entity references.

Well, it IS a choice..  It's one instance/entity from a choice of classes -- but
in this case it's assumed to have a constant interface.  The "CHOICE" is just a
placeholder, not a first-class object in itself.  I.e., you cannot have an
empty  CHOICE; it has to have one (and ONLY one) object..  And the choice
itself is just a passthrough for all the query code.

> I used QofCollection because of the tight control of 1 type per
> collection. It makes it easy to handle multiple entities. A GList of
> entities of more than one type is much more difficult to handle. Even if
> each instance only contains one entity, the fact that the one parameter
> can access entities of more than one type makes it very difficult to
> handle generically.

But that's not actually correct.  The "collection" can be any of Job, Employee,
Vendor, or Customer... So you kind of need to know ahead of time what it is.

> The current backend knows about these things in advance, QOF cannot.

Why not?

Why can't there be a QOF_CHOICE object which is sort of like a C++ template.. 
QOF_CHOICE doesn't really exist by itself, it's a QOF_CHOICE<QOF_X, QOF_Y,
QOF_Z> and holds a single entity of type X, Y, or Z for the pursposes of
QOF/QSF..  But for querying the object it queries as if it's an X, Y, or Z.

> > It is always One and ONLY ONE object, but it's a single object of a 
> > bunch of different types.  An owner can be a Job, a Customer, a 
> > Vendor, or an Employee...  But there is still One and ONLY ONE 
> > object...
> Agreed.
> The collection was designed with a view to general QOF objects, not
> exclusively for GncOwner. I need a better solution that is still
> generic. I'm wondering (out loud) about KVP.

I don't think you need KVP per se; although GncOwner is sort of implemented that
way currently.  There's a "type" and "guid" inside the owner and it just

> > So...  IMHO the "collection" is the wrong abstraction for an owner. 
> > I've just not been able to say this in a way that I think makes it 
> > clear to you.
> I see the problem and I'm going to have to revert the change.
> I still need one parameter capable of retrieving multiple entity
> references in two examples:
> 1. The Owner parameter that is one entity with one of 4 different entity
> types.
> 2. The entries in the invoice that can be many instances of 1 entity type.

Sounds like you need two different QOF types to handle these two cases, because
they DO behave differently.

> I first tried this by making GncOwner and GncEntry available for export
> directly. Even with GncEntry available, I still need to find the entries
> from the invoice via QOF parameters. I may go for a temporary KVP frame.
> (Created by QOF within the object, used to build the list of entities to
> find and then discarded). These would then be retrieved using (yet more)
> dedicated parameters and functions, removing the need for a param_setfcn
> on the Owner parameter so that QOF can query it but not export or merge it.

No, QOF_COLLECTION is the right solution for the GncEntries, I think..

> One (poor) alternative is to hard-code into the export routines that a
> GncInvoice always has a GncOwner, the export routine would have to
> obtain and look up the owner and add that GncCustomer (etc.) entity to
> the export explicitly. The exported invoice would then contain a GUID
> reference to the GncCustomer, or whichever is used. However, if the
> invoice object changes, hardcoded exports would need to be
> re-written.

Well, I was kind of thinking that it might be easier to have an "Export Book" --
where you take a query of objects you want to export, and then "copy" those and
all the other relevant objects into the Export Book..  Then you can just
iterate over the export book and that would contain all the relevant objects to

The downside is that this requires extra work outside of QOF; each object would
need to know all the references to other objects and be able to add them to the
Export Book.

> IMHO, a temporary KvpFrame is a better option, QOF could look up the
> reference and use the value of that key to know the type. It's not as
> robust as QofCollection but it could be OK.

I'm not sure you need to add all the overhead of an actual QOF KVP Frame.  But I
think using the same concept "base-type + guid/reference" is a good way to do

> I wanted to allow QOF to follow the references between objects and
> enable some form of recursion so that exporting an invoice would
> automatically bring along each referenced entity so that the export was
> a more usable item. Just exporting an invoice with only the GUID of the
> entries, the owner and the bill terms seemed a little underwhelming.

Well, it would work just fine IFF you added an API that would allow QOF to ask
the invoice to return all the sub-objects so that QOF could export them.

> KVP could be used to indicate that this invoice entity needs to be
> exported with that GncCustomer entity, etc.
> For now, I may keep QOF_TYPE_COLLECT in QOF itself but remove it's
> expression in the GnuCash objects. What GnuCash doesn't know can't hurt
> it. (!!). If it turns out that it can be done slightly differently, it
> can always be renamed to better express the concept. I'll then hard-code
> the exports so that the UI code recurses through the objects that it
> already understands and copies the relevant entities into the export
> QofBook or use temporary KVP frames.
> Comments?

That would work.  :)

       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL:    PP-ASEL-IA     N1NWH
       warlord at MIT.EDU                        PGP key available

More information about the gnucash-devel mailing list