Problem with QOF_TYPE_COLLECT

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with QOF_TYPE_COLLECT

David Hampton-2
I'm having a problem with the new QOF_TYPE_COLLECT that was recently
introduced in the g2 branch.  I'm consistently getting the error
messages:

  Error: qof_class_get_parameter(): no object of type collection
  file qofquerycore.c: line 1477 (qof_query_core_to_string):
    assertion `toString' failed

I'm currently getting this error when I open the "Due Bills" dialog, and
one of the fields in the dialog isn't populated.  I suspect the second
error message is related to the first, but haven't investigated it yet.

Tracking down the first message, I started where the due bills dialog
sets up a search query for invoices, one term of which is the owner of
the invoice, set here.

    param_list = gnc_search_param_prepend (param_list, _("Company"), NULL, type,
                                           INVOICE_OWNER, OWNER_NAME, NULL);

The gnc_search_param_prepend() function calls
gnc_search_param_set_param_path(), which determines that an
INVOICE_OWNER is of type QOF_TYPE_COLLECT, tries to look up the
definition of a collection with gncQueryObjectGetParameter, and fails
miserably.  I am able to find where all the other core qof types are
registered with this code in qofquerycore.c, but I can't find anywhere
where the collection type is registered.

Can anyone help me out with this problem?   Thanks.

David


_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Neil Williams-2
On Tue, Jul 05, 2005 at 08:43:34PM -0400, David Hampton wrote:
> I'm having a problem with the new QOF_TYPE_COLLECT that was recently
> introduced in the g2 branch.  I'm consistently getting the error
> messages:
>
>   Error: qof_class_get_parameter(): no object of type collection
>   file qofquerycore.c: line 1477 (qof_query_core_to_string):
>     assertion `toString' failed

I'll need to add a prompt in qofclass.h that qofquerycore.c needs work
when a new type is added.

> Tracking down the first message, I started where the due bills dialog
> sets up a search query for invoices, one term of which is the owner of
> the invoice, set here.
>
>     param_list = gnc_search_param_prepend (param_list, _("Company"), NULL, type,
>   INVOICE_OWNER, OWNER_NAME, NULL);
>
> The gnc_search_param_prepend() function calls
> gnc_search_param_set_param_path(), which determines that an
> INVOICE_OWNER is of type QOF_TYPE_COLLECT, tries to look up the
> definition of a collection with gncQueryObjectGetParameter,
Why do we have these duplicate names defined? What's the advantage? It
makes it more difficult because in Anjuta I can right click each
function to go to it's definition or declaration - if it's defined as
another name, that doesn't work.

Anyways, it's actually calling qof_class_get_parameter, as shown in the
error report.

> and fails
> miserably.  I am able to find where all the other core qof types are
> registered with this code in qofquerycore.c, but I can't find anywhere
> where the collection type is registered.

I'll have to add that code to qofquerycore.

> Can anyone help me out with this problem?   Thanks.

I'll look at it today, hopefully.

--

Neil Williams
=============
http://www.data-freedom.org/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/



_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

signature.asc (264 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Derek Atkins
Neil Williams <[hidden email]> writes:

>>   Error: qof_class_get_parameter(): no object of type collection
>>   file qofquerycore.c: line 1477 (qof_query_core_to_string):
>>     assertion `toString' failed
>
> I'll need to add a prompt in qofclass.h that qofquerycore.c needs work
> when a new type is added.

Additional dev documentation is never a bad idea ;)

>> Tracking down the first message, I started where the due bills dialog
>> sets up a search query for invoices, one term of which is the owner of
>> the invoice, set here.
>>
>>     param_list = gnc_search_param_prepend (param_list, _("Company"), NULL, type,
>>   INVOICE_OWNER, OWNER_NAME, NULL);
>>
>> The gnc_search_param_prepend() function calls
>> gnc_search_param_set_param_path(), which determines that an
>> INVOICE_OWNER is of type QOF_TYPE_COLLECT, tries to look up the
>> definition of a collection with gncQueryObjectGetParameter,
>
> Why do we have these duplicate names defined? What's the advantage? It
> makes it more difficult because in Anjuta I can right click each
> function to go to it's definition or declaration - if it's defined as
> another name, that doesn't work.
>
> Anyways, it's actually calling qof_class_get_parameter, as shown in the
> error report.

Sorry, what duplicate names?  Which names are duplicates?  And what
are they duplicates of?

-derek

--
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       [hidden email]                        PGP key available
_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Neil Williams-2
In reply to this post by Neil Williams-2
>> Tracking down the first message, I started where the due bills
>> dialog sets up a search query for invoices, one term of which is
>> the owner of the invoice, set here.
>>
>> param_list = gnc_search_param_prepend (param_list, _("Company"),
>> NULL, type, INVOICE_OWNER, OWNER_NAME, NULL)
>>
>> and fails miserably.  I am able to find where all the other core
>> qof types are registered with this code in qofquerycore.c, but I
>> can't find anywhere where the collection type is registered.

The collection is a "secondary" collection, not the same as the main
ones in the book and can contain entity/ies of a different type to the
parent object - naturally all entities in any one collection must be of
the same type. Additionally, a QOF_TYPE_COLLECT can hold entities of ANY
registered type, the object defining the collect type determines which
entity types it will accept and which it can ignore at runtime. So
GncInvoice handles a collect type holding GncCustomer, or GncJob, or
GncEmployee entities (GncInvoice only uses the first one in the
collection and GncOwner is used to determine the acceptable types) -
the precise entity type determined when the data file is read in.

I've written a starter for the QOF_TYPE_COLLECT query predicates, I'm
just checking that I've got it right:

The comparison routine uses qof_collection_compare.
The equality function does the same.
The predicate uses a list of GUID's.
Matches are done according to the GUID.

Will that preclude the existing searches (e.g. for Company_Name) - is
there a test routine?

So I get:
QofQueryPredData *
qof_query_collect_predicate (QofGuidMatch options, QofCollection *coll)

    { QOF_TYPE_COLLECT, collect_match_predicate, collect_compare_func,
      collect_copy_predicate, collect_free_pdata, NULL,
      collect_predicate_equal },

collect_match_predicate is largely lifted from guid_match_predicate -
qof_query_collect_predicate lifts the GUID's of each entity in the
QofCollection into a GList in query_coll_def, (*query_coll_t).

I'm not sure about the ToString because I don't see how that can be
enabled for a collection of entities - it isn't enabled for GUID's
either so maybe that's a red herring and completing the registration of
QOF_TYPE_COLLECT with the query engine will be sufficient.

Before I commit, I thought I'd best check if I'm way off (again).

Is this the correct way to handle a collection in a query?

(and I'm growing to hate Thunderbird's preference for full screen
message composing! There's a bug in kmail related to yet more string
problems, this time QString.)

Will this require any changes elsewhere?

--

Neil Williams
=============
http://www.data-freedom.org/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/



_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

signature.asc (264 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Derek Atkins
See, this is why I've said all along that an Owner is _NOT_ a collection.. It's
a CHOICE.  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...

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.

Unfortunately your workarounds are not sufficient.  It will break a lot of
existing queries in a number of places.

-derek

Quoting Neil Williams <[hidden email]>:

> >> Tracking down the first message, I started where the due bills
> >> dialog sets up a search query for invoices, one term of which is
> >> the owner of the invoice, set here.
> >>
> >> param_list = gnc_search_param_prepend (param_list, _("Company"),
> >> NULL, type, INVOICE_OWNER, OWNER_NAME, NULL)
> >>
> >> and fails miserably.  I am able to find where all the other core
> >> qof types are registered with this code in qofquerycore.c, but I
> >> can't find anywhere where the collection type is registered.
>
> The collection is a "secondary" collection, not the same as the main
> ones in the book and can contain entity/ies of a different type to the
> parent object - naturally all entities in any one collection must be of
> the same type. Additionally, a QOF_TYPE_COLLECT can hold entities of ANY
> registered type, the object defining the collect type determines which
> entity types it will accept and which it can ignore at runtime. So
> GncInvoice handles a collect type holding GncCustomer, or GncJob, or
> GncEmployee entities (GncInvoice only uses the first one in the
> collection and GncOwner is used to determine the acceptable types) -
> the precise entity type determined when the data file is read in.
>
> I've written a starter for the QOF_TYPE_COLLECT query predicates, I'm
> just checking that I've got it right:
>
> The comparison routine uses qof_collection_compare.
> The equality function does the same.
> The predicate uses a list of GUID's.
> Matches are done according to the GUID.
>
> Will that preclude the existing searches (e.g. for Company_Name) - is
> there a test routine?
>
> So I get:
> QofQueryPredData *
> qof_query_collect_predicate (QofGuidMatch options, QofCollection *coll)
>
>     { QOF_TYPE_COLLECT, collect_match_predicate, collect_compare_func,
>       collect_copy_predicate, collect_free_pdata, NULL,
>       collect_predicate_equal },
>
> collect_match_predicate is largely lifted from guid_match_predicate -
> qof_query_collect_predicate lifts the GUID's of each entity in the
> QofCollection into a GList in query_coll_def, (*query_coll_t).
>
> I'm not sure about the ToString because I don't see how that can be
> enabled for a collection of entities - it isn't enabled for GUID's
> either so maybe that's a red herring and completing the registration of
> QOF_TYPE_COLLECT with the query engine will be sufficient.
>
> Before I commit, I thought I'd best check if I'm way off (again).
>
> Is this the correct way to handle a collection in a query?
>
> (and I'm growing to hate Thunderbird's preference for full screen
> message composing! There's a bug in kmail related to yet more string
> problems, this time QString.)
>
> Will this require any changes elsewhere?
>
> --
>
> Neil Williams
> =============
> http://www.data-freedom.org/
> http://www.nosoftwarepatents.com/
> http://www.linux.codehelp.co.uk/
>
>
>


--
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       [hidden email]                        PGP key available

_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Neil Williams-2
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.

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.

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

> 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.

> 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.

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.

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.

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 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.

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?

--

Neil Williams
=============
http://www.data-freedom.org/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/


_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

signature.asc (264 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Derek Atkins
Quoting Neil Williams <[hidden email]>:

> 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
redirects.

> > 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
export.

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
it.

> 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
--
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       [hidden email]                        PGP key available

_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Neil Williams-2
On Wednesday 06 July 2005 10:11 pm, Derek Atkins wrote:

(bear with me, this is a long one).

> > 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.
I was handling that inside the object - it would only use objects it knew in
advance. It's fine for an object to know about other objects that it
references. Doesn't matter now.

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

Turns out it probably can.

> 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.

Eeek! Sounds great but I must admit I haven't any experience of templates.
:-0

How's this for starters?

Each choice type would need it's own definition of the allowable objects -
each of which would need to be registered as normal. Objects would declare
themselves to be one option of a particular choice. That could be a new
component of QofObject, "choice". If GncOwner declared itself as
choice: QOF_CHOICE,
GncCustomer could set:
choice: GNC_ID_OWNER
in it's QofObject definition, declaring gncCustomer as an option for
GNC_ID_OWNER.

(maybe choice_parent: instead). That should be easily extensible.

As for the order in which objects are registered, QOF will either create a new
key and an empty hash value if GncOwner is registered first or it will create
the GNC_ID_OWNER key and it's first value if GncCustomer is registered first.

So GncOwner would end up with a QofObject description but could set a NULL
foreach:. Queries would use the original QofAccessFuncs to obtain the
GncCustomer etc..

The GncInvoice would have a GNC_ID_OWNER parameter (as before) and QOF would
lookup a new static table (alongside the existing GList* in qofobject.c) that
identifies the allowable choices for that object as it is identified as a
choice. A simple gboolean qof_object_is_choice(QofIdType) and GList*
qof_object_get_choices(QofIdType) that each refer to a static GHashTable
qof_choice_table;.

The table would be populated by the same qof_object_register() function - it
would also be v.small.

QOF could use the original GNC_ID_OWNER type parameter to retrieve the
owner.customer etc. instance (this keeps existing queries happy). QOF would
look up the param_type and if it's a QOF_CHOICE, handle it as a simple
QofEntity instead of using the param_type that is set to GNC_ID_OWNER.

QOF now has a QofEntity and therefore a ent->e_type, belonging to the current
invoice object, using the GNC_ID_OWNER QofParam. That is sufficient for QSF
to write out a QofEntityReference and export it. This would also allow
recursion as the invoice entity would contain an owner that would provide the
entity that can be copied to the export book.

This would be done in QSF for all QOF_CHOICE objects - an extra conditional.
The QSF would then contain:
<object type="gncInvoice">
  <guid type="guid">invoice_guid_as_string</guid>
  <guid type="gncCustomer">customer_guid_as_string</guid>
...
</object>

On importing/merging, QOF would create the GncCustomer etc. from it's object
tag block in the same file. When populating the invoice, QOF would come
across the GNC_ID_OWNER QofParam and lookup GNC_ID_OWNER in the choice table.
QOF would need to create an owner object to pass to the QofSetterFunc for the
invoice. GncOwner, as a choice object, would look up it's registered choices
and accept the entity using the QofSetterFunc for that type. The invoice for
it's part would use the param_setfcn to receive the owner.

Would that work?

(Phew! That took two hours to work out!)
(and it'll take a few minutes to read and understand too!)
:-))

> Well, I was kind of thinking that it might be easier to have an "Export
> Book"

Next on my list ...

> 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.

i.e. the export routine in GnuCash is hard-coded with the list of objects that
comprise the book.

Not if QOF_CHOICE works - it should allow the recursion needed to find the
references within QOF with no explicit help from the export routine - just
the objects concerned.

> 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.

That's what should happen. The Choice will allow the invoice to tell QOF about
a GncCustomer (as opposed to a vendor etc.). The Collect will allow the
invoice to tell QOF about the list of GncEntry entities. As you recommended,
two is better than one.


--

Neil Williams
=============
http://www.data-freedom.org/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/


_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

attachment0 (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Derek Atkins
Quoting Neil Williams <[hidden email]>:

> On Wednesday 06 July 2005 10:11 pm, Derek Atkins wrote:
>
> (bear with me, this is a long one).

Uh oh... ;)     Me, I'm gonna snip stuff to shorten it..

> How's this for starters?
>
> Each choice type would need it's own definition of the allowable objects -
> each of which would need to be registered as normal. Objects would declare
> themselves to be one option of a particular choice. That could be a new
> component of QofObject, "choice". If GncOwner declared itself as
> choice: QOF_CHOICE,
> GncCustomer could set:
> choice: GNC_ID_OWNER
> in it's QofObject definition, declaring gncCustomer as an option for
> GNC_ID_OWNER.
>
> (maybe choice_parent: instead). That should be easily extensible.

I don't like that.  It means that each object can be in only one choice.  I'd
rather have the definitions of the allowable objects as part of the choice
definition.  It would mean that you'd need to store either a GList of types or
a HashTable of types for each choice object you define, but it's more
extensible than what you've got.

Perhaps an API like:

  qof_choice_create(GNC_ID_OWNER);
  qof_choice_add_class(GNC_ID_OWNER, GNC_ID_CUSTOMER);
  qof_choice_add_class(GNC_ID_OWNER, GNC_ID_VENDOR);
  qof_choice_add_class(GNC_ID_OWNER, GNC_ID_EMPLOYEE);
  qof_choice_add_class(GNC_ID_OWNER, GNC_ID_JOB);

And then you could use QOF_CHOICE "GNC_ID_OWNER" elsewhere in the qof
definitions?

> So GncOwner would end up with a QofObject description but could set a NULL
> foreach:. Queries would use the original QofAccessFuncs to obtain the
> GncCustomer etc..

Just need to make sure our code all checks for this...

> The GncInvoice would have a GNC_ID_OWNER parameter (as before) and QOF would
> lookup a new static table (alongside the existing GList* in qofobject.c) that
> identifies the allowable choices for that object as it is identified as a
> choice. A simple gboolean qof_object_is_choice(QofIdType) and GList*
> qof_object_get_choices(QofIdType) that each refer to a static GHashTable
> qof_choice_table;.

That works.  :)

> The table would be populated by the same qof_object_register() function - it
> would also be v.small.
>
> QOF could use the original GNC_ID_OWNER type parameter to retrieve the
> owner.customer etc. instance (this keeps existing queries happy). QOF would
> look up the param_type and if it's a QOF_CHOICE, handle it as a simple
> QofEntity instead of using the param_type that is set to GNC_ID_OWNER.
>
> QOF now has a QofEntity and therefore a ent->e_type, belonging to the current
> invoice object, using the GNC_ID_OWNER QofParam. That is sufficient for QSF
> to write out a QofEntityReference and export it. This would also allow
> recursion as the invoice entity would contain an owner that would provide the
> entity that can be copied to the export book.

Yea, this is exactly what I was talking about earlier..  :)

> This would be done in QSF for all QOF_CHOICE objects - an extra conditional.
>
> The QSF would then contain:
> <object type="gncInvoice">
>   <guid type="guid">invoice_guid_as_string</guid>
>   <guid type="gncCustomer">customer_guid_as_string</guid>
> ...
> </object>
>
> On importing/merging, QOF would create the GncCustomer etc. from it's object
> tag block in the same file. When populating the invoice, QOF would come
> across the GNC_ID_OWNER QofParam and lookup GNC_ID_OWNER in the choice table.
>
> QOF would need to create an owner object to pass to the QofSetterFunc for the
> invoice. GncOwner, as a choice object, would look up it's registered choices
> and accept the entity using the QofSetterFunc for that type. The invoice for
> it's part would use the param_setfcn to receive the owner.

Note that in many cases the Owner is "inlined" in the object and not a
standalone reference, so if you did this you'd have to malloc, set the setter,
and then free the object.  (or the QofSetter would just need to free it).

> Would that work?

I _think_ so.

> (Phew! That took two hours to work out!)
> (and it'll take a few minutes to read and understand too!)
> :-))
>
> > Well, I was kind of thinking that it might be easier to have an "Export
> > Book"
>
> Next on my list ...
>
> > 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.
>
> i.e. the export routine in GnuCash is hard-coded with the list of objects
> that
> comprise the book.
>
> Not if QOF_CHOICE works - it should allow the recursion needed to find the
> references within QOF with no explicit help from the export routine - just
> the objects concerned.

True.

> > 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.
>
> That's what should happen. The Choice will allow the invoice to tell QOF
> about
> a GncCustomer (as opposed to a vendor etc.). The Collect will allow the
> invoice to tell QOF about the list of GncEntry entities. As you recommended,
> two is better than one.

I do try to provide good advice ;)

-derek

--
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       [hidden email]                        PGP key available

_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Neil Williams-2
In reply to this post by Derek Atkins
On Wednesday 06 July 2005 3:50 pm, Derek Atkins wrote:
> > Why do we have these duplicate names defined? What's the advantage? It
> > makes it more difficult because in Anjuta I can right click each
> > function to go to it's definition or declaration - if it's defined as
> > another name, that doesn't work.
> >
> > Anyways, it's actually calling qof_class_get_parameter, as shown in the
> > error report.
>
> Sorry, what duplicate names?

Where an API function is redefined with a new name e.g.
$ cd gnucash-gnome2/src/engine/
$ grep "define gnc" *.h

Most, in this case, are from gncObject.h, QueryCore.h and QueryNew.h

Are these all deprecated? Should they be?

Are they just historical or is there an advantage?

--

Neil Williams
=============
http://www.data-freedom.org/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/


_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

attachment0 (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problem with QOF_TYPE_COLLECT

Derek Atkins
Neil Williams <[hidden email]> writes:

>> > Anyways, it's actually calling qof_class_get_parameter, as shown in the
>> > error report.
>>
>> Sorry, what duplicate names?
>
> Where an API function is redefined with a new name e.g.
> $ cd gnucash-gnome2/src/engine/
> $ grep "define gnc" *.h
>
> Most, in this case, are from gncObject.h, QueryCore.h and QueryNew.h
>
> Are these all deprecated? Should they be?
>
> Are they just historical or is there an advantage?

They exist because we have old APIs and new APIs and didn't
want to have to re-write a LOT of code just because we changed
function names.  The old names are deprecated but should probably
only be removed in the next release, not the current G2 code.

-derek
--
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       [hidden email]                        PGP key available
_______________________________________________
gnucash-devel mailing list
[hidden email]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel