qofquery-deserial.c

00001 /********************************************************************\
00002  * qofquery-deserial.c -- Convert Qof-Query XML to QofQuery         *
00003  * Copyright (C) 2001,2002,2004 Linas Vepstas <linas@linas.org>     *
00004  *                                                                  *
00005  * This program is free software; you can redistribute it and/or    *
00006  * modify it under the terms of the GNU General Public License as   *
00007  * published by the Free Software Foundation; either version 2 of   *
00008  * the License, or (at your option) any later version.              *
00009  *                                                                  *
00010  * This program is distributed in the hope that it will be useful,  *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00013  * GNU General Public License for more details.                     *
00014  *                                                                  *
00015  * You should have received a copy of the GNU General Public License*
00016  * along with this program; if not, contact:                        *
00017  *                                                                  *
00018  * Free Software Foundation           Voice:  +1-617-542-5942       *
00019  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00020  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00021  *                                                                  *
00022 \********************************************************************/
00023 
00024 #include "config.h"
00025 
00026 /* NOTE: Development of this idea has ceased and this file is
00027 no longer built into the QOF library. It remains in CVS until libqof2.*/
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 /* Autogen the code for the simple, repetitive predicates */
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         /* char pred doesn't have GET_HOW */
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                 // XXX error!  let someone know!
00331             }
00332         }
00333     }
00334 
00335     pred = qof_query_guid_predicate (sm, guid_list);
00336 
00337     /* The predicate made a copy of everything, so free our stuff */
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         /* char pred doesn't have GET_HOW */
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             // warning unhandled predicate type
00583         }
00584     }
00585 
00586     /* At this level, the terms should always be anded */
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         // XXX something is wrong. warn ... 
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 // XXX unfinished  I'm bored
00673         }
00674         else
00675         {
00676             // XXX unknown node type tell someone about it
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     // qof_sql_query_parse (sq, "SELECT * from GncABC;");
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     /* If the before and after trees are the same, the test pases. */
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 /* UNIT_TEST */
00768 
00769 /* ======================== END OF FILE =================== */

Generated on Thu Jan 31 22:50:26 2008 for QOF by  doxygen 1.5.4