QOF: qofquerycore.c Source File

QOF 0.7.5

qofquerycore.c
1 /********************************************************************\
2 * QueryCore.c -- API for providing core Query data types *
3 * Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
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
27 #include <glib.h>
28
29 #include "qof.h"
30 #include "qofquerycore-p.h"
31
32 static QofLogModule log_module = QOF_MOD_QUERY;
33
34 /* A function to destroy a query predicate's pdata */
35 typedef void (*QueryPredDataFree) (QofQueryPredData * pdata);
36
37 /* A function to copy a query's predicate data */
38 typedef QofQueryPredData *(*QueryPredicateCopyFunc) (QofQueryPredData *
39 pdata);
40
41 /* A function to take the object, apply the getter->param_getfcn,
42 * and return a printable string. Note that this QofParam->getfnc
43 * function should be returning a type equal to this core object type.
44 *
45 * Note that this string MUST be freed by the caller.
46 */
47 typedef gchar *(*QueryToString) (gpointer object, QofParam * getter);
48
49 /* A function to test for equality of predicate data */
50 typedef gboolean (*QueryPredicateEqual) (QofQueryPredData * p1,
51 QofQueryPredData * p2);
52
53 static QueryPredicateCopyFunc qof_query_copy_predicate (QofType type);
54 static QueryPredDataFree qof_query_predicate_free (QofType type);
55
56 /* Core Type Predicate helpers */
57 typedef const gchar *(*query_string_getter) (gpointer, QofParam *);
58 static const gchar *query_string_type = QOF_TYPE_STRING;
59
60 typedef QofTime *(*query_time_getter) (gpointer, QofParam *);
61 static const gchar *query_time_type = QOF_TYPE_TIME;
62
63 typedef QofNumeric (*query_numeric_getter) (gpointer, QofParam *);
64 static const gchar *query_numeric_type = QOF_TYPE_NUMERIC;
65
66 typedef GList *(*query_glist_getter) (gpointer, QofParam *);
67 typedef const GUID *(*query_guid_getter) (gpointer, QofParam *);
68 static const gchar *query_guid_type = QOF_TYPE_GUID;
69
70 typedef gint32 (*query_int32_getter) (gpointer, QofParam *);
71 static const gchar *query_int32_type = QOF_TYPE_INT32;
72
73 typedef gint64 (*query_int64_getter) (gpointer, QofParam *);
74 static const char *query_int64_type = QOF_TYPE_INT64;
75
76 typedef double (*query_double_getter) (gpointer, QofParam *);
77 static const gchar *query_double_type = QOF_TYPE_DOUBLE;
78
79 typedef gboolean (*query_boolean_getter) (gpointer, QofParam *);
80 static const gchar *query_boolean_type = QOF_TYPE_BOOLEAN;
81
82 typedef char (*query_char_getter) (gpointer, QofParam *);
83 static const char *query_char_type = QOF_TYPE_CHAR;
84
85 typedef KvpFrame *(*query_kvp_getter) (gpointer, QofParam *);
86 static const gchar *query_kvp_type = QOF_TYPE_KVP;
87
88 typedef QofCollection *(*query_collect_getter) (gpointer, QofParam *);
89 static const gchar *query_collect_type = QOF_TYPE_COLLECT;
90
91 typedef const GUID *(*query_choice_getter) (gpointer, QofParam *);
92 static const gchar *query_choice_type = QOF_TYPE_CHOICE;
93
94 /* Tables for predicate storage and lookup */
95 static gboolean initialized = FALSE;
96 static GHashTable *predTable = NULL;
97 static GHashTable *cmpTable = NULL;
98 static GHashTable *copyTable = NULL;
99 static GHashTable *freeTable = NULL;
100 static GHashTable *toStringTable = NULL;
101 static GHashTable *predEqualTable = NULL;
102
103 #define COMPARE_ERROR -3
104 #define PREDICATE_ERROR -2
105
106 #define VERIFY_PDATA(str) { \
107 g_return_if_fail (pd != NULL); \
108 g_return_if_fail (pd->type_name == str || \
109 !safe_strcmp (str, pd->type_name)); \
110 }
111 #define VERIFY_PDATA_R(str) { \
112 g_return_val_if_fail (pd != NULL, NULL); \
113 g_return_val_if_fail (pd->type_name == str || \
114 !safe_strcmp (str, pd->type_name), \
115 NULL); \
116 }
117 #define VERIFY_PREDICATE(str) { \
118 g_return_val_if_fail (getter != NULL, PREDICATE_ERROR); \
119 g_return_val_if_fail (getter->param_getfcn != NULL, PREDICATE_ERROR); \
120 g_return_val_if_fail (pd != NULL, PREDICATE_ERROR); \
121 g_return_val_if_fail (pd->type_name == str || \
122 !safe_strcmp (str, pd->type_name), \
123 PREDICATE_ERROR); \
124 }
125
126 /* *******************************************************************/
127 /* TYPE-HANDLING FUNCTIONS */
128
129 /* QOF_TYPE_STRING */
130
131 static gint
132 string_match_predicate (gpointer object,
133 QofParam * getter, QofQueryPredData * pd)
134 {
135 query_string_t pdata = (query_string_t) pd;
136 const gchar *s;
137 gint ret = 0;
138
139 VERIFY_PREDICATE (query_string_type);
140
141 s = ((query_string_getter) getter->param_getfcn) (object, getter);
142
143 if (!s)
144 s = "";
145
146 if (pdata->is_regex)
147 {
148 regmatch_t match;
149 if (!regexec (&pdata->compiled, s, 1, &match, 0))
150 ret = 1;
151
152 }
153 else if (pdata->options == QOF_STRING_MATCH_CASEINSENSITIVE)
154 {
155 if (strcasestr (s, pdata->matchstring))
156 ret = 1;
157
158 }
159 else
160 {
161 if (strstr (s, pdata->matchstring))
162 ret = 1;
163 }
164
165 switch (pd->how)
166 {
167 case QOF_COMPARE_EQUAL:
168 return ret;
169 case QOF_COMPARE_NEQ:
170 return !ret;
171 default:
172 PWARN ("bad match type: %d", pd->how);
173 return 0;
174 }
175 }
176
177 static gint
178 string_compare_func (gpointer a, gpointer b, gint options,
179 QofParam * getter)
180 {
181 const gchar *s1, *s2;
182 g_return_val_if_fail (a && b && getter
183 && getter->param_getfcn, COMPARE_ERROR);
184
185 s1 = ((query_string_getter) getter->param_getfcn) (a, getter);
186 s2 = ((query_string_getter) getter->param_getfcn) (b, getter);
187
188 if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
189 return safe_strcasecmp (s1, s2);
190
191 return safe_strcmp (s1, s2);
192 }
193
194 static void
195 string_free_pdata (QofQueryPredData * pd)
196 {
197 query_string_t pdata = (query_string_t) pd;
198
199 VERIFY_PDATA (query_string_type);
200
201 if (pdata->is_regex)
202 regfree (&pdata->compiled);
203 else
204 g_free (pdata->matchstring);
205
206 g_free (pdata);
207 }
208
209 static QofQueryPredData *
210 string_copy_predicate (QofQueryPredData * pd)
211 {
212 query_string_t pdata = (query_string_t) pd;
213
214 VERIFY_PDATA_R (query_string_type);
215
216 return qof_query_string_predicate (pd->how, pdata->matchstring,
217 pdata->options, pdata->is_regex);
218 }
219
220 static gboolean
221 string_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
222 {
223 query_string_t pd1 = (query_string_t) p1;
224 query_string_t pd2 = (query_string_t) p2;
225
226 if (pd1->options != pd2->options)
227 return FALSE;
228 if (pd1->is_regex != pd2->is_regex)
229 return FALSE;
230 return (safe_strcmp (pd1->matchstring, pd2->matchstring) == 0);
231 }
232
233 QofQueryPredData *
234 qof_query_string_predicate (QofQueryCompare how,
235 const gchar *str, QofStringMatch options, gboolean is_regex)
236 {
237 query_string_t pdata;
238
239 g_return_val_if_fail (str, NULL);
240 g_return_val_if_fail (*str != '\0', NULL);
241 g_return_val_if_fail (how == QOF_COMPARE_EQUAL
242 || how == QOF_COMPARE_NEQ, NULL);
243
244 pdata = g_new0 (query_string_def, 1);
245 pdata->pd.type_name = query_string_type;
246 pdata->pd.how = how;
247 pdata->options = options;
248 pdata->matchstring = g_strdup (str);
249
250 if (is_regex)
251 {
252 int flags = REG_EXTENDED;
253 if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
254 flags |= REG_ICASE;
255
256 regcomp (&pdata->compiled, str, flags);
257 pdata->is_regex = TRUE;
258 }
259
260 return ((QofQueryPredData *) pdata);
261 }
262
263 static gchar *
264 string_to_string (gpointer object, QofParam * getter)
265 {
266 const char *res;
267 res = ((query_string_getter) getter->param_getfcn) (object, getter);
268 if (res)
269 return g_strdup (res);
270 return NULL;
271 }
272
273 /* QOF_TYPE_TIME */
274
275 static gint
276 time_compare (QofTime *ta, QofTime *tb, QofDateMatch options)
277 {
278 if (options == QOF_DATE_MATCH_DAY)
279 {
280 qof_time_set_day_start (ta);
281 qof_time_set_day_start (tb);
282 }
283 return qof_time_cmp (ta, tb);
284 }
285
286 static int
287 time_match_predicate (gpointer object, QofParam * getter,
288 QofQueryPredData * pd)
289 {
290 query_time_t pdata = (query_time_t) pd;
291 QofTime *objtime;
292 gint compare;
293
294 VERIFY_PREDICATE (query_time_type);
295
296 objtime = ((query_time_getter) getter->param_getfcn) (object, getter);
297 compare = time_compare (objtime, pdata->qt, pdata->options);
298
299 switch (pd->how)
300 {
301 case QOF_COMPARE_LT:
302 return (compare < 0);
303 case QOF_COMPARE_LTE:
304 return (compare <= 0);
305 case QOF_COMPARE_EQUAL:
306 return (compare == 0);
307 case QOF_COMPARE_GT:
308 return (compare > 0);
309 case QOF_COMPARE_GTE:
310 return (compare >= 0);
311 case QOF_COMPARE_NEQ:
312 return (compare != 0);
313 default:
314 PWARN ("bad match type: %d", pd->how);
315 return 0;
316 }
317 }
318
319 static gint
320 time_compare_func (gpointer a, gpointer b, gint options,
321 QofParam * getter)
322 {
323 QofTime *ta, *tb;
324
325 g_return_val_if_fail (a && b && getter
326 && getter->param_getfcn, COMPARE_ERROR);
327
328 ta = ((query_time_getter) getter->param_getfcn) (a, getter);
329 tb = ((query_time_getter) getter->param_getfcn) (b, getter);
330
331 return time_compare (ta, tb, options);
332 }
333
334 static void
335 time_free_pdata (QofQueryPredData * pd)
336 {
337 query_time_t pdata = (query_time_t) pd;
338
339 VERIFY_PDATA (query_time_type);
340
341 g_free (pdata);
342 }
343
344 static QofQueryPredData *
345 time_copy_predicate (QofQueryPredData * pd)
346 {
347 query_time_t pdata = (query_time_t) pd;
348
349 VERIFY_PDATA_R (query_time_type);
350
351 return qof_query_time_predicate (pd->how, pdata->options,
352 pdata->qt);
353 }
354
355 static gboolean
356 time_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
357 {
358 query_time_t pd1 = (query_time_t) p1;
359 query_time_t pd2 = (query_time_t) p2;
360
361 if (pd1->options != pd2->options)
362 return FALSE;
363 return qof_time_equal (pd1->qt, pd2->qt);
364 }
365
366 QofQueryPredData *
367 qof_query_time_predicate (QofQueryCompare how,
368 QofDateMatch options, QofTime *qt)
369 {
370 query_time_t pdata;
371
372 pdata = g_new0 (query_time_def, 1);
373 pdata->pd.type_name = query_time_type;
374 pdata->pd.how = how;
375 pdata->options = options;
376 pdata->qt = qt;
377 return ((QofQueryPredData *) pdata);
378 }
379
380 gboolean
381 qof_query_time_predicate_get_time (QofQueryPredData * pd,
382 QofTime *qt)
383 {
384 query_time_t pdata = (query_time_t) pd;
385
386 if (pdata->pd.type_name != query_time_type)
387 return FALSE;
388 qt = pdata->qt;
389 return TRUE;
390 }
391
392 static gchar *
393 time_to_string (gpointer object, QofParam * getter)
394 {
395 QofDate *qd;
396 QofTime *qt =
397 ((query_time_getter) getter->param_getfcn) (object, getter);
398
399 qd = qof_date_from_qtime (qt);
400 return qof_date_print (qd, QOF_DATE_FORMAT_UTC);
401 }
402
403 /* QOF_TYPE_NUMERIC ================================================= */
404
405 static int
406 numeric_match_predicate (gpointer object, QofParam * getter,
407 QofQueryPredData * pd)
408 {
409 query_numeric_t pdata = (query_numeric_t) pd;
410 QofNumeric obj_val;
411 gint compare;
412
413 VERIFY_PREDICATE (query_numeric_type);
414
415 obj_val =
416 ((query_numeric_getter) getter->param_getfcn) (object, getter);
417
418 switch (pdata->options)
419 {
420 case QOF_NUMERIC_MATCH_CREDIT:
421 if (qof_numeric_positive_p (obj_val))
422 return 0;
423 break;
424 case QOF_NUMERIC_MATCH_DEBIT:
425 if (qof_numeric_negative_p (obj_val))
426 return 0;
427 break;
428 default:
429 break;
430 }
431
432 /* Amounts are considered to be 'equal' if they match to
433 * four decimal places. (epsilon=1/10000) */
434 if (pd->how == QOF_COMPARE_EQUAL || pd->how == QOF_COMPARE_NEQ)
435 {
436 QofNumeric cmp_val = qof_numeric_create (1, 10000);
437 compare =
438 (qof_numeric_compare (qof_numeric_abs
439 (qof_numeric_sub (qof_numeric_abs (obj_val),
440 qof_numeric_abs (pdata->
441 amount),
442 100000, QOF_HOW_RND_ROUND)), cmp_val) < 0);
443 }
444 else
445 compare =
446 qof_numeric_compare (qof_numeric_abs (obj_val), pdata->amount);
447
448 switch (pd->how)
449 {
450 case QOF_COMPARE_LT:
451 return (compare < 0);
452 case QOF_COMPARE_LTE:
453 return (compare <= 0);
454 case QOF_COMPARE_EQUAL:
455 return compare;
456 case QOF_COMPARE_GT:
457 return (compare > 0);
458 case QOF_COMPARE_GTE:
459 return (compare >= 0);
460 case QOF_COMPARE_NEQ:
461 return !compare;
462 default:
463 PWARN ("bad match type: %d", pd->how);
464 return 0;
465 }
466 }
467
468 static int
469 numeric_compare_func (gpointer a, gpointer b,
470 gint options __attribute__ ((unused)), QofParam * getter)
471 {
472 QofNumeric va, vb;
473
474 g_return_val_if_fail (a && b && getter
475 && getter->param_getfcn, COMPARE_ERROR);
476
477 va = ((query_numeric_getter) getter->param_getfcn) (a, getter);
478 vb = ((query_numeric_getter) getter->param_getfcn) (b, getter);
479
480 return qof_numeric_compare (va, vb);
481 }
482
483 static void
484 numeric_free_pdata (QofQueryPredData * pd)
485 {
486 query_numeric_t pdata = (query_numeric_t) pd;
487 VERIFY_PDATA (query_numeric_type);
488 g_free (pdata);
489 }
490
491 static QofQueryPredData *
492 numeric_copy_predicate (QofQueryPredData * pd)
493 {
494 query_numeric_t pdata = (query_numeric_t) pd;
495 VERIFY_PDATA_R (query_numeric_type);
496 return qof_query_numeric_predicate (pd->how, pdata->options,
497 pdata->amount);
498 }
499
500 static gboolean
501 numeric_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
502 {
503 query_numeric_t pd1 = (query_numeric_t) p1;
504 query_numeric_t pd2 = (query_numeric_t) p2;
505
506 if (pd1->options != pd2->options)
507 return FALSE;
508 return qof_numeric_equal (pd1->amount, pd2->amount);
509 }
510
511 QofQueryPredData *
512 qof_query_numeric_predicate (QofQueryCompare how,
513 QofNumericMatch options, QofNumeric value)
514 {
515 query_numeric_t pdata;
516 pdata = g_new0 (query_numeric_def, 1);
517 pdata->pd.type_name = query_numeric_type;
518 pdata->pd.how = how;
519 pdata->options = options;
520 pdata->amount = value;
521 return ((QofQueryPredData *) pdata);
522 }
523
524 static char *
525 numeric_to_string (gpointer object, QofParam * getter)
526 {
527 QofNumeric num;
528 num = ((query_numeric_getter) getter->param_getfcn) (object, getter);
529
530 return qof_numeric_to_string (num);
531 }
532
533 static char *
534 debcred_to_string (gpointer object, QofParam * getter)
535 {
536 QofNumeric num;
537 num = ((query_numeric_getter) getter->param_getfcn) (object, getter);
538
539 return qof_numeric_to_string (num);
540 }
541
542 /* QOF_TYPE_GUID =================================================== */
543
544 static int
545 guid_match_predicate (gpointer object, QofParam * getter,
546 QofQueryPredData * pd)
547 {
548 query_guid_t pdata = (query_guid_t) pd;
549 GList *node, *o_list;
550 const GUID *guid = NULL;
551
552 VERIFY_PREDICATE (query_guid_type);
553
554 switch (pdata->options)
555 {
556
557 case QOF_GUID_MATCH_ALL:
558 /* object is a GList of objects; param_getfcn must be called on each one.
559 * See if every guid in the predicate is accounted-for in the
560 * object list
561 */
562
563 for (node = pdata->guids; node; node = node->next)
564 {
565 /* See if this GUID matches the object's guid */
566 for (o_list = object; o_list; o_list = o_list->next)
567 {
568 guid =
569 ((query_guid_getter) getter->param_getfcn) (o_list->
570 data, getter);
571 if (guid_equal (node->data, guid))
572 break;
573 }
574
575 /*
576 * If o_list is NULL, we've walked the whole list without finding
577 * a match. Therefore break out now, the match has failed.
578 */
579 if (o_list == NULL)
580 break;
581 }
582
583 /*
584 * The match is complete. If node == NULL then we've succesfully
585 * found a match for all the guids in the predicate. Return
586 * appropriately below.
587 */
588
589 break;
590
591 case QOF_GUID_MATCH_LIST_ANY:
592 /* object is a single object, getter returns a GList* of GUID*
593 *
594 * See if any GUID* in the returned list matches any guid in the
595 * predicate match list.
596 */
597
598 o_list =
599 ((query_glist_getter) getter->param_getfcn) (object, getter);
600
601 for (node = o_list; node; node = node->next)
602 {
603 GList *node2;
604
605 /* Search the predicate data for a match */
606 for (node2 = pdata->guids; node2; node2 = node2->next)
607 {
608 if (guid_equal (node->data, node2->data))
609 break;
610 }
611
612 /* Check to see if we found a match. If so, break now */
613 if (node2 != NULL)
614 break;
615 }
616
617 g_list_free (o_list);
618
619 /* yea, node may point to an invalid location, but that's ok.
620 * we're not _USING_ the value, just checking that it's non-NULL
621 */
622
623 break;
624
625 default:
626 /* object is a single object, getter returns a GUID*
627 *
628 * See if the guid is in the list
629 */
630
631 guid = ((query_guid_getter) getter->param_getfcn) (object, getter);
632 for (node = pdata->guids; node; node = node->next)
633 {
634 if (guid_equal (node->data, guid))
635 break;
636 }
637 }
638
639 switch (pdata->options)
640 {
641 case QOF_GUID_MATCH_ANY:
642 case QOF_GUID_MATCH_LIST_ANY:
643 return (node != NULL);
644 break;
645 case QOF_GUID_MATCH_NONE:
646 case QOF_GUID_MATCH_ALL:
647 return (node == NULL);
648 break;
649 case QOF_GUID_MATCH_NULL:
650 return (guid == NULL);
651 break;
652 default:
653 PWARN ("bad match type");
654 return 0;
655 }
656 }
657
658 static void
659 guid_free_pdata (QofQueryPredData * pd)
660 {
661 query_guid_t pdata = (query_guid_t) pd;
662 GList *node;
663 VERIFY_PDATA (query_guid_type);
664 for (node = pdata->guids; node; node = node->next)
665 {
666 guid_free (node->data);
667 }
668 g_list_free (pdata->guids);
669 g_free (pdata);
670 }
671
672 static QofQueryPredData *
673 guid_copy_predicate (QofQueryPredData * pd)
674 {
675 query_guid_t pdata = (query_guid_t) pd;
676 VERIFY_PDATA_R (query_guid_type);
677 return qof_query_guid_predicate (pdata->options, pdata->guids);
678 }
679
680 static gboolean
681 guid_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
682 {
683 query_guid_t pd1 = (query_guid_t) p1;
684 query_guid_t pd2 = (query_guid_t) p2;
685 GList *l1 = pd1->guids, *l2 = pd2->guids;
686
687 if (pd1->options != pd2->options)
688 return FALSE;
689 if (g_list_length (l1) != g_list_length (l2))
690 return FALSE;
691 for (; l1; l1 = l1->next, l2 = l2->next)
692 {
693 if (!guid_equal (l1->data, l2->data))
694 return FALSE;
695 }
696 return TRUE;
697 }
698
699 QofQueryPredData *
700 qof_query_guid_predicate (QofGuidMatch options, GList * guid_list)
701 {
702 query_guid_t pdata;
703 GList *node;
704
705 if (NULL == guid_list)
706 return NULL;
707
708 pdata = g_new0 (query_guid_def, 1);
709 pdata->pd.how = QOF_COMPARE_EQUAL;
710 pdata->pd.type_name = query_guid_type;
711 pdata->options = options;
712
713 pdata->guids = g_list_copy (guid_list);
714 for (node = pdata->guids; node; node = node->next)
715 {
716 GUID *guid = guid_malloc ();
717 *guid = *((GUID *) node->data);
718 node->data = guid;
719 }
720 return ((QofQueryPredData *) pdata);
721 }
722
723 /* ================================================================ */
724 /* QOF_TYPE_INT32 */
725
726 static int
727 int32_match_predicate (gpointer object, QofParam * getter,
728 QofQueryPredData * pd)
729 {
730 gint32 val;
731 query_int32_t pdata = (query_int32_t) pd;
732
733 VERIFY_PREDICATE (query_int32_type);
734
735 val = ((query_int32_getter) getter->param_getfcn) (object, getter);
736
737 switch (pd->how)
738 {
739 case QOF_COMPARE_LT:
740 return (val < pdata->val);
741 case QOF_COMPARE_LTE:
742 return (val <= pdata->val);
743 case QOF_COMPARE_EQUAL:
744 return (val == pdata->val);
745 case QOF_COMPARE_GT:
746 return (val > pdata->val);
747 case QOF_COMPARE_GTE:
748 return (val >= pdata->val);
749 case QOF_COMPARE_NEQ:
750 return (val != pdata->val);
751 default:
752 PWARN ("bad match type: %d", pd->how);
753 return 0;
754 }
755 }
756
757 static int
758 int32_compare_func (gpointer a, gpointer b,
759 gint options __attribute__ ((unused)),
760 QofParam * getter)
761 {
762 gint32 v1, v2;
763 g_return_val_if_fail (a && b && getter
764 && getter->param_getfcn, COMPARE_ERROR);
765
766 v1 = ((query_int32_getter) getter->param_getfcn) (a, getter);
767 v2 = ((query_int32_getter) getter->param_getfcn) (b, getter);
768
769 if (v1 < v2)
770 return -1;
771 if (v1 > v2)
772 return 1;
773 return 0;
774 }
775
776 static void
777 int32_free_pdata (QofQueryPredData * pd)
778 {
779 query_int32_t pdata = (query_int32_t) pd;
780 VERIFY_PDATA (query_int32_type);
781 g_free (pdata);
782 }
783
784 static QofQueryPredData *
785 int32_copy_predicate (QofQueryPredData * pd)
786 {
787 query_int32_t pdata = (query_int32_t) pd;
788 VERIFY_PDATA_R (query_int32_type);
789 return qof_query_int32_predicate (pd->how, pdata->val);
790 }
791
792 static gboolean
793 int32_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
794 {
795 query_int32_t pd1 = (query_int32_t) p1;
796 query_int32_t pd2 = (query_int32_t) p2;
797
798 return (pd1->val == pd2->val);
799 }
800
801 QofQueryPredData *
802 qof_query_int32_predicate (QofQueryCompare how, gint32 val)
803 {
804 query_int32_t pdata = g_new0 (query_int32_def, 1);
805 pdata->pd.type_name = query_int32_type;
806 pdata->pd.how = how;
807 pdata->val = val;
808 return ((QofQueryPredData *) pdata);
809 }
810
811 static char *
812 int32_to_string (gpointer object, QofParam * getter)
813 {
814 gint32 num =
815 ((query_int32_getter) getter->param_getfcn) (object, getter);
816
817 return g_strdup_printf ("%d", num);
818 }
819
820 /* ================================================================ */
821 /* QOF_TYPE_INT64 */
822
823 static int
824 int64_match_predicate (gpointer object, QofParam * getter,
825 QofQueryPredData * pd)
826 {
827 gint64 val;
828 query_int64_t pdata = (query_int64_t) pd;
829
830 VERIFY_PREDICATE (query_int64_type);
831
832 val = ((query_int64_getter) getter->param_getfcn) (object, getter);
833
834 switch (pd->how)
835 {
836 case QOF_COMPARE_LT:
837 return (val < pdata->val);
838 case QOF_COMPARE_LTE:
839 return (val <= pdata->val);
840 case QOF_COMPARE_EQUAL:
841 return (val == pdata->val);
842 case QOF_COMPARE_GT:
843 return (val > pdata->val);
844 case QOF_COMPARE_GTE:
845 return (val >= pdata->val);
846 case QOF_COMPARE_NEQ:
847 return (val != pdata->val);
848 default:
849 PWARN ("bad match type: %d", pd->how);
850 return 0;
851 }
852 }
853
854 static int
855 int64_compare_func (gpointer a, gpointer b,
856 gint options __attribute__ ((unused)), QofParam * getter)
857 {
858 gint64 v1, v2;
859 g_return_val_if_fail (a && b && getter
860 && getter->param_getfcn, COMPARE_ERROR);
861
862 v1 = ((query_int64_getter) getter->param_getfcn) (a, getter);
863 v2 = ((query_int64_getter) getter->param_getfcn) (b, getter);
864
865 if (v1 < v2)
866 return -1;
867 if (v1 > v2)
868 return 1;
869 return 0;
870 }
871
872 static void
873 int64_free_pdata (QofQueryPredData * pd)
874 {
875 query_int64_t pdata = (query_int64_t) pd;
876 VERIFY_PDATA (query_int64_type);
877 g_free (pdata);
878 }
879
880 static QofQueryPredData *
881 int64_copy_predicate (QofQueryPredData * pd)
882 {
883 query_int64_t pdata = (query_int64_t) pd;
884 VERIFY_PDATA_R (query_int64_type);
885 return qof_query_int64_predicate (pd->how, pdata->val);
886 }
887
888 static gboolean
889 int64_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
890 {
891 query_int64_t pd1 = (query_int64_t) p1;
892 query_int64_t pd2 = (query_int64_t) p2;
893
894 return (pd1->val == pd2->val);
895 }
896
897 QofQueryPredData *
898 qof_query_int64_predicate (QofQueryCompare how, gint64 val)
899 {
900 query_int64_t pdata = g_new0 (query_int64_def, 1);
901 pdata->pd.type_name = query_int64_type;
902 pdata->pd.how = how;
903 pdata->val = val;
904 return ((QofQueryPredData *) pdata);
905 }
906
907 static char *
908 int64_to_string (gpointer object, QofParam * getter)
909 {
910 gint64 num =
911 ((query_int64_getter) getter->param_getfcn) (object, getter);
912
913 return g_strdup_printf ("%" G_GINT64_FORMAT, num);
914 }
915
916 /* ================================================================ */
917 /* QOF_TYPE_DOUBLE */
918
919 static int
920 double_match_predicate (gpointer object, QofParam * getter,
921 QofQueryPredData * pd)
922 {
923 double val;
924 query_double_t pdata = (query_double_t) pd;
925
926 VERIFY_PREDICATE (query_double_type);
927
928 val = ((query_double_getter) getter->param_getfcn) (object, getter);
929
930 switch (pd->how)
931 {
932 case QOF_COMPARE_LT:
933 return (val < pdata->val);
934 case QOF_COMPARE_LTE:
935 return (val <= pdata->val);
936 case QOF_COMPARE_EQUAL:
937 return (val == pdata->val);
938 case QOF_COMPARE_GT:
939 return (val > pdata->val);
940 case QOF_COMPARE_GTE:
941 return (val >= pdata->val);
942 case QOF_COMPARE_NEQ:
943 return (val != pdata->val);
944 default:
945 PWARN ("bad match type: %d", pd->how);
946 return 0;
947 }
948 }
949
950 static int
951 double_compare_func (gpointer a, gpointer b,
952 gint options __attribute__ ((unused)), QofParam * getter)
953 {
954 double v1, v2;
955 g_return_val_if_fail (a && b && getter
956 && getter->param_getfcn, COMPARE_ERROR);
957
958 v1 = ((query_double_getter) getter->param_getfcn) (a, getter);
959 v2 = ((query_double_getter) getter->param_getfcn) (b, getter);
960
961 if (v1 < v2)
962 return -1;
963 if (v1 > v2)
964 return 1;
965 return 0;
966 }
967
968 static void
969 double_free_pdata (QofQueryPredData * pd)
970 {
971 query_double_t pdata = (query_double_t) pd;
972 VERIFY_PDATA (query_double_type);
973 g_free (pdata);
974 }
975
976 static QofQueryPredData *
977 double_copy_predicate (QofQueryPredData * pd)
978 {
979 query_double_t pdata = (query_double_t) pd;
980 VERIFY_PDATA_R (query_double_type);
981 return qof_query_double_predicate (pd->how, pdata->val);
982 }
983
984 static gboolean
985 double_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
986 {
987 query_double_t pd1 = (query_double_t) p1;
988 query_double_t pd2 = (query_double_t) p2;
989
990 return (pd1->val == pd2->val);
991 }
992
993 QofQueryPredData *
994 qof_query_double_predicate (QofQueryCompare how, double val)
995 {
996 query_double_t pdata = g_new0 (query_double_def, 1);
997 pdata->pd.type_name = query_double_type;
998 pdata->pd.how = how;
999 pdata->val = val;
1000 return ((QofQueryPredData *) pdata);
1001 }
1002
1003 static char *
1004 double_to_string (gpointer object, QofParam * getter)
1005 {
1006 double num =
1007 ((query_double_getter) getter->param_getfcn) (object, getter);
1008
1009 return g_strdup_printf ("%f", num);
1010 }
1011
1012 /* QOF_TYPE_BOOLEAN =================================================== */
1013
1014 static int
1015 boolean_match_predicate (gpointer object, QofParam * getter,
1016 QofQueryPredData * pd)
1017 {
1018 gboolean val;
1019 query_boolean_t pdata = (query_boolean_t) pd;
1020
1021 VERIFY_PREDICATE (query_boolean_type);
1022
1023 val = ((query_boolean_getter) getter->param_getfcn) (object, getter);
1024
1025 switch (pd->how)
1026 {
1027 case QOF_COMPARE_EQUAL:
1028 return (val == pdata->val);
1029 case QOF_COMPARE_NEQ:
1030 return (val != pdata->val);
1031 default:
1032 PWARN ("bad match type: %d", pd->how);
1033 return 0;
1034 }
1035 }
1036
1037 static int
1038 boolean_compare_func (gpointer a, gpointer b,
1039 gint options __attribute__ ((unused)), QofParam * getter)
1040 {
1041 gboolean va, vb;
1042 g_return_val_if_fail (a && b && getter
1043 && getter->param_getfcn, COMPARE_ERROR);
1044 va = ((query_boolean_getter) getter->param_getfcn) (a, getter);
1045 vb = ((query_boolean_getter) getter->param_getfcn) (b, getter);
1046 if (!va && vb)
1047 return -1;
1048 if (va && !vb)
1049 return 1;
1050 return 0;
1051 }
1052
1053 static void
1054 boolean_free_pdata (QofQueryPredData * pd)
1055 {
1056 query_boolean_t pdata = (query_boolean_t) pd;
1057 VERIFY_PDATA (query_boolean_type);
1058 g_free (pdata);
1059 }
1060
1061 static QofQueryPredData *
1062 boolean_copy_predicate (QofQueryPredData * pd)
1063 {
1064 query_boolean_t pdata = (query_boolean_t) pd;
1065 VERIFY_PDATA_R (query_boolean_type);
1066 return qof_query_boolean_predicate (pd->how, pdata->val);
1067 }
1068
1069 static gboolean
1070 boolean_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
1071 {
1072 query_boolean_t pd1 = (query_boolean_t) p1;
1073 query_boolean_t pd2 = (query_boolean_t) p2;
1074
1075 return (pd1->val == pd2->val);
1076 }
1077
1078 QofQueryPredData *
1079 qof_query_boolean_predicate (QofQueryCompare how, gboolean val)
1080 {
1081 query_boolean_t pdata;
1082 g_return_val_if_fail (how == QOF_COMPARE_EQUAL
1083 || how == QOF_COMPARE_NEQ, NULL);
1084
1085 pdata = g_new0 (query_boolean_def, 1);
1086 pdata->pd.type_name = query_boolean_type;
1087 pdata->pd.how = how;
1088 pdata->val = val;
1089 return ((QofQueryPredData *) pdata);
1090 }
1091
1092 static char *
1093 boolean_to_string (gpointer object, QofParam * getter)
1094 {
1095 gboolean num =
1096 ((query_boolean_getter) getter->param_getfcn) (object, getter);
1097
1098 return g_strdup_printf ("%s", (num ? "X" : ""));
1099 }
1100
1101 /* QOF_TYPE_CHAR =================================================== */
1102
1103 static int
1104 char_match_predicate (gpointer object, QofParam * getter,
1105 QofQueryPredData * pd)
1106 {
1107 char c;
1108 query_char_t pdata = (query_char_t) pd;
1109
1110 VERIFY_PREDICATE (query_char_type);
1111
1112 c = ((query_char_getter) getter->param_getfcn) (object, getter);
1113
1114 switch (pdata->options)
1115 {
1116 case QOF_CHAR_MATCH_ANY:
1117 if (strchr (pdata->char_list, c))
1118 return 1;
1119 return 0;
1120 case QOF_CHAR_MATCH_NONE:
1121 if (!strchr (pdata->char_list, c))
1122 return 1;
1123 return 0;
1124 default:
1125 PWARN ("bad match type");
1126 return 0;
1127 }
1128 }
1129
1130 static int
1131 char_compare_func (gpointer a, gpointer b,
1132 gint options __attribute__ ((unused)), QofParam * getter)
1133 {
1134 char va, vb;
1135 g_return_val_if_fail (a && b && getter
1136 && getter->param_getfcn, COMPARE_ERROR);
1137 va = ((query_char_getter) getter->param_getfcn) (a, getter);
1138 vb = ((query_char_getter) getter->param_getfcn) (b, getter);
1139 return (va - vb);
1140 }
1141
1142 static void
1143 char_free_pdata (QofQueryPredData * pd)
1144 {
1145 query_char_t pdata = (query_char_t) pd;
1146 VERIFY_PDATA (query_char_type);
1147 g_free (pdata->char_list);
1148 g_free (pdata);
1149 }
1150
1151 static QofQueryPredData *
1152 char_copy_predicate (QofQueryPredData * pd)
1153 {
1154 query_char_t pdata = (query_char_t) pd;
1155 VERIFY_PDATA_R (query_char_type);
1156 return qof_query_char_predicate (pdata->options, pdata->char_list);
1157 }
1158
1159 static gboolean
1160 char_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
1161 {
1162 query_char_t pd1 = (query_char_t) p1;
1163 query_char_t pd2 = (query_char_t) p2;
1164
1165 if (pd1->options != pd2->options)
1166 return FALSE;
1167 return (safe_strcmp (pd1->char_list, pd2->char_list) == 0);
1168 }
1169
1170 QofQueryPredData *
1171 qof_query_char_predicate (QofCharMatch options, const char *chars)
1172 {
1173 query_char_t pdata;
1174 g_return_val_if_fail (chars, NULL);
1175 pdata = g_new0 (query_char_def, 1);
1176 pdata->pd.type_name = query_char_type;
1177 pdata->pd.how = QOF_COMPARE_EQUAL;
1178 pdata->options = options;
1179 pdata->char_list = g_strdup (chars);
1180 return ((QofQueryPredData *) pdata);
1181 }
1182
1183 static char *
1184 char_to_string (gpointer object, QofParam * getter)
1185 {
1186 char num = ((query_char_getter) getter->param_getfcn) (object, getter);
1187
1188 return g_strdup_printf ("%c", num);
1189 }
1190
1191 /* QOF_TYPE_KVP ================================================ */
1192
1193 static int
1194 kvp_match_predicate (gpointer object, QofParam * getter,
1195 QofQueryPredData * pd)
1196 {
1197 int compare;
1198 KvpFrame *kvp;
1199 KvpValue *value;
1200 query_kvp_t pdata = (query_kvp_t) pd;
1201
1202 VERIFY_PREDICATE (query_kvp_type);
1203
1204 kvp = ((query_kvp_getter) getter->param_getfcn) (object, getter);
1205 if (!kvp)
1206 return 0;
1207
1208 value = kvp_frame_get_slot_path_gslist (kvp, pdata->path);
1209 if (!value)
1210 return 0;
1211
1212 if (kvp_value_get_type (value) != kvp_value_get_type (pdata->value))
1213 return 0;
1214
1215 compare = kvp_value_compare (value, pdata->value);
1216
1217 switch (pd->how)
1218 {
1219 case QOF_COMPARE_LT:
1220 return (compare < 0);
1221 case QOF_COMPARE_LTE:
1222 return (compare <= 0);
1223 case QOF_COMPARE_EQUAL:
1224 return (compare == 0);
1225 case QOF_COMPARE_GTE:
1226 return (compare >= 0);
1227 case QOF_COMPARE_GT:
1228 return (compare > 0);
1229 case QOF_COMPARE_NEQ:
1230 return (compare != 0);
1231 default:
1232 PWARN ("bad match type: %d", pd->how);
1233 return 0;
1234 }
1235 }
1236
1237 static void
1238 kvp_free_pdata (QofQueryPredData * pd)
1239 {
1240 query_kvp_t pdata = (query_kvp_t) pd;
1241 GSList *node;
1242
1243 VERIFY_PDATA (query_kvp_type);
1244 kvp_value_delete (pdata->value);
1245 for (node = pdata->path; node; node = node->next)
1246 {
1247 g_free (node->data);
1248 node->data = NULL;
1249 }
1250 g_slist_free (pdata->path);
1251 g_free (pdata);
1252 }
1253
1254 static QofQueryPredData *
1255 kvp_copy_predicate (QofQueryPredData * pd)
1256 {
1257 query_kvp_t pdata = (query_kvp_t) pd;
1258 VERIFY_PDATA_R (query_kvp_type);
1259 return qof_query_kvp_predicate (pd->how, pdata->path, pdata->value);
1260 }
1261
1262 static gboolean
1263 kvp_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
1264 {
1265 query_kvp_t pd1 = (query_kvp_t) p1;
1266 query_kvp_t pd2 = (query_kvp_t) p2;
1267 GSList *n1, *n2;
1268
1269 n1 = pd1->path;
1270 n2 = pd2->path;
1271
1272 for (; n1 && n2; n1 = n1->next, n2 = n2->next)
1273 {
1274 if (safe_strcmp (n1->data, n2->data) != 0)
1275 return FALSE;
1276 }
1277
1278 if (n1 || n2)
1279 return FALSE;
1280
1281 return (kvp_value_compare (pd1->value, pd2->value) == 0);
1282 }
1283
1284 QofQueryPredData *
1285 qof_query_kvp_predicate (QofQueryCompare how,
1286 GSList * path, const KvpValue * value)
1287 {
1288 query_kvp_t pdata;
1289 GSList *node;
1290
1291 g_return_val_if_fail (path && value, NULL);
1292
1293 pdata = g_new0 (query_kvp_def, 1);
1294 pdata->pd.type_name = query_kvp_type;
1295 pdata->pd.how = how;
1296 pdata->value = kvp_value_copy (value);
1297 pdata->path = g_slist_copy (path);
1298 for (node = pdata->path; node; node = node->next)
1299 node->data = g_strdup (node->data);
1300
1301 return ((QofQueryPredData *) pdata);
1302 }
1303
1304 QofQueryPredData *
1305 qof_query_kvp_predicate_path (QofQueryCompare how,
1306 const char *path, const KvpValue * value)
1307 {
1308 QofQueryPredData *pd;
1309 GSList *spath = NULL;
1310 char *str, *p;
1311
1312 if (!path)
1313 return NULL;
1314
1315 str = g_strdup (path);
1316 p = str;
1317 if (0 == *p)
1318 return NULL;
1319 if ('/' == *p)
1320 p++;
1321
1322 while (p)
1323 {
1324 spath = g_slist_append (spath, p);
1325 p = strchr (p, '/');
1326 if (p)
1327 {
1328 *p = 0;
1329 p++;
1330 }
1331 }
1332
1333 pd = qof_query_kvp_predicate (how, spath, value);
1334 g_free (str);
1335 return pd;
1336 }
1337
1338
1339 /* QOF_TYPE_COLLECT =============================================== */
1340
1341 static int
1342 collect_match_predicate (gpointer object, QofParam * getter,
1343 QofQueryPredData * pd)
1344 {
1345 query_coll_t pdata;
1346 QofCollection *coll;
1347 GList *node, *node2, *o_list;
1348 const GUID *guid;
1349
1350 pdata = (query_coll_t) pd;
1351 VERIFY_PREDICATE (query_collect_type);
1352 coll = ((query_collect_getter) getter->param_getfcn) (object, getter);
1353 guid = NULL;
1354 switch (pdata->options)
1355 {
1356 case QOF_GUID_MATCH_ALL:
1357 {
1358 for (node = pdata->guids; node; node = node->next)
1359 {
1360 for (o_list = object; o_list; o_list = o_list->next)
1361 {
1362 guid = ((query_guid_getter) getter->param_getfcn)
1363 (o_list->data, getter);
1364 if (guid_equal (node->data, guid))
1365 {
1366 break;
1367 }
1368 }
1369 if (o_list == NULL)
1370 {
1371 break;
1372 }
1373 }
1374 break;
1375 }
1376 case QOF_GUID_MATCH_LIST_ANY:
1377 {
1378 o_list =
1379 ((query_glist_getter) getter->param_getfcn) (object,
1380 getter);
1381 for (node = o_list; node; node = node->next)
1382 {
1383 for (node2 = pdata->guids; node2; node2 = node2->next)
1384 {
1385 if (guid_equal (node->data, node2->data))
1386 {
1387 break;
1388 }
1389 }
1390 if (node2 != NULL)
1391 {
1392 break;
1393 }
1394 }
1395 g_list_free (o_list);
1396 break;
1397 }
1398 default:
1399 {
1400 guid =
1401 ((query_guid_getter) getter->param_getfcn) (object,
1402 getter);
1403 for (node = pdata->guids; node; node = node->next)
1404 {
1405 if (guid_equal (node->data, guid))
1406 {
1407 break;
1408 }
1409 }
1410 }
1411 switch (pdata->options)
1412 {
1413 case QOF_GUID_MATCH_ANY:
1414 case QOF_GUID_MATCH_LIST_ANY:
1415 {
1416 return (node != NULL);
1417 break;
1418 }
1419 case QOF_GUID_MATCH_NONE:
1420 case QOF_GUID_MATCH_ALL:
1421 {
1422 return (node == NULL);
1423 break;
1424 }
1425 case QOF_GUID_MATCH_NULL:
1426 {
1427 return (guid == NULL);
1428 break;
1429 }
1430 default:
1431 {
1432 PWARN ("bad match type");
1433 return 0;
1434 }
1435 }
1436 }
1437 return 0;
1438 }
1439
1440 static int
1441 collect_compare_func (gpointer a, gpointer b,
1442 gint options __attribute__ ((unused)),
1443 QofParam * getter)
1444 {
1445 gint result;
1446 QofCollection *c1, *c2;
1447
1448 c1 = ((query_collect_getter) getter->param_getfcn) (a, getter);
1449 c2 = ((query_collect_getter) getter->param_getfcn) (b, getter);
1450 result = qof_collection_compare (c1, c2);
1451 return result;
1452 }
1453
1454 static void
1455 collect_free_pdata (QofQueryPredData * pd)
1456 {
1457 query_coll_t pdata;
1458 GList *node;
1459
1460 node = NULL;
1461 pdata = (query_coll_t) pd;
1462 VERIFY_PDATA (query_collect_type);
1463 for (node = pdata->guids; node; node = node->next)
1464 {
1465 guid_free (node->data);
1466 }
1467 qof_collection_destroy (pdata->coll);
1468 g_list_free (pdata->guids);
1469 g_free (pdata);
1470 }
1471
1472 static QofQueryPredData *
1473 collect_copy_predicate (QofQueryPredData * pd)
1474 {
1475 query_coll_t pdata = (query_coll_t) pd;
1476
1477 VERIFY_PDATA_R (query_collect_type);
1478 return qof_query_collect_predicate (pdata->options, pdata->coll);
1479 }
1480
1481 static gboolean
1482 collect_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
1483 {
1484 query_coll_t pd1;
1485 query_coll_t pd2;
1486 gint result;
1487
1488 pd1 = (query_coll_t) p1;
1489 pd2 = (query_coll_t) p2;
1490 result = qof_collection_compare (pd1->coll, pd2->coll);
1491 if (result == 0)
1492 {
1493 return TRUE;
1494 }
1495 return FALSE;
1496 }
1497
1498 static void
1499 query_collect_cb (QofEntity * ent, gpointer user_data)
1500 {
1501 query_coll_t pdata;
1502 GUID *guid;
1503
1504 guid = guid_malloc ();
1505 guid = (GUID *) qof_entity_get_guid (ent);
1506 pdata = (query_coll_t) user_data;
1507 pdata->guids = g_list_append (pdata->guids, guid);
1508 }
1509
1510 QofQueryPredData *
1511 qof_query_collect_predicate (QofGuidMatch options, QofCollection * coll)
1512 {
1513 query_coll_t pdata;
1514
1515 g_return_val_if_fail (coll, NULL);
1516 pdata = g_new0 (query_coll_def, 1);
1517 pdata->pd.type_name = query_collect_type;
1518 pdata->options = options;
1519 qof_collection_foreach (coll, query_collect_cb, pdata);
1520 if (NULL == pdata->guids)
1521 {
1522 return NULL;
1523 }
1524 return ((QofQueryPredData *) pdata);
1525 }
1526
1527 /* QOF_TYPE_CHOICE */
1528
1529 static int
1530 choice_match_predicate (gpointer object, QofParam * getter,
1531 QofQueryPredData * pd)
1532 {
1533 query_choice_t pdata = (query_choice_t) pd;
1534 GList *node, *o_list;
1535 const GUID *guid = NULL;
1536
1537 VERIFY_PREDICATE (query_choice_type);
1538
1539 switch (pdata->options)
1540 {
1541
1542 case QOF_GUID_MATCH_ALL:
1543 /* object is a GList of objects; param_getfcn must be called on each one.
1544 * See if every guid in the predicate is accounted-for in the
1545 * object list
1546 */
1547
1548 for (node = pdata->guids; node; node = node->next)
1549 {
1550 /* See if this GUID matches the object's guid */
1551 for (o_list = object; o_list; o_list = o_list->next)
1552 {
1553 guid =
1554 ((query_choice_getter) getter->param_getfcn) (o_list->
1555 data, getter);
1556 if (guid_equal (node->data, guid))
1557 break;
1558 }
1559
1560 /*
1561 * If o_list is NULL, we've walked the whole list without finding
1562 * a match. Therefore break out now, the match has failed.
1563 */
1564 if (o_list == NULL)
1565 break;
1566 }
1567
1568 /*
1569 * The match is complete. If node == NULL then we've succesfully
1570 * found a match for all the guids in the predicate. Return
1571 * appropriately below.
1572 */
1573
1574 break;
1575
1576 case QOF_GUID_MATCH_LIST_ANY:
1577
1578 o_list =
1579 ((query_glist_getter) getter->param_getfcn) (object, getter);
1580
1581 for (node = o_list; node; node = node->next)
1582 {
1583 GList *node2;
1584
1585 for (node2 = pdata->guids; node2; node2 = node2->next)
1586 {
1587 if (guid_equal (node->data, node2->data))
1588 break;
1589 }
1590
1591 if (node2 != NULL)
1592 break;
1593 }
1594
1595 g_list_free (o_list);
1596
1597 break;
1598
1599 default:
1600 /* object is a single object, getter returns a GUID*
1601 *
1602 * See if the guid is in the list
1603 */
1604
1605 guid =
1606 ((query_choice_getter) getter->param_getfcn) (object, getter);
1607 for (node = pdata->guids; node; node = node->next)
1608 {
1609 if (guid_equal (node->data, guid))
1610 break;
1611 }
1612 }
1613
1614 switch (pdata->options)
1615 {
1616 case QOF_GUID_MATCH_ANY:
1617 case QOF_GUID_MATCH_LIST_ANY:
1618 return (node != NULL);
1619 break;
1620 case QOF_GUID_MATCH_NONE:
1621 case QOF_GUID_MATCH_ALL:
1622 return (node == NULL);
1623 break;
1624 case QOF_GUID_MATCH_NULL:
1625 return (guid == NULL);
1626 break;
1627 default:
1628 PWARN ("bad match type");
1629 return 0;
1630 }
1631 }
1632
1633 static void
1634 choice_free_pdata (QofQueryPredData * pd)
1635 {
1636 query_choice_t pdata = (query_choice_t) pd;
1637 GList *node;
1638 VERIFY_PDATA (query_choice_type);
1639 for (node = pdata->guids; node; node = node->next)
1640 {
1641 guid_free (node->data);
1642 }
1643 g_list_free (pdata->guids);
1644 g_free (pdata);
1645 }
1646
1647 static QofQueryPredData *
1648 choice_copy_predicate (QofQueryPredData * pd)
1649 {
1650 query_choice_t pdata = (query_choice_t) pd;
1651 VERIFY_PDATA_R (query_choice_type);
1652 return qof_query_choice_predicate (pdata->options, pdata->guids);
1653 }
1654
1655 static gboolean
1656 choice_predicate_equal (QofQueryPredData * p1, QofQueryPredData * p2)
1657 {
1658 query_choice_t pd1 = (query_choice_t) p1;
1659 query_choice_t pd2 = (query_choice_t) p2;
1660 GList *l1 = pd1->guids, *l2 = pd2->guids;
1661
1662 if (pd1->options != pd2->options)
1663 return FALSE;
1664 if (g_list_length (l1) != g_list_length (l2))
1665 return FALSE;
1666 for (; l1; l1 = l1->next, l2 = l2->next)
1667 {
1668 if (!guid_equal (l1->data, l2->data))
1669 return FALSE;
1670 }
1671 return TRUE;
1672 }
1673
1674 QofQueryPredData *
1675 qof_query_choice_predicate (QofGuidMatch options, GList * guid_list)
1676 {
1677 query_choice_t pdata;
1678 GList *node;
1679
1680 if (NULL == guid_list)
1681 return NULL;
1682
1683 pdata = g_new0 (query_choice_def, 1);
1684 pdata->pd.how = QOF_COMPARE_EQUAL;
1685 pdata->pd.type_name = query_choice_type;
1686 pdata->options = options;
1687
1688 pdata->guids = g_list_copy (guid_list);
1689 for (node = pdata->guids; node; node = node->next)
1690 {
1691 GUID *guid = guid_malloc ();
1692 *guid = *((GUID *) node->data);
1693 node->data = guid;
1694 }
1695 return ((QofQueryPredData *) pdata);
1696 }
1697
1698
1699 /* initialization ================================================== */
1711 static void
1712 qof_query_register_core_object (QofType core_name,
1713 QofQueryPredicateFunc pred,
1714 QofCompareFunc comp,
1715 QueryPredicateCopyFunc copy,
1716 QueryPredDataFree pd_free,
1717 QueryToString toString, QueryPredicateEqual pred_equal)
1718 {
1719 g_return_if_fail (core_name);
1720 g_return_if_fail (*core_name != '\0');
1721
1722 if (pred)
1723 g_hash_table_insert (predTable, (char *) core_name, pred);
1724
1725 if (comp)
1726 g_hash_table_insert (cmpTable, (char *) core_name, comp);
1727
1728 if (copy)
1729 g_hash_table_insert (copyTable, (char *) core_name, copy);
1730
1731 if (pd_free)
1732 g_hash_table_insert (freeTable, (char *) core_name, pd_free);
1733
1734 if (toString)
1735 g_hash_table_insert (toStringTable, (char *) core_name, toString);
1736
1737 if (pred_equal)
1738 g_hash_table_insert (predEqualTable, (char *) core_name,
1739 pred_equal);
1740 }
1741
1742 /* Deprecated */
1743 #ifndef QOF_DISABLE_DEPRECATED
1744 /* QOF_TYPE_DATE =================================================== */
1745 typedef Timespec (*query_date_getter) (gpointer, QofParam *);
1746 static const gchar *query_date_type = QOF_TYPE_DATE;
1747
1748 static gint
1749 date_compare (Timespec ta, Timespec tb, QofDateMatch options)
1750 {
1751
1752 if (options == QOF_DATE_MATCH_DAY)
1753 {
1754 ta = timespecCanonicalDayTime (ta);
1755 tb = timespecCanonicalDayTime (tb);
1756 }
1757
1758 if (ta.tv_sec < tb.tv_sec)
1759 return -1;
1760 if (ta.tv_sec > tb.tv_sec)
1761 return 1;
1762
1763 if (ta.tv_nsec < tb.tv_nsec)
1764 return -1;
1765 if (ta.tv_nsec > tb.tv_nsec)
1766 return 1;
1767
1768 return 0;
1769 }
1770
1771 static int
1772 date_match_predicate (gpointer object, QofParam *getter,
1773 QofQueryPredData *pd)
1774 {
1775 query_date_t pdata = (query_date_t)pd;
1776 Timespec objtime;
1777 int compare;
1778
1779 VERIFY_PREDICATE (query_date_type);
1780
1781 objtime = ((query_date_getter)getter->param_getfcn) (object, getter);
1782 compare = date_compare (objtime, pdata->date, pdata->options);
1783
1784 switch (pd->how) {
1785 case QOF_COMPARE_LT:
1786 return (compare < 0);
1787 case QOF_COMPARE_LTE:
1788 return (compare <= 0);
1789 case QOF_COMPARE_EQUAL:
1790 return (compare == 0);
1791 case QOF_COMPARE_GT:
1792 return (compare > 0);
1793 case QOF_COMPARE_GTE:
1794 return (compare >= 0);
1795 case QOF_COMPARE_NEQ:
1796 return (compare != 0);
1797 default:
1798 PWARN ("bad match type: %d", pd->how);
1799 return 0;
1800 }
1801 }
1802
1803 static gint
1804 date_compare_func (gpointer a, gpointer b, gint options, QofParam * getter)
1805 {
1806 Timespec ta, tb;
1807
1808 g_return_val_if_fail (a && b && getter
1809 && getter->param_getfcn, COMPARE_ERROR);
1810
1811 ta = ((query_date_getter) getter->param_getfcn) (a, getter);
1812 tb = ((query_date_getter) getter->param_getfcn) (b, getter);
1813
1814 return date_compare (ta, tb, options);
1815 }
1816
1817 static void
1818 date_free_pdata (QofQueryPredData * pd)
1819 {
1820 query_date_t pdata = (query_date_t) pd;
1821
1822 VERIFY_PDATA (query_date_type);
1823
1824 g_free (pdata);
1825 }
1826
1827 static QofQueryPredData *
1828 date_copy_predicate (QofQueryPredData *pd)
1829 {
1830 query_date_t pdata = (query_date_t)pd;
1831
1832 VERIFY_PDATA_R (query_date_type);
1833
1834 return qof_query_date_predicate (pd->how, pdata->options, pdata->date);
1835 }
1836
1837 static gboolean
1838 date_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
1839 {
1840 query_date_t pd1 = (query_date_t) p1;
1841 query_date_t pd2 = (query_date_t) p2;
1842
1843 if (pd1->options != pd2->options) return FALSE;
1844 return timespec_equal (&(pd1->date), &(pd2->date));
1845 }
1846
1847 QofQueryPredData *
1848 qof_query_date_predicate (QofQueryCompare how,
1849 QofDateMatch options, Timespec date)
1850 {
1851 query_date_t pdata;
1852
1853 pdata = g_new0 (query_date_def, 1);
1854 pdata->pd.type_name = query_date_type;
1855 pdata->pd.how = how;
1856 pdata->options = options;
1857 pdata->date = date;
1858 return ((QofQueryPredData*)pdata);
1859 }
1860
1861 gboolean
1862 qof_query_date_predicate_get_date (QofQueryPredData *pd, Timespec *date)
1863 {
1864 query_date_t pdata = (query_date_t)pd;
1865
1866 if (pdata->pd.type_name != query_date_type)
1867 return FALSE;
1868 *date = pdata->date;
1869 return TRUE;
1870 }
1871
1872 static gchar *
1873 date_to_string (gpointer object, QofParam * getter)
1874 {
1875 Timespec ts =
1876 ((query_date_getter) getter->param_getfcn) (object, getter);
1877
1878 if (ts.tv_sec || ts.tv_nsec)
1879 return g_strdup (gnc_print_date (ts));
1880
1881 return NULL;
1882 }
1883
1884 #endif // QOF_DISABLE_DEPRECATED QOF_TYPE_DATE
1885
1886 static void
1887 init_tables (void)
1888 {
1889 guint i;
1890 struct
1891 {
1892 QofType name;
1893 QofQueryPredicateFunc pred;
1894 QofCompareFunc comp;
1895 QueryPredicateCopyFunc copy;
1896 QueryPredDataFree pd_free;
1897 QueryToString toString;
1898 QueryPredicateEqual pred_equal;
1899 } knownTypes[] =
1900 {
1901 {
1902 QOF_TYPE_STRING, string_match_predicate, string_compare_func,
1903 string_copy_predicate, string_free_pdata,
1904 string_to_string, string_predicate_equal},
1905 #ifndef QOF_DISABLE_DEPRECATED
1906 {
1907 QOF_TYPE_DATE, date_match_predicate, date_compare_func,
1908 date_copy_predicate, date_free_pdata, date_to_string,
1909 date_predicate_equal},
1910 #endif
1911 {
1912 QOF_TYPE_TIME, time_match_predicate, time_compare_func,
1913 time_copy_predicate, time_free_pdata, time_to_string,
1914 time_predicate_equal},
1915 {
1916 QOF_TYPE_DEBCRED, numeric_match_predicate,
1917 numeric_compare_func, numeric_copy_predicate,
1918 numeric_free_pdata, debcred_to_string,
1919 numeric_predicate_equal},
1920 {
1921 QOF_TYPE_NUMERIC, numeric_match_predicate,
1922 numeric_compare_func, numeric_copy_predicate,
1923 numeric_free_pdata, numeric_to_string,
1924 numeric_predicate_equal},
1925 {
1926 QOF_TYPE_GUID, guid_match_predicate, NULL,
1927 guid_copy_predicate, guid_free_pdata, NULL,
1928 guid_predicate_equal},
1929 {
1930 QOF_TYPE_INT32, int32_match_predicate, int32_compare_func,
1931 int32_copy_predicate, int32_free_pdata,
1932 int32_to_string, int32_predicate_equal},
1933 {
1934 QOF_TYPE_INT64, int64_match_predicate, int64_compare_func,
1935 int64_copy_predicate, int64_free_pdata,
1936 int64_to_string, int64_predicate_equal},
1937 {
1938 QOF_TYPE_DOUBLE, double_match_predicate, double_compare_func,
1939 double_copy_predicate, double_free_pdata,
1940 double_to_string, double_predicate_equal},
1941 {
1942 QOF_TYPE_BOOLEAN, boolean_match_predicate,
1943 boolean_compare_func, boolean_copy_predicate,
1944 boolean_free_pdata, boolean_to_string,
1945 boolean_predicate_equal},
1946 {
1947 QOF_TYPE_CHAR, char_match_predicate, char_compare_func,
1948 char_copy_predicate, char_free_pdata, char_to_string,
1949 char_predicate_equal},
1950 {
1951 QOF_TYPE_KVP, kvp_match_predicate, NULL, kvp_copy_predicate,
1952 kvp_free_pdata, NULL, kvp_predicate_equal},
1953 {
1954 QOF_TYPE_COLLECT, collect_match_predicate,
1955 collect_compare_func, collect_copy_predicate,
1956 collect_free_pdata, NULL, collect_predicate_equal},
1957 {
1958 QOF_TYPE_CHOICE, choice_match_predicate, NULL,
1959 choice_copy_predicate, choice_free_pdata, NULL,
1960 choice_predicate_equal},};
1961
1962 /* Register the known data types */
1963 for (i = 0; i < (sizeof (knownTypes) / sizeof (*knownTypes)); i++)
1964 {
1965 qof_query_register_core_object (knownTypes[i].name,
1966 knownTypes[i].pred,
1967 knownTypes[i].comp,
1968 knownTypes[i].copy,
1969 knownTypes[i].pd_free,
1970 knownTypes[i].toString, knownTypes[i].pred_equal);
1971 }
1972 }
1973
1974 static QueryPredicateCopyFunc
1975 qof_query_copy_predicate (QofType type)
1976 {
1977 QueryPredicateCopyFunc rc;
1978 g_return_val_if_fail (type, NULL);
1979 rc = g_hash_table_lookup (copyTable, type);
1980 return rc;
1981 }
1982
1983 static QueryPredDataFree
1984 qof_query_predicate_free (QofType type)
1985 {
1986 g_return_val_if_fail (type, NULL);
1987 return g_hash_table_lookup (freeTable, type);
1988 }
1989
1990 /********************************************************************/
1991 /* PUBLISHED API FUNCTIONS */
1992
1993 void
1994 qof_query_core_init (void)
1995 {
1996 /* Only let us initialize once */
1997 if (initialized)
1998 return;
1999 initialized = TRUE;
2000
2001 /* Create the tables */
2002 predTable = g_hash_table_new (g_str_hash, g_str_equal);
2003 cmpTable = g_hash_table_new (g_str_hash, g_str_equal);
2004 copyTable = g_hash_table_new (g_str_hash, g_str_equal);
2005 freeTable = g_hash_table_new (g_str_hash, g_str_equal);
2006 toStringTable = g_hash_table_new (g_str_hash, g_str_equal);
2007 predEqualTable = g_hash_table_new (g_str_hash, g_str_equal);
2008
2009 init_tables ();
2010 }
2011
2012 void
2013 qof_query_core_shutdown (void)
2014 {
2015 if (!initialized)
2016 return;
2017 initialized = FALSE;
2018
2019 g_hash_table_destroy (predTable);
2020 g_hash_table_destroy (cmpTable);
2021 g_hash_table_destroy (copyTable);
2022 g_hash_table_destroy (freeTable);
2023 g_hash_table_destroy (toStringTable);
2024 g_hash_table_destroy (predEqualTable);
2025 }
2026
2027 QofQueryPredicateFunc
2028 qof_query_core_get_predicate (QofType type)
2029 {
2030 g_return_val_if_fail (type, NULL);
2031 return g_hash_table_lookup (predTable, type);
2032 }
2033
2034 QofCompareFunc
2035 qof_query_core_get_compare (QofType type)
2036 {
2037 g_return_val_if_fail (type, NULL);
2038 return g_hash_table_lookup (cmpTable, type);
2039 }
2040
2041 void
2042 qof_query_core_predicate_free (QofQueryPredData * pdata)
2043 {
2044 QueryPredDataFree free_fcn;
2045
2046 g_return_if_fail (pdata);
2047 g_return_if_fail (pdata->type_name);
2048
2049 free_fcn = qof_query_predicate_free (pdata->type_name);
2050 free_fcn (pdata);
2051 }
2052
2053 QofQueryPredData *
2054 qof_query_core_predicate_copy (QofQueryPredData * pdata)
2055 {
2056 QueryPredicateCopyFunc copy;
2057
2058 g_return_val_if_fail (pdata, NULL);
2059 g_return_val_if_fail (pdata->type_name, NULL);
2060
2061 copy = qof_query_copy_predicate (pdata->type_name);
2062 return (copy (pdata));
2063 }
2064
2065 gchar *
2066 qof_query_core_to_string (QofType type, gpointer object,
2067 QofParam * getter)
2068 {
2069 QueryToString toString;
2070
2071 g_return_val_if_fail (type, NULL);
2072 g_return_val_if_fail (object, NULL);
2073 g_return_val_if_fail (getter, NULL);
2074
2075 toString = g_hash_table_lookup (toStringTable, type);
2076 g_return_val_if_fail (toString, NULL);
2077
2078 return toString (object, getter);
2079 }
2080
2081 gboolean
2082 qof_query_core_predicate_equal (QofQueryPredData * p1,
2083 QofQueryPredData * p2)
2084 {
2085 QueryPredicateEqual pred_equal;
2086
2087 if (p1 == p2)
2088 return TRUE;
2089 if (!p1 || !p2)
2090 return FALSE;
2091
2092 if (p1->how != p2->how)
2093 return FALSE;
2094 if (safe_strcmp (p1->type_name, p2->type_name))
2095 return FALSE;
2096
2097 pred_equal = g_hash_table_lookup (predEqualTable, p1->type_name);
2098 g_return_val_if_fail (pred_equal, FALSE);
2099
2100 return pred_equal (p1, p2);
2101 }
QOF_TYPE_DATE
#define QOF_TYPE_DATE
Definition: deprecated.h:336
guid_equal
gboolean guid_equal(const GUID *guid_1, const GUID *guid_2)
Definition: guid.c:652
query_date_def
Definition: deprecated.h:392
QOF_DATE_FORMAT_UTC
#define QOF_DATE_FORMAT_UTC
QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".
Definition: qofdate.h:277
qof_collection_compare
gint qof_collection_compare(QofCollection *target, QofCollection *merge)
Compare two secondary collections.
Definition: qofid.c:293
qof_query_kvp_predicate_path
QofQueryPredData * qof_query_kvp_predicate_path(QofQueryCompare how, const gchar *path, const KvpValue *value)
QOF_TYPE_COLLECT
#define QOF_TYPE_COLLECT
Definition: qofclass.h:93
qof_numeric_compare
gint qof_numeric_compare(QofNumeric a, QofNumeric b)
Definition: qofnumeric.c:174
Timespec
struct timespec64 Timespec
QofNumeric
struct _QofNumeric QofNumeric
A rational-number type.
Definition: qofnumeric.h:61
query_string_def
Definition: qofquerycore-p.h:74
_QofParam
Definition: qofclass.h:195
qof_date_from_qtime
QofDate * qof_date_from_qtime(const QofTime *qt)
Definition: qofdate.c:850
qof_query_core_predicate_free
void qof_query_core_predicate_free(QofQueryPredData *pdata)
Definition: qofquerycore.c:2042
query_boolean_def
Definition: qofquerycore-p.h:122
timespec_equal
gboolean timespec_equal(const Timespec *ta, const Timespec *tb)
Definition: deprecated.c:276
guid_malloc
GUID * guid_malloc(void)
Definition: guid.c:100
QofEntity_s
Definition: qofid.h:147
KvpFrame
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
safe_strcasecmp
gint safe_strcasecmp(const gchar *da, const gchar *db)
Definition: qofutil.c:92
qof_date_print
gchar * qof_date_print(const QofDate *date, QofDateFormat df)
Convert a QofDate to a timestamp according to the specified date format.
Definition: qofdate.c:547
gnc_print_date
const char * gnc_print_date(Timespec ts)
Definition: deprecated.c:780
timespec64
Definition: qoftime.h:97
query_guid_def
Definition: qofquerycore-p.h:97
QofStringMatch
QofStringMatch
Definition: qofquerycore.h:65
qof_time_set_day_start
gboolean qof_time_set_day_start(QofTime *qt)
set the given QofTime to the first second of that day.
Definition: qoftime.c:374
query_time_def
Definition: qofquerycore-p.h:83
QOF_GUID_MATCH_ANY
Definition: qofquerycore.h:108
query_numeric_def
Definition: qofquerycore-p.h:90
qof_numeric_equal
gboolean qof_numeric_equal(QofNumeric a, QofNumeric b)
Definition: qofnumeric.c:233
QofDate_s
Full range replacement for struct tm.
Definition: qofdate.h:138
query_int64_def
Definition: qofquerycore-p.h:110
QofCollection
struct QofCollection_s QofCollection
Definition: qofid.h:138
KvpValue
struct _KvpValue KvpValue
Definition: kvpframe.h:78
qof_numeric_abs
QofNumeric qof_numeric_abs(QofNumeric a)
Definition: qofnumeric.c:650
QofGuidMatch
QofGuidMatch
Definition: qofquerycore.h:104
query_int32_def
Definition: qofquerycore-p.h:104
kvp_value_copy
KvpValue * kvp_value_copy(const KvpValue *value)
Definition: kvpframe.c:1601
qof_query_date_predicate_get_date
gboolean qof_query_date_predicate_get_date(QofQueryPredData *pd, Timespec *date)
Definition: qofquerycore.c:1862
query_double_def
Definition: qofquerycore-p.h:116
qof_collection_foreach
void qof_collection_foreach(QofCollection *col, QofEntityForeachCB cb_func, gpointer user_data)
Definition: qofid.c:421
qof_time_cmp
gint qof_time_cmp(const QofTime *ta, const QofTime *tb)
Definition: qoftime.c:165
query_char_def
Definition: qofquerycore-p.h:128
_QofNumeric
Definition: qofnumeric.h:52
qof_numeric_create
static QofNumeric qof_numeric_create(gint64 num, gint64 denom)
Definition: qofnumeric.h:243
query_choice_def
Definition: qofquerycore-p.h:150
qof_query_core_predicate_copy
QofQueryPredData * qof_query_core_predicate_copy(QofQueryPredData *pdata)
Definition: qofquerycore.c:2054
qof_time_equal
gboolean qof_time_equal(const QofTime *ta, const QofTime *tb)
Definition: qoftime.c:148
QofQueryCompare
QofQueryCompare
Definition: qofquerycore.h:51
QofCharMatch
QofCharMatch
Definition: qofquerycore.h:127
QOF_GUID_MATCH_LIST_ANY
Definition: qofquerycore.h:116
QofType
const gchar * QofType
Definition: qofclass.h:150
QOF_GUID_MATCH_ALL
Definition: qofquerycore.h:113
qof_numeric_sub
QofNumeric qof_numeric_sub(QofNumeric a, QofNumeric b, gint64 denom, gint how)
Definition: qofnumeric.c:388
_GUID
Definition: guid.h:53
qof_numeric_to_string
gchar * qof_numeric_to_string(QofNumeric n)
Definition: qofnumeric.c:1089
qof_query_time_predicate_get_time
gboolean qof_query_time_predicate_get_time(QofQueryPredData *pd, QofTime *qt)
Definition: qofquerycore.c:381
qof_numeric_negative_p
gboolean qof_numeric_negative_p(QofNumeric a)
Definition: qofnumeric.c:137
query_kvp_def
Definition: qofquerycore-p.h:135
_QofQueryPredData
Definition: qofquerycore.h:138
PWARN
#define PWARN(format, args...)
Definition: qoflog.h:191
query_coll_def
Definition: qofquerycore-p.h:142
QofTime
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:120
qof_collection_destroy
void qof_collection_destroy(QofCollection *col)
Definition: qofid.c:161
qof_entity_get_guid
const GUID * qof_entity_get_guid(QofEntity *ent)
Definition: qofid.c:105
qof_numeric_positive_p
gboolean qof_numeric_positive_p(QofNumeric a)
Definition: qofnumeric.c:155
QOF_HOW_RND_ROUND
Definition: qofnumeric.h:158
QofDateMatch
QofDateMatch
Definition: qofquerycore.h:78
qof_query_date_predicate
QofQueryPredData * qof_query_date_predicate(QofQueryCompare how, QofDateMatch options, Timespec date)
Definition: qofquerycore.c:1848
qof_query_core_to_string
gchar * qof_query_core_to_string(QofType type, gpointer object, QofParam *getter)
Definition: qofquerycore.c:2066
safe_strcmp
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:72
qof_query_kvp_predicate
QofQueryPredData * qof_query_kvp_predicate(QofQueryCompare how, GSList *path, const KvpValue *value)
Definition: qofquerycore.c:1285
kvp_value_delete
void kvp_value_delete(KvpValue *value)
Definition: kvpframe.c:1361
kvp_frame_get_slot_path_gslist
KvpValue * kvp_frame_get_slot_path_gslist(KvpFrame *frame, GSList *key_path)
Definition: kvpframe.c:1098
timespecCanonicalDayTime
Timespec timespecCanonicalDayTime(Timespec t)
Definition: deprecated.c:348
QOF_TYPE_CHOICE
#define QOF_TYPE_CHOICE
Identify an object as containing a choice.
Definition: qofchoice.h:103
kvp_value_compare
gint kvp_value_compare(const KvpValue *kva, const KvpValue *kvb)
Definition: kvpframe.c:1662
QofNumericMatch
QofNumericMatch
Definition: qofquerycore.h:96
QofLogModule
const gchar * QofLogModule
Definition: qofid.h:85