GnuCash  5.6-150-g038405b370+
qofid.cpp
1 /********************************************************************\
2  * qofid.c -- QOF entity identifier implementation *
3  * Copyright (C) 2000 Dave Peticolas <dave@krondo.com> *
4  * Copyright (C) 2003 Linas Vepstas <linas@linas.org> *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA gnu@gnu.org *
22  * *
23 \********************************************************************/
24 
25 #include <glib.h>
26 
27 #include <config.h>
28 #include <string.h>
29 
30 #include "qof.h"
31 #include "qofid-p.h"
32 #include "qofinstance-p.h"
33 
34 static QofLogModule log_module = QOF_MOD_ENGINE;
35 
37 {
38  QofIdType e_type;
39  gboolean is_dirty;
40 
41  GHashTable * hash_of_entities;
42  gpointer data; /* place where object class can hang arbitrary data */
43 };
44 
45 /* =============================================================== */
46 
47 QofCollection *
49 {
50  QofCollection *col;
51  col = g_new0(QofCollection, 1);
52  col->e_type = static_cast<QofIdType>(CACHE_INSERT (type));
53  col->is_dirty = FALSE;
54  col->hash_of_entities = guid_hash_table_new();
55  col->data = NULL;
56  return col;
57 }
58 
59 void
60 qof_collection_destroy (QofCollection *col)
61 {
62  CACHE_REMOVE (col->e_type);
63  g_hash_table_destroy(col->hash_of_entities);
64  col->e_type = NULL;
65  col->hash_of_entities = NULL;
66  col->data = NULL;
67  g_free (col);
68 }
69 
70 /* =============================================================== */
71 /* getters */
72 
74 qof_collection_get_type (const QofCollection *col)
75 {
76  return col->e_type;
77 }
78 
79 /* =============================================================== */
80 
81 void
82 qof_collection_remove_entity (QofInstance *ent)
83 {
84  QofCollection *col;
85  const GncGUID *guid;
86 
87  if (!ent) return;
88  col = qof_instance_get_collection(ent);
89  if (!col) return;
90  guid = qof_instance_get_guid(ent);
91  g_hash_table_remove (col->hash_of_entities, guid);
92  qof_instance_set_collection(ent, NULL);
93 }
94 
95 void
96 qof_collection_insert_entity (QofCollection *col, QofInstance *ent)
97 {
98  const GncGUID *guid;
99 
100  if (!col || !ent) return;
101  guid = qof_instance_get_guid(ent);
102  if (guid_equal(guid, guid_null())) return;
103  g_return_if_fail (col->e_type == ent->e_type);
104  qof_collection_remove_entity (ent);
105  g_hash_table_insert (col->hash_of_entities, (gpointer)guid, ent);
106  qof_instance_set_collection(ent, col);
107 }
108 
109 gboolean
110 qof_collection_add_entity (QofCollection *coll, QofInstance *ent)
111 {
112  QofInstance *e;
113  const GncGUID *guid;
114 
115  e = NULL;
116  if (!coll || !ent)
117  {
118  return FALSE;
119  }
120  guid = qof_instance_get_guid(ent);
121  if (guid_equal(guid, guid_null()))
122  {
123  return FALSE;
124  }
125  g_return_val_if_fail (coll->e_type == ent->e_type, FALSE);
126  e = qof_collection_lookup_entity(coll, guid);
127  if ( e != NULL )
128  {
129  return FALSE;
130  }
131  g_hash_table_insert (coll->hash_of_entities, (gpointer)guid, ent);
132  return TRUE;
133 }
134 
135 
136 static void
137 collection_compare_cb (QofInstance *ent, gpointer user_data)
138 {
139  QofCollection *target;
140  QofInstance *e;
141  const GncGUID *guid;
142  gint* value;
143 
144  e = NULL;
145  target = (QofCollection*)user_data;
146  if (!target || !ent)
147  {
148  return;
149  }
150  value = (gint*)qof_collection_get_data(target);
151  if (*value != 0)
152  {
153  return;
154  }
155  guid = qof_instance_get_guid(ent);
156  if (guid_equal(guid, guid_null()))
157  {
158  *value = -1;
159  return;
160  }
161  g_return_if_fail (target->e_type == ent->e_type);
162  e = qof_collection_lookup_entity(target, guid);
163  if ( e == NULL )
164  {
165  *value = 1;
166  return;
167  }
168  *value = 0;
169 }
170 
171 gint
172 qof_collection_compare (QofCollection *target, QofCollection *merge)
173 {
174  gint value;
175 
176  value = 0;
177  if (!target && !merge)
178  {
179  return 0;
180  }
181  if (target == merge)
182  {
183  return 0;
184  }
185  if (!target && merge)
186  {
187  return -1;
188  }
189  if (target && !merge)
190  {
191  return 1;
192  }
193  if (target->e_type != merge->e_type)
194  {
195  return -1;
196  }
197  qof_collection_set_data(target, &value);
198  qof_collection_foreach(merge, collection_compare_cb, target);
199  value = *(gint*)qof_collection_get_data(target);
200  if (value == 0)
201  {
202  qof_collection_set_data(merge, &value);
203  qof_collection_foreach(target, collection_compare_cb, merge);
204  value = *(gint*)qof_collection_get_data(merge);
205  }
206  return value;
207 }
208 
209 QofInstance *
210 qof_collection_lookup_entity (const QofCollection *col, const GncGUID * guid)
211 {
212  QofInstance *ent;
213  g_return_val_if_fail (col, NULL);
214  if (guid == NULL) return NULL;
215  ent = static_cast<QofInstance*>(g_hash_table_lookup (col->hash_of_entities,
216  guid));
217  if (ent != NULL && qof_instance_get_destroying(ent)) return NULL;
218  return ent;
219 }
220 
221 guint
222 qof_collection_count (const QofCollection *col)
223 {
224  guint c;
225 
226  c = g_hash_table_size(col->hash_of_entities);
227  return c;
228 }
229 
230 /* =============================================================== */
231 
232 gboolean
233 qof_collection_is_dirty (const QofCollection *col)
234 {
235  return col ? col->is_dirty : FALSE;
236 }
237 
238 void
239 qof_collection_mark_clean (QofCollection *col)
240 {
241  if (col)
242  {
243  col->is_dirty = FALSE;
244  }
245 }
246 
247 void
248 qof_collection_mark_dirty (QofCollection *col)
249 {
250  if (col)
251  {
252  col->is_dirty = TRUE;
253  }
254 }
255 
256 void
257 qof_collection_print_dirty (const QofCollection *col, gpointer dummy)
258 {
259  if (col->is_dirty)
260  printf("%s collection is dirty.\n", col->e_type);
261  qof_collection_foreach(col, (QofInstanceForeachCB)qof_instance_print_dirty, NULL);
262 }
263 
264 /* =============================================================== */
265 
266 gpointer
267 qof_collection_get_data (const QofCollection *col)
268 {
269  return col ? col->data : NULL;
270 }
271 
272 void
273 qof_collection_set_data (QofCollection *col, gpointer user_data)
274 {
275  if (col)
276  {
277  col->data = user_data;
278  }
279 }
280 
281 /* =============================================================== */
282 
283 void
284 qof_collection_foreach_sorted (const QofCollection *col, QofInstanceForeachCB cb_func,
285  gpointer user_data, GCompareFunc sort_fn)
286 {
287  GList *entries;
288 
289  g_return_if_fail (col);
290  g_return_if_fail (cb_func);
291 
292  PINFO("Hash Table size of %s before is %d", col->e_type, g_hash_table_size(col->hash_of_entities));
293 
294  entries = g_hash_table_get_values (col->hash_of_entities);
295  if (sort_fn)
296  entries = g_list_sort (entries, sort_fn);
297  g_list_foreach (entries, (GFunc)cb_func, user_data);
298  g_list_free (entries);
299 
300  PINFO("Hash Table size of %s after is %d", col->e_type, g_hash_table_size(col->hash_of_entities));
301 }
302 
303 void
304 qof_collection_foreach (const QofCollection *col, QofInstanceForeachCB cb_func,
305  gpointer user_data)
306 {
307  qof_collection_foreach_sorted (col, cb_func, user_data, nullptr);
308 }
309 /* =============================================================== */
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
gboolean qof_collection_is_dirty(const QofCollection *col)
Return value of &#39;dirty&#39; flag on collection.
Definition: qofid.cpp:233
QofInstance * qof_collection_lookup_entity(const QofCollection *col, const GncGUID *guid)
Find the entity going only from its guid.
Definition: qofid.cpp:210
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
void(* QofInstanceForeachCB)(QofInstance *, gpointer user_data)
Callback type for qof_collection_foreach.
Definition: qofid.h:146
GHashTable * guid_hash_table_new(void)
Returns a GHashTable with <GUID*> as key and a <gpointer> as value and no destructor functions for ke...
Definition: guid.cpp:276
QofCollection * qof_instance_get_collection(gconstpointer ptr)
Return the collection this instance belongs to.
void qof_collection_foreach_sorted(const QofCollection *col, QofInstanceForeachCB cb_func, gpointer user_data, GCompareFunc sort_fn)
Call the callback for each entity in the collection.
Definition: qofid.cpp:284
gint qof_collection_compare(QofCollection *target, QofCollection *merge)
Compare two secondary collections.
Definition: qofid.cpp:172
const gchar * QofIdType
QofIdType declaration.
Definition: qofid.h:80
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Given two GUIDs, return TRUE if they are non-NULL and equal.
Definition: guid.cpp:237
void qof_collection_insert_entity(QofCollection *col, QofInstance *ent)
Take entity, remove it from whatever collection its currently in, and place it in a new collection...
Definition: qofid.cpp:96
void qof_collection_mark_clean(QofCollection *col)
reset value of dirty flag
Definition: qofid.cpp:239
void qof_collection_destroy(QofCollection *col)
destroy the collection
Definition: qofid.cpp:60
QofIdType qof_collection_get_type(const QofCollection *col)
return the type that the collection stores
Definition: qofid.cpp:74
QofIdType e_type
Entity type.
Definition: qofinstance.h:75
gboolean qof_collection_add_entity(QofCollection *coll, QofInstance *ent)
Add an entity to a QOF_TYPE_COLLECT.
Definition: qofid.cpp:110
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
Definition: guid.cpp:165
guint qof_collection_count(const QofCollection *col)
return the number of entities in the collection.
Definition: qofid.cpp:222
gpointer qof_collection_get_data(const QofCollection *col)
Store and retrieve arbitrary object-defined data.
Definition: qofid.cpp:267
The type used to store guids in C.
Definition: guid.h:75
QofCollection * qof_collection_new(QofIdType type)
create a new collection of entities of type
Definition: qofid.cpp:48