QOF  0.8.7
kvputil.c
1 /********************************************************************\
2  * kvp_util.c -- misc odd-job kvp utils *
3  * Copyright (C) 2001 Linas Vepstas <linas@linas.org> *
4  * Copyright (C) 2006 Neil Williams <linux@codehelp.co.uk> *
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 "config.h"
26 #include <glib.h>
27 #include <stdio.h>
28 #include "qof.h"
29 #include "kvputil-p.h"
30 
31 static KvpFrame *
32 qof_kvp_array_va (KvpFrame * kvp_root, const gchar *path,
33  QofTime *qt, const gchar *first_name, va_list ap)
34 {
35  KvpFrame *cwd;
36  const gchar *name;
37 
38  if (!kvp_root)
39  return NULL;
40  if (!first_name)
41  return NULL;
42 
43  /* Create subdirectory and put the actual data */
44  cwd = kvp_frame_new ();
45 
46  /* Record the time */
47  kvp_frame_set_time (cwd, "time", qt);
48 
49  /* Loop over the args */
50  name = first_name;
51  while (name)
52  {
53  const GUID *guid;
54  guid = va_arg (ap, const GUID *);
55 
56  kvp_frame_set_guid (cwd, name, guid);
57 
58  name = va_arg (ap, const char *);
59  }
60 
61  /* Attach cwd into the array */
62  kvp_frame_add_frame_nc (kvp_root, path, cwd);
63  return cwd;
64 }
65 
66 KvpFrame *
67 qof_kvp_bag_add (KvpFrame * pwd, const gchar *path,
68  QofTime *qt, const gchar *first_name, ...)
69 {
70  KvpFrame *cwd;
71  va_list ap;
72  va_start (ap, first_name);
73  cwd = qof_kvp_array_va (pwd, path, qt, first_name, ap);
74  va_end (ap);
75  return cwd;
76 }
77 
78 /* ================================================================ */
79 
80 #define MATCH_GUID(elt) { \
81  KvpFrame *fr = kvp_value_get_frame (elt); \
82  if (fr) { \
83  GUID *guid = kvp_frame_get_guid (fr, guid_name); \
84  if (guid && guid_equal (desired_guid, guid)) return fr; \
85  } \
86 }
87 
88 KvpFrame *
89 qof_kvp_bag_find_by_guid (KvpFrame * root, const gchar *path,
90  const gchar *guid_name, GUID * desired_guid)
91 {
92  KvpValue *arr;
93  KvpValueType valtype;
94  GList *node;
95 
96  arr = kvp_frame_get_value (root, path);
97  valtype = kvp_value_get_type (arr);
98  if (KVP_TYPE_FRAME == valtype)
99  {
100  MATCH_GUID (arr);
101  return NULL;
102  }
103 
104  /* Its got to be a single isolated frame, or a list of them. */
105  if (KVP_TYPE_GLIST != valtype)
106  return NULL;
107 
108  for (node = kvp_value_get_glist (arr); node; node = node->next)
109  {
110  KvpValue *va = node->data;
111  MATCH_GUID (va);
112  }
113  return NULL;
114 }
115 
116 /* ================================================================ */
117 
118 void
119 qof_kvp_bag_remove_frame (KvpFrame * root, const gchar *path, KvpFrame * fr)
120 {
121  KvpValue *arr;
122  KvpValueType valtype;
123  GList *node, *listhead;
124 
125  arr = kvp_frame_get_value (root, path);
126  valtype = kvp_value_get_type (arr);
127  if (KVP_TYPE_FRAME == valtype)
128  {
129  if (fr == kvp_value_get_frame (arr))
130  {
131  KvpValue *old_val =
132  kvp_frame_replace_value_nc (root, path, NULL);
133  kvp_value_replace_frame_nc (old_val, NULL);
134  kvp_value_delete (old_val);
135  }
136  return;
137  }
138 
139  /* Its got to be a single isolated frame, or a list of them. */
140  if (KVP_TYPE_GLIST != valtype)
141  return;
142 
143  listhead = kvp_value_get_glist (arr);
144  for (node = listhead; node; node = node->next)
145  {
146  KvpValue *va = node->data;
147  if (fr == kvp_value_get_frame (va))
148  {
149  listhead = g_list_remove_link (listhead, node);
150  g_list_free_1 (node);
151  kvp_value_replace_glist_nc (arr, listhead);
152  kvp_value_replace_frame_nc (va, NULL);
153  kvp_value_delete (va);
154  return;
155  }
156  }
157 }
158 
159 /* ================================================================ */
160 
161 static KvpFrame *
162 qof_kvp_bag_get_first (KvpFrame * root, const gchar *path)
163 {
164  KvpValue *arr, *va;
165  KvpValueType valtype;
166  GList *node;
167 
168  arr = kvp_frame_get_value (root, path);
169  valtype = kvp_value_get_type (arr);
170  if (KVP_TYPE_FRAME == valtype)
171  return kvp_value_get_frame (arr);
172 
173  /* Its gotta be a single isolated frame, or a list of them. */
174  if (KVP_TYPE_GLIST != valtype)
175  return NULL;
176 
177  node = kvp_value_get_glist (arr);
178  if (NULL == node)
179  return NULL;
180 
181  va = node->data;
182  return kvp_value_get_frame (va);
183 }
184 
185 void
186 qof_kvp_bag_merge (KvpFrame * kvp_into, const gchar *intopath,
187  KvpFrame * kvp_from, const gchar *frompath)
188 {
189  KvpFrame *fr;
190 
191  fr = qof_kvp_bag_get_first (kvp_from, frompath);
192  while (fr)
193  {
194  qof_kvp_bag_remove_frame (kvp_from, frompath, fr);
195  kvp_frame_add_frame_nc (kvp_into, intopath, fr);
196  fr = qof_kvp_bag_get_first (kvp_from, frompath);
197  }
198 }
199 
200 static void
201 kv_pair_helper (gpointer key, gpointer val, gpointer user_data)
202 {
203  GSList **result = (GSList **) user_data;
204  GHashTableKVPair *kvp = g_new0 (GHashTableKVPair, 1);
205 
206  kvp->key = key;
207  kvp->value = val;
208  *result = g_slist_prepend (*result, kvp);
209 }
210 
211 GSList *
212 g_hash_table_key_value_pairs (GHashTable * table)
213 {
214  GSList *result_list = NULL;
215  g_hash_table_foreach (table, kv_pair_helper, &result_list);
216  return result_list;
217 }
218 
219 void
220 g_hash_table_kv_pair_free_gfunc (gpointer data, gpointer user_data
221  __attribute__ ((unused)))
222 {
223  GHashTableKVPair *kvp = (GHashTableKVPair *) data;
224  g_free (kvp);
225 }
226 
229 {
230  if (0 == safe_strcmp (QOF_TYPE_INT64, type_string))
231  return KVP_TYPE_GINT64;
232  if (0 == safe_strcmp (QOF_TYPE_DOUBLE, type_string))
233  return KVP_TYPE_DOUBLE;
234  if (0 == safe_strcmp (QOF_TYPE_NUMERIC, type_string))
235  return KVP_TYPE_NUMERIC;
236  if (0 == safe_strcmp (QOF_TYPE_STRING, type_string))
237  return KVP_TYPE_STRING;
238  if (0 == safe_strcmp (QOF_TYPE_GUID, type_string))
239  return KVP_TYPE_GUID;
240  if (0 == safe_strcmp (QOF_TYPE_TIME, type_string))
241  return KVP_TYPE_TIME;
242  return 0;
243 }
244 
247 {
248  switch (n)
249  {
250  case KVP_TYPE_GINT64:
251  {
252  return QOF_TYPE_INT64;
253  break;
254  }
255  case KVP_TYPE_DOUBLE:
256  {
257  return QOF_TYPE_DOUBLE;
258  break;
259  }
260  case KVP_TYPE_NUMERIC:
261  {
262  return QOF_TYPE_NUMERIC;
263  break;
264  }
265  case KVP_TYPE_STRING:
266  {
267  return QOF_TYPE_STRING;
268  break;
269  }
270  case KVP_TYPE_GUID:
271  {
272  return QOF_TYPE_GUID;
273  break;
274  }
275  case KVP_TYPE_BOOLEAN :
276  {
277  return QOF_TYPE_BOOLEAN;
278  break;
279  }
280  case KVP_TYPE_TIME :
281  {
282  return QOF_TYPE_TIME;
283  break;
284  }
285  default:
286  {
287  return NULL;
288  }
289  }
290 }
291 
292 /*======================== END OF FILE =============================*/
Private KVP utilities for backends etc.
GList * kvp_value_replace_glist_nc(KvpValue *value, GList *newlist)
Definition: kvpframe.c:1578
void kvp_frame_set_guid(KvpFrame *frame, const gchar *path, const GUID *guid)
Store a copy of the GUID at the indicated path.
Definition: kvpframe.c:450
QofIdTypeConst kvp_value_type_to_qof_id(KvpValueType n)
Convert a KvpValueType to a QofIdType.
Definition: kvputil.c:246
KvpValueType
possible types in the union KvpValue
Definition: kvpframe.h:87
Unique identifier.
Definition: kvpframe.h:118
void kvp_frame_set_time(KvpFrame *frame, const gchar *path, QofTime *qt)
Store a copy of the QofTime at the indicated path.
Definition: kvpframe.c:407
void kvp_frame_add_frame_nc(KvpFrame *frame, const gchar *path, KvpFrame *fr)
Add the frame to the glist bag without copying.
Definition: kvpframe.c:669
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
void qof_kvp_bag_remove_frame(KvpFrame *root, const gchar *path, KvpFrame *fr)
Definition: kvputil.c:119
void qof_kvp_bag_merge(KvpFrame *kvp_into, const gchar *intopath, KvpFrame *kvp_from, const gchar *frompath)
Definition: kvputil.c:186
128bit denominator/numerator maths.
Definition: kvpframe.h:106
KvpValue * kvp_frame_replace_value_nc(KvpFrame *frame, const gchar *key_path, KvpValue *new_value)
Definition: kvpframe.c:513
struct _KvpValue KvpValue
Definition: kvpframe.h:78
KvpFrame * qof_kvp_bag_add(KvpFrame *pwd, const gchar *path, QofTime *qt, const gchar *first_name,...)
Definition: kvputil.c:67
KvpValueType qof_id_to_kvp_value_type(QofIdTypeConst type_string)
Convert a QofIdType to a KvpValueType.
Definition: kvputil.c:228
64bit integer
Definition: kvpframe.h:94
GSList * g_hash_table_key_value_pairs(GHashTable *table)
Definition: kvputil.c:212
GList * kvp_value_get_glist(const KvpValue *value)
Definition: kvpframe.c:1531
KvpFrame * kvp_value_replace_frame_nc(KvpValue *value, KvpFrame *newframe)
Definition: kvpframe.c:1561
Definition: guid.h:53
const gchar * QofIdTypeConst
Definition: qofid.h:83
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:112
Simple boolean type.
Definition: kvpframe.h:136
KvpFrame * qof_kvp_bag_find_by_guid(KvpFrame *root, const gchar *path, const gchar *guid_name, GUID *desired_guid)
Definition: kvputil.c:89
standard C string
Definition: kvpframe.h:112
KvpFrame * kvp_frame_new(void)
Definition: kvpframe.c:97
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:75
KvpFrame * kvp_value_get_frame(const KvpValue *value)
Definition: kvpframe.c:1546
standard C double type
Definition: kvpframe.h:100
void kvp_value_delete(KvpValue *value)
Definition: kvpframe.c:1358
64bit time/date handling.
Definition: kvpframe.h:124