diff --git a/src/engine/FreqSpec.c b/src/engine/FreqSpec.c index fe12d9acae..5a48a71170 100644 --- a/src/engine/FreqSpec.c +++ b/src/engine/FreqSpec.c @@ -278,6 +278,8 @@ xaccFreqSpecGetNextInstance( FreqSpec *fs, GList *list; g_return_if_fail( fs ); + g_return_if_fail( in_date ); + g_return_if_fail( out_date ); switch( fs->type ) { case INVALID: /* this is okay, just lame. */ diff --git a/src/engine/FreqSpec.h b/src/engine/FreqSpec.h index fd947a2904..11065c5986 100644 --- a/src/engine/FreqSpec.h +++ b/src/engine/FreqSpec.h @@ -207,9 +207,12 @@ GList* xaccFreqSpecCompositeGet( FreqSpec *fs ); void xaccFreqSpecCompositeAdd( FreqSpec *fs, FreqSpec *fsToAdd ); /** - * Returns the next instance of the FreqSpec after a given input date. - * Note that if the given date happens to be a repeat date, - * then the next repeat date will be returned. + * Computes the next instance of the FreqSpec after a given input date. + * The object pointed at by 'out_date' is set to the computed value. + * The 'in_date' can be any date. It is gaurenteed that the 'out_date' + * is strictly greater than the 'in_date'. That is, if the 'in_date' + * happens to be a repeat date (e.g. a previous out_date), then + * the out_date will be the next repeat date after that. **/ void xaccFreqSpecGetNextInstance( FreqSpec *fs, const GDate* in_date, diff --git a/src/engine/qofquery.c b/src/engine/qofquery.c index 3bb22ee211..884f60afd1 100644 --- a/src/engine/qofquery.c +++ b/src/engine/qofquery.c @@ -287,9 +287,9 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort, g_return_val_if_fail (default_sort, 0); /* See if this is a default sort */ - if (sort->use_default) { - if (default_sort) - return default_sort ((gpointer)a, (gpointer)b); + if (sort->use_default) + { + if (default_sort) return default_sort ((gpointer)a, (gpointer)b); return 0; } @@ -302,7 +302,8 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort, /* Do the list of conversions */ conva = (gpointer)a; convb = (gpointer)b; - for (node = sort->param_fcns; node; node = node->next) { + for (node = sort->param_fcns; node; node = node->next) + { get_fcn = node->data; /* The last term is really the "parameter getter", @@ -314,10 +315,12 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort, conva = get_fcn (conva); convb = get_fcn (convb); } - /* And now return the (appropriate) compare */ if (sort->comp_fcn) - return sort->comp_fcn (conva, convb, sort->options, get_fcn); + { + int rc = sort->comp_fcn (conva, convb, sort->options, get_fcn); + return rc; + } return sort->obj_cmp (conva, convb); } @@ -331,17 +334,23 @@ static int sort_func (gconstpointer a, gconstpointer b) g_return_val_if_fail (sortQuery, 0); retval = cmp_func (&(sortQuery->primary_sort), sortQuery->defaultSort, a, b); - if (retval == 0) { + if (retval == 0) + { retval = cmp_func (&(sortQuery->secondary_sort), sortQuery->defaultSort, a, b); - if (retval == 0) { + if (retval == 0) + { retval = cmp_func (&(sortQuery->tertiary_sort), sortQuery->defaultSort, a, b); return sortQuery->tertiary_sort.increasing ? retval : -retval; - } else { + } + else + { return sortQuery->secondary_sort.increasing ? retval : -retval; } - } else { + } + else + { return sortQuery->primary_sort.increasing ? retval : -retval; } } @@ -360,7 +369,7 @@ check_object (QofQuery *q, gpointer object) QofQueryTerm * qt; int and_terms_ok=1; - ENTER (" object=%p terms=%p\n", object, q->terms); + ENTER (" object=%p terms=%p", object, q->terms); for(or_ptr = q->terms; or_ptr; or_ptr = or_ptr->next) { and_terms_ok = 1; @@ -423,18 +432,18 @@ static GSList * compile_params (GSList *param_list, QofIdType start_obj, const QofQueryObject *objDef = NULL; GSList *fcns = NULL; - ENTER (" "); + ENTER ("param_list=%p id=%s", param_list, start_obj); g_return_val_if_fail (param_list, NULL); g_return_val_if_fail (start_obj, NULL); g_return_val_if_fail (final, NULL); - for (; param_list; param_list = param_list->next) { + for (; param_list; param_list = param_list->next) + { QofIdType param_name = param_list->data; objDef = qof_query_object_get_parameter (start_obj, param_name); /* If it doesn't exist, then we've reached the end */ - if (!objDef) - break; + if (!objDef) break; /* Save off this function */ fcns = g_slist_prepend (fcns, objDef->param_getfcn); @@ -446,7 +455,7 @@ static GSList * compile_params (GSList *param_list, QofIdType start_obj, start_obj = (QofIdType) objDef->param_type; } - LEAVE (" "); + LEAVE ("fcns=%p", fcns); return (g_slist_reverse (fcns)); } @@ -455,6 +464,7 @@ compile_sort (QofQuerySort *sort, QofIdType obj) { const QofQueryObject *resObj = NULL; + ENTER ("sort=%p id=%s params=%p", sort, obj, sort->param_list); sort->use_default = FALSE; g_slist_free (sort->param_fcns); @@ -463,8 +473,7 @@ compile_sort (QofQuerySort *sort, QofIdType obj) sort->obj_cmp = NULL; /* An empty param_list implies "no sort" */ - if (!sort->param_list) - return; + if (!sort->param_list) return; /* Walk the parameter list of obtain the parameter functions */ sort->param_fcns = compile_params (sort->param_list, obj, &resObj); @@ -472,15 +481,21 @@ compile_sort (QofQuerySort *sort, QofIdType obj) /* If we have valid parameters, grab the compare function, * If not, check if this is the default sort. */ - if (sort->param_fcns) { + if (sort->param_fcns) + { sort->comp_fcn = qof_query_core_get_compare (resObj->param_type); /* Hrm, perhaps this is an object compare, not a core compare? */ if (sort->comp_fcn == NULL) + { sort->obj_cmp = qof_query_object_default_sort (resObj->param_type); - - } else if (!safe_strcmp (sort->param_list->data, QUERY_DEFAULT_SORT)) + } + } + else if (!safe_strcmp (sort->param_list->data, QUERY_DEFAULT_SORT)) + { sort->use_default = TRUE; + } + LEAVE ("sort=%p id=%s", sort, obj); } static void compile_terms (QofQuery *q) @@ -687,6 +702,7 @@ GList * qof_query_run (QofQuery *q) ENTER (" q=%p", q); if (!q) return NULL; g_return_val_if_fail (q->search_for, NULL); + g_return_val_if_fail (q->books, NULL); /* XXX: Prioritize the query terms? */ @@ -749,7 +765,7 @@ GList * qof_query_run (QofQuery *q) matching_objects = g_list_sort(matching_objects, sort_func); sortQuery = NULL; - /* crop the list to limit the number of splits */ + /* Crop the list to limit the number of splits. */ if((object_count > q->max_results) && (q->max_results > -1)) { if(q->max_results > 0) diff --git a/src/engine/qofquery.h b/src/engine/qofquery.h index 66f180c1d5..3075050831 100644 --- a/src/engine/qofquery.h +++ b/src/engine/qofquery.h @@ -1,5 +1,5 @@ /********************************************************************\ - * qofquery.h -- API for finding objects that can be queried * + * qofquery.h -- find objects that match a certain expression. * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -21,8 +21,9 @@ \********************************************************************/ /** @file qofquery.h - @breif API for finding objects that can be queried + @breif find objects that match a certain expression. @author Copyright (C) 2002 Derek Atkins + @author Copyright (C) 2003 Linas Vepstas */ @@ -68,16 +69,23 @@ void qof_query_shutdown (void); GSList * qof_query_build_param_list (char const *param, ...); -/** Create a new query. A Query MUST be set with a 'search-for' type. - * you can create and set this value in one step or two */ +/** Create a new query. A Query MUST be set with a 'search-for' + * type. The results of the query is a list of the indicated + * search-for type. + */ QofQuery * qof_query_create (void); QofQuery * qof_query_create_for (QofIdTypeConst obj_type); void qof_query_destroy (QofQuery *q); -/** Set the object type to be searched for */ +/** Set the object type to be searched for. The results of + * performuing the query will be a list of this obj_type. + */ void qof_query_search_for (QofQuery *query, QofIdTypeConst obj_type); -/** Set the book to be searched (you can search multiple books) */ +/** Set the book to be searched (you can search multiple books) + * If no books are set, no results will be returned (since there + * is nothing to search over). + */ void qof_query_set_book (QofQuery *q, QofBook *book); @@ -109,13 +117,27 @@ void qof_query_add_guid_list_match (QofQuery *q, GSList *param_list, GList *guid_list, QofGuidMatch options, QofQueryOp op); -void qof_query_add_boolean_match (QofQuery *q, GSList *param_list, gboolean value, - QofQueryOp op); +void qof_query_add_boolean_match (QofQuery *q, + GSList *param_list, + gboolean value, + QofQueryOp op); -/** Run the query: */ +/** Perform the query, return the results. + * The returned list is a list of the 'search-for' type that was + * previously set with the qof_query_search_for() or the + * qof_query_create_for() routines. The returned list will have + * been sorted using the indicated sort order, and trimed to the + * max_results length. + * + * Do NOT free the resulting list. This list is managed internally + * by QofQuery. + */ GList * qof_query_run (QofQuery *query); -/** Return the results of the last query, without re-running */ +/** Return the results of the last query, without causing the query to + * be re-run. Do NOT free the resulting list. This list is managed + * internally by QofQuery. + */ GList * qof_query_last_run (QofQuery *query); void qof_query_clear (QofQuery *query); @@ -141,8 +163,25 @@ QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op); */ void qof_query_merge_in_place(QofQuery *q1, QofQuery *q2, QofQueryOp op); -/** The lists become the property of the Query and will be freed - * by the query when it is destroyed. +/** + * When a query is run, the results are sorted before being returned. + * This routine can be used to set the paramters on which the sort will + * be performed. Two objects in the result list will be compared using + * the 'primary_sort_params', and sorted based on that order. If the + * comparison shows that they are equal, then the + * 'secondary_sort_params' will be used. If still equal, then the + * tertiary params will be compared. Any or all of these parameter + * lists may be NULL. Any of these parameter lists may be set to + * QUERY_DEFAULT_SORT. + * + * Note that if there are more results than the 'max-results' value, + * then only the *last* max-results will be returned. For example, + * if the sort is set to be increasing date order, then only the + * objects with the most recent dates will be returned. + * + * The input lists become the property of QofQuery and are managed + * by it. They will be freed when the query is destroyed (or when + * new lists are set). */ void qof_query_set_sort_order (QofQuery *q, GSList *primary_sort_params, @@ -152,15 +191,39 @@ void qof_query_set_sort_order (QofQuery *q, void qof_query_set_sort_options (QofQuery *q, gint prim_op, gint sec_op, gint tert_op); +/** + * When a query is run, the results are sorted before being returned. + * This routine can be used to control the direction of the ordering. + * A value of TRUE indicates the sort will be in increasing order, + * a value of FALSE will order results in decreasing order. + * + * Note that if there are more results than the 'max-results' value, + * then only the *last* max-results will be returned. For example, + * if the sort is set to be increasing date order, then only the + * objects with the most recent dates will be returned. + */ void qof_query_set_sort_increasing (QofQuery *q, gboolean prim_inc, gboolean sec_inc, gboolean tert_inc); +/** + * Set the maximum number of results that should be returned. + * If 'max-results' is set to -1, then all of the results are + * returned. If there are more results than 'max-results', + * then the result list is trimmed. Note that there is an + * important interplay between 'max-results' and the sort order: + * only the last bit of results are returned. For example, + * if the sort order is set to be increasing date order, then + * only the objects with the most recent dates will be returned. + */ void qof_query_set_max_results (QofQuery *q, int n); -/** Compare two queries for equality. This is a simplistic +/** Compare two queries for equality. + * Query terms are compared each to each. + * This is a simplistic * implementation -- logical equivalences between different - * and/or trees are ignored. */ + * and/or trees are ignored. + */ gboolean qof_query_equal (QofQuery *q1, QofQuery *q2); /* Print the Query in human-readable format.