00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025
00026
00027
00028
00029 #include <stdlib.h>
00030 #include <glib.h>
00031 #include <libxml/parser.h>
00032
00033 #include "qofquery-deserial.h"
00034 #include "qofquery-serialize.h"
00035 #include "qofquery-p.h"
00036 #include "qofquerycore-p.h"
00037 #include "gnc-engine-util.h"
00038
00039
00040
00041 #define GET_TEXT(node) ({ \
00042 char * sstr = NULL; \
00043 xmlNodePtr text; \
00044 text = node->xmlChildrenNode; \
00045 if (text && 0 == strcmp ("text", text->name)) { \
00046 sstr = text->content; \
00047 } \
00048 sstr; \
00049 })
00050
00051 #define GET_STR(SELF,FN,TOK) \
00052 if (0 == strcmp (TOK, node->name)) \
00053 { \
00054 const char *str = GET_TEXT (node); \
00055 FN (SELF, str); \
00056 } \
00057 else
00058
00059 #define GET_DBL(SELF,FN,TOK) \
00060 if (0 == strcmp (TOK, node->name)) \
00061 { \
00062 const char *str = GET_TEXT (node); \
00063 double rate = atof (str); \
00064 FN (SELF, rate); \
00065 } \
00066 else
00067
00068 #define GET_INT32(SELF,FN,TOK) \
00069 if (0 == strcmp (TOK, node->name)) \
00070 { \
00071 const char *str = GET_TEXT (node); \
00072 gint32 ival = atoi (str); \
00073 FN (SELF, ival); \
00074 } \
00075 else
00076
00077 #define GET_INT64(SELF,FN,TOK) \
00078 if (0 == strcmp (TOK, node->name)) \
00079 { \
00080 const char *str = GET_TEXT (node); \
00081 gint64 ival = atoll (str); \
00082 FN (SELF, ival); \
00083 } \
00084 else
00085
00086 #define GET_DATE(SELF,FN,TOK) \
00087 if (0 == strcmp (TOK, node->name)) \
00088 { \
00089 const char *str = GET_TEXT (node); \
00090 Timespec tval = gnc_iso8601_to_timespec_gmt (str); \
00091 FN (SELF, tval); \
00092 } \
00093 else
00094
00095 #define GET_BOOL(SELF,FN,TOK) \
00096 if (0 == strcmp (TOK, node->name)) \
00097 { \
00098 const char *str = GET_TEXT (node); \
00099 gboolean bval = qof_util_bool_to_int (str); \
00100 FN (SELF, bval); \
00101 } \
00102 else
00103
00104 #define GET_NUMERIC(SELF,FN,TOK) \
00105 if (0 == strcmp (TOK, node->name)) \
00106 { \
00107 const char *str = GET_TEXT (node); \
00108 gnc_numeric nval; \
00109 string_to_gnc_numeric (str, &nval); \
00110 FN (SELF, nval); \
00111 } \
00112 else
00113
00114 #define GET_GUID(SELF,FN,TOK) \
00115 if (0 == strcmp (TOK, node->name)) \
00116 { \
00117 const char *str = GET_TEXT (node); \
00118 GUID guid; \
00119 string_to_guid (str, &guid); \
00120 FN (SELF, &guid); \
00121 } \
00122 else
00123
00124 #define GET_HOW(VAL,TOK,A,B,C,D,E,F) \
00125 if (0 == strcmp (TOK, node->name)) \
00126 { \
00127 const char *str = GET_TEXT (node); \
00128 int ival = QOF_COMPARE_##A; \
00129 if (!strcmp (#A, str)) ival = QOF_COMPARE_##A; \
00130 else if (!strcmp (#B, str)) ival = QOF_COMPARE_##B; \
00131 else if (!strcmp (#C, str)) ival = QOF_COMPARE_##C; \
00132 else if (!strcmp (#D, str)) ival = QOF_COMPARE_##D; \
00133 else if (!strcmp (#E, str)) ival = QOF_COMPARE_##E; \
00134 else if (!strcmp (#F, str)) ival = QOF_COMPARE_##F; \
00135 VAL = ival; \
00136 } \
00137 else
00138
00139 #define GET_MATCH2(VAL,TOK,PFX,A,B) \
00140 if (0 == strcmp (TOK, node->name)) \
00141 { \
00142 const char *str = GET_TEXT (node); \
00143 int ival = QOF_##PFX##_##A; \
00144 if (!strcmp (#A, str)) ival = QOF_##PFX##_##A; \
00145 else if (!strcmp (#B, str)) ival = QOF_##PFX##_##B; \
00146 VAL = ival; \
00147 } \
00148 else
00149
00150 #define GET_MATCH3(VAL,TOK,PFX,A,B,C) \
00151 if (0 == strcmp (TOK, node->name)) \
00152 { \
00153 const char *str = GET_TEXT (node); \
00154 int ival = QOF_##PFX##_##A; \
00155 if (!strcmp (#A, str)) ival = QOF_##PFX##_##A; \
00156 else if (!strcmp (#B, str)) ival = QOF_##PFX##_##B; \
00157 else if (!strcmp (#C, str)) ival = QOF_##PFX##_##C; \
00158 VAL = ival; \
00159 } \
00160 else
00161
00162 #define GET_MATCH5(VAL,TOK,PFX,A,B,C,D,E) \
00163 if (0 == strcmp (TOK, node->name)) \
00164 { \
00165 const char *str = GET_TEXT (node); \
00166 int ival = QOF_##PFX##_##A; \
00167 if (!strcmp (#A, str)) ival = QOF_##PFX##_##A; \
00168 else if (!strcmp (#B, str)) ival = QOF_##PFX##_##B; \
00169 else if (!strcmp (#C, str)) ival = QOF_##PFX##_##C; \
00170 else if (!strcmp (#D, str)) ival = QOF_##PFX##_##D; \
00171 else if (!strcmp (#E, str)) ival = QOF_##PFX##_##E; \
00172 VAL = ival; \
00173 } \
00174 else
00175
00176
00177
00178
00179 #define SIMPLE_PRED_HANDLER(SUBRNAME,CTYPE,GETTER,XMLTYPE,PRED) \
00180 static QofQueryPredData * \
00181 SUBRNAME (xmlNodePtr root) \
00182 { \
00183 QofQueryPredData *pred; \
00184 xmlNodePtr xp; \
00185 xmlNodePtr node; \
00186 QofQueryCompare how; \
00187 CTYPE val; \
00188 xp = root->xmlChildrenNode; \
00189 \
00190 how = QOF_COMPARE_EQUAL; \
00191 val = 0; \
00192 \
00193 for (node=xp; node; node = node->next) \
00194 { \
00195 if (node->type != XML_ELEMENT_NODE) continue; \
00196 \
00197 GET_HOW (how, "qofquery:compare", LT, LTE, EQUAL, GT, GTE, NEQ); \
00198 GETTER (0, val=, XMLTYPE); \
00199 {} \
00200 } \
00201 \
00202 pred = PRED (how, val); \
00203 return pred; \
00204 }
00205
00206 SIMPLE_PRED_HANDLER (qof_query_pred_double_from_xml,
00207 double, GET_DBL, "qofquery:double", qof_query_double_predicate);
00208
00209 SIMPLE_PRED_HANDLER (qof_query_pred_int64_from_xml,
00210 gint64, GET_INT64, "qofquery:int64", qof_query_int64_predicate);
00211
00212 SIMPLE_PRED_HANDLER (qof_query_pred_int32_from_xml,
00213 gint32, GET_INT32, "qofquery:int32", qof_query_int32_predicate);
00214
00215 SIMPLE_PRED_HANDLER (qof_query_pred_boolean_from_xml,
00216 gboolean, GET_BOOL, "qofquery:boolean", qof_query_boolean_predicate);
00217
00218
00219
00220 static void
00221 wrap_new_gint64 (KvpValue ** v, gint64 value)
00222 {
00223 *v = kvp_value_new_gint64 (value);
00224 }
00225 static void
00226 wrap_new_double (KvpValue ** v, double value)
00227 {
00228 *v = kvp_value_new_double (value);
00229 }
00230 static void
00231 wrap_new_numeric (KvpValue ** v, gnc_numeric value)
00232 {
00233 *v = kvp_value_new_gnc_numeric (value);
00234 }
00235 static void
00236 wrap_new_string (KvpValue ** v, const char *value)
00237 {
00238 *v = kvp_value_new_string (value);
00239 }
00240 static void
00241 wrap_new_guid (KvpValue ** v, const GUID * value)
00242 {
00243 *v = kvp_value_new_guid (value);
00244 }
00245 static void
00246 wrap_new_timespec (KvpValue ** v, Timespec value)
00247 {
00248 *v = kvp_value_new_timespec (value);
00249 }
00250
00251
00252 static QofQueryPredData *
00253 qof_query_pred_kvp_from_xml (xmlNodePtr root)
00254 {
00255 QofQueryCompare how;
00256 GSList *path;
00257 KvpValue *value;
00258 QofQueryPredData *pred;
00259 xmlNodePtr xp;
00260 xmlNodePtr node;
00261
00262 how = QOF_COMPARE_EQUAL;
00263 xp = root->xmlChildrenNode;
00264 path = NULL;
00265 value = NULL;
00266
00267 for (node = xp; node; node = node->next)
00268 {
00269 if (node->type != XML_ELEMENT_NODE)
00270 continue;
00271
00272 GET_HOW (how, "qofquery:compare", LT, LTE, EQUAL, GT, GTE, NEQ);
00273 if (0 == strcmp ("qofquery:kvp-path", node->name))
00274 {
00275 const char *str = GET_TEXT (node);
00276 path = g_slist_append (path, (gpointer) str);
00277 }
00278 else
00279 GET_INT64 (&value, wrap_new_gint64, "qofquery:int64");
00280 GET_DBL (&value, wrap_new_double, "qofquery:double");
00281 GET_NUMERIC (&value, wrap_new_numeric, "qofquery:numeric");
00282 GET_STR (&value, wrap_new_string, "qofquery:string");
00283 GET_GUID (&value, wrap_new_guid, "qofquery:guid");
00284 GET_DATE (&value, wrap_new_timespec, "qofquery:date");
00285 }
00286
00287 pred = qof_query_kvp_predicate (how, path, value);
00288 g_slist_free (path);
00289 return pred;
00290 }
00291
00292
00293
00294 static QofQueryPredData *
00295 qof_query_pred_guid_from_xml (xmlNodePtr root)
00296 {
00297 GList *guid_list, *n;
00298 const char *str;
00299 GUID *guid;
00300 gboolean decode;
00301 QofQueryPredData *pred;
00302 QofGuidMatch sm;
00303 xmlNodePtr xp;
00304 xmlNodePtr node;
00305 guid_list = NULL;
00306
00307 sm = QOF_GUID_MATCH_ANY;
00308 xp = root->xmlChildrenNode;
00309 for (node = xp; node; node = node->next)
00310 {
00311 if (node->type != XML_ELEMENT_NODE)
00312 continue;
00313
00314
00315 GET_MATCH5 (sm, "qofquery:guid-match",
00316 GUID_MATCH, ANY, NONE, NULL, ALL, LIST_ANY);
00317
00318 if (0 == strcmp ("qofquery:guid", node->name))
00319 {
00320 str = GET_TEXT (node);
00321 guid = guid_malloc ();
00322 decode = string_to_guid (str, guid);
00323 if (decode)
00324 {
00325 guid_list = g_list_append (guid_list, guid);
00326 }
00327 else
00328 {
00329 guid_free (guid);
00330
00331 }
00332 }
00333 }
00334
00335 pred = qof_query_guid_predicate (sm, guid_list);
00336
00337
00338 for (n = guid_list; n; n = n->next)
00339 {
00340 guid_free (n->data);
00341 }
00342 g_list_free (guid_list);
00343 return pred;
00344 }
00345
00346
00347
00348 static QofQueryPredData *
00349 qof_query_pred_char_from_xml (xmlNodePtr root)
00350 {
00351 QofQueryPredData *pred;
00352 QofCharMatch sm;
00353 const char *char_list;
00354 xmlNodePtr xp;
00355 xmlNodePtr node;
00356
00357 char_list = NULL;
00358 xp = root->xmlChildrenNode;
00359 sm = QOF_CHAR_MATCH_ANY;
00360
00361 for (node = xp; node; node = node->next)
00362 {
00363 if (node->type != XML_ELEMENT_NODE)
00364 continue;
00365
00366
00367 GET_MATCH2 (sm, "qofquery:char-match", CHAR_MATCH, ANY, NONE);
00368 GET_STR (0, char_list =, "qofquery:char-list");
00369 {
00370 }
00371 }
00372
00373 pred = qof_query_char_predicate (sm, char_list);
00374 return pred;
00375 }
00376
00377
00378
00379 static QofQueryPredData *
00380 qof_query_pred_numeric_from_xml (xmlNodePtr root)
00381 {
00382 QofQueryPredData *pred;
00383 xmlNodePtr node;
00384 QofQueryCompare how;
00385 QofNumericMatch sm;
00386 gnc_numeric num;
00387 xmlNodePtr xp;
00388
00389 xp = root->xmlChildrenNode;
00390 how = QOF_COMPARE_EQUAL;
00391 sm = QOF_NUMERIC_MATCH_ANY;
00392
00393 for (node = xp; node; node = node->next)
00394 {
00395 if (node->type != XML_ELEMENT_NODE)
00396 continue;
00397
00398 GET_HOW (how, "qofquery:compare", LT, LTE, EQUAL, GT, GTE, NEQ);
00399 GET_MATCH3 (sm, "qofquery:numeric-match",
00400 NUMERIC_MATCH, DEBIT, CREDIT, ANY);
00401 GET_NUMERIC (0, num =, "qofquery:numeric");
00402 {
00403 }
00404 }
00405
00406 pred = qof_query_numeric_predicate (how, sm, num);
00407 return pred;
00408 }
00409
00410
00411
00412 static QofQueryPredData *
00413 qof_query_pred_date_from_xml (xmlNodePtr root)
00414 {
00415 xmlNodePtr xp;
00416 xmlNodePtr node;
00417 QofQueryCompare how;
00418 QofDateMatch sm;
00419 Timespec date;
00420 QofQueryPredData *pred;
00421
00422 xp = root->xmlChildrenNode;
00423
00424 how = QOF_COMPARE_EQUAL;
00425 sm = QOF_DATE_MATCH_DAY;
00426 date = (Timespec)
00427 {
00428 0, 0};
00429
00430 for (node = xp; node; node = node->next)
00431 {
00432 if (node->type != XML_ELEMENT_NODE)
00433 continue;
00434
00435 GET_HOW (how, "qofquery:compare", LT, LTE, EQUAL, GT, GTE, NEQ);
00436 GET_MATCH2 (sm, "qofquery:date-match", DATE_MATCH, NORMAL, DAY);
00437 GET_DATE (0, date =, "qofquery:date");
00438 {
00439 }
00440 }
00441
00442 pred = qof_query_date_predicate (how, sm, date);
00443 return pred;
00444 }
00445
00446
00447
00448 static QofQueryPredData *
00449 qof_query_pred_string_from_xml (xmlNodePtr root)
00450 {
00451 QofQueryPredData *pred;
00452 xmlNodePtr xp;
00453 xmlNodePtr node;
00454 QofQueryCompare how;
00455 QofStringMatch sm;
00456 gboolean is_regex;
00457 const char *pstr;
00458
00459 xp = root->xmlChildrenNode;
00460 how = QOF_COMPARE_EQUAL;
00461 sm = QOF_STRING_MATCH_CASEINSENSITIVE;
00462 is_regex = FALSE;
00463 pstr = NULL;
00464
00465 for (node = xp; node; node = node->next)
00466 {
00467 if (node->type != XML_ELEMENT_NODE)
00468 continue;
00469
00470 GET_HOW (how, "qofquery:compare", LT, LTE, EQUAL, GT, GTE, NEQ);
00471 GET_BOOL (0, is_regex =, "qofquery:is-regex");
00472 GET_STR (0, pstr =, "qofquery:string");
00473 GET_MATCH2 (sm, "qofquery:string-match",
00474 STRING_MATCH, NORMAL, CASEINSENSITIVE);
00475 {
00476 }
00477 }
00478 pred = qof_query_string_predicate (how, pstr, sm, is_regex);
00479 return pred;
00480 }
00481
00482
00483
00484 static GSList *
00485 qof_query_param_path_from_xml (xmlNodePtr root)
00486 {
00487 xmlNodePtr pterms;
00488 GSList *plist;
00489 xmlNodePtr node;
00490
00491 pterms = root->xmlChildrenNode;
00492 plist = NULL;
00493 for (node = pterms; node; node = node->next)
00494 {
00495 if (node->type != XML_ELEMENT_NODE)
00496 continue;
00497
00498 if (0 == strcmp (node->name, "qofquery:param"))
00499 {
00500 const char *str = GET_TEXT (node);
00501 plist = g_slist_append (plist, CACHE_INSERT (str));
00502 }
00503 }
00504 return plist;
00505 }
00506
00507
00508
00509 static void
00510 qof_query_term_from_xml (QofQuery * q, xmlNodePtr root)
00511 {
00512 xmlNodePtr node;
00513 xmlNodePtr term;
00514 QofQueryPredData *pred;
00515 GSList *path;
00516 QofQuery *qt;
00517 QofQuery *qinv;
00518
00519 pred = NULL;
00520 path = NULL;
00521 term = root->xmlChildrenNode;
00522 for (node = term; node; node = node->next)
00523 {
00524 if (node->type != XML_ELEMENT_NODE)
00525 continue;
00526 if (0 == strcmp (node->name, "qofquery:invert"))
00527 {
00528 qt = qof_query_create ();
00529 qof_query_term_from_xml (qt, node);
00530 qinv = qof_query_invert (qt);
00531 qof_query_merge_in_place (q, qinv, QOF_QUERY_AND);
00532 qof_query_destroy (qinv);
00533 qof_query_destroy (qt);
00534 return;
00535 }
00536 else if (0 == strcmp (node->name, "qofquery:param-path"))
00537 {
00538 path = qof_query_param_path_from_xml (node);
00539 }
00540 else if (0 == strcmp (node->name, "qofquery:pred-string"))
00541 {
00542 pred = qof_query_pred_string_from_xml (node);
00543 }
00544 else if (0 == strcmp (node->name, "qofquery:pred-date"))
00545 {
00546 pred = qof_query_pred_date_from_xml (node);
00547 }
00548 else if (0 == strcmp (node->name, "qofquery:pred-numeric"))
00549 {
00550 pred = qof_query_pred_numeric_from_xml (node);
00551 }
00552 else if (0 == strcmp (node->name, "qofquery:pred-int32"))
00553 {
00554 pred = qof_query_pred_int32_from_xml (node);
00555 }
00556 else if (0 == strcmp (node->name, "qofquery:pred-int64"))
00557 {
00558 pred = qof_query_pred_int64_from_xml (node);
00559 }
00560 else if (0 == strcmp (node->name, "qofquery:pred-double"))
00561 {
00562 pred = qof_query_pred_double_from_xml (node);
00563 }
00564 else if (0 == strcmp (node->name, "qofquery:pred-boolean"))
00565 {
00566 pred = qof_query_pred_boolean_from_xml (node);
00567 }
00568 else if (0 == strcmp (node->name, "qofquery:pred-char"))
00569 {
00570 pred = qof_query_pred_char_from_xml (node);
00571 }
00572 else if (0 == strcmp (node->name, "qofquery:pred-guid"))
00573 {
00574 pred = qof_query_pred_guid_from_xml (node);
00575 }
00576 else if (0 == strcmp (node->name, "qofquery:pred-kvp"))
00577 {
00578 pred = qof_query_pred_kvp_from_xml (node);
00579 }
00580 else
00581 {
00582
00583 }
00584 }
00585
00586
00587 qof_query_add_term (q, path, pred, QOF_QUERY_AND);
00588 }
00589
00590
00591
00592 static void
00593 qof_query_and_terms_from_xml (QofQuery * q, xmlNodePtr root)
00594 {
00595 xmlNodePtr andterms;
00596 xmlNodePtr node;
00597
00598 andterms = root->xmlChildrenNode;
00599 for (node = andterms; node; node = node->next)
00600 {
00601 if (node->type != XML_ELEMENT_NODE)
00602 continue;
00603
00604 if (0 == strcmp (node->name, "qofquery:term"))
00605 {
00606 qof_query_term_from_xml (q, node);
00607 }
00608 }
00609 }
00610
00611
00612
00613 static void
00614 qof_query_or_terms_from_xml (QofQuery * q, xmlNodePtr root)
00615 {
00616 xmlNodePtr andterms;
00617 xmlNodePtr node;
00618 QofQuery *qand;
00619
00620 andterms = root->xmlChildrenNode;
00621 for (node = andterms; node; node = node->next)
00622 {
00623 if (node->type != XML_ELEMENT_NODE)
00624 continue;
00625
00626 if (0 == strcmp (node->name, "qofquery:and-terms"))
00627 {
00628 qand = qof_query_create ();
00629 qof_query_and_terms_from_xml (qand, node);
00630 qof_query_merge_in_place (q, qand, QOF_QUERY_OR);
00631 qof_query_destroy (qand);
00632 }
00633 }
00634 }
00635
00636
00637
00638 QofQuery *
00639 qof_query_from_xml (xmlNodePtr root)
00640 {
00641 QofQuery *q;
00642 xmlChar *version;
00643 xmlNodePtr qpart;
00644 xmlNodePtr node;
00645
00646 if (!root)
00647 return NULL;
00648
00649 version = xmlGetProp (root, "version");
00650 if (!root->name || strcmp ("qof:qofquery", root->name))
00651 {
00652
00653 return NULL;
00654 }
00655
00656 q = qof_query_create ();
00657
00658 qpart = root->xmlChildrenNode;
00659 for (node = qpart; node; node = node->next)
00660 {
00661 if (node->type != XML_ELEMENT_NODE)
00662 continue;
00663
00664 GET_STR (q, qof_query_search_for, "qofquery:search-for");
00665 GET_INT32 (q, qof_query_set_max_results, "qofquery:max-results");
00666 if (0 == strcmp (node->name, "qofquery:or-terms"))
00667 {
00668 qof_query_or_terms_from_xml (q, node);
00669 }
00670 else if (0 == strcmp (node->name, "qofquery:sort-list"))
00671 {
00672
00673 }
00674 else
00675 {
00676
00677 }
00678 }
00679
00680 return q;
00681 }
00682
00683
00684
00685 #ifdef UNIT_TEST
00686
00687 #include <stdio.h>
00688 #include <qof/qofsql.h>
00689
00690 int
00691 main (int argc, char *argv[])
00692 {
00693 QofQuery *q, *qnew;
00694 QofSqlQuery *sq;
00695 xmlNodePtr topnode;
00696
00697 guid_init ();
00698 qof_query_init ();
00699 qof_object_initialize ();
00700
00701 static QofParam params[] = {
00702 {"adate", QOF_TYPE_DATE, NULL, NULL},
00703 {"aint", QOF_TYPE_INT32, NULL, NULL},
00704 {"aint64", QOF_TYPE_INT64, NULL, NULL},
00705 {"aflt", QOF_TYPE_DOUBLE, NULL, NULL},
00706 {"abool", QOF_TYPE_BOOLEAN, NULL, NULL},
00707 {"astr", QOF_TYPE_STRING, NULL, NULL},
00708 {"adate", QOF_TYPE_DATE, NULL, NULL},
00709 {"anum", QOF_TYPE_NUMERIC, NULL, NULL},
00710 {"achar", QOF_TYPE_CHAR, NULL, NULL},
00711 {"aguid", QOF_TYPE_GUID, NULL, NULL},
00712 {"akvp", QOF_TYPE_KVP, NULL, NULL},
00713 {NULL},
00714 };
00715
00716 qof_class_register ("GncABC", NULL, params);
00717 sq = qof_sql_query_new ();
00718
00719 qof_sql_query_parse (sq,
00720 "SELECT * from GncABC WHERE aint = 123 "
00721 "and not aint64 = 6123123456789 "
00722 "or abool = TRUE "
00723 "and not aflt >= \'3.14159265358979\' "
00724 "and not astr=\'asdf\' "
00725 "and adate<\'01-01-01\' "
00726 "or anum<\'12301/100\' "
00727 "or achar != asdf "
00728 "and aguid != abcdef01234567890fedcba987654321 "
00729 "and akvp != \'/some/path:abcdef01234567890fedcba987654321\' "
00730 "and not akvp != \'/some/path/glop:1234\' "
00731 "and akvp = \'/arf/arf/arf:10.234\' "
00732 "and akvp != \'/some/other/path:qwerty1234uiop\' "
00733 "and not akvp = \'/some/final/path:123401/100\' ");
00734
00735 q = qof_sql_query_get_query (sq);
00736
00737 qof_query_print (q);
00738
00739 xmlNodePtr topnode = qof_query_to_xml (q);
00740
00741 qnew = qof_query_from_xml (topnode);
00742 printf
00743 (" ------------------------------------------------------- \n");
00744 qof_query_print (qnew);
00745
00746
00747 gboolean eq = qof_query_equal (q, qnew);
00748 printf ("Are the two equal? answer=%d\n", eq);
00749
00750 #define DOPRINT 1
00751 #ifdef DOPRINT
00752 xmlDocPtr doc = doc = xmlNewDoc ("1.0");
00753 xmlDocSetRootElement (doc, topnode);
00754
00755 xmlChar *xbuf;
00756 int bufsz;
00757 xmlDocDumpFormatMemory (doc, &xbuf, &bufsz, 1);
00758
00759 printf ("%s\n", xbuf);
00760 xmlFree (xbuf);
00761 xmlFreeDoc (doc);
00762 #endif
00763
00764 return 0;
00765 }
00766
00767 #endif
00768
00769