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  QofCollection_s (QofIdType type) : e_type{static_cast<QofIdType>(CACHE_INSERT(type))}
45  , is_dirty{FALSE}
46  , hash_of_entities{guid_hash_table_new()}
47  , data{NULL} {}
48  ~QofCollection_s ()
49  {
50  CACHE_REMOVE (e_type);
51  g_hash_table_destroy (hash_of_entities);
52  }
53 };
54 
55 /* =============================================================== */
56 
57 QofCollection *
59 {
60  return new QofCollection (type);
61 }
62 
63 void
64 qof_collection_destroy (QofCollection *col)
65 {
66  delete col;
67 }
68 
69 /* =============================================================== */
70 /* getters */
71 
73 qof_collection_get_type (const QofCollection *col)
74 {
75  return col->e_type;
76 }
77 
78 /* =============================================================== */
79 
80 void
81 qof_collection_remove_entity (QofInstance *ent)
82 {
83  QofCollection *col;
84  const GncGUID *guid;
85 
86  if (!ent) return;
87  col = qof_instance_get_collection(ent);
88  if (!col) return;
89  guid = qof_instance_get_guid(ent);
90  g_hash_table_remove (col->hash_of_entities, guid);
91  qof_instance_set_collection(ent, NULL);
92 }
93 
94 void
95 qof_collection_insert_entity (QofCollection *col, QofInstance *ent)
96 {
97  const GncGUID *guid;
98 
99  if (!col || !ent) return;
100  guid = qof_instance_get_guid(ent);
101  if (guid_equal(guid, guid_null())) return;
102  g_return_if_fail (col->e_type == ent->e_type);
103  qof_collection_remove_entity (ent);
104  g_hash_table_insert (col->hash_of_entities, (gpointer)guid, ent);
105  qof_instance_set_collection(ent, col);
106 }
107 
108 gboolean
109 qof_collection_add_entity (QofCollection *coll, QofInstance *ent)
110 {
111  QofInstance *e;
112  const GncGUID *guid;
113 
114  e = NULL;
115  if (!coll || !ent)
116  {
117  return FALSE;
118  }
119  guid = qof_instance_get_guid(ent);
120  if (guid_equal(guid, guid_null()))
121  {
122  return FALSE;
123  }
124  g_return_val_if_fail (coll->e_type == ent->e_type, FALSE);
125  e = qof_collection_lookup_entity(coll, guid);
126  if ( e != NULL )
127  {
128  return FALSE;
129  }
130  g_hash_table_insert (coll->hash_of_entities, (gpointer)guid, ent);
131  return TRUE;
132 }
133 
134 
135 static void
136 collection_compare_cb (QofInstance *ent, gpointer user_data)
137 {
138  QofCollection *target;
139  QofInstance *e;
140  const GncGUID *guid;
141  gint* value;
142 
143  e = NULL;
144  target = (QofCollection*)user_data;
145  if (!target || !ent)
146  {
147  return;
148  }
149  value = (gint*)qof_collection_get_data(target);
150  if (*value != 0)
151  {
152  return;
153  }
154  guid = qof_instance_get_guid(ent);
155  if (guid_equal(guid, guid_null()))
156  {
157  *value = -1;
158  return;
159  }
160  g_return_if_fail (target->e_type == ent->e_type);
161  e = qof_collection_lookup_entity(target, guid);
162  if ( e == NULL )
163  {
164  *value = 1;
165  return;
166  }
167  *value = 0;
168 }
169 
170 gint
171 qof_collection_compare (QofCollection *target, QofCollection *merge)
172 {
173  gint value;
174 
175  value = 0;
176  if (!target && !merge)
177  {
178  return 0;
179  }
180  if (target == merge)
181  {
182  return 0;
183  }
184  if (!target && merge)
185  {
186  return -1;
187  }
188  if (target && !merge)
189  {
190  return 1;
191  }
192  if (target->e_type != merge->e_type)
193  {
194  return -1;
195  }
196  qof_collection_set_data(target, &value);
197  qof_collection_foreach(merge, collection_compare_cb, target);
198  value = *(gint*)qof_collection_get_data(target);
199  if (value == 0)
200  {
201  qof_collection_set_data(merge, &value);
202  qof_collection_foreach(target, collection_compare_cb, merge);
203  value = *(gint*)qof_collection_get_data(merge);
204  }
205  return value;
206 }
207 
208 QofInstance *
209 qof_collection_lookup_entity (const QofCollection *col, const GncGUID * guid)
210 {
211  QofInstance *ent;
212  g_return_val_if_fail (col, NULL);
213  if (guid == NULL) return NULL;
214  ent = static_cast<QofInstance*>(g_hash_table_lookup (col->hash_of_entities,
215  guid));
216  if (ent != NULL && qof_instance_get_destroying(ent)) return NULL;
217  return ent;
218 }
219 
220 guint
221 qof_collection_count (const QofCollection *col)
222 {
223  guint c;
224 
225  c = g_hash_table_size(col->hash_of_entities);
226  return c;
227 }
228 
229 /* =============================================================== */
230 
231 gboolean
232 qof_collection_is_dirty (const QofCollection *col)
233 {
234  return col ? col->is_dirty : FALSE;
235 }
236 
237 void
238 qof_collection_mark_clean (QofCollection *col)
239 {
240  if (col)
241  {
242  col->is_dirty = FALSE;
243  }
244 }
245 
246 void
247 qof_collection_mark_dirty (QofCollection *col)
248 {
249  if (col)
250  {
251  col->is_dirty = TRUE;
252  }
253 }
254 
255 void
256 qof_collection_print_dirty (const QofCollection *col, gpointer dummy)
257 {
258  if (col->is_dirty)
259  printf("%s collection is dirty.\n", col->e_type);
260  qof_collection_foreach(col, (QofInstanceForeachCB)qof_instance_print_dirty, NULL);
261 }
262 
263 /* =============================================================== */
264 
265 gpointer
266 qof_collection_get_data (const QofCollection *col)
267 {
268  return col ? col->data : NULL;
269 }
270 
271 void
272 qof_collection_set_data (QofCollection *col, gpointer user_data)
273 {
274  if (col)
275  {
276  col->data = user_data;
277  }
278 }
279 
280 /* =============================================================== */
281 
282 void
283 qof_collection_foreach_sorted (const QofCollection *col, QofInstanceForeachCB cb_func,
284  gpointer user_data, GCompareFunc sort_fn)
285 {
286  GList *entries;
287 
288  g_return_if_fail (col);
289  g_return_if_fail (cb_func);
290 
291  PINFO("Hash Table size of %s before is %d", col->e_type, g_hash_table_size(col->hash_of_entities));
292 
293  entries = g_hash_table_get_values (col->hash_of_entities);
294  if (sort_fn)
295  entries = g_list_sort (entries, sort_fn);
296  g_list_foreach (entries, (GFunc)cb_func, user_data);
297  g_list_free (entries);
298 
299  PINFO("Hash Table size of %s after is %d", col->e_type, g_hash_table_size(col->hash_of_entities));
300 }
301 
302 void
303 qof_collection_foreach (const QofCollection *col, QofInstanceForeachCB cb_func,
304  gpointer user_data)
305 {
306  qof_collection_foreach_sorted (col, cb_func, user_data, nullptr);
307 }
308 /* =============================================================== */
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:232
QofInstance * qof_collection_lookup_entity(const QofCollection *col, const GncGUID *guid)
Find the entity going only from its guid.
Definition: qofid.cpp:209
#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:283
gint qof_collection_compare(QofCollection *target, QofCollection *merge)
Compare two secondary collections.
Definition: qofid.cpp:171
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:95
void qof_collection_mark_clean(QofCollection *col)
reset value of dirty flag
Definition: qofid.cpp:238
void qof_collection_destroy(QofCollection *col)
destroy the collection
Definition: qofid.cpp:64
QofIdType qof_collection_get_type(const QofCollection *col)
return the type that the collection stores
Definition: qofid.cpp:73
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:109
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:221
gpointer qof_collection_get_data(const QofCollection *col)
Store and retrieve arbitrary object-defined data.
Definition: qofid.cpp:266
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:58