mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
f450305ca2
commit
d636f3a798
@ -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.
|
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.
|
||||||
|
|
||||||
|
@ -3196,7 +3196,7 @@ static QofObject split_object_def = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
split_account_guid_getter (gpointer obj)
|
split_account_guid_getter (gpointer obj, const QofParam *p)
|
||||||
{
|
{
|
||||||
Split *s = obj;
|
Split *s = obj;
|
||||||
Account *acc;
|
Account *acc;
|
||||||
@ -3214,7 +3214,8 @@ DxaccSplitGetShareAmount (const Split * split)
|
|||||||
return gnc_numeric_to_double(xaccSplitGetAmount(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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,12 @@ QofBook * qof_book_new (void);
|
|||||||
associated with it. */
|
associated with it. */
|
||||||
void qof_book_destroy (QofBook *book);
|
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);
|
QofCollection * qof_book_get_collection (QofBook *, QofIdType);
|
||||||
|
|
||||||
/** Invoke the indicated callback on each collection in the book. */
|
/** 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 */
|
/** \return The kvp data for the book */
|
||||||
KvpFrame * qof_book_get_slots (QofBook *book);
|
KvpFrame * qof_book_get_slots (QofBook *book);
|
||||||
|
|
||||||
/** The qof_book_set_data() allows
|
/** The qof_book_set_data() allows arbitrary pointers to structs
|
||||||
* arbitrary pointers to structs to be stored in QofBook.
|
* to be stored in QofBook. This is the "prefered" method for
|
||||||
* This is the "prefered" method for extending QofBook to hold
|
* extending QofBook to hold new data types.
|
||||||
* 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);
|
void qof_book_set_data (QofBook *book, const char *key, gpointer data);
|
||||||
|
|
||||||
|
@ -46,9 +46,10 @@ static gboolean clear_table (gpointer key, gpointer value, gpointer user_data)
|
|||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
/* PUBLISHED API FUNCTIONS */
|
/* PUBLISHED API FUNCTIONS */
|
||||||
|
|
||||||
void qof_class_register (QofIdTypeConst obj_name,
|
void
|
||||||
QofSortFunc default_sort_function,
|
qof_class_register (QofIdTypeConst obj_name,
|
||||||
const QofParam *params)
|
QofSortFunc default_sort_function,
|
||||||
|
const QofParam *params)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -74,7 +75,8 @@ void qof_class_register (QofIdTypeConst obj_name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qof_class_init(void)
|
void
|
||||||
|
qof_class_init(void)
|
||||||
{
|
{
|
||||||
if (initialized) return;
|
if (initialized) return;
|
||||||
initialized = TRUE;
|
initialized = TRUE;
|
||||||
@ -83,7 +85,8 @@ void qof_class_init(void)
|
|||||||
sortTable = g_hash_table_new (g_str_hash, g_str_equal);
|
sortTable = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qof_class_shutdown (void)
|
void
|
||||||
|
qof_class_shutdown (void)
|
||||||
{
|
{
|
||||||
if (!initialized) return;
|
if (!initialized) return;
|
||||||
initialized = FALSE;
|
initialized = FALSE;
|
||||||
@ -105,8 +108,10 @@ qof_class_get_parameter (QofIdTypeConst obj_name,
|
|||||||
|
|
||||||
ht = g_hash_table_lookup (paramTable, obj_name);
|
ht = g_hash_table_lookup (paramTable, obj_name);
|
||||||
if (!ht)
|
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));
|
return (g_hash_table_lookup (ht, parameter));
|
||||||
}
|
}
|
||||||
|
@ -56,14 +56,24 @@
|
|||||||
/** Type of Paramters (String, Date, Numeric, GUID, etc.) */
|
/** Type of Paramters (String, Date, Numeric, GUID, etc.) */
|
||||||
typedef const char * QofType;
|
typedef const char * QofType;
|
||||||
|
|
||||||
|
typedef struct _QofParam QofParam;
|
||||||
|
|
||||||
/** The QofAccessFunc defines an arbitrary function pointer
|
/** The QofAccessFunc defines an arbitrary function pointer
|
||||||
* for access functions. This is needed because C doesn't have
|
* for access functions. This is needed because C doesn't have
|
||||||
* templates, so we just cast a lot. Real functions must be of
|
* templates, so we just cast a lot. Real functions must be of
|
||||||
* the form:
|
* the form:
|
||||||
*
|
*
|
||||||
* param_type getter_func (object_type *self);
|
* param_type getter_func (object_type *self);
|
||||||
|
* or
|
||||||
|
* param_type getter_func (object_type *self, QofParam *param);
|
||||||
|
*
|
||||||
|
* The additional argument 'param' allows generic getter functions
|
||||||
|
* to be implemented, because this argument provides for a way to
|
||||||
|
* identify the expected getter_func return type at runtime. It
|
||||||
|
* also provides a place for the user to hang additional user-defined
|
||||||
|
* data.
|
||||||
*/
|
*/
|
||||||
typedef gpointer (*QofAccessFunc)(gpointer);
|
typedef gpointer (*QofAccessFunc)(gpointer object, const QofParam *param);
|
||||||
|
|
||||||
/** The QofSetterFunc defines an function pointer for parameter
|
/** The QofSetterFunc defines an function pointer for parameter
|
||||||
* setters. Real functions must be of the form:
|
* 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).
|
* object (QofIdType) or it can be a core data type (QofType).
|
||||||
* -- param_getfcn is the function to actually obtain the parameter
|
* -- param_getfcn is the function to actually obtain the parameter
|
||||||
* -- param_setfcn is the function to actually set 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.
|
* 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;
|
const char * param_name;
|
||||||
QofType param_type;
|
QofType param_type;
|
||||||
QofAccessFunc param_getfcn;
|
QofAccessFunc param_getfcn;
|
||||||
QofSetterFunc param_setfcn;
|
QofSetterFunc param_setfcn;
|
||||||
} QofParam;
|
gpointer param_userdata;
|
||||||
|
};
|
||||||
|
|
||||||
/** This function is the default sort function for a particular object type */
|
/** This function is the default sort function for a particular object type */
|
||||||
typedef int (*QofSortFunc)(gpointer, gpointer);
|
typedef int (*QofSortFunc)(gpointer, gpointer);
|
||||||
|
@ -134,7 +134,12 @@ typedef void (*QofEntityForeachCB) (QofEntity *, gpointer user_data);
|
|||||||
void qof_collection_foreach (QofCollection *,
|
void qof_collection_foreach (QofCollection *,
|
||||||
QofEntityForeachCB, gpointer user_data);
|
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);
|
gpointer qof_collection_get_data (QofCollection *col);
|
||||||
void qof_collection_set_data (QofCollection *col, gpointer user_data);
|
void qof_collection_set_data (QofCollection *col, gpointer user_data);
|
||||||
|
|
||||||
|
@ -135,6 +135,11 @@ qof_object_foreach (QofIdTypeConst type_name, QofBook *book,
|
|||||||
ENTER ("type=%s", type_name);
|
ENTER ("type=%s", type_name);
|
||||||
|
|
||||||
obj = qof_object_lookup (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);
|
col = qof_book_get_collection (book, obj->e_type);
|
||||||
PINFO ("lookup obj=%p for type=%s", obj, type_name);
|
PINFO ("lookup obj=%p for type=%s", obj, type_name);
|
||||||
if (!obj) return;
|
if (!obj) return;
|
||||||
|
@ -72,9 +72,9 @@ struct _QofQuerySort
|
|||||||
* convert types.
|
* convert types.
|
||||||
*/
|
*/
|
||||||
gboolean use_default;
|
gboolean use_default;
|
||||||
GSList * param_fcns;
|
GSList * param_fcns; /* Chain of paramters to walk */
|
||||||
QofSortFunc obj_cmp; /* In case you are comparing objects */
|
QofSortFunc obj_cmp; /* In case you are comparing objects */
|
||||||
QofCompareFunc comp_fcn; /* When you are comparing core types */
|
QofCompareFunc comp_fcn; /* When you are comparing core types */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The QUERY structure */
|
/* The QUERY structure */
|
||||||
@ -280,9 +280,9 @@ static void free_members (QofQuery *q)
|
|||||||
static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort,
|
static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort,
|
||||||
gconstpointer a, gconstpointer b)
|
gconstpointer a, gconstpointer b)
|
||||||
{
|
{
|
||||||
|
QofParam *param = NULL;
|
||||||
GSList *node;
|
GSList *node;
|
||||||
gpointer conva, convb;
|
gpointer conva, convb;
|
||||||
QofAccessFunc get_fcn = NULL; /* to appease the compiler */
|
|
||||||
|
|
||||||
g_return_val_if_fail (sort, 0);
|
g_return_val_if_fail (sort, 0);
|
||||||
|
|
||||||
@ -304,7 +304,7 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort,
|
|||||||
convb = (gpointer)b;
|
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;
|
param = node->data;
|
||||||
|
|
||||||
/* The last term is really the "parameter getter",
|
/* The last term is really the "parameter getter",
|
||||||
* unless we're comparing objects ;) */
|
* unless we're comparing objects ;) */
|
||||||
@ -312,13 +312,14 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Do the converstions */
|
/* Do the converstions */
|
||||||
conva = get_fcn (conva);
|
conva = (param->param_getfcn) (conva, param);
|
||||||
convb = get_fcn (convb);
|
convb = (param->param_getfcn) (convb, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And now return the (appropriate) compare */
|
/* And now return the (appropriate) compare */
|
||||||
if (sort->comp_fcn)
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,21 +382,21 @@ check_object (QofQuery *q, gpointer object)
|
|||||||
if (qt->param_fcns && qt->pred_fcn)
|
if (qt->param_fcns && qt->pred_fcn)
|
||||||
{
|
{
|
||||||
GSList *node;
|
GSList *node;
|
||||||
QofAccessFunc get_fcn;
|
QofParam *param = NULL;
|
||||||
gpointer conv_obj = object;
|
gpointer conv_obj = object;
|
||||||
|
|
||||||
/* iterate through the conversions */
|
/* iterate through the conversions */
|
||||||
for (node = qt->param_fcns; node; node = node->next) {
|
for (node = qt->param_fcns; node; node = node->next)
|
||||||
get_fcn = node->data;
|
{
|
||||||
|
param = node->data;
|
||||||
|
|
||||||
/* The last term is the actual parameter getter */
|
/* The last term is the actual parameter getter */
|
||||||
if (!node->next)
|
if (!node->next) break;
|
||||||
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;
|
and_terms_ok = 0;
|
||||||
break;
|
break;
|
||||||
@ -428,8 +429,9 @@ check_object (QofQuery *q, gpointer object)
|
|||||||
*
|
*
|
||||||
* returns NULL if the first parameter is bad (and final is unchanged).
|
* returns NULL if the first parameter is bad (and final is unchanged).
|
||||||
*/
|
*/
|
||||||
static GSList * compile_params (GSList *param_list, QofIdType start_obj,
|
static GSList *
|
||||||
QofParam const **final)
|
compile_params (GSList *param_list, QofIdType start_obj,
|
||||||
|
QofParam const **final)
|
||||||
{
|
{
|
||||||
const QofParam *objDef = NULL;
|
const QofParam *objDef = NULL;
|
||||||
GSList *fcns = NULL;
|
GSList *fcns = NULL;
|
||||||
@ -447,8 +449,8 @@ static GSList * compile_params (GSList *param_list, QofIdType start_obj,
|
|||||||
/* If it doesn't exist, then we've reached the end */
|
/* If it doesn't exist, then we've reached the end */
|
||||||
if (!objDef) break;
|
if (!objDef) break;
|
||||||
|
|
||||||
/* Save off this function */
|
/* Save off this parameter */
|
||||||
fcns = g_slist_prepend (fcns, objDef->param_getfcn);
|
fcns = g_slist_prepend (fcns, (gpointer) objDef);
|
||||||
|
|
||||||
/* Save this off, just in case */
|
/* Save this off, just in case */
|
||||||
*final = objDef;
|
*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);
|
qof_object_foreach (q->search_for, book, (QofEntityForeachCB) check_item_cb, &qcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,22 +37,22 @@ void qof_query_core_init(void);
|
|||||||
void qof_query_core_shutdown (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
|
* particular parameter get-function (obtained from the registry by
|
||||||
* the Query internals), compare the object's parameter to the
|
* the Query internals), compare the object's parameter to the
|
||||||
* predicate data
|
* predicate data.
|
||||||
*/
|
*/
|
||||||
typedef int (*QofQueryPredicateFunc) (gpointer object,
|
typedef int (*QofQueryPredicateFunc) (gpointer object,
|
||||||
QofAccessFunc get_fcn,
|
QofParam *getter,
|
||||||
QofQueryPredData *pdata);
|
QofQueryPredData *pdata);
|
||||||
|
|
||||||
/* A callback for how to compare two (same-type) objects based on a
|
/* 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).
|
* options (which are the type-specific options).
|
||||||
*/
|
*/
|
||||||
typedef int (*QofCompareFunc) (gpointer a, gpointer b,
|
typedef int (*QofCompareFunc) (gpointer a, gpointer b,
|
||||||
gint compare_options,
|
gint compare_options,
|
||||||
QofAccessFunc get_fcn);
|
QofParam *getter);
|
||||||
|
|
||||||
/* Lookup functions */
|
/* Lookup functions */
|
||||||
QofQueryPredicateFunc qof_query_core_get_predicate (char const *type);
|
QofQueryPredicateFunc qof_query_core_get_predicate (char const *type);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -146,7 +146,6 @@ void qof_query_core_predicate_free (QofQueryPredData *pdata);
|
|||||||
/** Return a printable string for a core data object. Caller needs
|
/** Return a printable string for a core data object. Caller needs
|
||||||
* to g_free() the returned string.
|
* to g_free() the returned string.
|
||||||
*/
|
*/
|
||||||
char * qof_query_core_to_string (char const *type, gpointer object,
|
char * qof_query_core_to_string (QofType, gpointer object, QofParam *getter);
|
||||||
QofAccessFunc fcn);
|
|
||||||
|
|
||||||
#endif /* QOF_QUERYCORE_H */
|
#endif /* QOF_QUERYCORE_H */
|
||||||
|
@ -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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
@ -25,8 +25,6 @@
|
|||||||
@breif QOF client-side SQL parser.
|
@breif QOF client-side SQL parser.
|
||||||
@author Copyright (C) 2004 Linas Vepstas <linas@linas.org>
|
@author Copyright (C) 2004 Linas Vepstas <linas@linas.org>
|
||||||
|
|
||||||
XXX: todo: replace printf error with proper error
|
|
||||||
handling/reporting.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
@ -34,11 +32,16 @@
|
|||||||
#include <qof/kvp_frame.h>
|
#include <qof/kvp_frame.h>
|
||||||
#include <qof/gnc-date.h>
|
#include <qof/gnc-date.h>
|
||||||
#include <qof/gnc-numeric.h>
|
#include <qof/gnc-numeric.h>
|
||||||
|
#include <qof/gnc-trace.h>
|
||||||
#include <qof/guid.h>
|
#include <qof/guid.h>
|
||||||
#include <qof/qofbook.h>
|
#include <qof/qofbook.h>
|
||||||
#include <qof/qofquery.h>
|
#include <qof/qofquery.h>
|
||||||
#include <qof/qofsql.h>
|
#include <qof/qofsql.h>
|
||||||
|
|
||||||
|
static short module = MOD_QUERY;
|
||||||
|
|
||||||
|
/* =================================================================== */
|
||||||
|
|
||||||
struct _QofSqlQuery
|
struct _QofSqlQuery
|
||||||
{
|
{
|
||||||
sql_statement *parse_result;
|
sql_statement *parse_result;
|
||||||
@ -168,7 +171,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
|
|||||||
|
|
||||||
if (NULL == cond)
|
if (NULL == cond)
|
||||||
{
|
{
|
||||||
printf ("Error: missing condition\n");
|
PWARN("missing condition");
|
||||||
return NULL;
|
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 */
|
/* XXX fix this so it can be either left or right */
|
||||||
if (NULL == cond->d.pair.left)
|
if (NULL == cond->d.pair.left)
|
||||||
{
|
{
|
||||||
printf ("Error: missing left paramter\n");
|
PWARN("missing left paramter");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sql_field_item * sparam = cond->d.pair.left->item;
|
sql_field_item * sparam = cond->d.pair.left->item;
|
||||||
if (SQL_name != sparam->type)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
char * qparam_name = sparam->d.name->data;
|
char * qparam_name = sparam->d.name->data;
|
||||||
if (NULL == qparam_name)
|
if (NULL == qparam_name)
|
||||||
{
|
{
|
||||||
printf ("Error: we missing paramter name\n");
|
PWARN ("missing paramter name");
|
||||||
return NULL;
|
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 */
|
/* XXX fix this so it can be either left or right */
|
||||||
if (NULL == cond->d.pair.right)
|
if (NULL == cond->d.pair.right)
|
||||||
{
|
{
|
||||||
printf ("Error: missing right paramter\n");
|
PWARN ("missing right paramter");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sql_field_item * svalue = cond->d.pair.right->item;
|
sql_field_item * svalue = cond->d.pair.right->item;
|
||||||
if (SQL_name != svalue->type)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
char * qvalue_name = svalue->d.name->data;
|
char * qvalue_name = svalue->d.name->data;
|
||||||
if (NULL == qvalue_name)
|
if (NULL == qvalue_name)
|
||||||
{
|
{
|
||||||
printf ("Error: we missing value\n");
|
PWARN("missing value");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
qvalue_name = dequote_string (qvalue_name);
|
qvalue_name = dequote_string (qvalue_name);
|
||||||
@ -222,7 +226,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
|
|||||||
{
|
{
|
||||||
if (NULL == query->kvp_join)
|
if (NULL == query->kvp_join)
|
||||||
{
|
{
|
||||||
printf ("Error: missing kvp frame\n");
|
PWARN ("missing kvp frame");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
KvpValue *kv = kvp_frame_get_value (query->kvp_join, qvalue_name+5);
|
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_GLIST:
|
||||||
case KVP_TYPE_NUMERIC:
|
case KVP_TYPE_NUMERIC:
|
||||||
case KVP_TYPE_FRAME:
|
case KVP_TYPE_FRAME:
|
||||||
printf ("Error: unhandled kvp type=%d\n", kvt);
|
PWARN ("unhandled kvp type=%d", kvt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,7 +285,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
|
|||||||
default:
|
default:
|
||||||
/* XXX for string-type queries, we should be able to
|
/* XXX for string-type queries, we should be able to
|
||||||
* support 'IN' for substring search. Also regex. */
|
* 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,11 +302,12 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
|
|||||||
|
|
||||||
if (NULL == table_name)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QofType param_type = qof_class_get_parameter_type (table_name, param_name);
|
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))
|
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);
|
int rc = qof_scan_date_secs (qvalue_name, &exact);
|
||||||
if (0 == rc)
|
if (0 == rc)
|
||||||
{
|
{
|
||||||
printf ("Error: unable to parse date: %s\n", qvalue_name);
|
PWARN ("unable to parse date: %s", qvalue_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Timespec ts;
|
Timespec ts;
|
||||||
@ -374,7 +379,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
|
|||||||
gboolean rc = string_to_guid (qvalue_name, guid);
|
gboolean rc = string_to_guid (qvalue_name, guid);
|
||||||
if (0 == rc)
|
if (0 == rc)
|
||||||
{
|
{
|
||||||
printf ("Error: unable to parse guid: %s\n", qvalue_name);
|
PWARN ("unable to parse guid: %s", qvalue_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,7 +400,7 @@ xxxxxhd
|
|||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("Error: predicate type unsupported for now \n");
|
PWARN ("The predicate type \"%s\" is unsupported for now", param_type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,14 +515,14 @@ qof_sql_query_run (QofSqlQuery *query, const char *str)
|
|||||||
|
|
||||||
if (!query->parse_result)
|
if (!query->parse_result)
|
||||||
{
|
{
|
||||||
printf ("parse error\n"); // XXX replace
|
PWARN ("parse error");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SQL_select != query->parse_result->type)
|
if (SQL_select != query->parse_result->type)
|
||||||
{
|
{
|
||||||
printf ("Error: currently, only SELECT statements are supported, "
|
PWARN("currently, only SELECT statements are supported, "
|
||||||
"got type=%d\n", query->parse_result);
|
"got type=%d", query->parse_result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
@ -20,6 +20,8 @@
|
|||||||
* *
|
* *
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
|
/** @addtogroup Engine
|
||||||
|
@{ */
|
||||||
/**
|
/**
|
||||||
@file qofsql.h
|
@file qofsql.h
|
||||||
@breif QOF client-side SQL parser.
|
@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 *);
|
void qof_sql_query_set_kvp (QofSqlQuery *, KvpFrame *);
|
||||||
|
|
||||||
#endif /* QOF_SQL_QUERY_H */
|
#endif /* QOF_SQL_QUERY_H */
|
||||||
|
/** @} */
|
||||||
|
@ -90,7 +90,7 @@ struct _GNCSearchWindow {
|
|||||||
/* What we're searching for, and how */
|
/* What we're searching for, and how */
|
||||||
GNCIdTypeConst search_for;
|
GNCIdTypeConst search_for;
|
||||||
GNCSearchType grouping; /* Match Any, Match All */
|
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 */
|
int search_type; /* New, Narrow, Add, Delete */
|
||||||
|
|
||||||
/* Our query status */
|
/* Our query status */
|
||||||
@ -441,14 +441,15 @@ search_new_item_cb (GtkButton *button, GNCSearchWindow *sw)
|
|||||||
|
|
||||||
res = (sw->new_item_cb)(sw->user_data);
|
res = (sw->new_item_cb)(sw->user_data);
|
||||||
|
|
||||||
if (res) {
|
if (res)
|
||||||
const GUID *guid = (const GUID *) ((sw->get_guid)(res));
|
{
|
||||||
|
const GUID *guid = (const GUID *) ((sw->get_guid->param_getfcn)(res, sw->get_guid));
|
||||||
QueryOp op = QUERY_OR;
|
QueryOp op = QUERY_OR;
|
||||||
|
|
||||||
if (!sw->q) {
|
if (!sw->q) {
|
||||||
if (!sw->start_q) {
|
if (!sw->start_q) {
|
||||||
sw->start_q = gncQueryCreateFor (sw->search_for);
|
sw->start_q = gncQueryCreateFor (sw->search_for);
|
||||||
gncQuerySetBook (sw->start_q, gnc_get_current_book ());
|
gncQuerySetBook (sw->start_q, gnc_get_current_book ());
|
||||||
}
|
}
|
||||||
sw->q = gncQueryCopy (sw->start_q);
|
sw->q = gncQueryCopy (sw->start_q);
|
||||||
op = QUERY_AND;
|
op = QUERY_AND;
|
||||||
@ -882,8 +883,8 @@ gnc_search_dialog_create (GNCIdTypeConst obj_type, GList *param_list,
|
|||||||
sw->free_cb = free_cb;
|
sw->free_cb = free_cb;
|
||||||
|
|
||||||
/* Grab the get_guid function */
|
/* Grab the get_guid function */
|
||||||
sw->get_guid = gncQueryObjectGetParameterGetter (sw->search_for,
|
sw->get_guid = qof_class_get_parameter (sw->search_for,
|
||||||
QUERY_PARAM_GUID);
|
QOF_QUERY_PARAM_GUID);
|
||||||
if (start_query)
|
if (start_query)
|
||||||
sw->start_q = gncQueryCopy (start_query);
|
sw->start_q = gncQueryCopy (start_query);
|
||||||
sw->q = show_start_query;
|
sw->q = show_start_query;
|
||||||
|
@ -62,7 +62,7 @@ struct _GNCGeneralSearchPrivate {
|
|||||||
GNCSearchCB search_cb;
|
GNCSearchCB search_cb;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
GNCSearchWindow * sw;
|
GNCSearchWindow * sw;
|
||||||
QueryAccess get_guid;
|
const QofParam * get_guid;
|
||||||
gint component_id;
|
gint component_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -295,11 +295,11 @@ gnc_general_search_new (GNCIdTypeConst type, const char *label,
|
|||||||
GNCSearchCB search_cb, gpointer user_data)
|
GNCSearchCB search_cb, gpointer user_data)
|
||||||
{
|
{
|
||||||
GNCGeneralSearch *gsl;
|
GNCGeneralSearch *gsl;
|
||||||
QueryAccess get_guid;
|
const QofParam *get_guid;
|
||||||
|
|
||||||
g_return_val_if_fail (type && label && search_cb, NULL);
|
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);
|
g_return_val_if_fail (get_guid, NULL);
|
||||||
|
|
||||||
gsl = gtk_type_new (gnc_general_search_get_type ());
|
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);
|
gnc_gui_component_clear_watches (gsl->priv->component_id);
|
||||||
|
|
||||||
if (selection) {
|
if (selection)
|
||||||
gsl->priv->guid = * ((GUID *)(gsl->priv->get_guid
|
{
|
||||||
(gsl->selected_item)));
|
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
|
gnc_gui_component_watch_entity
|
||||||
(gsl->priv->component_id, &(gsl->priv->guid),
|
(gsl->priv->component_id, &(gsl->priv->guid),
|
||||||
GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
|
GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
|
||||||
|
@ -43,9 +43,10 @@ enum
|
|||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GNCQueryListPriv {
|
struct _GNCQueryListPriv
|
||||||
QueryAccess get_guid;
|
{
|
||||||
gint component_id;
|
const QofParam * get_guid;
|
||||||
|
gint component_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Impossible to get at runtime. Assume this is a reasonable number */
|
/* Impossible to get at runtime. Assume this is a reasonable number */
|
||||||
@ -125,8 +126,8 @@ gnc_query_list_construct (GNCQueryList *list, GList *param_list, Query *query)
|
|||||||
|
|
||||||
/* cache the function to get the guid of this query type */
|
/* cache the function to get the guid of this query type */
|
||||||
list->priv->get_guid =
|
list->priv->get_guid =
|
||||||
gncQueryObjectGetParameterGetter (gncQueryGetSearchFor (query),
|
qof_class_get_parameter (qof_query_get_search_for(query),
|
||||||
QUERY_PARAM_GUID);
|
QOF_QUERY_PARAM_GUID);
|
||||||
|
|
||||||
/* Initialize the CList */
|
/* Initialize the CList */
|
||||||
gnc_query_list_init_clist(list);
|
gnc_query_list_init_clist(list);
|
||||||
@ -776,6 +777,7 @@ gnc_query_list_fill(GNCQueryList *list)
|
|||||||
{
|
{
|
||||||
GList *node;
|
GList *node;
|
||||||
gint row;
|
gint row;
|
||||||
|
QofParam *qp= NULL;
|
||||||
|
|
||||||
for (i = 0, node = list->column_params; node; node = node->next)
|
for (i = 0, node = list->column_params; node; node = node->next)
|
||||||
{
|
{
|
||||||
@ -783,33 +785,35 @@ gnc_query_list_fill(GNCQueryList *list)
|
|||||||
GSList *converters = gnc_search_param_get_converters (param);
|
GSList *converters = gnc_search_param_get_converters (param);
|
||||||
const char *type = gnc_search_param_get_param_type (param);
|
const char *type = gnc_search_param_get_param_type (param);
|
||||||
gpointer res = item->data;
|
gpointer res = item->data;
|
||||||
QueryAccess fcn = NULL;
|
|
||||||
|
|
||||||
/* if this is a boolean, ignore it now -- we'll use a checkmark later */
|
/* if this is a boolean, ignore it now -- we'll use a checkmark later */
|
||||||
if (!safe_strcmp (type, QUERYCORE_BOOLEAN)) {
|
if (!safe_strcmp (type, QUERYCORE_BOOLEAN)) {
|
||||||
strings[i++] = g_strdup("");
|
strings[i++] = g_strdup("");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do all the object conversions */
|
/* Do all the object conversions */
|
||||||
for (; converters; converters = converters->next) {
|
for (; converters; converters = converters->next)
|
||||||
fcn = converters->data;
|
{
|
||||||
|
qp = converters->data;
|
||||||
if (converters->next)
|
if (converters->next)
|
||||||
res = fcn (res);
|
{
|
||||||
|
res = (qp->param_getfcn)(res, qp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now convert this to a text value for the row */
|
/* Now convert this to a text value for the row */
|
||||||
if (!safe_strcmp(type, QUERYCORE_DEBCRED) ||
|
if (!safe_strcmp(type, QUERYCORE_DEBCRED) ||
|
||||||
!safe_strcmp(type, QUERYCORE_NUMERIC))
|
!safe_strcmp(type, QUERYCORE_NUMERIC))
|
||||||
{
|
{
|
||||||
gnc_numeric (*nfcn)(gpointer) = (gnc_numeric(*)(gpointer))fcn;
|
gnc_numeric (*nfcn)(gpointer, QofParam *) =
|
||||||
gnc_numeric value = nfcn(res);
|
(gnc_numeric(*)(gpointer, QofParam *))(qp->param_getfcn);
|
||||||
if (list->numeric_abs)
|
gnc_numeric value = nfcn(res, qp);
|
||||||
value = gnc_numeric_abs (value);
|
if (list->numeric_abs)
|
||||||
strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE)));
|
value = gnc_numeric_abs (value);
|
||||||
|
strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE)));
|
||||||
} else
|
} else
|
||||||
strings[i++] = gncQueryCoreToString (type, res, fcn);
|
strings[i++] = gncQueryCoreToString (type, res, qp);
|
||||||
}
|
}
|
||||||
|
|
||||||
row = gtk_clist_append (GTK_CLIST(list), (gchar **) strings);
|
row = gtk_clist_append (GTK_CLIST(list), (gchar **) strings);
|
||||||
@ -818,14 +822,15 @@ gnc_query_list_fill(GNCQueryList *list)
|
|||||||
/* Free up our strings */
|
/* Free up our strings */
|
||||||
for (i = 0; i < list->num_columns; i++) {
|
for (i = 0; i < list->num_columns; i++) {
|
||||||
if (strings[i])
|
if (strings[i])
|
||||||
g_free (strings[i]);
|
g_free (strings[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now update any checkmarks */
|
/* Now update any checkmarks */
|
||||||
update_booleans (list, row);
|
update_booleans (list, row);
|
||||||
|
|
||||||
/* and set a watcher on this item */
|
/* 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_gui_component_watch_entity (list->priv->component_id, guid,
|
||||||
GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
|
GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ gnc_search_param_set_param_path (GNCSearchParam *param,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Save the converter */
|
/* Save the converter */
|
||||||
converters = g_slist_prepend (converters, objDef->param_getfcn);
|
converters = g_slist_prepend (converters, (gpointer) objDef);
|
||||||
|
|
||||||
/* And reset for the next parameter */
|
/* And reset for the next parameter */
|
||||||
type = search_type = objDef->param_type;
|
type = search_type = objDef->param_type;
|
||||||
@ -372,13 +372,13 @@ gnc_search_param_compute_value (GNCSearchParam *param, gpointer object)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
GSList *converters = gnc_search_param_get_converters (param);
|
GSList *converters = gnc_search_param_get_converters (param);
|
||||||
QueryAccess fcn = NULL;
|
|
||||||
gpointer res = object;
|
gpointer res = object;
|
||||||
|
|
||||||
/* Do all the object conversions */
|
/* Do all the object conversions */
|
||||||
for (; converters; converters = converters->next) {
|
for (; converters; converters = converters->next)
|
||||||
fcn = converters->data;
|
{
|
||||||
res = fcn (res);
|
QofParam *qp = converters->data;
|
||||||
|
res = (qp->param_getfcn) (res, qp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
Loading…
Reference in New Issue
Block a user