Forgotten patch: qofid.diff
Chris Shoemaker
c.shoemaker at cox.net
Tue Oct 25 10:18:29 EDT 2005
Subject: [qofid.diff] Minor tweaks to Qof Code in src/engine.
Neil, I don't know if this patch messes up your plans. The only
essential thing here is qof_collection_get_list(). If we have to, I
suppose we could pull this into the budget namespace until the next
qof release. What do you think?
* src/engine/qof-be-utils.h
- avoid declare-after-statement
- minor tweaks to ugly macros
* src/engine/qofid.[ch]:
- Collection's hash of entities was using guid->data as lookup key.
The key is actually just guid everywhere else.
- Introduced qof_collection_get_list() for getting GList of entity GUIDs.
- line-wrap and whitespace fixes
- add comment about problems with get/set_data interface.
* src/engine/qofclass.c:
- Catch uses of qof_class system without qof_class_init and throw error.
- Comment that 3 qof_class functions are actually private.
* src/engine/qofquery.c:
- ENTER/LEAVE balance.
src/engine/qof-be-utils.h | 22 +++++++-------
src/engine/qofclass.c | 69 +++++++++++++++++++++++++++-------------------
src/engine/qofid.c | 46 ++++++++++++++++++++----------
src/engine/qofid.h | 30 +++++++++++++++-----
src/engine/qofquery.c | 1
5 files changed, 106 insertions(+), 62 deletions(-)
Index: gnucash/src/engine/qof-be-utils.h
===================================================================
--- gnucash.orig/src/engine/qof-be-utils.h
+++ gnucash/src/engine/qof-be-utils.h
@@ -52,7 +52,6 @@
*/
#define QOF_BEGIN_EDIT(inst) \
- QofBackend * be; \
if (!(inst)) return; \
\
(inst)->editlevel++; \
@@ -66,12 +65,13 @@
ENTER ("(inst=%p)", (inst)); \
\
/* See if there's a backend. If there is, invoke it. */ \
- be = qof_book_get_backend ((inst)->book); \
- if (be && qof_backend_begin_exists((be))) { \
- qof_backend_run_begin((be), (inst)); \
- } else { \
- /* We tried and failed to start transaction! */ \
- (inst)->dirty = TRUE; \
+ { \
+ QofBackend * be; \
+ be = qof_book_get_backend ((inst)->book); \
+ if (be && qof_backend_begin_exists(be)) \
+ qof_backend_run_begin(be, (inst)); \
+ else /* We tried and failed to start transaction! */ \
+ (inst)->dirty = TRUE; \
} \
LEAVE (" ");
@@ -109,8 +109,8 @@ gboolean qof_begin_edit(QofInstance *ins
{ \
QofBackend * be; \
be = qof_book_get_backend ((inst)->book); \
- if (be && qof_backend_begin_exists((be))) { \
- qof_backend_run_begin((be), (inst)); \
+ if (be && qof_backend_begin_exists(be)) { \
+ qof_backend_run_begin(be, (inst)); \
} \
(inst)->editlevel = 0; \
} \
@@ -148,7 +148,7 @@ gboolean qof_commit_edit(QofInstance *in
\
/* See if there's a backend. If there is, invoke it. */ \
be = qof_book_get_backend ((inst)->book); \
- if (be && qof_backend_commit_exists((be))) \
+ if (be && qof_backend_commit_exists(be)) \
{ \
QofBackendError errcode; \
\
@@ -157,7 +157,7 @@ gboolean qof_commit_edit(QofInstance *in
errcode = qof_backend_get_error (be); \
} while (ERR_BACKEND_NO_ERR != errcode); \
\
- qof_backend_run_commit((be), (inst)); \
+ qof_backend_run_commit(be, (inst)); \
errcode = qof_backend_get_error (be); \
if (ERR_BACKEND_NO_ERR != errcode) \
{ \
Index: gnucash/src/engine/qofclass.c
===================================================================
--- gnucash.orig/src/engine/qofclass.c
+++ gnucash/src/engine/qofclass.c
@@ -43,6 +43,44 @@ static gboolean clear_table (gpointer ke
return TRUE;
}
+static gboolean check_init (void)
+{
+ if (initialized) return TRUE;
+
+ PERR("You must call qof_class_init() before using qof_class.");
+ return FALSE;
+}
+
+/********************************************************************/
+/* PRIVATE PUBLISHED API FUNCTIONS */
+void
+qof_class_init(void)
+{
+ if (initialized) return;
+ initialized = TRUE;
+
+ classTable = 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)
+{
+ if (!initialized) return;
+ initialized = FALSE;
+
+ g_hash_table_foreach_remove (classTable, clear_table, NULL);
+ g_hash_table_destroy (classTable);
+ g_hash_table_destroy (sortTable);
+}
+
+QofSortFunc
+qof_class_get_default_sort (QofIdTypeConst obj_name)
+{
+ if (!obj_name) return NULL;
+ return g_hash_table_lookup (sortTable, obj_name);
+}
+
/********************************************************************/
/* PUBLISHED API FUNCTIONS */
@@ -55,6 +93,7 @@ qof_class_register (QofIdTypeConst obj_n
int i;
if (!obj_name) return;
+ if (!check_init()) return;
if (default_sort_function)
{
@@ -83,31 +122,11 @@ qof_class_register (QofIdTypeConst obj_n
}
}
-void
-qof_class_init(void)
-{
- if (initialized) return;
- initialized = TRUE;
-
- classTable = 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)
-{
- if (!initialized) return;
- initialized = FALSE;
-
- g_hash_table_foreach_remove (classTable, clear_table, NULL);
- g_hash_table_destroy (classTable);
- g_hash_table_destroy (sortTable);
-}
-
gboolean
qof_class_is_registered (QofIdTypeConst obj_name)
{
if (!obj_name) return FALSE;
+ if (!check_init()) return FALSE;
if (g_hash_table_lookup (classTable, obj_name)) return TRUE;
@@ -122,6 +141,7 @@ qof_class_get_parameter (QofIdTypeConst
g_return_val_if_fail (obj_name, NULL);
g_return_val_if_fail (parameter, NULL);
+ if (!check_init()) return NULL;
ht = g_hash_table_lookup (classTable, obj_name);
if (!ht)
@@ -179,13 +199,6 @@ qof_class_get_parameter_type (QofIdTypeC
return (prm->param_type);
}
-QofSortFunc
-qof_class_get_default_sort (QofIdTypeConst obj_name)
-{
- if (!obj_name) return NULL;
- return g_hash_table_lookup (sortTable, obj_name);
-}
-
/* ================================================================ */
struct class_iterate {
Index: gnucash/src/engine/qofid.c
===================================================================
--- gnucash.orig/src/engine/qofid.c
+++ gnucash/src/engine/qofid.c
@@ -53,11 +53,11 @@ qof_entity_init (QofEntity *ent, QofIdTy
g_return_if_fail (NULL != tab);
/* XXX We passed redundant info to this routine ... but I think that's
- * OK, it might eliminate programming errors. */
+ * OK, it might eliminate programming errors. */
if (safe_strcmp(tab->e_type, type))
{
PERR ("attempt to insert \"%s\" into \"%s\"", type, tab->e_type);
- return;
+ return;
}
ent->e_type = CACHE_INSERT (type);
@@ -158,8 +158,8 @@ void
qof_collection_destroy (QofCollection *col)
{
CACHE_REMOVE (col->e_type);
- g_hash_table_destroy(col->hash_of_entities);
col->e_type = NULL;
+ g_hash_table_destroy(col->hash_of_entities);
col->hash_of_entities = NULL;
col->data = NULL; /** XXX there should be a destroy notifier for this */
g_free (col);
@@ -289,7 +289,7 @@ qof_collection_lookup_entity (QofCollect
QofEntity *ent;
g_return_val_if_fail (col, NULL);
if (guid == NULL) return NULL;
- ent = g_hash_table_lookup (col->hash_of_entities, guid->data);
+ ent = g_hash_table_lookup (col->hash_of_entities, guid);
return ent;
}
@@ -326,22 +326,21 @@ qof_collection_count (QofCollection *col
gboolean
qof_collection_is_dirty (QofCollection *col)
{
- if (!col) return FALSE;
- return col->is_dirty;
+ return col ? col->is_dirty : FALSE;
}
void
qof_collection_mark_clean (QofCollection *col)
{
- if (!col) return;
- col->is_dirty = FALSE;
+ if (col)
+ col->is_dirty = FALSE;
}
void
qof_collection_mark_dirty (QofCollection *col)
{
- if (!col) return;
- col->is_dirty = TRUE;
+ if (col)
+ col->is_dirty = TRUE;
}
/* =============================================================== */
@@ -349,15 +348,14 @@ qof_collection_mark_dirty (QofCollection
gpointer
qof_collection_get_data (QofCollection *col)
{
- if (!col) return NULL;
- return col->data;
+ return col ? col->data : NULL;
}
void
qof_collection_set_data (QofCollection *col, gpointer user_data)
{
- if (!col) return;
- col->data = user_data;
+ if (col)
+ col->data = user_data;
}
/* =============================================================== */
@@ -376,8 +374,8 @@ static void foreach_cb (gpointer key, gp
}
void
-qof_collection_foreach (QofCollection *col,
- QofEntityForeachCB cb_func, gpointer user_data)
+qof_collection_foreach (QofCollection *col, QofEntityForeachCB cb_func,
+ gpointer user_data)
{
struct _iterate iter;
@@ -390,4 +388,20 @@ qof_collection_foreach (QofCollection *c
g_hash_table_foreach (col->hash_of_entities, foreach_cb, &iter);
}
+
+static void
+add_to_list(gpointer key, gpointer val, gpointer data) {
+ GList **list = data;
+ *list = g_list_append(*list, QOF_ENTITY(val));
+}
+
+GList *
+qof_collection_get_list(QofCollection *col) {
+ GList *list = NULL;
+ g_return_val_if_fail (col, NULL);
+
+ g_hash_table_foreach(col->hash_of_entities, add_to_list, &list);
+ return list;
+}
+
/* =============================================================== */
Index: gnucash/src/engine/qofid.h
===================================================================
--- gnucash.orig/src/engine/qofid.h
+++ gnucash/src/engine/qofid.h
@@ -105,7 +105,8 @@ typedef const gchar* QofLogModule;
})
/** return TRUE if object is of the given type */
-#define QOF_CHECK_TYPE(obj,type) (0 == QSTRCMP((type),(((QofEntity *)(obj))->e_type)))
+#define QOF_CHECK_TYPE(obj,type) ( ((obj) != NULL) && \
+ (0 == QSTRCMP((type),(((QofEntity *)(obj))->e_type))))
/** cast object to the indicated type, print error message if its bad */
#define QOF_CHECK_CAST(obj,e_type,c_type) ( \
@@ -138,9 +139,9 @@ typedef struct QofCollection_s QofCollec
struct QofEntity_s
{
- QofIdType e_type;
- GUID guid;
- QofCollection * collection;
+ QofIdType e_type;
+ GUID guid;
+ QofCollection * collection;
};
/** @name QOF Entity Initialization & Shutdown
@@ -178,14 +179,29 @@ QofEntity * qof_collection_lookup_entity
typedef void (*QofEntityForeachCB) (QofEntity *, gpointer user_data);
/** Call the callback for each entity in the collection. */
-void qof_collection_foreach (QofCollection *,
- QofEntityForeachCB, gpointer user_data);
+void qof_collection_foreach (QofCollection *, QofEntityForeachCB,
+ gpointer user_data);
-/** Store and retreive arbitrary object-defined data
+/** Get a list of entities in the collection. Caller owns the list. */
+GList * qof_collection_get_list(QofCollection *col);
+
+/** Store and retrieve 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.
+ *
+ * CAS: Besides the potential leak, this interface is kind of bogus in
+ * other ways, too. For example, using collection data is risky
+ * because even though the collection data is very public, its use
+ * must be universally consistent. That's a visibility violation.
+ *
+ * Here's what I think is needed: Object implementations need to be
+ * allowed a say in how their collection is managed. Maybe they can
+ * register functions that control what happens to the collection when
+ * an object is added to or removed from the book. Then we can remove
+ * public access to the collection's data via these two functions here.
+ *
*/
gpointer qof_collection_get_data (QofCollection *col);
void qof_collection_set_data (QofCollection *col, gpointer user_data);
Index: gnucash/src/engine/qofquery.c
===================================================================
--- gnucash.orig/src/engine/qofquery.c
+++ gnucash/src/engine/qofquery.c
@@ -1273,6 +1273,7 @@ void qof_query_init (void)
ENTER (" ");
qof_query_core_init ();
qof_class_init ();
+ LEAVE ("Completed initialization of QofQuery");
}
void qof_query_shutdown (void)
More information about the gnucash-patches
mailing list