From d636f3a798776449b247708b7d3530fad41b24ea Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 19 Apr 2004 15:45:46 +0000 Subject: [PATCH] This time, I'm going to say 'cvs commit' in the correct directory. Same set of patches as before: replace naked function call pointers for working with object parameters by 'clothed' paramters. make clean; make; make install is required to get a functional system, because these changes change structure sizes and offsets in the engine libraries. If you don't make clean; you will probably get weird, impossible-to-find crashes. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@9900 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/doc/guid.txt | 10 + src/engine/Transaction.c | 5 +- src/engine/qofbook.h | 18 +- src/engine/qofclass.c | 19 +- src/engine/qofclass.h | 26 +- src/engine/qofid.h | 7 +- src/engine/qofobject.c | 5 + src/engine/qofquery.c | 40 ++- src/engine/qofquerycore-p.h | 10 +- src/engine/qofquerycore.c | 487 ++++++++++++++------------ src/engine/qofquerycore.h | 3 +- src/engine/qofsql.c | 45 +-- src/engine/qofsql.h | 5 +- src/gnome-search/dialog-search.c | 15 +- src/gnome-search/gnc-general-search.c | 14 +- src/gnome-utils/gnc-query-list.c | 49 +-- src/gnome-utils/search-param.c | 10 +- 17 files changed, 445 insertions(+), 323 deletions(-) diff --git a/src/doc/guid.txt b/src/doc/guid.txt index dbbe1f0b22..088adcf726 100644 --- a/src/doc/guid.txt +++ b/src/doc/guid.txt @@ -49,4 +49,14 @@ transactions, while the 'open book' looks just like it (has the same accounts, etc), but doesn't have the old transactions. +The Issue: +---------- +The current book-closing code makes a copy of the account tree, +and sorts all transactions, by date, into the new or the old +account tree. With the goal of not confusing the new and the +old account trees, the book closing code issues the old accounts +a new set of guids. The Pro's & Con's of this scheme: + +Pro: The 'old', closed accounts can be uniquely accessed according +to thier GUID's, without causing confusion with similar/same. diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index c36ff8de92..5f973ae0bf 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -3196,7 +3196,7 @@ static QofObject split_object_def = { }; static gpointer -split_account_guid_getter (gpointer obj) +split_account_guid_getter (gpointer obj, const QofParam *p) { Split *s = obj; Account *acc; @@ -3214,7 +3214,8 @@ DxaccSplitGetShareAmount (const Split * split) return gnc_numeric_to_double(xaccSplitGetAmount(split)); } -static gpointer no_op (gpointer obj) +static gpointer +no_op (gpointer obj, const QofParam *p) { return obj; } diff --git a/src/engine/qofbook.h b/src/engine/qofbook.h index d2112c89a9..3004ca2b10 100644 --- a/src/engine/qofbook.h +++ b/src/engine/qofbook.h @@ -71,7 +71,12 @@ QofBook * qof_book_new (void); associated with it. */ void qof_book_destroy (QofBook *book); -/** \return The table of entities of the given type. */ +/** \return The table of entities of the given type. + * If the collection doesn't yet exist for the indicated type, + * it is created. Thus, this routine is gaurenteed to return + * a non-NULL value. (Unless the system malloc failed (out of + * memory) in which case what happens??). + */ QofCollection * qof_book_get_collection (QofBook *, QofIdType); /** Invoke the indicated callback on each collection in the book. */ @@ -81,10 +86,13 @@ void qof_book_foreach_collection (QofBook *, QofCollectionForeachCB, gpointer); /** \return The kvp data for the book */ KvpFrame * qof_book_get_slots (QofBook *book); -/** The qof_book_set_data() allows - * arbitrary pointers to structs to be stored in QofBook. - * This is the "prefered" method for extending QofBook to hold - * new data types. +/** The qof_book_set_data() allows arbitrary pointers to structs + * to be stored in QofBook. This is the "prefered" method for + * extending QofBook to hold new data types. + * + * XXX FIXME: we need to add a destroy callback, so that when the + * book gets destroyed, the user gets notified and thus has a chance + * to clean up. */ void qof_book_set_data (QofBook *book, const char *key, gpointer data); diff --git a/src/engine/qofclass.c b/src/engine/qofclass.c index 8bf814ec66..24d9e6fb2a 100644 --- a/src/engine/qofclass.c +++ b/src/engine/qofclass.c @@ -46,9 +46,10 @@ static gboolean clear_table (gpointer key, gpointer value, gpointer user_data) /********************************************************************/ /* PUBLISHED API FUNCTIONS */ -void qof_class_register (QofIdTypeConst obj_name, - QofSortFunc default_sort_function, - const QofParam *params) +void +qof_class_register (QofIdTypeConst obj_name, + QofSortFunc default_sort_function, + const QofParam *params) { int i; @@ -74,7 +75,8 @@ void qof_class_register (QofIdTypeConst obj_name, } } -void qof_class_init(void) +void +qof_class_init(void) { if (initialized) return; initialized = TRUE; @@ -83,7 +85,8 @@ void qof_class_init(void) sortTable = g_hash_table_new (g_str_hash, g_str_equal); } -void qof_class_shutdown (void) +void +qof_class_shutdown (void) { if (!initialized) return; initialized = FALSE; @@ -105,8 +108,10 @@ qof_class_get_parameter (QofIdTypeConst obj_name, ht = g_hash_table_lookup (paramTable, obj_name); if (!ht) - PERR ("no object type %s", obj_name); - g_return_val_if_fail (ht, NULL); + { + PERR ("no object of type %s", obj_name); + return NULL; + } return (g_hash_table_lookup (ht, parameter)); } diff --git a/src/engine/qofclass.h b/src/engine/qofclass.h index 54df093b0f..86217294be 100644 --- a/src/engine/qofclass.h +++ b/src/engine/qofclass.h @@ -56,14 +56,24 @@ /** Type of Paramters (String, Date, Numeric, GUID, etc.) */ typedef const char * QofType; +typedef struct _QofParam QofParam; + /** The QofAccessFunc defines an arbitrary function pointer * for access functions. This is needed because C doesn't have * templates, so we just cast a lot. Real functions must be of * the form: * - * param_type getter_func (object_type *self); + * param_type getter_func (object_type *self); + * or + * param_type getter_func (object_type *self, QofParam *param); + * + * The additional argument 'param' allows generic getter functions + * to be implemented, because this argument provides for a way to + * identify the expected getter_func return type at runtime. It + * also provides a place for the user to hang additional user-defined + * data. */ -typedef gpointer (*QofAccessFunc)(gpointer); +typedef gpointer (*QofAccessFunc)(gpointer object, const QofParam *param); /** The QofSetterFunc defines an function pointer for parameter * setters. Real functions must be of the form: @@ -79,16 +89,24 @@ typedef void (*QofSetterFunc) (gpointer, gpointer); * object (QofIdType) or it can be a core data type (QofType). * -- param_getfcn is the function to actually obtain the parameter * -- param_setfcn is the function to actually set the parameter + * -- param_userdata is a place where the user can place any desiered + * user-defined data (and thus can be used by the user-defined + * setter/getter). * * Either the getter or the setter may be NULL. + * + * XXX todo/fixme: need to define a destroy callback, so that when + * the param memory is freed, the callback can be used to release the + * user-defined data. */ -typedef struct _QofParam +struct _QofParam { const char * param_name; QofType param_type; QofAccessFunc param_getfcn; QofSetterFunc param_setfcn; -} QofParam; + gpointer param_userdata; +}; /** This function is the default sort function for a particular object type */ typedef int (*QofSortFunc)(gpointer, gpointer); diff --git a/src/engine/qofid.h b/src/engine/qofid.h index a51c4109ea..f5dcfd1ebe 100644 --- a/src/engine/qofid.h +++ b/src/engine/qofid.h @@ -134,7 +134,12 @@ typedef void (*QofEntityForeachCB) (QofEntity *, gpointer user_data); void qof_collection_foreach (QofCollection *, QofEntityForeachCB, gpointer user_data); -/** store and retreive arbitrary object-defined data */ +/** Store and retreive arbitrary object-defined data + * + * XXX We need to add a callback for when the collection is being + * destroyed, so that the user has a chance to clean up anything + * that was put in the 'data' member here. + */ gpointer qof_collection_get_data (QofCollection *col); void qof_collection_set_data (QofCollection *col, gpointer user_data); diff --git a/src/engine/qofobject.c b/src/engine/qofobject.c index 6ee380cc8f..7286de99ee 100644 --- a/src/engine/qofobject.c +++ b/src/engine/qofobject.c @@ -135,6 +135,11 @@ qof_object_foreach (QofIdTypeConst type_name, QofBook *book, ENTER ("type=%s", type_name); obj = qof_object_lookup (type_name); + if (!obj) + { + PERR ("No object of type %s", type_name); + return; + } col = qof_book_get_collection (book, obj->e_type); PINFO ("lookup obj=%p for type=%s", obj, type_name); if (!obj) return; diff --git a/src/engine/qofquery.c b/src/engine/qofquery.c index 225f39c063..eee755ec15 100644 --- a/src/engine/qofquery.c +++ b/src/engine/qofquery.c @@ -72,9 +72,9 @@ struct _QofQuerySort * convert types. */ gboolean use_default; - GSList * param_fcns; + GSList * param_fcns; /* Chain of paramters to walk */ QofSortFunc obj_cmp; /* In case you are comparing objects */ - QofCompareFunc comp_fcn; /* When you are comparing core types */ + QofCompareFunc comp_fcn; /* When you are comparing core types */ }; /* The QUERY structure */ @@ -280,9 +280,9 @@ static void free_members (QofQuery *q) static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort, gconstpointer a, gconstpointer b) { + QofParam *param = NULL; GSList *node; gpointer conva, convb; - QofAccessFunc get_fcn = NULL; /* to appease the compiler */ g_return_val_if_fail (sort, 0); @@ -304,7 +304,7 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort, convb = (gpointer)b; for (node = sort->param_fcns; node; node = node->next) { - get_fcn = node->data; + param = node->data; /* The last term is really the "parameter getter", * unless we're comparing objects ;) */ @@ -312,13 +312,14 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort, break; /* Do the converstions */ - conva = get_fcn (conva); - convb = get_fcn (convb); + conva = (param->param_getfcn) (conva, param); + convb = (param->param_getfcn) (convb, param); } + /* And now return the (appropriate) compare */ if (sort->comp_fcn) { - int rc = sort->comp_fcn (conva, convb, sort->options, get_fcn); + int rc = sort->comp_fcn (conva, convb, sort->options, param); return rc; } @@ -381,21 +382,21 @@ check_object (QofQuery *q, gpointer object) if (qt->param_fcns && qt->pred_fcn) { GSList *node; - QofAccessFunc get_fcn; + QofParam *param = NULL; gpointer conv_obj = object; /* iterate through the conversions */ - for (node = qt->param_fcns; node; node = node->next) { - get_fcn = node->data; + for (node = qt->param_fcns; node; node = node->next) + { + param = node->data; /* The last term is the actual parameter getter */ - if (!node->next) - break; + if (!node->next) break; - conv_obj = get_fcn (conv_obj); + conv_obj = param->param_getfcn (conv_obj, param); } - if (((qt->pred_fcn)(conv_obj, get_fcn, qt->pdata)) == qt->invert) + if (((qt->pred_fcn)(conv_obj, param, qt->pdata)) == qt->invert) { and_terms_ok = 0; break; @@ -428,8 +429,9 @@ check_object (QofQuery *q, gpointer object) * * returns NULL if the first parameter is bad (and final is unchanged). */ -static GSList * compile_params (GSList *param_list, QofIdType start_obj, - QofParam const **final) +static GSList * +compile_params (GSList *param_list, QofIdType start_obj, + QofParam const **final) { const QofParam *objDef = NULL; GSList *fcns = NULL; @@ -447,8 +449,8 @@ static GSList * compile_params (GSList *param_list, QofIdType start_obj, /* If it doesn't exist, then we've reached the end */ if (!objDef) break; - /* Save off this function */ - fcns = g_slist_prepend (fcns, objDef->param_getfcn); + /* Save off this parameter */ + fcns = g_slist_prepend (fcns, (gpointer) objDef); /* Save this off, just in case */ *final = objDef; @@ -742,7 +744,7 @@ GList * qof_query_run (QofQuery *q) } } - /* and then iterate over all the objects */ + /* And then iterate over all the objects */ qof_object_foreach (q->search_for, book, (QofEntityForeachCB) check_item_cb, &qcb); } diff --git a/src/engine/qofquerycore-p.h b/src/engine/qofquerycore-p.h index 0dd6380eb5..ecf8f72008 100644 --- a/src/engine/qofquerycore-p.h +++ b/src/engine/qofquerycore-p.h @@ -37,22 +37,22 @@ void qof_query_core_init(void); void qof_query_core_shutdown (void); /* - * An arbitrary Query Predicate. Given the gnucash object and the + * An arbitrary Query Predicate. Given the object and the * particular parameter get-function (obtained from the registry by * the Query internals), compare the object's parameter to the - * predicate data + * predicate data. */ typedef int (*QofQueryPredicateFunc) (gpointer object, - QofAccessFunc get_fcn, + QofParam *getter, QofQueryPredData *pdata); /* A callback for how to compare two (same-type) objects based on a - * common get_fcn (parameter member), using the provided comparrison + * common getter (parameter member), using the provided comparison * options (which are the type-specific options). */ typedef int (*QofCompareFunc) (gpointer a, gpointer b, gint compare_options, - QofAccessFunc get_fcn); + QofParam *getter); /* Lookup functions */ QofQueryPredicateFunc qof_query_core_get_predicate (char const *type); diff --git a/src/engine/qofquerycore.c b/src/engine/qofquerycore.c index 5130f06261..c6d829a3c4 100644 --- a/src/engine/qofquerycore.c +++ b/src/engine/qofquerycore.c @@ -39,69 +39,51 @@ typedef void (*QueryPredDataFree) (QofQueryPredData *pdata); /* A function to copy a query's predicate data */ typedef QofQueryPredData *(*QueryPredicateCopyFunc) (QofQueryPredData *pdata); -/* A function to take the object, apply the get_fcn, and return - * a printable string. Note that this QofAccessFunc function should - * be returning a type equal to this core object type. +/* A function to take the object, apply the getter->param_getfcn, + * and return a printable string. Note that this QofParam->getfnc + * function should be returning a type equal to this core object type. * * Note that this string MUST be freed by the caller. */ -typedef char * (*QueryToString) (gpointer object, QofAccessFunc get_fcn); +typedef char * (*QueryToString) (gpointer object, QofParam *getter); /* A function to test for equality of predicate data */ typedef gboolean (*QueryPredicateEqual) (QofQueryPredData *p1, QofQueryPredData *p2); -/* This function registers a new Core Object with the QofQuery - * subsystem. It maps the "core_name" object to the given - * query_predicate, predicate_copy, and predicate_data_free functions. - */ -static void qof_query_register_core_object (char const *type_name, - QofQueryPredicateFunc pred, - QofCompareFunc comp, - QueryPredicateCopyFunc copy, - QueryPredDataFree pd_free, - QueryToString to_string, - QueryPredicateEqual pred_equal); -/* An example: - * - * qof_query_register_core_object (QOF_TYPE_STRING, string_match_predicate, - * string_compare_fcn, string_free_pdata, - * string_print_fcn, pred_equal_fcn); - */ - -static QueryPredicateCopyFunc gncQueryCoreGetCopy (char const *type); -static QueryPredDataFree gncQueryCoreGetPredFree (char const *type); +static QueryPredicateCopyFunc qof_query_copy_predicate (QofType type); +static QueryPredDataFree qof_query_predicate_free (QofType type); /* Core Type Predicate helpers */ -typedef const char * (*query_string_getter) (gpointer); +typedef const char * (*query_string_getter) (gpointer, QofParam *); static const char * query_string_type = QOF_TYPE_STRING; -typedef Timespec (*query_date_getter) (gpointer); +typedef Timespec (*query_date_getter) (gpointer, QofParam *); static const char * query_date_type = QOF_TYPE_DATE; -typedef gnc_numeric (*query_numeric_getter) (gpointer); +typedef gnc_numeric (*query_numeric_getter) (gpointer, QofParam *); static const char * query_numeric_type = QOF_TYPE_NUMERIC; -typedef GList * (*query_glist_getter) (gpointer); -typedef const GUID * (*query_guid_getter) (gpointer); +typedef GList * (*query_glist_getter) (gpointer, QofParam *); +typedef const GUID * (*query_guid_getter) (gpointer, QofParam *); static const char * query_guid_type = QOF_TYPE_GUID; -typedef gint32 (*query_int32_getter) (gpointer); +typedef gint32 (*query_int32_getter) (gpointer, QofParam *); static const char * query_int32_type = QOF_TYPE_INT32; -typedef gint64 (*query_int64_getter) (gpointer); +typedef gint64 (*query_int64_getter) (gpointer, QofParam *); static const char * query_int64_type = QOF_TYPE_INT64; -typedef double (*query_double_getter) (gpointer); +typedef double (*query_double_getter) (gpointer, QofParam *); static const char * query_double_type = QOF_TYPE_DOUBLE; -typedef gboolean (*query_boolean_getter) (gpointer); +typedef gboolean (*query_boolean_getter) (gpointer, QofParam *); static const char * query_boolean_type = QOF_TYPE_BOOLEAN; -typedef char (*query_char_getter) (gpointer); +typedef char (*query_char_getter) (gpointer, QofParam *); static const char * query_char_type = QOF_TYPE_CHAR; -typedef KvpFrame * (*query_kvp_getter) (gpointer); +typedef KvpFrame * (*query_kvp_getter) (gpointer, QofParam *); static const char * query_kvp_type = QOF_TYPE_KVP; /* Tables for predicate storage and lookup */ @@ -128,7 +110,8 @@ static GHashTable *predEqualTable = NULL; NULL); \ } #define VERIFY_PREDICATE(str) { \ - g_return_val_if_fail (get_fcn != NULL, PREDICATE_ERROR); \ + g_return_val_if_fail (getter != NULL, PREDICATE_ERROR); \ + g_return_val_if_fail (getter->param_getfcn != NULL, PREDICATE_ERROR); \ g_return_val_if_fail (pd != NULL, PREDICATE_ERROR); \ g_return_val_if_fail (pd->type_name == str || \ !safe_strcmp (str, pd->type_name), \ @@ -140,8 +123,10 @@ static GHashTable *predEqualTable = NULL; /* QOF_TYPE_STRING */ -static int string_match_predicate (gpointer object, QofAccessFunc get_fcn, - QofQueryPredData *pd) +static int +string_match_predicate (gpointer object, + QofParam *getter, + QofQueryPredData *pd) { query_string_t pdata = (query_string_t) pd; const char *s; @@ -149,7 +134,7 @@ static int string_match_predicate (gpointer object, QofAccessFunc get_fcn, VERIFY_PREDICATE (query_string_type); - s = ((query_string_getter)get_fcn) (object); + s = ((query_string_getter)getter->param_getfcn) (object, getter); if (!s) s = ""; @@ -178,14 +163,15 @@ static int string_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static int string_compare_func (gpointer a, gpointer b, gint options, - QofAccessFunc get_fcn) +static int +string_compare_func (gpointer a, gpointer b, gint options, + QofParam *getter) { const char *s1, *s2; - g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR); + g_return_val_if_fail (a && b && getter &&getter->param_getfcn, COMPARE_ERROR); - s1 = ((query_string_getter)get_fcn) (a); - s2 = ((query_string_getter)get_fcn) (b); + s1 = ((query_string_getter)getter->param_getfcn) (a, getter); + s2 = ((query_string_getter)getter->param_getfcn) (b, getter); if (options == QOF_STRING_MATCH_CASEINSENSITIVE) return safe_strcasecmp (s1, s2); @@ -193,7 +179,8 @@ static int string_compare_func (gpointer a, gpointer b, gint options, return safe_strcmp (s1, s2); } -static void string_free_pdata (QofQueryPredData *pd) +static void +string_free_pdata (QofQueryPredData *pd) { query_string_t pdata = (query_string_t) pd; @@ -207,18 +194,20 @@ static void string_free_pdata (QofQueryPredData *pd) g_free (pdata); } -static QofQueryPredData *string_copy_predicate (QofQueryPredData *pd) +static QofQueryPredData * +string_copy_predicate (QofQueryPredData *pd) { query_string_t pdata = (query_string_t) pd; VERIFY_PDATA_R (query_string_type); - return qof_query_string_predicate (pd->how, pdata->matchstring, pdata->options, - pdata->is_regex); + return qof_query_string_predicate (pd->how, pdata->matchstring, + pdata->options, + pdata->is_regex); } -static gboolean string_predicate_equal (QofQueryPredData *p1, -QofQueryPredData *p2) +static gboolean +string_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2) { query_string_t pd1 = (query_string_t) p1; query_string_t pd2 = (query_string_t) p2; @@ -228,9 +217,10 @@ QofQueryPredData *p2) return (safe_strcmp (pd1->matchstring, pd2->matchstring) == 0); } -QofQueryPredData *qof_query_string_predicate (QofQueryCompare how, - char *str, QofStringMatch options, - gboolean is_regex) +QofQueryPredData * +qof_query_string_predicate (QofQueryCompare how, + char *str, QofStringMatch options, + gboolean is_regex) { query_string_t pdata; @@ -256,17 +246,20 @@ QofQueryPredData *qof_query_string_predicate (QofQueryCompare how, return ((QofQueryPredData*)pdata); } -static char * string_to_string (gpointer object, QofAccessFunc get) +static char * +string_to_string (gpointer object, QofParam *getter) { - const char *res = ((query_string_getter)get)(object); + const char *res; + res = ((query_string_getter)getter->param_getfcn)(object, getter); if (res) return g_strdup (res); return NULL; } -/* QOF_TYPE_DATE */ +/* QOF_TYPE_DATE =================================================== */ -static int date_compare (Timespec ta, Timespec tb, QofDateMatch options) +static int +date_compare (Timespec ta, Timespec tb, QofDateMatch options) { if (options == QOF_DATE_MATCH_ROUNDED) { ta = timespecCanonicalDayTime (ta); @@ -286,7 +279,8 @@ static int date_compare (Timespec ta, Timespec tb, QofDateMatch options) return 0; } -static int date_match_predicate (gpointer object, QofAccessFunc get_fcn, +static int +date_match_predicate (gpointer object, QofParam *getter, QofQueryPredData *pd) { query_date_t pdata = (query_date_t)pd; @@ -295,7 +289,7 @@ static int date_match_predicate (gpointer object, QofAccessFunc get_fcn, VERIFY_PREDICATE (query_date_type); - objtime = ((query_date_getter)get_fcn) (object); + objtime = ((query_date_getter)getter->param_getfcn) (object, getter); compare = date_compare (objtime, pdata->date, pdata->options); switch (pd->how) { @@ -317,20 +311,21 @@ static int date_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static int date_compare_func (gpointer a, gpointer b, gint options, - QofAccessFunc get_fcn) +static int +date_compare_func (gpointer a, gpointer b, gint options, QofParam *getter) { Timespec ta, tb; - g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR); + g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR); - ta = ((query_date_getter)get_fcn) (a); - tb = ((query_date_getter)get_fcn) (b); + ta = ((query_date_getter)getter->param_getfcn) (a, getter); + tb = ((query_date_getter)getter->param_getfcn) (b, getter); return date_compare (ta, tb, options); } -static void date_free_pdata (QofQueryPredData *pd) +static void +date_free_pdata (QofQueryPredData *pd) { query_date_t pdata = (query_date_t)pd; @@ -349,7 +344,8 @@ date_copy_predicate (QofQueryPredData *pd) return qof_query_date_predicate (pd->how, pdata->options, pdata->date); } -static gboolean date_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2) +static gboolean +date_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2) { query_date_t pd1 = (query_date_t) p1; query_date_t pd2 = (query_date_t) p2; @@ -360,7 +356,7 @@ static gboolean date_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2 QofQueryPredData * qof_query_date_predicate (QofQueryCompare how, - QofDateMatch options, Timespec date) + QofDateMatch options, Timespec date) { query_date_t pdata; @@ -372,9 +368,10 @@ qof_query_date_predicate (QofQueryCompare how, return ((QofQueryPredData*)pdata); } -static char * date_to_string (gpointer object, QofAccessFunc get) +static char * +date_to_string (gpointer object, QofParam *getter) { - Timespec ts = ((query_date_getter)get)(object); + Timespec ts = ((query_date_getter)getter->param_getfcn)(object, getter); if (ts.tv_sec || ts.tv_nsec) return g_strdup (gnc_print_date (ts)); @@ -382,10 +379,11 @@ static char * date_to_string (gpointer object, QofAccessFunc get) return NULL; } -/* QOF_TYPE_NUMERIC */ +/* QOF_TYPE_NUMERIC ================================================= */ -static int numeric_match_predicate (gpointer object, QofAccessFunc get_fcn, - QofQueryPredData* pd) +static int +numeric_match_predicate (gpointer object, QofParam *getter, + QofQueryPredData* pd) { query_numeric_t pdata = (query_numeric_t)pd; gnc_numeric obj_val; @@ -393,7 +391,7 @@ static int numeric_match_predicate (gpointer object, QofAccessFunc get_fcn, VERIFY_PREDICATE (query_numeric_type); - obj_val = ((query_numeric_getter)get_fcn) (object); + obj_val = ((query_numeric_getter)getter->param_getfcn) (object, getter); switch (pdata->options) { case QOF_NUMERIC_MATCH_CREDIT: @@ -436,20 +434,21 @@ static int numeric_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static int numeric_compare_func (gpointer a, gpointer b, gint options, - QofAccessFunc get_fcn) +static int +numeric_compare_func (gpointer a, gpointer b, gint options, QofParam *getter) { gnc_numeric va, vb; - g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR); + g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR); - va = ((query_numeric_getter)get_fcn) (a); - vb = ((query_numeric_getter)get_fcn) (b); + va = ((query_numeric_getter)getter->param_getfcn) (a, getter); + vb = ((query_numeric_getter)getter->param_getfcn) (b, getter); return gnc_numeric_compare (va, vb); } -static void numeric_free_pdata (QofQueryPredData* pd) +static void +numeric_free_pdata (QofQueryPredData* pd) { query_numeric_t pdata = (query_numeric_t)pd; VERIFY_PDATA (query_numeric_type); @@ -476,8 +475,8 @@ numeric_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2) QofQueryPredData * qof_query_numeric_predicate (QofQueryCompare how, - QofNumericMatch options, - gnc_numeric value) + QofNumericMatch options, + gnc_numeric value) { query_numeric_t pdata; pdata = g_new0 (query_numeric_def, 1); @@ -488,24 +487,29 @@ qof_query_numeric_predicate (QofQueryCompare how, return ((QofQueryPredData*)pdata); } -static char * numeric_to_string (gpointer object, QofAccessFunc get) +static char * +numeric_to_string (gpointer object, QofParam *getter) { - gnc_numeric num = ((query_numeric_getter)get)(object); + gnc_numeric num; + num = ((query_numeric_getter)getter->param_getfcn)(object, getter); return g_strdup (gnc_numeric_to_string (num)); } -static char * debcred_to_string (gpointer object, QofAccessFunc get) +static char * +debcred_to_string (gpointer object, QofParam *getter) { - gnc_numeric num = ((query_numeric_getter)get)(object); + gnc_numeric num; + num = ((query_numeric_getter)getter->param_getfcn)(object, getter); return g_strdup (gnc_numeric_to_string (num)); } -/* QOF_TYPE_GUID */ +/* QOF_TYPE_GUID =================================================== */ -static int guid_match_predicate (gpointer object, QofAccessFunc get_fcn, - QofQueryPredData *pd) +static int +guid_match_predicate (gpointer object, QofParam *getter, + QofQueryPredData *pd) { query_guid_t pdata = (query_guid_t)pd; GList *node, *o_list; @@ -516,17 +520,18 @@ static int guid_match_predicate (gpointer object, QofAccessFunc get_fcn, switch (pdata->options) { case QOF_GUID_MATCH_ALL: - /* object is a GList of objects; get_fcn must be called on each one. + /* object is a GList of objects; param_getfcn must be called on each one. * See if every guid in the predicate is accounted-for in the * object list */ - for (node = pdata->guids; node; node = node->next) { - + for (node = pdata->guids; node; node = node->next) + { /* See if this GUID matches the object's guid */ - for (o_list = object; o_list; o_list = o_list->next) { - guid = ((query_guid_getter)get_fcn) (o_list->data); - if (guid_equal (node->data, guid)) + for (o_list = object; o_list; o_list = o_list->next) + { + guid = ((query_guid_getter)getter->param_getfcn) (o_list->data, getter); + if (guid_equal (node->data, guid)) break; } @@ -549,17 +554,19 @@ static int guid_match_predicate (gpointer object, QofAccessFunc get_fcn, case QOF_GUID_MATCH_LIST_ANY: /* object is a single object, getter returns a GList* of GUID* * - * see if any GUID* in the returned list matches any guid in the - * predicate match list + * See if any GUID* in the returned list matches any guid in the + * predicate match list. */ - o_list = ((query_glist_getter)get_fcn) (object); + o_list = ((query_glist_getter)getter->param_getfcn) (object, getter); - for (node = o_list; node; node = node->next) { + for (node = o_list; node; node = node->next) + { GList *node2; /* Search the predicate data for a match */ - for (node2 = pdata->guids; node2; node2 = node2->next) { + for (node2 = pdata->guids; node2; node2 = node2->next) + { if (guid_equal (node->data, node2->data)) break; } @@ -583,8 +590,9 @@ static int guid_match_predicate (gpointer object, QofAccessFunc get_fcn, * See if the guid is in the list */ - guid = ((query_guid_getter)get_fcn) (object); - for (node = pdata->guids; node; node = node->next) { + guid = ((query_guid_getter)getter->param_getfcn) (object, getter); + for (node = pdata->guids; node; node = node->next) + { if (guid_equal (node->data, guid)) break; } @@ -608,13 +616,16 @@ static int guid_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static void guid_free_pdata (QofQueryPredData *pd) +static void +guid_free_pdata (QofQueryPredData *pd) { query_guid_t pdata = (query_guid_t)pd; GList *node; VERIFY_PDATA (query_guid_type); for (node = pdata->guids; node; node = node->next) + { guid_free (node->data); + } g_list_free (pdata->guids); g_free (pdata); } @@ -637,8 +648,10 @@ guid_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2) if (pd1->options != pd2->options) return FALSE; if (g_list_length (l1) != g_list_length (l2)) return FALSE; for ( ; l1 ; l1 = l1->next, l2 = l2->next) + { if (!guid_equal (l1->data, l2->data)) return FALSE; + } return TRUE; } @@ -653,7 +666,8 @@ qof_query_guid_predicate (QofGuidMatch options, GList *guids) pdata->pd.type_name = query_guid_type; pdata->options = options; pdata->guids = g_list_copy (guids); - for (node = pdata->guids; node; node = node->next) { + for (node = pdata->guids; node; node = node->next) + { GUID *guid = guid_malloc (); *guid = *((GUID *)node->data); node->data = guid; @@ -664,15 +678,16 @@ qof_query_guid_predicate (QofGuidMatch options, GList *guids) /* ================================================================ */ /* QOF_TYPE_INT32 */ -static int int32_match_predicate (gpointer object, QofAccessFunc get_fcn, - QofQueryPredData *pd) +static int +int32_match_predicate (gpointer object, QofParam *getter, + QofQueryPredData *pd) { gint32 val; query_int32_t pdata = (query_int32_t)pd; VERIFY_PREDICATE (query_int32_type); - val = ((query_int32_getter)get_fcn) (object); + val = ((query_int32_getter)getter->param_getfcn) (object, getter); switch (pd->how) { case QOF_COMPARE_LT: @@ -693,21 +708,23 @@ static int int32_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static int int32_compare_func (gpointer a, gpointer b, gint options, - QofAccessFunc get_fcn) +static int +int32_compare_func (gpointer a, gpointer b, gint options, + QofParam *getter) { gint32 v1, v2; - g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR); + g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR); - v1 = ((query_int32_getter)get_fcn)(a); - v2 = ((query_int32_getter)get_fcn)(b); + v1 = ((query_int32_getter)getter->param_getfcn)(a, getter); + v2 = ((query_int32_getter)getter->param_getfcn)(b, getter); if (v1 < v2) return -1; if (v1 > v2) return 1; return 0; } -static void int32_free_pdata (QofQueryPredData *pd) +static void +int32_free_pdata (QofQueryPredData *pd) { query_int32_t pdata = (query_int32_t)pd; VERIFY_PDATA (query_int32_type); @@ -741,9 +758,10 @@ qof_query_int32_predicate (QofQueryCompare how, gint32 val) return ((QofQueryPredData*)pdata); } -static char * int32_to_string (gpointer object, QofAccessFunc get) +static char * +int32_to_string (gpointer object, QofParam *getter) { - gint32 num = ((query_int32_getter)get)(object); + gint32 num = ((query_int32_getter)getter->param_getfcn)(object, getter); return g_strdup_printf ("%d", num); } @@ -751,15 +769,16 @@ static char * int32_to_string (gpointer object, QofAccessFunc get) /* ================================================================ */ /* QOF_TYPE_INT64 */ -static int int64_match_predicate (gpointer object, QofAccessFunc get_fcn, - QofQueryPredData *pd) +static int +int64_match_predicate (gpointer object, QofParam *getter, + QofQueryPredData *pd) { gint64 val; query_int64_t pdata = (query_int64_t)pd; VERIFY_PREDICATE (query_int64_type); - val = ((query_int64_getter)get_fcn) (object); + val = ((query_int64_getter)getter->param_getfcn) (object, getter); switch (pd->how) { case QOF_COMPARE_LT: @@ -780,21 +799,23 @@ static int int64_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static int int64_compare_func (gpointer a, gpointer b, gint options, - QofAccessFunc get_fcn) +static int +int64_compare_func (gpointer a, gpointer b, gint options, + QofParam *getter) { gint64 v1, v2; - g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR); + g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR); - v1 = ((query_int64_getter)get_fcn)(a); - v2 = ((query_int64_getter)get_fcn)(b); + v1 = ((query_int64_getter)getter->param_getfcn)(a, getter); + v2 = ((query_int64_getter)getter->param_getfcn)(b, getter); if (v1 < v2) return -1; if (v1 > v2) return 1; return 0; } -static void int64_free_pdata (QofQueryPredData *pd) +static void +int64_free_pdata (QofQueryPredData *pd) { query_int64_t pdata = (query_int64_t)pd; VERIFY_PDATA (query_int64_type); @@ -828,9 +849,10 @@ qof_query_int64_predicate (QofQueryCompare how, gint64 val) return ((QofQueryPredData*)pdata); } -static char * int64_to_string (gpointer object, QofAccessFunc get) +static char * +int64_to_string (gpointer object, QofParam *getter) { - gint64 num = ((query_int64_getter)get)(object); + gint64 num = ((query_int64_getter)getter->param_getfcn)(object, getter); return g_strdup_printf (GNC_SCANF_LLD, num); } @@ -838,15 +860,16 @@ static char * int64_to_string (gpointer object, QofAccessFunc get) /* ================================================================ */ /* QOF_TYPE_DOUBLE */ -static int double_match_predicate (gpointer object, QofAccessFunc get_fcn, - QofQueryPredData *pd) +static int +double_match_predicate (gpointer object, QofParam *getter, + QofQueryPredData *pd) { double val; query_double_t pdata = (query_double_t)pd; VERIFY_PREDICATE (query_double_type); - val = ((query_double_getter)get_fcn) (object); + val = ((query_double_getter)getter->param_getfcn) (object, getter); switch (pd->how) { case QOF_COMPARE_LT: @@ -867,21 +890,23 @@ static int double_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static int double_compare_func (gpointer a, gpointer b, gint options, - QofAccessFunc get_fcn) +static int +double_compare_func (gpointer a, gpointer b, gint options, + QofParam *getter) { double v1, v2; - g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR); + g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR); - v1 = ((query_double_getter)get_fcn) (a); - v2 = ((query_double_getter)get_fcn) (b); + v1 = ((query_double_getter)getter->param_getfcn) (a, getter); + v2 = ((query_double_getter)getter->param_getfcn) (b, getter); if (v1 < v2) return -1; if (v1 > v2) return 1; return 0; } -static void double_free_pdata (QofQueryPredData *pd) +static void +double_free_pdata (QofQueryPredData *pd) { query_double_t pdata = (query_double_t)pd; VERIFY_PDATA (query_double_type); @@ -915,24 +940,26 @@ qof_query_double_predicate (QofQueryCompare how, double val) return ((QofQueryPredData*)pdata); } -static char * double_to_string (gpointer object, QofAccessFunc get) +static char * +double_to_string (gpointer object, QofParam *getter) { - double num = ((query_double_getter)get)(object); + double num = ((query_double_getter)getter->param_getfcn)(object, getter); return g_strdup_printf ("%f", num); } -/* QOF_TYPE_BOOLEAN */ +/* QOF_TYPE_BOOLEAN =================================================== */ -static int boolean_match_predicate (gpointer object, QofAccessFunc get_fcn, - QofQueryPredData *pd) +static int +boolean_match_predicate (gpointer object, QofParam *getter, + QofQueryPredData *pd) { gboolean val; query_boolean_t pdata = (query_boolean_t)pd; VERIFY_PREDICATE (query_boolean_type); - val = ((query_boolean_getter)get_fcn) (object); + val = ((query_boolean_getter)getter->param_getfcn) (object, getter); switch (pd->how) { case QOF_COMPARE_EQUAL: @@ -945,19 +972,21 @@ static int boolean_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static int boolean_compare_func (gpointer a, gpointer b, gint options, - QofAccessFunc get_fcn) +static int +boolean_compare_func (gpointer a, gpointer b, gint options, + QofParam *getter) { gboolean va, vb; - g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR); - va = ((query_boolean_getter)get_fcn) (a); - vb = ((query_boolean_getter)get_fcn) (b); + g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR); + va = ((query_boolean_getter)getter->param_getfcn) (a, getter); + vb = ((query_boolean_getter)getter->param_getfcn) (b, getter); if (!va && vb) return -1; if (va && !vb) return 1; return 0; } -static void boolean_free_pdata (QofQueryPredData *pd) +static void +boolean_free_pdata (QofQueryPredData *pd) { query_boolean_t pdata = (query_boolean_t)pd; VERIFY_PDATA (query_boolean_type); @@ -994,16 +1023,18 @@ qof_query_boolean_predicate (QofQueryCompare how, gboolean val) return ((QofQueryPredData*)pdata); } -static char * boolean_to_string (gpointer object, QofAccessFunc get) +static char * +boolean_to_string (gpointer object, QofParam *getter) { - gboolean num = ((query_boolean_getter)get)(object); + gboolean num = ((query_boolean_getter)getter->param_getfcn)(object, getter); return g_strdup_printf ("%s", (num ? "X" : "")); } -/* QOF_TYPE_CHAR */ +/* QOF_TYPE_CHAR =================================================== */ -static int char_match_predicate (gpointer object, QofAccessFunc get_fcn, +static int +char_match_predicate (gpointer object, QofParam *getter, QofQueryPredData *pd) { char c; @@ -1011,7 +1042,7 @@ static int char_match_predicate (gpointer object, QofAccessFunc get_fcn, VERIFY_PREDICATE (query_char_type); - c = ((query_char_getter)get_fcn) (object); + c = ((query_char_getter)getter->param_getfcn) (object, getter); switch (pdata->options) { case QOF_CHAR_MATCH_ANY: @@ -1026,17 +1057,18 @@ static int char_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static int char_compare_func (gpointer a, gpointer b, gint options, - QofAccessFunc get_fcn) +static int +char_compare_func (gpointer a, gpointer b, gint options, QofParam *getter) { char va, vb; - g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR); - va = ((query_char_getter)get_fcn)(a); - vb = ((query_char_getter)get_fcn)(b); + g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR); + va = ((query_char_getter)getter->param_getfcn)(a, getter); + vb = ((query_char_getter)getter->param_getfcn)(b, getter); return (va-vb); } -static void char_free_pdata (QofQueryPredData *pd) +static void +char_free_pdata (QofQueryPredData *pd) { query_char_t pdata = (query_char_t)pd; VERIFY_PDATA (query_char_type); @@ -1075,17 +1107,19 @@ qof_query_char_predicate (QofCharMatch options, const char *chars) return ((QofQueryPredData*)pdata); } -static char * char_to_string (gpointer object, QofAccessFunc get) +static char * +char_to_string (gpointer object, QofParam *getter) { - char num = ((query_char_getter)get)(object); + char num = ((query_char_getter)getter->param_getfcn)(object, getter); return g_strdup_printf ("%c", num); } -/* QOF_TYPE_KVP */ +/* QOF_TYPE_KVP ================================================ */ -static int kvp_match_predicate (gpointer object, QofAccessFunc get_fcn, - QofQueryPredData *pd) +static int +kvp_match_predicate (gpointer object, QofParam *getter, + QofQueryPredData *pd) { int compare; KvpFrame *kvp; @@ -1094,7 +1128,7 @@ static int kvp_match_predicate (gpointer object, QofAccessFunc get_fcn, VERIFY_PREDICATE (query_kvp_type); - kvp = ((query_kvp_getter)get_fcn) (object); + kvp = ((query_kvp_getter)getter->param_getfcn) (object, getter); if (!kvp) return 0; @@ -1127,14 +1161,16 @@ static int kvp_match_predicate (gpointer object, QofAccessFunc get_fcn, } } -static void kvp_free_pdata (QofQueryPredData *pd) +static void +kvp_free_pdata (QofQueryPredData *pd) { query_kvp_t pdata = (query_kvp_t)pd; GSList *node; VERIFY_PDATA (query_kvp_type); kvp_value_delete (pdata->value); - for (node = pdata->path; node; node = node->next) { + for (node = pdata->path; node; node = node->next) + { g_free (node->data); node->data = NULL; } @@ -1161,8 +1197,10 @@ kvp_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2) n2 = pd2->path; for ( ; n1 && n2; n1 = n1->next, n2 = n2->next) + { if (safe_strcmp (n1->data, n2->data) != 0) return FALSE; + } if (n1 || n2) return FALSE; @@ -1172,7 +1210,7 @@ kvp_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2) QofQueryPredData * qof_query_kvp_predicate (QofQueryCompare how, - GSList *path, const KvpValue *value) + GSList *path, const KvpValue *value) { query_kvp_t pdata; GSList *node; @@ -1190,20 +1228,63 @@ qof_query_kvp_predicate (QofQueryCompare how, return ((QofQueryPredData*)pdata); } -/* initialization */ +/* initialization ================================================== */ +/** This function registers a new Core Object with the QofQuery + * subsystem. It maps the "core_name" object to the given + * query_predicate, predicate_copy, and predicate_data_free functions. + * + * An example: + * qof_query_register_core_object (QOF_TYPE_STRING, string_match_predicate, + * string_compare_fcn, string_free_pdata, + * string_print_fcn, pred_equal_fcn); + */ + + +static void +qof_query_register_core_object (QofType core_name, + QofQueryPredicateFunc pred, + QofCompareFunc comp, + QueryPredicateCopyFunc copy, + QueryPredDataFree pd_free, + QueryToString toString, + QueryPredicateEqual pred_equal) +{ + g_return_if_fail (core_name); + g_return_if_fail (*core_name != '\0'); + + if (pred) + g_hash_table_insert (predTable, (char *)core_name, pred); + + if (comp) + g_hash_table_insert (cmpTable, (char *)core_name, comp); + + if (copy) + g_hash_table_insert (copyTable, (char *)core_name, copy); + + if (pd_free) + g_hash_table_insert (freeTable, (char *)core_name, pd_free); + + if (toString) + g_hash_table_insert (toStringTable, (char *)core_name, toString); + + if (pred_equal) + g_hash_table_insert (predEqualTable, (char *)core_name, pred_equal); +} static void init_tables (void) { unsigned int i; - struct { - char const *name; - QofQueryPredicateFunc pred; - QofCompareFunc comp; + struct + { + QofType name; + QofQueryPredicateFunc pred; + QofCompareFunc comp; QueryPredicateCopyFunc copy; - QueryPredDataFree pd_free; - QueryToString toString; - QueryPredicateEqual pred_equal; - } knownTypes[] = { + QueryPredDataFree pd_free; + QueryToString toString; + QueryPredicateEqual pred_equal; + } knownTypes[] = + { { QOF_TYPE_STRING, string_match_predicate, string_compare_func, string_copy_predicate, string_free_pdata, string_to_string, string_predicate_equal }, @@ -1239,7 +1320,8 @@ static void init_tables (void) }; /* Register the known data types */ - for (i = 0; i < (sizeof(knownTypes)/sizeof(*knownTypes)); i++) { + for (i = 0; i < (sizeof(knownTypes)/sizeof(*knownTypes)); i++) + { qof_query_register_core_object (knownTypes[i].name, knownTypes[i].pred, knownTypes[i].comp, @@ -1250,7 +1332,8 @@ static void init_tables (void) } } -static QueryPredicateCopyFunc gncQueryCoreGetCopy (char const *type) +static QueryPredicateCopyFunc +qof_query_copy_predicate (QofType type) { QueryPredicateCopyFunc rc; g_return_val_if_fail (type, NULL); @@ -1258,43 +1341,13 @@ static QueryPredicateCopyFunc gncQueryCoreGetCopy (char const *type) return rc; } -static QueryPredDataFree gncQueryCoreGetPredFree (char const *type) +static QueryPredDataFree +qof_query_predicate_free (QofType type) { g_return_val_if_fail (type, NULL); return g_hash_table_lookup (freeTable, type); } -static void -qof_query_register_core_object (char const *core_name, - QofQueryPredicateFunc pred, - QofCompareFunc comp, - QueryPredicateCopyFunc copy, - QueryPredDataFree pd_free, - QueryToString toString, - QueryPredicateEqual pred_equal) -{ - g_return_if_fail (core_name); - g_return_if_fail (*core_name != '\0'); - - if (pred) - g_hash_table_insert (predTable, (char *)core_name, pred); - - if (comp) - g_hash_table_insert (cmpTable, (char *)core_name, comp); - - if (copy) - g_hash_table_insert (copyTable, (char *)core_name, copy); - - if (pd_free) - g_hash_table_insert (freeTable, (char *)core_name, pd_free); - - if (toString) - g_hash_table_insert (toStringTable, (char *)core_name, toString); - - if (pred_equal) - g_hash_table_insert (predEqualTable, (char *)core_name, pred_equal); -} - /********************************************************************/ /* PUBLISHED API FUNCTIONS */ @@ -1329,14 +1382,14 @@ void qof_query_core_shutdown (void) } QofQueryPredicateFunc -qof_query_core_get_predicate (char const *type) +qof_query_core_get_predicate (QofType type) { g_return_val_if_fail (type, NULL); return g_hash_table_lookup (predTable, type); } QofCompareFunc -qof_query_core_get_compare (char const *type) +qof_query_core_get_compare (QofType type) { g_return_val_if_fail (type, NULL); return g_hash_table_lookup (cmpTable, type); @@ -1350,7 +1403,7 @@ qof_query_core_predicate_free (QofQueryPredData *pdata) g_return_if_fail (pdata); g_return_if_fail (pdata->type_name); - free_fcn = gncQueryCoreGetPredFree (pdata->type_name); + free_fcn = qof_query_predicate_free (pdata->type_name); free_fcn (pdata); } @@ -1362,24 +1415,24 @@ qof_query_core_predicate_copy (QofQueryPredData *pdata) g_return_val_if_fail (pdata, NULL); g_return_val_if_fail (pdata->type_name, NULL); - copy = gncQueryCoreGetCopy (pdata->type_name); + copy = qof_query_copy_predicate (pdata->type_name); return (copy (pdata)); } char * -qof_query_core_to_string (char const *type, gpointer object, - QofAccessFunc get) +qof_query_core_to_string (QofType type, gpointer object, + QofParam *getter) { QueryToString toString; g_return_val_if_fail (type, NULL); g_return_val_if_fail (object, NULL); - g_return_val_if_fail (get, NULL); + g_return_val_if_fail (getter, NULL); toString = g_hash_table_lookup (toStringTable, type); g_return_val_if_fail (toString, NULL); - return toString (object, get); + return toString (object, getter); } gboolean diff --git a/src/engine/qofquerycore.h b/src/engine/qofquerycore.h index ff994dec55..0e1e227794 100644 --- a/src/engine/qofquerycore.h +++ b/src/engine/qofquerycore.h @@ -146,7 +146,6 @@ void qof_query_core_predicate_free (QofQueryPredData *pdata); /** Return a printable string for a core data object. Caller needs * to g_free() the returned string. */ -char * qof_query_core_to_string (char const *type, gpointer object, - QofAccessFunc fcn); +char * qof_query_core_to_string (QofType, gpointer object, QofParam *getter); #endif /* QOF_QUERYCORE_H */ diff --git a/src/engine/qofsql.c b/src/engine/qofsql.c index 0f90a721e9..a3ba6e03fb 100644 --- a/src/engine/qofsql.c +++ b/src/engine/qofsql.c @@ -1,5 +1,5 @@ /********************************************************************\ - * qofsql.h -- QOF cleint-side SQL parser * + * qofsql.c -- QOF client-side SQL parser * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -25,8 +25,6 @@ @breif QOF client-side SQL parser. @author Copyright (C) 2004 Linas Vepstas - XXX: todo: replace printf error with proper error - handling/reporting. */ #include @@ -34,11 +32,16 @@ #include #include #include +#include #include #include #include #include +static short module = MOD_QUERY; + +/* =================================================================== */ + struct _QofSqlQuery { sql_statement *parse_result; @@ -168,7 +171,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) if (NULL == cond) { - printf ("Error: missing condition\n"); + PWARN("missing condition"); return NULL; } @@ -177,19 +180,20 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) /* XXX fix this so it can be either left or right */ if (NULL == cond->d.pair.left) { - printf ("Error: missing left paramter\n"); + PWARN("missing left paramter"); return NULL; } sql_field_item * sparam = cond->d.pair.left->item; if (SQL_name != sparam->type) { - printf ("Error: we support only paramter names\n"); + PWARN("we support only paramter names at this time (parsed %d)", + sparam->type); return NULL; } char * qparam_name = sparam->d.name->data; if (NULL == qparam_name) { - printf ("Error: we missing paramter name\n"); + PWARN ("missing paramter name"); return NULL; } @@ -198,19 +202,19 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) /* XXX fix this so it can be either left or right */ if (NULL == cond->d.pair.right) { - printf ("Error: missing right paramter\n"); + PWARN ("missing right paramter"); return NULL; } sql_field_item * svalue = cond->d.pair.right->item; if (SQL_name != svalue->type) { - printf ("Error: we support only simple values\n"); + PWARN("we support only simple values (parsed as %d)", svalue->type); return NULL; } char * qvalue_name = svalue->d.name->data; if (NULL == qvalue_name) { - printf ("Error: we missing value\n"); + PWARN("missing value"); return NULL; } qvalue_name = dequote_string (qvalue_name); @@ -222,7 +226,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) { if (NULL == query->kvp_join) { - printf ("Error: missing kvp frame\n"); + PWARN ("missing kvp frame"); return NULL; } KvpValue *kv = kvp_frame_get_value (query->kvp_join, qvalue_name+5); @@ -259,7 +263,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) case KVP_TYPE_GLIST: case KVP_TYPE_NUMERIC: case KVP_TYPE_FRAME: - printf ("Error: unhandled kvp type=%d\n", kvt); + PWARN ("unhandled kvp type=%d", kvt); return NULL; } } @@ -281,7 +285,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) default: /* XXX for string-type queries, we should be able to * support 'IN' for substring search. Also regex. */ - printf ("Error: unsupported compare op for now\n"); + PWARN ("Unsupported compare op (parsed as %s)", cond->op); return NULL; } @@ -298,11 +302,12 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) if (NULL == table_name) { - printf ("Error: Need to specify a table to query\n"); + PWARN ("Need to specify an object class to query"); return NULL; } QofType param_type = qof_class_get_parameter_type (table_name, param_name); + if (!param_type) return NULL; /* Can't happen */ if (!strcmp (param_type, QOF_TYPE_STRING)) { @@ -347,7 +352,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) int rc = qof_scan_date_secs (qvalue_name, &exact); if (0 == rc) { - printf ("Error: unable to parse date: %s\n", qvalue_name); + PWARN ("unable to parse date: %s", qvalue_name); return NULL; } Timespec ts; @@ -374,7 +379,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond) gboolean rc = string_to_guid (qvalue_name, guid); if (0 == rc) { - printf ("Error: unable to parse guid: %s\n", qvalue_name); + PWARN ("unable to parse guid: %s", qvalue_name); return NULL; } @@ -395,7 +400,7 @@ xxxxxhd #endif else { - printf ("Error: predicate type unsupported for now \n"); + PWARN ("The predicate type \"%s\" is unsupported for now", param_type); return NULL; } @@ -510,14 +515,14 @@ qof_sql_query_run (QofSqlQuery *query, const char *str) if (!query->parse_result) { - printf ("parse error\n"); // XXX replace + PWARN ("parse error"); return NULL; } if (SQL_select != query->parse_result->type) { - printf ("Error: currently, only SELECT statements are supported, " - "got type=%d\n", query->parse_result); + PWARN("currently, only SELECT statements are supported, " + "got type=%d", query->parse_result); return NULL; } diff --git a/src/engine/qofsql.h b/src/engine/qofsql.h index 42489e84a1..22b25b43da 100644 --- a/src/engine/qofsql.h +++ b/src/engine/qofsql.h @@ -1,5 +1,5 @@ /********************************************************************\ - * qofsql.h -- QOF cleint-side SQL parser * + * qofsql.h -- QOF client-side SQL parser * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -20,6 +20,8 @@ * * \********************************************************************/ +/** @addtogroup Engine + @{ */ /** @file qofsql.h @breif QOF client-side SQL parser. @@ -111,3 +113,4 @@ GList * qof_sql_query_run (QofSqlQuery *query, const char * str); void qof_sql_query_set_kvp (QofSqlQuery *, KvpFrame *); #endif /* QOF_SQL_QUERY_H */ +/** @} */ diff --git a/src/gnome-search/dialog-search.c b/src/gnome-search/dialog-search.c index 46fc92700d..5f096b911c 100644 --- a/src/gnome-search/dialog-search.c +++ b/src/gnome-search/dialog-search.c @@ -90,7 +90,7 @@ struct _GNCSearchWindow { /* What we're searching for, and how */ GNCIdTypeConst search_for; GNCSearchType grouping; /* Match Any, Match All */ - QueryAccess get_guid; /* Function to GetGUID from the object */ + const QofParam * get_guid; /* Function to GetGUID from the object */ int search_type; /* New, Narrow, Add, Delete */ /* Our query status */ @@ -441,14 +441,15 @@ search_new_item_cb (GtkButton *button, GNCSearchWindow *sw) res = (sw->new_item_cb)(sw->user_data); - if (res) { - const GUID *guid = (const GUID *) ((sw->get_guid)(res)); + if (res) + { + const GUID *guid = (const GUID *) ((sw->get_guid->param_getfcn)(res, sw->get_guid)); QueryOp op = QUERY_OR; if (!sw->q) { if (!sw->start_q) { - sw->start_q = gncQueryCreateFor (sw->search_for); - gncQuerySetBook (sw->start_q, gnc_get_current_book ()); + sw->start_q = gncQueryCreateFor (sw->search_for); + gncQuerySetBook (sw->start_q, gnc_get_current_book ()); } sw->q = gncQueryCopy (sw->start_q); op = QUERY_AND; @@ -882,8 +883,8 @@ gnc_search_dialog_create (GNCIdTypeConst obj_type, GList *param_list, sw->free_cb = free_cb; /* Grab the get_guid function */ - sw->get_guid = gncQueryObjectGetParameterGetter (sw->search_for, - QUERY_PARAM_GUID); + sw->get_guid = qof_class_get_parameter (sw->search_for, + QOF_QUERY_PARAM_GUID); if (start_query) sw->start_q = gncQueryCopy (start_query); sw->q = show_start_query; diff --git a/src/gnome-search/gnc-general-search.c b/src/gnome-search/gnc-general-search.c index 2882143bf5..47969dcbd7 100644 --- a/src/gnome-search/gnc-general-search.c +++ b/src/gnome-search/gnc-general-search.c @@ -62,7 +62,7 @@ struct _GNCGeneralSearchPrivate { GNCSearchCB search_cb; gpointer user_data; GNCSearchWindow * sw; - QueryAccess get_guid; + const QofParam * get_guid; gint component_id; }; @@ -295,11 +295,11 @@ gnc_general_search_new (GNCIdTypeConst type, const char *label, GNCSearchCB search_cb, gpointer user_data) { GNCGeneralSearch *gsl; - QueryAccess get_guid; + const QofParam *get_guid; g_return_val_if_fail (type && label && search_cb, NULL); - get_guid = gncQueryObjectGetParameterGetter (type, QUERY_PARAM_GUID); + get_guid = qof_class_get_parameter (type, QOF_QUERY_PARAM_GUID); g_return_val_if_fail (get_guid, NULL); gsl = gtk_type_new (gnc_general_search_get_type ()); @@ -341,9 +341,11 @@ gnc_general_search_set_selected (GNCGeneralSearch *gsl, gpointer selection) gnc_gui_component_clear_watches (gsl->priv->component_id); - if (selection) { - gsl->priv->guid = * ((GUID *)(gsl->priv->get_guid - (gsl->selected_item))); + if (selection) + { + const QofParam *get_guid = gsl->priv->get_guid; + gsl->priv->guid = * ((GUID *)(get_guid->param_getfcn + (gsl->selected_item, get_guid))); gnc_gui_component_watch_entity (gsl->priv->component_id, &(gsl->priv->guid), GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); diff --git a/src/gnome-utils/gnc-query-list.c b/src/gnome-utils/gnc-query-list.c index 34677c6622..74e5708451 100644 --- a/src/gnome-utils/gnc-query-list.c +++ b/src/gnome-utils/gnc-query-list.c @@ -43,9 +43,10 @@ enum LAST_SIGNAL }; -struct _GNCQueryListPriv { - QueryAccess get_guid; - gint component_id; +struct _GNCQueryListPriv +{ + const QofParam * get_guid; + gint component_id; }; /* Impossible to get at runtime. Assume this is a reasonable number */ @@ -125,8 +126,8 @@ gnc_query_list_construct (GNCQueryList *list, GList *param_list, Query *query) /* cache the function to get the guid of this query type */ list->priv->get_guid = - gncQueryObjectGetParameterGetter (gncQueryGetSearchFor (query), - QUERY_PARAM_GUID); + qof_class_get_parameter (qof_query_get_search_for(query), + QOF_QUERY_PARAM_GUID); /* Initialize the CList */ gnc_query_list_init_clist(list); @@ -776,6 +777,7 @@ gnc_query_list_fill(GNCQueryList *list) { GList *node; gint row; + QofParam *qp= NULL; for (i = 0, node = list->column_params; node; node = node->next) { @@ -783,33 +785,35 @@ gnc_query_list_fill(GNCQueryList *list) GSList *converters = gnc_search_param_get_converters (param); const char *type = gnc_search_param_get_param_type (param); gpointer res = item->data; - QueryAccess fcn = NULL; /* if this is a boolean, ignore it now -- we'll use a checkmark later */ if (!safe_strcmp (type, QUERYCORE_BOOLEAN)) { - strings[i++] = g_strdup(""); - continue; + strings[i++] = g_strdup(""); + continue; } /* Do all the object conversions */ - for (; converters; converters = converters->next) { - fcn = converters->data; - - if (converters->next) - res = fcn (res); + for (; converters; converters = converters->next) + { + qp = converters->data; + if (converters->next) + { + res = (qp->param_getfcn)(res, qp); + } } /* Now convert this to a text value for the row */ if (!safe_strcmp(type, QUERYCORE_DEBCRED) || - !safe_strcmp(type, QUERYCORE_NUMERIC)) + !safe_strcmp(type, QUERYCORE_NUMERIC)) { - gnc_numeric (*nfcn)(gpointer) = (gnc_numeric(*)(gpointer))fcn; - gnc_numeric value = nfcn(res); - if (list->numeric_abs) - value = gnc_numeric_abs (value); - strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE))); + gnc_numeric (*nfcn)(gpointer, QofParam *) = + (gnc_numeric(*)(gpointer, QofParam *))(qp->param_getfcn); + gnc_numeric value = nfcn(res, qp); + if (list->numeric_abs) + value = gnc_numeric_abs (value); + strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE))); } else - strings[i++] = gncQueryCoreToString (type, res, fcn); + strings[i++] = gncQueryCoreToString (type, res, qp); } row = gtk_clist_append (GTK_CLIST(list), (gchar **) strings); @@ -818,14 +822,15 @@ gnc_query_list_fill(GNCQueryList *list) /* Free up our strings */ for (i = 0; i < list->num_columns; i++) { if (strings[i]) - g_free (strings[i]); + g_free (strings[i]); } /* Now update any checkmarks */ update_booleans (list, row); /* and set a watcher on this item */ - guid = (const GUID*)((list->priv->get_guid)(item->data)); + const QofParam *gup = list->priv->get_guid; + guid = (const GUID*)((gup->param_getfcn)(item->data, gup)); gnc_gui_component_watch_entity (list->priv->component_id, guid, GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); diff --git a/src/gnome-utils/search-param.c b/src/gnome-utils/search-param.c index 988fa90f88..e9d38d27a1 100644 --- a/src/gnome-utils/search-param.c +++ b/src/gnome-utils/search-param.c @@ -171,7 +171,7 @@ gnc_search_param_set_param_path (GNCSearchParam *param, break; /* Save the converter */ - converters = g_slist_prepend (converters, objDef->param_getfcn); + converters = g_slist_prepend (converters, (gpointer) objDef); /* And reset for the next parameter */ type = search_type = objDef->param_type; @@ -372,13 +372,13 @@ gnc_search_param_compute_value (GNCSearchParam *param, gpointer object) else { GSList *converters = gnc_search_param_get_converters (param); - QueryAccess fcn = NULL; gpointer res = object; /* Do all the object conversions */ - for (; converters; converters = converters->next) { - fcn = converters->data; - res = fcn (res); + for (; converters; converters = converters->next) + { + QofParam *qp = converters->data; + res = (qp->param_getfcn) (res, qp); } return res;