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
This commit is contained in:
Linas Vepstas 2004-04-19 15:45:46 +00:00
parent f450305ca2
commit d636f3a798
17 changed files with 445 additions and 323 deletions

View File

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

View File

@ -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;
}

View File

@ -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);

View File

@ -46,7 +46,8 @@ static gboolean clear_table (gpointer key, gpointer value, gpointer user_data)
/********************************************************************/
/* PUBLISHED API FUNCTIONS */
void qof_class_register (QofIdTypeConst obj_name,
void
qof_class_register (QofIdTypeConst obj_name,
QofSortFunc default_sort_function,
const QofParam *params)
{
@ -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));
}

View File

@ -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);
* 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);

View File

@ -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);

View File

@ -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;

View File

@ -72,7 +72,7 @@ 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 */
};
@ -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,7 +429,8 @@ 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,
static GSList *
compile_params (GSList *param_list, QofIdType start_obj,
QofParam const **final)
{
const QofParam *objDef = 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);
}

View File

@ -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);

View File

@ -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,7 +123,9 @@ static GHashTable *predEqualTable = NULL;
/* QOF_TYPE_STRING */
static int string_match_predicate (gpointer object, QofAccessFunc get_fcn,
static int
string_match_predicate (gpointer object,
QofParam *getter,
QofQueryPredData *pd)
{
query_string_t pdata = (query_string_t) pd;
@ -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,
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,7 +217,8 @@ QofQueryPredData *p2)
return (safe_strcmp (pd1->matchstring, pd2->matchstring) == 0);
}
QofQueryPredData *qof_query_string_predicate (QofQueryCompare how,
QofQueryPredData *
qof_query_string_predicate (QofQueryCompare how,
char *str, QofStringMatch options,
gboolean is_regex)
{
@ -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;
@ -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,9 +379,10 @@ 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,
static int
numeric_match_predicate (gpointer object, QofParam *getter,
QofQueryPredData* pd)
{
query_numeric_t pdata = (query_numeric_t)pd;
@ -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);
@ -488,23 +487,28 @@ 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,
static int
guid_match_predicate (gpointer object, QofParam *getter,
QofQueryPredData *pd)
{
query_guid_t pdata = (query_guid_t)pd;
@ -516,16 +520,17 @@ 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);
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,7 +678,8 @@ qof_query_guid_predicate (QofGuidMatch options, GList *guids)
/* ================================================================ */
/* QOF_TYPE_INT32 */
static int int32_match_predicate (gpointer object, QofAccessFunc get_fcn,
static int
int32_match_predicate (gpointer object, QofParam *getter,
QofQueryPredData *pd)
{
gint32 val;
@ -672,7 +687,7 @@ static int int32_match_predicate (gpointer object, QofAccessFunc get_fcn,
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,7 +769,8 @@ static char * int32_to_string (gpointer object, QofAccessFunc get)
/* ================================================================ */
/* QOF_TYPE_INT64 */
static int int64_match_predicate (gpointer object, QofAccessFunc get_fcn,
static int
int64_match_predicate (gpointer object, QofParam *getter,
QofQueryPredData *pd)
{
gint64 val;
@ -759,7 +778,7 @@ static int int64_match_predicate (gpointer object, QofAccessFunc get_fcn,
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,7 +860,8 @@ static char * int64_to_string (gpointer object, QofAccessFunc get)
/* ================================================================ */
/* QOF_TYPE_DOUBLE */
static int double_match_predicate (gpointer object, QofAccessFunc get_fcn,
static int
double_match_predicate (gpointer object, QofParam *getter,
QofQueryPredData *pd)
{
double val;
@ -846,7 +869,7 @@ static int double_match_predicate (gpointer object, QofAccessFunc get_fcn,
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,16 +940,18 @@ 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,
static int
boolean_match_predicate (gpointer object, QofParam *getter,
QofQueryPredData *pd)
{
gboolean val;
@ -932,7 +959,7 @@ static int boolean_match_predicate (gpointer object, QofAccessFunc get_fcn,
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,16 +1107,18 @@ 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,
static int
kvp_match_predicate (gpointer object, QofParam *getter,
QofQueryPredData *pd)
{
int compare;
@ -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;
@ -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;
struct
{
QofType name;
QofQueryPredicateFunc pred;
QofCompareFunc comp;
QueryPredicateCopyFunc copy;
QueryPredDataFree pd_free;
QueryToString toString;
QueryPredicateEqual pred_equal;
} knownTypes[] = {
} 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

View File

@ -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 */

View File

@ -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 <linas@linas.org>
XXX: todo: replace printf error with proper error
handling/reporting.
*/
#include <glib.h>
@ -34,11 +32,16 @@
#include <qof/kvp_frame.h>
#include <qof/gnc-date.h>
#include <qof/gnc-numeric.h>
#include <qof/gnc-trace.h>
#include <qof/guid.h>
#include <qof/qofbook.h>
#include <qof/qofquery.h>
#include <qof/qofsql.h>
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;
}

View File

@ -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 */
/** @} */

View File

@ -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,8 +441,9 @@ 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) {
@ -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;

View File

@ -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);

View File

@ -43,8 +43,9 @@ enum
LAST_SIGNAL
};
struct _GNCQueryListPriv {
QueryAccess get_guid;
struct _GNCQueryListPriv
{
const QofParam * get_guid;
gint component_id;
};
@ -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,7 +785,6 @@ 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)) {
@ -792,24 +793,27 @@ gnc_query_list_fill(GNCQueryList *list)
}
/* Do all the object conversions */
for (; converters; converters = converters->next) {
fcn = converters->data;
for (; converters; converters = converters->next)
{
qp = converters->data;
if (converters->next)
res = fcn (res);
{
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))
{
gnc_numeric (*nfcn)(gpointer) = (gnc_numeric(*)(gpointer))fcn;
gnc_numeric value = nfcn(res);
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);
@ -825,7 +829,8 @@ gnc_query_list_fill(GNCQueryList *list)
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);

View File

@ -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;