|
GnuCash 2.4.99
|
00001 /********************************************************************\ 00002 * qofid.c -- QOF entity identifier implementation * 00003 * Copyright (C) 2000 Dave Peticolas <dave@krondo.com> * 00004 * Copyright (C) 2003 Linas Vepstas <linas@linas.org> * 00005 * * 00006 * This program is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU General Public License as * 00008 * published by the Free Software Foundation; either version 2 of * 00009 * the License, or (at your option) any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License* 00017 * along with this program; if not, contact: * 00018 * * 00019 * Free Software Foundation Voice: +1-617-542-5942 * 00020 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 00021 * Boston, MA 02110-1301, USA gnu@gnu.org * 00022 * * 00023 \********************************************************************/ 00024 00025 #include "config.h" 00026 00027 #include <string.h> 00028 #include <glib.h> 00029 00030 #include "qof.h" 00031 #include "qofid-p.h" 00032 00033 static QofLogModule log_module = QOF_MOD_ENGINE; 00034 static gboolean qof_alt_dirty_mode = FALSE; 00035 00036 struct QofCollection_s 00037 { 00038 QofIdType e_type; 00039 gboolean is_dirty; 00040 00041 GHashTable * hash_of_entities; 00042 gpointer data; /* place where object class can hang arbitrary data */ 00043 }; 00044 00045 /* =============================================================== */ 00046 00047 gboolean 00048 qof_get_alt_dirty_mode (void) 00049 { 00050 return qof_alt_dirty_mode; 00051 } 00052 00053 void 00054 qof_set_alt_dirty_mode (gboolean enabled) 00055 { 00056 qof_alt_dirty_mode = enabled; 00057 } 00058 00059 /* =============================================================== */ 00060 00061 QofCollection * 00062 qof_collection_new (QofIdType type) 00063 { 00064 QofCollection *col; 00065 col = g_new0(QofCollection, 1); 00066 col->e_type = CACHE_INSERT (type); 00067 col->hash_of_entities = guid_hash_table_new(); 00068 col->data = NULL; 00069 return col; 00070 } 00071 00072 void 00073 qof_collection_destroy (QofCollection *col) 00074 { 00075 CACHE_REMOVE (col->e_type); 00076 g_hash_table_destroy(col->hash_of_entities); 00077 col->e_type = NULL; 00078 col->hash_of_entities = NULL; 00079 col->data = NULL; 00080 g_free (col); 00081 } 00082 00083 /* =============================================================== */ 00084 /* getters */ 00085 00086 QofIdType 00087 qof_collection_get_type (const QofCollection *col) 00088 { 00089 return col->e_type; 00090 } 00091 00092 /* =============================================================== */ 00093 00094 void 00095 qof_collection_remove_entity (QofInstance *ent) 00096 { 00097 QofCollection *col; 00098 const GncGUID *guid; 00099 00100 if (!ent) return; 00101 col = qof_instance_get_collection(ent); 00102 if (!col) return; 00103 guid = qof_instance_get_guid(ent); 00104 g_hash_table_remove (col->hash_of_entities, guid); 00105 if (!qof_alt_dirty_mode) 00106 qof_collection_mark_dirty(col); 00107 qof_instance_set_collection(ent, NULL); 00108 } 00109 00110 void 00111 qof_collection_insert_entity (QofCollection *col, QofInstance *ent) 00112 { 00113 const GncGUID *guid; 00114 00115 if (!col || !ent) return; 00116 guid = qof_instance_get_guid(ent); 00117 if (guid_equal(guid, guid_null())) return; 00118 g_return_if_fail (col->e_type == ent->e_type); 00119 qof_collection_remove_entity (ent); 00120 g_hash_table_insert (col->hash_of_entities, (gpointer)guid, ent); 00121 if (!qof_alt_dirty_mode) 00122 qof_collection_mark_dirty(col); 00123 qof_instance_set_collection(ent, col); 00124 } 00125 00126 gboolean 00127 qof_collection_add_entity (QofCollection *coll, QofInstance *ent) 00128 { 00129 QofInstance *e; 00130 const GncGUID *guid; 00131 00132 e = NULL; 00133 if (!coll || !ent) 00134 { 00135 return FALSE; 00136 } 00137 guid = qof_instance_get_guid(ent); 00138 if (guid_equal(guid, guid_null())) 00139 { 00140 return FALSE; 00141 } 00142 g_return_val_if_fail (coll->e_type == ent->e_type, FALSE); 00143 e = qof_collection_lookup_entity(coll, guid); 00144 if ( e != NULL ) 00145 { 00146 return FALSE; 00147 } 00148 g_hash_table_insert (coll->hash_of_entities, (gpointer)guid, ent); 00149 if (!qof_alt_dirty_mode) 00150 qof_collection_mark_dirty(coll); 00151 return TRUE; 00152 } 00153 00154 00155 static void 00156 collection_compare_cb (QofInstance *ent, gpointer user_data) 00157 { 00158 QofCollection *target; 00159 QofInstance *e; 00160 const GncGUID *guid; 00161 gint value; 00162 00163 e = NULL; 00164 target = (QofCollection*)user_data; 00165 if (!target || !ent) 00166 { 00167 return; 00168 } 00169 value = *(gint*)qof_collection_get_data(target); 00170 if (value != 0) 00171 { 00172 return; 00173 } 00174 guid = qof_instance_get_guid(ent); 00175 if (guid_equal(guid, guid_null())) 00176 { 00177 value = -1; 00178 qof_collection_set_data(target, &value); 00179 return; 00180 } 00181 g_return_if_fail (target->e_type == ent->e_type); 00182 e = qof_collection_lookup_entity(target, guid); 00183 if ( e == NULL ) 00184 { 00185 value = 1; 00186 qof_collection_set_data(target, &value); 00187 return; 00188 } 00189 value = 0; 00190 qof_collection_set_data(target, &value); 00191 } 00192 00193 gint 00194 qof_collection_compare (QofCollection *target, QofCollection *merge) 00195 { 00196 gint value; 00197 00198 value = 0; 00199 if (!target && !merge) 00200 { 00201 return 0; 00202 } 00203 if (target == merge) 00204 { 00205 return 0; 00206 } 00207 if (!target && merge) 00208 { 00209 return -1; 00210 } 00211 if (target && !merge) 00212 { 00213 return 1; 00214 } 00215 if (target->e_type != merge->e_type) 00216 { 00217 return -1; 00218 } 00219 qof_collection_set_data(target, &value); 00220 qof_collection_foreach(merge, collection_compare_cb, target); 00221 value = *(gint*)qof_collection_get_data(target); 00222 if (value == 0) 00223 { 00224 qof_collection_set_data(merge, &value); 00225 qof_collection_foreach(target, collection_compare_cb, merge); 00226 value = *(gint*)qof_collection_get_data(merge); 00227 } 00228 return value; 00229 } 00230 00231 QofInstance * 00232 qof_collection_lookup_entity (const QofCollection *col, const GncGUID * guid) 00233 { 00234 QofInstance *ent; 00235 g_return_val_if_fail (col, NULL); 00236 if (guid == NULL) return NULL; 00237 ent = g_hash_table_lookup (col->hash_of_entities, guid); 00238 return ent; 00239 } 00240 00241 QofCollection * 00242 qof_collection_from_glist (QofIdType type, const GList *glist) 00243 { 00244 QofCollection *coll; 00245 QofInstance *ent; 00246 const GList *list; 00247 00248 coll = qof_collection_new(type); 00249 for (list = glist; list != NULL; list = list->next) 00250 { 00251 ent = QOF_INSTANCE(list->data); 00252 if (FALSE == qof_collection_add_entity(coll, ent)) 00253 { 00254 return NULL; 00255 } 00256 } 00257 return coll; 00258 } 00259 00260 guint 00261 qof_collection_count (const QofCollection *col) 00262 { 00263 guint c; 00264 00265 c = g_hash_table_size(col->hash_of_entities); 00266 return c; 00267 } 00268 00269 /* =============================================================== */ 00270 00271 gboolean 00272 qof_collection_is_dirty (const QofCollection *col) 00273 { 00274 return col ? col->is_dirty : FALSE; 00275 } 00276 00277 void 00278 qof_collection_mark_clean (QofCollection *col) 00279 { 00280 if (col) 00281 { 00282 col->is_dirty = FALSE; 00283 } 00284 } 00285 00286 void 00287 qof_collection_mark_dirty (QofCollection *col) 00288 { 00289 if (col) 00290 { 00291 col->is_dirty = TRUE; 00292 } 00293 } 00294 00295 void 00296 qof_collection_print_dirty (const QofCollection *col, gpointer dummy) 00297 { 00298 if (col->is_dirty) 00299 printf("%s collection is dirty.\n", col->e_type); 00300 qof_collection_foreach(col, (QofInstanceForeachCB)qof_instance_print_dirty, NULL); 00301 } 00302 00303 /* =============================================================== */ 00304 00305 gpointer 00306 qof_collection_get_data (const QofCollection *col) 00307 { 00308 return col ? col->data : NULL; 00309 } 00310 00311 void 00312 qof_collection_set_data (QofCollection *col, gpointer user_data) 00313 { 00314 if (col) 00315 { 00316 col->data = user_data; 00317 } 00318 } 00319 00320 /* =============================================================== */ 00321 00322 struct _iterate 00323 { 00324 QofInstanceForeachCB fcn; 00325 gpointer data; 00326 }; 00327 00328 static void 00329 foreach_cb (gpointer item, gpointer arg) 00330 { 00331 struct _iterate *iter = arg; 00332 QofInstance *ent = item; 00333 00334 iter->fcn (ent, iter->data); 00335 } 00336 00337 void 00338 qof_collection_foreach (const QofCollection *col, QofInstanceForeachCB cb_func, 00339 gpointer user_data) 00340 { 00341 struct _iterate iter; 00342 GList *entries; 00343 00344 g_return_if_fail (col); 00345 g_return_if_fail (cb_func); 00346 00347 iter.fcn = cb_func; 00348 iter.data = user_data; 00349 00350 PINFO("Hash Table size of %s before is %d", col->e_type, g_hash_table_size(col->hash_of_entities)); 00351 00352 entries = g_hash_table_get_values (col->hash_of_entities); 00353 g_list_foreach (entries, foreach_cb, &iter); 00354 g_list_free (entries); 00355 00356 PINFO("Hash Table size of %s after is %d", col->e_type, g_hash_table_size(col->hash_of_entities)); 00357 } 00358 /* =============================================================== */
1.7.4