Add the ability to override the default sort (#150799).

Override the Transaction Number to sort numerically.
	* lib/libqof/qof/qofclass.h:
	* lib/libqof/qof/qofquery.c:
	* lib/libqof/qof/qofquerycore-p.h:
	* lib/libqof/qof/qofquerycore.[ch]:
	  - Publish the QofCompareFunc prototype.
	  - Add a new QofParam param_compfcn parameter
	  - Change QofQuery to use the param_compfcn over the
	    default type compare function.
	  - create (and publish) a qof API to compare strings
	    as numbers:  qof_string_number_compare_func()
	* src/engine/Transaction.c:
	  Assign TRANS_NUM to use qof_string_numer_compare_func()



git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@14903 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins 2006-09-27 13:39:32 +00:00
parent 8bf369217a
commit c7c9199800
7 changed files with 72 additions and 13 deletions

View File

@ -4,6 +4,21 @@
Implement SubQuery functionality in QOF: qof_query_run_subquery() Implement SubQuery functionality in QOF: qof_query_run_subquery()
Now you can run one query off of the results of another query. Now you can run one query off of the results of another query.
Add the ability to override the default sort (#150799).
Override the Transaction Number to sort numerically.
* lib/libqof/qof/qofclass.h:
* lib/libqof/qof/qofquery.c:
* lib/libqof/qof/qofquerycore-p.h:
* lib/libqof/qof/qofquerycore.[ch]:
- Publish the QofCompareFunc prototype.
- Add a new QofParam param_compfcn parameter
- Change QofQuery to use the param_compfcn over the
default type compare function.
- create (and publish) a qof API to compare strings
as numbers: qof_string_number_compare_func()
* src/engine/Transaction.c:
Assign TRANS_NUM to use qof_string_numer_compare_func()
2006-09-23 Derek Atkins <derek@ihtfp.com> 2006-09-23 Derek Atkins <derek@ihtfp.com>
* src/ledger-core/split-register*.c: * src/ledger-core/split-register*.c:

View File

@ -151,6 +151,14 @@ typedef gpointer (*QofAccessFunc)(gpointer object, const QofParam *param);
*/ */
typedef void (*QofSetterFunc) (gpointer, gpointer); typedef void (*QofSetterFunc) (gpointer, gpointer);
/* A callback for how to compare two (same-type) objects based on a
* common getter (parameter member), using the provided comparison
* options (which are the type-specific options).
*/
typedef gint (*QofCompareFunc) (gpointer a, gpointer b,
gint compare_options,
QofParam *getter);
/** This structure is for each queriable parameter in an object /** This structure is for each queriable parameter in an object
* *
* -- param_name is the name of the parameter. * -- param_name is the name of the parameter.
@ -174,6 +182,7 @@ struct _QofParam
QofType param_type; QofType param_type;
QofAccessFunc param_getfcn; QofAccessFunc param_getfcn;
QofSetterFunc param_setfcn; QofSetterFunc param_setfcn;
QofCompareFunc param_compfcn;
gpointer param_userdata; gpointer param_userdata;
}; };

View File

@ -473,13 +473,17 @@ compile_sort (QofQuerySort *sort, QofIdType obj)
*/ */
if (sort->param_fcns) if (sort->param_fcns)
{ {
sort->comp_fcn = qof_query_core_get_compare (resObj->param_type); /* First, check if this parameter has a sort function override.
* if not then check if there's a global compare function for the type
*/
if (resObj->param_compfcn)
sort->comp_fcn = resObj->param_compfcn;
else
sort->comp_fcn = qof_query_core_get_compare (resObj->param_type);
/* Hrm, perhaps this is an object compare, not a core compare? */ /* Next, perhaps this is an object compare, not a core type compare? */
if (sort->comp_fcn == NULL) if (sort->comp_fcn == NULL)
{
sort->obj_cmp = qof_class_get_default_sort (resObj->param_type); sort->obj_cmp = qof_class_get_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))
{ {

View File

@ -45,14 +45,6 @@ typedef gint (*QofQueryPredicateFunc) (gpointer object,
QofParam *getter, QofParam *getter,
QofQueryPredData *pdata); QofQueryPredData *pdata);
/* A callback for how to compare two (same-type) objects based on a
* common getter (parameter member), using the provided comparison
* options (which are the type-specific options).
*/
typedef gint (*QofCompareFunc) (gpointer a, gpointer b,
gint compare_options,
QofParam *getter);
/* Lookup functions */ /* Lookup functions */
QofQueryPredicateFunc qof_query_core_get_predicate (gchar const *type); QofQueryPredicateFunc qof_query_core_get_predicate (gchar const *type);
QofCompareFunc qof_query_core_get_compare (gchar const *type); QofCompareFunc qof_query_core_get_compare (gchar const *type);

View File

@ -182,6 +182,36 @@ string_compare_func (gpointer a, gpointer b, gint options,
return safe_strcmp (s1, s2); return safe_strcmp (s1, s2);
} }
int
qof_string_number_compare_func (gpointer a, gpointer b, gint options,
QofParam *getter)
{
const char *s1, *s2;
char *sr1, *sr2;
long i1, i2;
g_return_val_if_fail (a && b && getter &&getter->param_getfcn, COMPARE_ERROR);
s1 = ((query_string_getter)getter->param_getfcn) (a, getter);
s2 = ((query_string_getter)getter->param_getfcn) (b, getter);
// Deal with NULL strings
if (s1 == s2) return 0;
if (!s1 && s2) return -1;
if (s1 && !s2) return 1;
// Convert to integers and test
i1 = strtol(s1, &sr1, 0);
i2 = strtol(s2, &sr2, 0);
if (i1 < i2) return -1;
if (i1 > i2) return 1;
// If the integers match, then test the REST of the string as text.
if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
return safe_strcasecmp (sr1, sr2);
return safe_strcmp (sr1, sr2);
}
static void static void
string_free_pdata (QofQueryPredData *pd) string_free_pdata (QofQueryPredData *pd)
{ {

View File

@ -187,6 +187,14 @@ gboolean qof_query_date_predicate_get_date (QofQueryPredData *pd, Timespec *date
*/ */
char * qof_query_core_to_string (QofType, gpointer object, QofParam *getter); char * qof_query_core_to_string (QofType, gpointer object, QofParam *getter);
/** Compare two parameter(strings) as if they are numbers!
* the two objects, a and b, are the objects being compared
* this_param is the QofParam for this parameter in the objects
*/
int qof_string_number_compare_func (gpointer a, gpointer b, gint options,
QofParam *this_param);
#endif /* QOF_QUERYCORE_H */ #endif /* QOF_QUERYCORE_H */
/* @} */ /* @} */
/* @} */ /* @} */

View File

@ -1968,7 +1968,8 @@ gboolean xaccTransRegister (void)
static QofParam params[] = { static QofParam params[] = {
{ TRANS_NUM, QOF_TYPE_STRING, { TRANS_NUM, QOF_TYPE_STRING,
(QofAccessFunc)xaccTransGetNum, (QofAccessFunc)xaccTransGetNum,
(QofSetterFunc)qofTransSetNum }, (QofSetterFunc)qofTransSetNum,
qof_string_number_compare_func },
{ TRANS_DESCRIPTION, QOF_TYPE_STRING, { TRANS_DESCRIPTION, QOF_TYPE_STRING,
(QofAccessFunc)xaccTransGetDescription, (QofAccessFunc)xaccTransGetDescription,
(QofSetterFunc)qofTransSetDescription }, (QofSetterFunc)qofTransSetDescription },