Add a new QOF_TYPE_NUMSTRING to add numeric sorts. (#150799).

This new type is like QOF_TYPE_STRING but it sorts numerically
	  (first) and then sorts alphanumerically (by the tail of the
	  number).  Added the QOF Type, the gnome-search support, and
	  modified TRANS_NUM to use the new type.



git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@14892 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins 2006-09-26 00:36:30 +00:00
parent bb5646f42c
commit 2bb357def4
20 changed files with 269 additions and 76 deletions

View File

@ -1,3 +1,12 @@
2006-09-25 Derek Atkins <derek@ihtfp.com>
[ Lots of files ]:
Add a new QOF_TYPE_NUMSTRING to add numeric sorts. (#150799).
This new type is like QOF_TYPE_STRING but it sorts numerically
(first) and then sorts alphanumerically (by the tail of the
number). Added the QOF Type, the gnome-search support, and
modified TRANS_NUM to use the new type.
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

@ -126,7 +126,8 @@ qof_book_merge_compare(QofBookMergeData *mergeData )
mergeParamName = qtparam->param_name; mergeParamName = qtparam->param_name;
g_return_val_if_fail(mergeParamName != NULL, -1); g_return_val_if_fail(mergeParamName != NULL, -1);
mergeType = qtparam->param_type; mergeType = qtparam->param_type;
if(safe_strcmp(mergeType, QOF_TYPE_STRING) == 0) { if(safe_strcmp(mergeType, QOF_TYPE_STRING) == 0 ||
safe_strcmp(mergeType, QOF_TYPE_NUMSTRING) == 0) {
stringImport = qtparam->param_getfcn(mergeEnt,qtparam); stringImport = qtparam->param_getfcn(mergeEnt,qtparam);
stringTarget = qtparam->param_getfcn(targetEnt,qtparam); stringTarget = qtparam->param_getfcn(targetEnt,qtparam);
/* very strict string matches may need to be relaxed. */ /* very strict string matches may need to be relaxed. */
@ -643,7 +644,8 @@ qof_book_merge_commit_rule_loop(
g_return_if_fail(rule->mergeParam->data); g_return_if_fail(rule->mergeParam->data);
cm_param = rule->mergeParam->data; cm_param = rule->mergeParam->data;
rule->mergeType = cm_param->param_type; rule->mergeType = cm_param->param_type;
if(safe_strcmp(rule->mergeType, QOF_TYPE_STRING) == 0) { if(safe_strcmp(rule->mergeType, QOF_TYPE_STRING) == 0 ||
safe_strcmp(rule->mergeType, QOF_TYPE_NUMSTRING) == 0) {
cm_string = cm_param->param_getfcn(rule->importEnt, cm_param); cm_string = cm_param->param_getfcn(rule->importEnt, cm_param);
string_setter = (void(*)(QofEntity*, const gchar*))cm_param->param_setfcn; string_setter = (void(*)(QofEntity*, const gchar*))cm_param->param_setfcn;
if(string_setter != NULL) { string_setter(rule->targetEnt, cm_string); } if(string_setter != NULL) { string_setter(rule->targetEnt, cm_string); }
@ -836,7 +838,8 @@ qof_book_merge_param_as_string(QofParam *qtparam, QofEntity *qtEnt)
param_string = NULL; param_string = NULL;
paramType = qtparam->param_type; paramType = qtparam->param_type;
if(safe_strcmp(paramType, QOF_TYPE_STRING) == 0) { if(safe_strcmp(paramType, QOF_TYPE_STRING) == 0 ||
safe_strcmp(paramType, QOF_TYPE_NUMSTRING) == 0) {
param_string = g_strdup(qtparam->param_getfcn(qtEnt,qtparam)); param_string = g_strdup(qtparam->param_getfcn(qtEnt,qtparam));
if(param_string == NULL) { param_string = ""; } if(param_string == NULL) { param_string = ""; }
return param_string; return param_string;

View File

@ -274,6 +274,7 @@ find_reference_param_cb(QofParam *param, gpointer user_data)
b = (struct param_ref_list*)user_data; b = (struct param_ref_list*)user_data;
if((param->param_getfcn == NULL)||(param->param_setfcn == NULL)) { return; } if((param->param_getfcn == NULL)||(param->param_setfcn == NULL)) { return; }
if(0 == safe_strcmp(param->param_type, QOF_TYPE_STRING)) { return; } if(0 == safe_strcmp(param->param_type, QOF_TYPE_STRING)) { return; }
if(0 == safe_strcmp(param->param_type, QOF_TYPE_NUMSTRING)) { return; }
if(0 == safe_strcmp(param->param_type, QOF_TYPE_NUMERIC)) { return; } if(0 == safe_strcmp(param->param_type, QOF_TYPE_NUMERIC)) { return; }
if(0 == safe_strcmp(param->param_type, QOF_TYPE_DATE)) { return; } if(0 == safe_strcmp(param->param_type, QOF_TYPE_DATE)) { return; }
if(0 == safe_strcmp(param->param_type, QOF_TYPE_CHAR)) { return; } if(0 == safe_strcmp(param->param_type, QOF_TYPE_CHAR)) { return; }

View File

@ -83,6 +83,8 @@ single reference between two known objects.
*/ */
#define QOF_TYPE_STRING "string" #define QOF_TYPE_STRING "string"
#define QOF_TYPE_NUMSTRING "numstring" /**< a string that sorts in numeric
order instead of typological order */
#define QOF_TYPE_DATE "date" #define QOF_TYPE_DATE "date"
#define QOF_TYPE_NUMERIC "numeric" #define QOF_TYPE_NUMERIC "numeric"
#define QOF_TYPE_DEBCRED "debcred" #define QOF_TYPE_DEBCRED "debcred"

View File

@ -694,6 +694,7 @@ int main (int argc, char * argv[])
{ "aflt", QOF_TYPE_DOUBLE, NULL, NULL}, { "aflt", QOF_TYPE_DOUBLE, NULL, NULL},
{ "abool", QOF_TYPE_BOOLEAN, NULL, NULL}, { "abool", QOF_TYPE_BOOLEAN, NULL, NULL},
{ "astr", QOF_TYPE_STRING, NULL, NULL}, { "astr", QOF_TYPE_STRING, NULL, NULL},
{ "nstr", QOF_TYPE_NUMSTRING, NULL, NULL},
{ "adate", QOF_TYPE_DATE, NULL, NULL}, { "adate", QOF_TYPE_DATE, NULL, NULL},
{ "anum", QOF_TYPE_NUMERIC, NULL, NULL}, { "anum", QOF_TYPE_NUMERIC, NULL, NULL},
{ "achar", QOF_TYPE_CHAR, NULL, NULL}, { "achar", QOF_TYPE_CHAR, NULL, NULL},

View File

@ -240,7 +240,8 @@ qof_query_pred_data_to_xml (QofQueryPredData *pd)
} }
return topnode; return topnode;
} }
if (!safe_strcmp (pd->type_name, QOF_TYPE_STRING)) if (!safe_strcmp (pd->type_name, QOF_TYPE_STRING) ||
!safe_strcmp (pd->type_name, QOF_TYPE_NUMSTRING))
{ {
topnode = xmlNewNode (NULL, "qofquery:pred-string"); topnode = xmlNewNode (NULL, "qofquery:pred-string");
PUT_HOW ("qofquery:compare", pd->how, LT, LTE, EQUAL, GT, GTE, NEQ); PUT_HOW ("qofquery:compare", pd->how, LT, LTE, EQUAL, GT, GTE, NEQ);
@ -555,6 +556,7 @@ int main (int argc, char * argv[])
{ "aint", QOF_TYPE_INT32, NULL, NULL}, { "aint", QOF_TYPE_INT32, NULL, NULL},
{ "aint64", QOF_TYPE_INT64, NULL, NULL}, { "aint64", QOF_TYPE_INT64, NULL, NULL},
{ "astr", QOF_TYPE_STRING, NULL, NULL}, { "astr", QOF_TYPE_STRING, NULL, NULL},
{ "nstr", QOF_TYPE_NUMSTRING, NULL, NULL},
{ NULL }, { NULL },
}; };

View File

@ -1693,7 +1693,8 @@ qof_query_printValueForParam (QofQueryPredData *pd, GString * gs)
} }
return; return;
} }
if (!safe_strcmp (pd->type_name, QOF_TYPE_STRING)) if (!safe_strcmp (pd->type_name, QOF_TYPE_STRING) ||
!safe_strcmp (pd->type_name, QOF_TYPE_NUMSTRING))
{ {
query_string_t pdata = (query_string_t) pd; query_string_t pdata = (query_string_t) pd;
g_string_append_printf (gs, " Match type %s", g_string_append_printf (gs, " Match type %s",

View File

@ -24,6 +24,7 @@
#include "config.h" #include "config.h"
#include <glib.h> #include <glib.h>
#include <stdlib.h>
#include "qof.h" #include "qof.h"
#include "qofquerycore-p.h" #include "qofquerycore-p.h"
@ -54,6 +55,7 @@ static QueryPredDataFree qof_query_predicate_free (QofType type);
/* Core Type Predicate helpers */ /* Core Type Predicate helpers */
typedef const char * (*query_string_getter) (gpointer, QofParam *); typedef const char * (*query_string_getter) (gpointer, QofParam *);
static const char * query_string_type = QOF_TYPE_STRING; static const char * query_string_type = QOF_TYPE_STRING;
static const char * query_numstring_type = QOF_TYPE_NUMSTRING;
typedef Timespec (*query_date_getter) (gpointer, QofParam *); typedef Timespec (*query_date_getter) (gpointer, QofParam *);
static const char * query_date_type = QOF_TYPE_DATE; static const char * query_date_type = QOF_TYPE_DATE;
@ -124,10 +126,10 @@ static GHashTable *predEqualTable = NULL;
/* *******************************************************************/ /* *******************************************************************/
/* TYPE-HANDLING FUNCTIONS */ /* TYPE-HANDLING FUNCTIONS */
/* QOF_TYPE_STRING */ /* QOF_TYPE_STRING and QOF_TYPE_NUMSTRING / common functions */
static int static int
string_match_predicate (gpointer object, string_match_predicate_common (gpointer object,
QofParam *getter, QofParam *getter,
QofQueryPredData *pd) QofQueryPredData *pd)
{ {
@ -135,8 +137,6 @@ string_match_predicate (gpointer object,
const char *s; const char *s;
int ret = 0; int ret = 0;
VERIFY_PREDICATE (query_string_type);
s = ((query_string_getter)getter->param_getfcn) (object, getter); s = ((query_string_getter)getter->param_getfcn) (object, getter);
if (!s) s = ""; if (!s) s = "";
@ -166,6 +166,81 @@ string_match_predicate (gpointer object,
} }
} }
static void
string_free_pdata_common (QofQueryPredData *pd)
{
query_string_t pdata = (query_string_t) pd;
if (pdata->is_regex)
regfree (&pdata->compiled);
else
g_free (pdata->matchstring);
g_free (pdata);
}
static QofQueryPredData *
qof_query_string_predicate_common (QofQueryCompare how,
const char *str, QofStringMatch options,
gboolean is_regex,
const char* type)
{
query_string_t pdata;
g_return_val_if_fail (str, NULL);
g_return_val_if_fail (*str != '\0', NULL);
g_return_val_if_fail (how == QOF_COMPARE_EQUAL || how == QOF_COMPARE_NEQ, NULL);
pdata = g_new0 (query_string_def, 1);
pdata->pd.type_name = type;
pdata->pd.how = how;
pdata->options = options;
pdata->matchstring = g_strdup (str);
if (is_regex) {
int flags = REG_EXTENDED;
if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
flags |= REG_ICASE;
regcomp(&pdata->compiled, str, flags);
pdata->is_regex = TRUE;
}
return ((QofQueryPredData*)pdata);
}
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;
if (pd1->options != pd2->options) return FALSE;
if (pd1->is_regex != pd2->is_regex) return FALSE;
return (safe_strcmp (pd1->matchstring, pd2->matchstring) == 0);
}
static char *
string_to_string (gpointer object, QofParam *getter)
{
const char *res;
res = ((query_string_getter)getter->param_getfcn)(object, getter);
if (res)
return g_strdup (res);
return NULL;
}
/* QOF_QUERY_STRING */
static int
string_match_predicate (gpointer object,
QofParam *getter,
QofQueryPredData *pd)
{
VERIFY_PREDICATE (query_string_type);
return string_match_predicate_common(object, getter, pd);
}
static int static int
string_compare_func (gpointer a, gpointer b, gint options, string_compare_func (gpointer a, gpointer b, gint options,
QofParam *getter) QofParam *getter)
@ -185,16 +260,8 @@ string_compare_func (gpointer a, gpointer b, gint options,
static void static void
string_free_pdata (QofQueryPredData *pd) string_free_pdata (QofQueryPredData *pd)
{ {
query_string_t pdata = (query_string_t) pd;
VERIFY_PDATA (query_string_type); VERIFY_PDATA (query_string_type);
return string_free_pdata_common(pd);
if (pdata->is_regex)
regfree (&pdata->compiled);
else
g_free (pdata->matchstring);
g_free (pdata);
} }
static QofQueryPredData * static QofQueryPredData *
@ -204,20 +271,10 @@ string_copy_predicate (QofQueryPredData *pd)
VERIFY_PDATA_R (query_string_type); VERIFY_PDATA_R (query_string_type);
return qof_query_string_predicate (pd->how, pdata->matchstring, return qof_query_string_predicate_common (pd->how, pdata->matchstring,
pdata->options, pdata->options,
pdata->is_regex); pdata->is_regex,
} query_string_type);
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;
if (pd1->options != pd2->options) return FALSE;
if (pd1->is_regex != pd2->is_regex) return FALSE;
return (safe_strcmp (pd1->matchstring, pd2->matchstring) == 0);
} }
QofQueryPredData * QofQueryPredData *
@ -225,38 +282,78 @@ qof_query_string_predicate (QofQueryCompare how,
const char *str, QofStringMatch options, const char *str, QofStringMatch options,
gboolean is_regex) gboolean is_regex)
{ {
query_string_t pdata; return qof_query_string_predicate_common(how, str, options, is_regex,
query_string_type);
g_return_val_if_fail (str, NULL);
g_return_val_if_fail (*str != '\0', NULL);
g_return_val_if_fail (how == QOF_COMPARE_EQUAL || how == QOF_COMPARE_NEQ, NULL);
pdata = g_new0 (query_string_def, 1);
pdata->pd.type_name = query_string_type;
pdata->pd.how = how;
pdata->options = options;
pdata->matchstring = g_strdup (str);
if (is_regex) {
int flags = REG_EXTENDED;
if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
flags |= REG_ICASE;
regcomp(&pdata->compiled, str, flags);
pdata->is_regex = TRUE;
} }
return ((QofQueryPredData*)pdata); /* QOF_QUERY_NUMSTRING */
}
static char * static int
string_to_string (gpointer object, QofParam *getter) numstring_match_predicate (gpointer object,
QofParam *getter,
QofQueryPredData *pd)
{ {
const char *res; VERIFY_PREDICATE (query_numstring_type);
res = ((query_string_getter)getter->param_getfcn)(object, getter); return string_match_predicate_common(object, getter, pd);
if (res) }
return g_strdup (res);
return NULL; static int
numstring_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
numstring_free_pdata (QofQueryPredData *pd)
{
VERIFY_PDATA (query_numstring_type);
return string_free_pdata_common(pd);
}
static QofQueryPredData *
numstring_copy_predicate (QofQueryPredData *pd)
{
query_string_t pdata = (query_string_t) pd;
VERIFY_PDATA_R (query_numstring_type);
return qof_query_string_predicate_common (pd->how, pdata->matchstring,
pdata->options,
pdata->is_regex,
query_numstring_type);
}
QofQueryPredData *
qof_query_numstring_predicate (QofQueryCompare how,
const char *str, QofStringMatch options,
gboolean is_regex)
{
return qof_query_string_predicate_common(how, str, options, is_regex,
query_numstring_type);
} }
/* QOF_TYPE_DATE =================================================== */ /* QOF_TYPE_DATE =================================================== */
@ -1661,6 +1758,9 @@ static void init_tables (void)
{ QOF_TYPE_STRING, string_match_predicate, string_compare_func, { QOF_TYPE_STRING, string_match_predicate, string_compare_func,
string_copy_predicate, string_free_pdata, string_to_string, string_copy_predicate, string_free_pdata, string_to_string,
string_predicate_equal }, string_predicate_equal },
{ QOF_TYPE_NUMSTRING, numstring_match_predicate, numstring_compare_func,
numstring_copy_predicate, numstring_free_pdata, string_to_string,
string_predicate_equal },
{ QOF_TYPE_DATE, date_match_predicate, date_compare_func, { QOF_TYPE_DATE, date_match_predicate, date_compare_func,
date_copy_predicate, date_free_pdata, date_to_string, date_copy_predicate, date_free_pdata, date_to_string,
date_predicate_equal }, date_predicate_equal },

View File

@ -141,6 +141,11 @@ QofQueryPredData *qof_query_string_predicate (QofQueryCompare how,
QofStringMatch options, QofStringMatch options,
gboolean is_regex); gboolean is_regex);
QofQueryPredData *qof_query_numstring_predicate (QofQueryCompare how,
const gchar *str,
QofStringMatch options,
gboolean is_regex);
QofQueryPredData *qof_query_date_predicate (QofQueryCompare how, QofQueryPredData *qof_query_date_predicate (QofQueryCompare how,
QofDateMatch options, QofDateMatch options,
Timespec date); Timespec date);

View File

@ -426,7 +426,8 @@ qof_entity_foreach_copy(gpointer data, gpointer user_data)
cm_param = (QofParam*) data; cm_param = (QofParam*) data;
g_return_if_fail(cm_param != NULL); g_return_if_fail(cm_param != NULL);
context->param = cm_param; context->param = cm_param;
if(safe_strcmp(cm_param->param_type, QOF_TYPE_STRING) == 0) { if(safe_strcmp(cm_param->param_type, QOF_TYPE_STRING) == 0 ||
safe_strcmp(cm_param->param_type, QOF_TYPE_NUMSTRING) == 0) {
cm_string = (gchar*)cm_param->param_getfcn(importEnt, cm_param); cm_string = (gchar*)cm_param->param_getfcn(importEnt, cm_param);
if(cm_string) { if(cm_string) {
string_setter = (void(*)(QofEntity*, const char*))cm_param->param_setfcn; string_setter = (void(*)(QofEntity*, const char*))cm_param->param_setfcn;

View File

@ -308,7 +308,8 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
return NULL; return NULL;
} }
if (!strcmp (param_type, QOF_TYPE_STRING)) if (!strcmp (param_type, QOF_TYPE_STRING) ||
!strcmp (param_type, QOF_TYPE_NUMSTRING))
{ {
pred_data = pred_data =
qof_query_string_predicate (qop, /* comparison to make */ qof_query_string_predicate (qop, /* comparison to make */
@ -605,7 +606,8 @@ qof_sql_insertCB(const QofParam *param, const gchar *insert_string, QofSqlQuery
ENTER (" param=%s param_type=%s type=%s content=%s", ENTER (" param=%s param_type=%s type=%s content=%s",
param->param_name, param->param_type, type, insert_string); param->param_name, param->param_type, type, insert_string);
if(safe_strcmp(param->param_type, QOF_TYPE_STRING) == 0) { if(safe_strcmp(param->param_type, QOF_TYPE_STRING) == 0 ||
safe_strcmp(param->param_type, QOF_TYPE_NUMSTRING) == 0) {
string_setter = (void(*)(QofEntity*, const char*))param->param_setfcn; string_setter = (void(*)(QofEntity*, const char*))param->param_setfcn;
if(string_setter != NULL) { string_setter(ent, insert_string); } if(string_setter != NULL) { string_setter(ent, insert_string); }
registered_type = TRUE; registered_type = TRUE;

View File

@ -416,7 +416,8 @@ qof_util_param_as_string(QofEntity *ent, QofParam *param)
param_string = NULL; param_string = NULL;
known_type = FALSE; known_type = FALSE;
paramType = param->param_type; paramType = param->param_type;
if(safe_strcmp(paramType, QOF_TYPE_STRING) == 0) { if(safe_strcmp(paramType, QOF_TYPE_STRING) == 0 ||
safe_strcmp(paramType, QOF_TYPE_NUMSTRING) == 0) {
param_string = g_strdup(param->param_getfcn(ent, param)); param_string = g_strdup(param->param_getfcn(ent, param));
if(param_string == NULL) { param_string = ""; } if(param_string == NULL) { param_string = ""; }
known_type = TRUE; known_type = TRUE;

View File

@ -958,7 +958,8 @@ sqlQuery_build(sqlQuery * sq, Query * q)
more_and = 0; more_and = 0;
} }
} else if (!safe_strcmp(pd->type_name, QOF_TYPE_STRING)) { } else if (!safe_strcmp(pd->type_name, QOF_TYPE_STRING) ||
!safe_strcmp(pd->type_name, QOF_TYPE_NUMSTRING)) {
query_string_t pdata = (query_string_t) pd; query_string_t pdata = (query_string_t) pd;
if (!safe_strcmp(path->data, SPLIT_ACTION)) { if (!safe_strcmp(path->data, SPLIT_ACTION)) {

View File

@ -319,6 +319,32 @@ xaccQueryAddStringMatch (Query* q, const char *matchstring,
qof_query_add_term (q, param_list, pred_data, op); qof_query_add_term (q, param_list, pred_data, op);
} }
void
xaccQueryAddNumStringMatch (Query* q, const char *matchstring,
int case_sens, int use_regexp, QofQueryOp op,
const char * path, ...)
{
QofQueryPredData *pred_data;
GSList *param_list;
va_list ap;
if (!path || !q)
return;
pred_data = qof_query_numstring_predicate (QOF_COMPARE_EQUAL, (char *)matchstring,
(case_sens ? QOF_STRING_MATCH_NORMAL :
QOF_STRING_MATCH_CASEINSENSITIVE),
use_regexp);
if (!pred_data)
return;
va_start (ap, path);
param_list = build_param_list_internal (path, ap);
va_end (ap);
qof_query_add_term (q, param_list, pred_data, op);
}
void void
xaccQueryAddNumericMatch (Query *q, gnc_numeric amount, QofNumericMatch sign, xaccQueryAddNumericMatch (Query *q, gnc_numeric amount, QofNumericMatch sign,
QofQueryCompare how, QofQueryOp op, QofQueryCompare how, QofQueryOp op,

View File

@ -127,11 +127,15 @@ void xaccQueryAddStringMatch (Query* q, const char *matchstring,
int case_sens, int use_regexp, QofQueryOp op, int case_sens, int use_regexp, QofQueryOp op,
const char * path, ...); const char * path, ...);
void xaccQueryAddNumStringMatch (Query* q, const char *matchstring,
int case_sens, int use_regexp, QofQueryOp op,
const char * path, ...);
#define xaccQueryAddDescriptionMatch(q,m,c,r,o) \ #define xaccQueryAddDescriptionMatch(q,m,c,r,o) \
xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_TRANS, \ xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_TRANS, \
TRANS_DESCRIPTION, NULL) TRANS_DESCRIPTION, NULL)
#define xaccQueryAddNumberMatch(q,m,c,r,o) \ #define xaccQueryAddNumberMatch(q,m,c,r,o) \
xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_TRANS, \ xaccQueryAddNumStringMatch ((q), (m), (c), (r), (o), SPLIT_TRANS, \
TRANS_NUM, NULL) TRANS_NUM, NULL)
#define xaccQueryAddActionMatch(q,m,c,r,o) \ #define xaccQueryAddActionMatch(q,m,c,r,o) \
xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_ACTION, \ xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_ACTION, \

View File

@ -1966,7 +1966,7 @@ trans_is_balanced_p (const Transaction *trans)
gboolean xaccTransRegister (void) gboolean xaccTransRegister (void)
{ {
static QofParam params[] = { static QofParam params[] = {
{ TRANS_NUM, QOF_TYPE_STRING, { TRANS_NUM, QOF_TYPE_NUMSTRING,
(QofAccessFunc)xaccTransGetNum, (QofAccessFunc)xaccTransGetNum,
(QofSetterFunc)qofTransSetNum }, (QofSetterFunc)qofTransSetNum },
{ TRANS_DESCRIPTION, QOF_TYPE_STRING, { TRANS_DESCRIPTION, QOF_TYPE_STRING,

View File

@ -864,7 +864,8 @@ gnc_queryterm2scm (QofQueryTerm *qt)
qt_scm = scm_cons (scm_str2symbol (pd->type_name), qt_scm); qt_scm = scm_cons (scm_str2symbol (pd->type_name), qt_scm);
qt_scm = scm_cons (gnc_query_compare2scm (pd->how), qt_scm); qt_scm = scm_cons (gnc_query_compare2scm (pd->how), qt_scm);
if (!safe_strcmp (pd->type_name, QOF_TYPE_STRING)) { if (!safe_strcmp (pd->type_name, QOF_TYPE_STRING) ||
!safe_strcmp (pd->type_name, QOF_TYPE_NUMSTRING)) {
query_string_t pdata = (query_string_t) pd; query_string_t pdata = (query_string_t) pd;
qt_scm = scm_cons (gnc_query_string2scm (pdata->options), qt_scm); qt_scm = scm_cons (gnc_query_string2scm (pdata->options), qt_scm);
@ -969,7 +970,8 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
/* Now compute the predicate */ /* Now compute the predicate */
if (!safe_strcmp (type, QOF_TYPE_STRING)) if (!safe_strcmp (type, QOF_TYPE_STRING) ||
!safe_strcmp (type, QOF_TYPE_NUMSTRING))
{ {
QofStringMatch options; QofStringMatch options;
gboolean is_regex; gboolean is_regex;
@ -991,8 +993,12 @@ gnc_scm2query_term_query_v2 (SCM qt_scm)
matchstring = SCM_STRING_CHARS (scm); matchstring = SCM_STRING_CHARS (scm);
if (!safe_strcmp (type, QOF_TYPE_STRING))
pd = qof_query_string_predicate (compare_how, matchstring, pd = qof_query_string_predicate (compare_how, matchstring,
options, is_regex); options, is_regex);
else
pd = qof_query_numstring_predicate (compare_how, matchstring,
options, is_regex);
} }
else if (!safe_strcmp (type, QOF_TYPE_DATE)) else if (!safe_strcmp (type, QOF_TYPE_DATE))
{ {

View File

@ -255,6 +255,8 @@ init_table (void)
{ {
gnc_search_core_register_type (QUERYCORE_STRING, gnc_search_core_register_type (QUERYCORE_STRING,
(GNCSearchCoreNew) gnc_search_string_new); (GNCSearchCoreNew) gnc_search_string_new);
gnc_search_core_register_type (QOF_TYPE_NUMSTRING,
(GNCSearchCoreNew) gnc_search_string_new_numstring);
gnc_search_core_register_type (QUERYCORE_DATE, gnc_search_core_register_type (QUERYCORE_DATE,
(GNCSearchCoreNew) gnc_search_date_new); (GNCSearchCoreNew) gnc_search_date_new);
gnc_search_core_register_type (QUERYCORE_INT64, gnc_search_core_register_type (QUERYCORE_INT64,

View File

@ -112,6 +112,7 @@ gnc_search_string_init (GNCSearchString *o)
o->value = NULL; o->value = NULL;
o->how = SEARCH_STRING_CONTAINS; o->how = SEARCH_STRING_CONTAINS;
o->ign_case = TRUE; o->ign_case = TRUE;
o->is_numstring = FALSE;
} }
static void static void
@ -139,6 +140,21 @@ gnc_search_string_new (void)
return o; return o;
} }
/**
* gnc_search_string_new_numstring:
*
* Create a new GNCSearchString object for a NumString.
*
* Return value: A new #GNCSearchString object.
**/
GNCSearchString *
gnc_search_string_new_numstring (void)
{
GNCSearchString *o = g_object_new(GNC_TYPE_SEARCH_STRING, NULL);
o->is_numstring = TRUE;
return o;
}
void void
gnc_search_string_set_value (GNCSearchString *fi, const char *value) gnc_search_string_set_value (GNCSearchString *fi, const char *value)
{ {
@ -359,6 +375,9 @@ static QueryPredData_t gncs_get_predicate (GNCSearchCoreType *fe)
if (ss->ign_case) if (ss->ign_case)
options = STRING_MATCH_CASEINSENSITIVE; options = STRING_MATCH_CASEINSENSITIVE;
if (ss->is_numstring)
return qof_query_numstring_predicate (how, ss->value, options, is_regex);
else
return gncQueryStringPredicate (how, ss->value, options, is_regex); return gncQueryStringPredicate (how, ss->value, options, is_regex);
} }
@ -369,6 +388,9 @@ static GNCSearchCoreType *gncs_clone(GNCSearchCoreType *fe)
g_return_val_if_fail (fse, NULL); g_return_val_if_fail (fse, NULL);
g_return_val_if_fail (IS_GNCSEARCH_STRING (fse), NULL); g_return_val_if_fail (IS_GNCSEARCH_STRING (fse), NULL);
if (fse->is_numstring)
se = gnc_search_string_new_numstring ();
else
se = gnc_search_string_new (); se = gnc_search_string_new ();
gnc_search_string_set_value (se, fse->value); gnc_search_string_set_value (se, fse->value);
gnc_search_string_set_how (se, fse->how); gnc_search_string_set_how (se, fse->how);

View File

@ -44,6 +44,9 @@ struct _GNCSearchString {
GNCSearchString_Type how; GNCSearchString_Type how;
gboolean ign_case; gboolean ign_case;
char * value; char * value;
/* Is this is String or a NumString */
gboolean is_numstring;
}; };
struct _GNCSearchStringClass { struct _GNCSearchStringClass {
@ -56,6 +59,7 @@ struct _GNCSearchStringClass {
guint gnc_search_string_get_type (void); guint gnc_search_string_get_type (void);
GNCSearchString *gnc_search_string_new (void); GNCSearchString *gnc_search_string_new (void);
GNCSearchString *gnc_search_string_new_numstring(void);
/* methods */ /* methods */
void gnc_search_string_set_value(GNCSearchString *fi, const char *value); void gnc_search_string_set_value(GNCSearchString *fi, const char *value);