Neil Williams linux at codehelp.co.uk
Sat May 7 05:29:48 EDT 2005

From the previous thread on containers, Derek wrote:
> that is basically just a 
> container class.  It's effectively a special QOF type that contains other
> QofClasses.  When you output a "reference" to this container class you get
> back a tuple: <container name, contained type, guid>.

As noted, this is a special QOF type rather than an entity of itself and I've 
been working on that idea.

Possible new QOF data type:
#define QOF_TYPE_COLLECT  "collection"

Template for additional GncInvoice parameters:
{ INVOICE_ENTRIES, QOF_TYPE_COLLECT, (QofAccessFunc)qofInvoiceGetEntries, 
(QofSetterFunc)qofInvoiceSetEntries },
{ Q_INVOICE_OWNER, QOF_TYPE_COLLECT, (QofAccessFunc)qofInvoiceGetOwner,
(QofSetterFunc)qofInvoiceSetOwner },
{ Q_INVOICE_BILLTO, QOF_TYPE_COLLECT, (QofAccessFunc)qofInvoiceGetBillTo,
(QofSetterFunc)qofInvoiceSetBillTo },

(these are all additional parameters, the existing GNC_ID_OWNER params would 
stay, just without my added (QofSetterFunc).)

QofCollection* qofInvoiceGetEntries(GncInvoice *invoice);
void qofInvoiceSetEntries (GncInvoice *invoice, QofCollection *entries);

Set function would convert QofCollection to the internal GList using 

New functions in qofbook.c:
gboolean qof_collection_add_entity(QofCollection *coll, QofEntity *ent);
gboolean qof_collection_merge(QofCollection *target, QofCollection *input);

Both would use qof_collection_lookup() to prevent the same entity being added 
twice, returning FALSE. (important as many collections are currently created 
using qof_book_get_collection where all entities of this type already exist 
in the collection).

Both would return FALSE if a request was made to add a QofEntity where the 
e_type did not match.

merge would be additive - if the type matches, the target collection would 
have all entities from the input collection that do not already exist in 
target, added.

In QSF (nested within the object tag for the invoice):
<collection type="entry">guid_as_string_output</collection>
<collection type="entry">guid_as_string_output</collection>

Would result in N entries in the invoice - all must exist as entities in their 
own right. i.e. GncEntry can be queried as a table.

1. Each QofCollection contains one or many entities - *all* of a single type.
2. The entity type within the collection can be determined at run time.
3. Easy conversions to GList or whatever in the param_setfcn handler.
4. Each parameter can have it's own collection.
5. Each entity can have a different *type* of collection to it's siblings, 
provided that it is acceptable to the set function.
6. Each object decides which types are acceptable for which parameter in the 
set functions. This is then part of the API for that object.

So, GncOwner would become utterly transparent. Instead of returning a GncOwner 
to QOF, GncInvoice passes a QofCollection. If that collection is a type e.g. 
GNC_ID_CUSTOMER, then the customer entity becomes the GncOwner of the 
invoice. The param_setfcn would have to reject unsupported types and set the 
GncOwner according to the type of the collection. In this case, the 
collection only contains one entity - again it is up to the set function to 
enforce this.

QOF_TYPE_COLLECT therefore has two functions, both related to one-to-many 
1. Represent a reference between 2 entities with a list of acceptable types.
	(one object linked to many types of single entities)
2. Represent a reference between one entity and many entities of another type.
	(one object linked to many entities of a single type.)

If the set function can handle it, it could also be used for true one-to-many 
links: one object linked to many entities of many types.

n.b. Always subject to each collection holding only one type at runtime.
(otherwise use books).

The QofClass parameters declares the type as QOF_TYPE_COLLECT and QOF will 
then ask the collection what type of entity it holds.

To write these out via the QSF backend: qof_collection_foreach
To load these from a QSF file: qof_collection_add
To merge entities using these parameters: qof_collection_merge.

When recursively copying entities, QOF can identify the references easily.

This will mean that a recursive copy of a GncInvoice would copy:
1. GncInvoice
2. GncBillTerm
3. A series of GncEntry references
4. A reference to the GncCustomer instead of the GncOwner owner;
5. A reference to (e.g.) GncJob instead of the GncOwner billto;
6. Each referenced GncEntry
7. Each referenced GncCustomer
8. Each referenced GncAddress
9. Each referenced GncJob and it's customer/address etc.
10. The accounts for each of the above
11. The transactions for each of the above.
12. The splits for each of the above.

The recursion includes the parents for each account but no transactions that 
are not specifically referenced from the invoice entries.

i.e. the export includes all data necessary to completely recreate the invoice 
in another book, even if that book has no existing business data.

Naturally, a recursive copy of all invoices would not duplicate any of this 
data, so as more invoices are added, the file size increases less and less 
each time.



Neil Williams

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.gnucash.org/pipermail/gnucash-devel/attachments/20050507/12fa84be/attachment.bin

More information about the gnucash-devel mailing list