Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

d_xpath_f.c

Go to the documentation of this file.
00001 
00078 /* GtkSQL -- an interactive graphical query tool for PostgreSQL, MySQL and XPath.
00079  * Copyright (C) 2003 Darryl Luff
00080  *
00081  * This program is free software; you can redistribute it and/or modify
00082  * it under the terms of the GNU General Public License as published by
00083  * the Free Software Foundation; either version 2 of the License, or
00084  * (at your option) any later version.
00085  *
00086  * This program is distributed in the hope that it will be useful,
00087  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00088  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00089  * GNU General Public License for more details.
00090  *
00091  * You should have received a copy of the GNU General Public License
00092  * along with this program; if not, write to the Free Software
00093  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00094  */
00095 
00096 #include "../config.h"
00097 
00098 #ifdef USE_XPATH
00099 
00100 #include <libxml/xmlmemory.h>
00101 #include <libxml/parser.h>
00102 #include <libxml/tree.h>
00103 #include <libxml/xpath.h>
00104 #include "buf.h"
00105 #include "dbapi.h"
00106 
00108 #define XMLFILE "XML File"
00109 
00111 enum {
00112     FLD_TYPE = 0,       
00113     FLD_NAME,           
00114     FLD_ATTRIB,         
00115     FLD_CONTENT         
00116 } FldTypes;
00117 
00119 #define FLD_COUNT   4
00120 
00122 typedef struct {
00123     /* table fields. These should be in the common part. */
00124     int tableCount;             
00125     DBTableDef *tableDef;       
00126     xmlDocPtr doc;              
00127     char *filename;             
00128     xmlXPathObjectPtr result;   
00129     int status;                 
00130     char *errmsg;               
00131 } DBConnection_XPath;
00132 
00134 static char *xpathKeywords[] = {
00135     "SELECT",
00136     NULL
00137 };
00138 
00142 void *xpath_query(DBConnection * dbc, char *xpstr)
00143 {
00144     DBConnection_XPath *dbcxp;
00145     xmlXPathContextPtr context;
00146     if (!dbc)
00147         return NULL;
00148 
00149     if (!dbc->pvt)
00150         return NULL;
00151 
00152     dbcxp = (DBConnection_XPath *) (dbc->pvt);
00153     dbcxp->status = DB_QUERY_RECORDS_OK;
00154 
00155     if (!dbcxp->doc) {
00156         dbcxp->status = DB_QUERY_ERROR;
00157         return NULL;
00158     }
00159 
00160     if (dbcxp->result) {
00161         printf("WARNING: Result already exists.\n");
00162         xmlXPathFreeObject(dbcxp->result);
00163     }
00164 
00165     context = xmlXPathNewContext(dbcxp->doc);
00166     dbcxp->result = xmlXPathEvalExpression(xpstr, context);
00167 
00168     if (xmlXPathNodeSetIsEmpty(dbcxp->result->nodesetval)) {
00169         dbcxp->status = DB_QUERY_EMPTY;
00170         printf("No result\n");
00171     }
00172 
00173     xmlXPathFreeContext(context);
00174     return dbcxp->result;
00175 }
00176 
00180 DBConnection *xpath_dbconnection_free(DBConnection * c)
00181 {
00182     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00183     free(dbxpath->filename);
00184 
00185     /* Clear Keywords memory */
00186     keywords_remove_all(c);
00187 
00188     /* Free structure memory */
00189     free(dbxpath);
00190     free(c);
00191     return NULL;
00192 }
00193 
00196 char *xpath_error()
00197 {
00198     g_warning("xpath_error() not implemented\n");
00199     return "Not implemented";
00200 }
00201 
00205 static void xp_DBclear_result(DBConnection * c, void *result)
00206 {
00207     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00208     if (!dbxpath)
00209         return;
00210 
00211     if (dbxpath->result) {
00212         xmlXPathFreeObject(dbxpath->result);
00213         dbxpath->result = NULL;
00214     }
00215 }
00216 
00220 static int xp_DBdisconnect(DBConnection * c)
00221 {
00222     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00223 
00224     /* End connection */
00225     xp_DBclear_result(c, NULL);
00226     if (dbxpath->doc) {
00227         xmlFreeDoc(dbxpath->doc);
00228         dbxpath->doc = NULL;
00229     }
00230     return 0;
00231 }
00232 
00236 static char *xp_DBget_error_message(DBConnection * c)
00237 {
00238     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00239     if (!dbxpath)
00240         return "Connection invalid";
00241 
00242     return xpath_error(dbxpath->filename);
00243 }
00244 
00248 static char *xp_DBget_db_name(DBConnection * c)
00249 {
00250     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00251     if (!dbxpath)
00252         return NULL;
00253     return dbxpath->filename;
00254 }
00255 
00260 static void *xp_DBexecute_query(DBConnection * c, char *query)
00261 {
00262     return xpath_query(c, query);
00263 }
00264 
00270 static int xp_DBget_query_status(DBConnection * c, void *result)
00271 {
00272     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00273     if (!dbxpath)
00274         return DB_QUERY_ERROR;
00275 
00276     return dbxpath->status;
00277 }
00278 
00283 static int xp_DBget_record_number(DBConnection * c, void *result)
00284 {
00285     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00286     if (!dbxpath)
00287         return 0;
00288 
00289     if (!dbxpath->result)
00290         return 0;
00291 
00292     if (!dbxpath->result->nodesetval)
00293         return 0;
00294 
00295     return dbxpath->result->nodesetval->nodeNr;
00296 }
00297 
00302 static int xp_DBget_field_number(DBConnection * c, void *result)
00303 {
00304     return FLD_COUNT;
00305 }
00306 
00311 static char *xp_DBget_field_name(DBConnection * c, void *result, int field)
00312 {
00313     switch (field) {
00314     case FLD_TYPE:
00315         return "Type";
00316     case FLD_NAME:
00317         return "Name";
00318     case FLD_ATTRIB:
00319         return "Attributes";
00320     case FLD_CONTENT:
00321         return "Content";
00322     }
00323     return "";
00324 }
00325 
00329 char *xp_DBget_field_value_type(xmlNodePtr node)
00330 {
00331     if (! node)
00332         return "";
00333 
00334     switch (node->type) {
00335         case XML_ELEMENT_NODE:
00336             return "NODE";
00337         case XML_ATTRIBUTE_NODE:
00338             return "ATTRIBUTE";
00339         case XML_TEXT_NODE:
00340             return "TEXT";
00341         case XML_CDATA_SECTION_NODE:
00342             return "CDATA";
00343         case XML_ENTITY_REF_NODE:
00344             return "ENTITY_REF";
00345         case XML_ENTITY_NODE:
00346             return "ENTITY";
00347         case XML_PI_NODE:
00348             return "PI";
00349         case XML_COMMENT_NODE:
00350             return "COMMENT";
00351         case XML_DOCUMENT_NODE:
00352             return "DOCUMENT";
00353         case XML_DOCUMENT_TYPE_NODE:
00354             return "DOCUMENT_TYPE";
00355         case XML_DOCUMENT_FRAG_NODE:
00356             return "DOCUMENT_FRAG";
00357         case XML_NOTATION_NODE:
00358             return "NOTATION";
00359         case XML_HTML_DOCUMENT_NODE:
00360             return "HTML_DOCUMENT";
00361         case XML_DTD_NODE:
00362             return "DTD";
00363         case XML_ELEMENT_DECL:
00364             return "ELEMENT_DECL";
00365         case XML_ATTRIBUTE_DECL:
00366             return "ATTRIBUTE_DECL";
00367         case XML_ENTITY_DECL:
00368             return "ENTITY_DECL";
00369         case XML_NAMESPACE_DECL:
00370             return "NAMESPACE_DECL";
00371         case XML_XINCLUDE_START:
00372             return "XINCLUDE_START";
00373         case XML_XINCLUDE_END:
00374             return "XINCLUDE_END";
00375         case XML_DOCB_DOCUMENT_NODE:
00376             return "DOCB_DOCUMENT";
00377         default:
00378             return "";
00379         }
00380 }
00381 
00383 static ABuf *contentbuf = NULL;
00384 static ABuf *attrbuf = NULL;
00385 
00389 char *xp_DBget_field_value_attrib(xmlNodePtr node) {
00390     xmlAttrPtr attr = NULL;
00391     xmlChar *txt;
00392     xmlNodePtr cur;
00393 
00394     if (! node)
00395         return "";
00396 
00397     cur = node;
00398     if (! cur)
00399         return "NIL: cur is NULL";
00400 
00401     attrbuf = buf_check(attrbuf, 1024);
00402     attrbuf = buf_strcpy(attrbuf, "");
00403 
00404     /* \todo Havent figured attributes out yet. The documentation isn't
00405      * very complete. Have to grab the libxml source. */
00406     attr = cur->properties;
00407     if (attr == NULL)
00408         attr = cur;
00409     
00410         //attrbuf = buf_strcat(attrbuf, "NIL: attr is NULL");
00411 
00412     while (attr != NULL) {
00413         if (attr->name)
00414             attrbuf = buf_strcat(attrbuf, (char *)attr->name);
00415         else
00416             attrbuf = buf_strcat(attrbuf, "NULL");
00417 
00418         attrbuf = buf_strcat(attrbuf, "=\"");
00419         txt = xmlNodeListGetString(node->doc, attr->children, 1);
00420         if (txt != NULL)
00421             attrbuf = buf_strcat(attrbuf, txt);
00422 
00423         attrbuf = buf_strcat(attrbuf, "\" ");
00424         attr = attr->next;
00425     }
00426     return attrbuf->b_dat;
00427 }
00428 
00432 char *xp_DBget_field_value_content(xmlNodePtr node) {
00433     xmlNodePtr child = NULL;
00434 
00435     if (! node)
00436         return "";
00437 
00438     switch (node->type) {
00439         case XML_ELEMENT_NODE:
00440             child = node->children;
00441             contentbuf = buf_strcpy(contentbuf, "");
00442             while (child) {
00443                 if (!strcmp(child->name, "text"))
00444                     contentbuf = buf_strcat(contentbuf, trimtext(child->content));
00445                 child = child->next;
00446             }
00447             return contentbuf->b_dat;
00448         case XML_ATTRIBUTE_NODE:
00449             return "ATTRIBUTE";
00450         case XML_TEXT_NODE:
00451             return "TEXT";
00452         case XML_CDATA_SECTION_NODE:
00453             return "CDATA";
00454         case XML_ENTITY_REF_NODE:
00455             return "ENTITY_REF";
00456         case XML_ENTITY_NODE:
00457             return "ENTITY";
00458         case XML_PI_NODE:
00459             return "PI";
00460         case XML_COMMENT_NODE:
00461             return "COMMENT";
00462         case XML_DOCUMENT_NODE:
00463             return "DOCUMENT";
00464         case XML_DOCUMENT_TYPE_NODE:
00465             return "DOCUMENT_TYPE";
00466         case XML_DOCUMENT_FRAG_NODE:
00467             return "DOCUMENT_FRAG";
00468         case XML_NOTATION_NODE:
00469             return "NOTATION";
00470         case XML_HTML_DOCUMENT_NODE:
00471             return "HTML_DOCUMENT";
00472         case XML_DTD_NODE:
00473             return "DTD";
00474         case XML_ELEMENT_DECL:
00475             return "ELEMENT_DECL";
00476         case XML_ATTRIBUTE_DECL:
00477             return "ATTRIBUTE_DECL";
00478         case XML_ENTITY_DECL:
00479             return "ENTITY_DECL";
00480         case XML_XINCLUDE_START:
00481             return "XINCLUDE_START";
00482         case XML_XINCLUDE_END:
00483             return "XINCLUDE_END";
00484         case XML_DOCB_DOCUMENT_NODE:
00485             return "DOCB_DOCUMENT";
00486         default:
00487             return "";
00488     }
00489 }
00490 
00497 static char *xp_DBget_field_value(DBConnection * c, void *result, int record,
00498                                   int field)
00499 {
00500     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00501     xmlNodePtr node = NULL;
00502 
00503     int rows = 0;
00504 
00505     if (!dbxpath)
00506         return "";
00507 
00508     if (!dbxpath->result)
00509         return "";
00510 
00511     if (!dbxpath->result->nodesetval)
00512         return "";
00513 
00514     rows = dbxpath->result->nodesetval->nodeNr;
00515     if (record >= rows)
00516         return "";
00517 
00518     node = dbxpath->result->nodesetval->nodeTab[record];
00519     if (!node)
00520         return "";
00521 
00522     /* Support four fields here, field 0 = type, field 1 = name, field 2 =
00523      * attributes, field 3 = contents */
00524     switch (field) {
00525     case FLD_TYPE:      return xp_DBget_field_value_type(node);
00526     case FLD_NAME:      return (char *)node->name;
00527     case FLD_ATTRIB:    return xp_DBget_field_value_attrib(node);
00528     case FLD_CONTENT:   return xp_DBget_field_value_content(node);
00529     default:
00530         return "";
00531     }
00532 }
00533 
00538 void xp_DBurl_to_form(Form *frm, char *url) {
00539     char *u;
00540     char *p;
00541     char *start;
00542 
00543     /* Clear the login parms    */
00544     frm_clear_fields(frm);
00545 
00546     if (url == NULL)
00547         return;
00548 
00549     u = strdup(url);
00550     start = u;
00551 
00552     /* Look for '://'   */
00553     p = strstr(start, "://");
00554     if (p != NULL) {
00555         p += 3;
00556 
00557         /* Set filename */
00558         frm_set_value_by_name(frm, XMLFILE, p);
00559     }
00560     free(u);
00561 }
00562 
00567 static int xp_add_field_def(DBConnection * c, DBTableDef * tbf)
00568 {
00569     int i;
00570     char *fname;
00571     char *rtype, *rnotnull, *rhasdef;
00572 
00573     tbf->field_num = FLD_COUNT;
00574     tbf->field_def =
00575         (DBFieldDef *) malloc(tbf->field_num * sizeof(DBFieldDef));
00576 
00577     for (i = 0; i < tbf->field_num; i++) {
00578         switch (i) {
00579         case FLD_TYPE:
00580             fname = "Type";
00581             break;
00582         case FLD_NAME:
00583             fname = "Name";
00584             break;
00585         case FLD_ATTRIB:
00586             fname = "Atrib";
00587             break;
00588         case FLD_CONTENT:
00589             fname = "Content";
00590             break;
00591         default:
00592             fname = "";
00593         }
00594         add_keyword(c, fname, KEYWORD_FIELD);
00595         rtype = "int";
00596         rnotnull = "NO";
00597         rhasdef = "";
00598 
00599         /* allocate type_str */
00600         tbf->field_def[i].name = g_strdup(fname);
00601         tbf->field_def[i].type = g_strdup("varchar(255)");
00602         tbf->field_def[i].length = g_strdup("??");
00603     }
00604     return 0;
00605 }
00606 
00611 static int xp_DBget_table_def(DBConnection * c)
00612 {
00613     int tables_in_list = 1;
00614 
00615     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00616 
00617     if (dbxpath->tableDef != NULL) {
00618         fprintf(stderr, "Internal error (memory leak)...\n");
00619         return -1;
00620     }
00621 
00622     /* Allocating table array */
00623     dbxpath->tableCount = 1;
00624     dbxpath->tableDef =
00625         (DBTableDef *) malloc(tables_in_list * sizeof(DBTableDef));
00626 
00627     /* Fill the table */
00628 
00629     /* Table name */
00630     dbxpath->tableDef[0].name = g_strdup("Dummy");
00631 
00632     /* Table fields */
00633     if (xp_add_field_def(c, dbxpath->tableDef + 0) < 0) {
00634         dbxpath->tableDef = NULL;
00635         return -1;
00636     }
00637 
00638     /* Keywords */
00639     // add_keyword(c, table_name, KEYWORD_TABLE);
00640     return 0;
00641 }
00642 
00643 static ABuf *f2ubuf = NULL;
00644 
00648 char *xp_DBform_to_url(Form *frm) {
00649     char *s;
00650 
00651     if (frm == NULL)
00652         return NULL;
00653 
00654     f2ubuf = buf_check(f2ubuf, 100);
00655     f2ubuf = buf_strcat(f2ubuf, "xpath://");
00656     s = frm_get_value_by_name(frm, XMLFILE);
00657     if (s != NULL) {
00658         f2ubuf = buf_strcat(f2ubuf, s);
00659     }
00660     
00661     return f2ubuf->b_dat;
00662 }
00663 
00666 static void xp_DBfree_table_def(DBConnection * c)
00667 {
00668     DBConnection_XPath *dbxpath = (DBConnection_XPath *) (c->pvt);
00669 
00670     if (dbxpath->tableDef == NULL) {
00671         fprintf(stderr, "Internal error (freeing a NULL connection)...\n"); /* Dont 
00672                                                                              * have 
00673                                                                              * to 
00674                                                                              * show 
00675                                                                              * an 
00676                                                                              * error 
00677                                                                              */
00678         return;
00679     }
00680     else {
00681         DBFieldDef *dbf;
00682         int i, j;
00683 
00684         for (j = 0; j < dbxpath->tableCount; j++) {
00685             int fnum = (dbxpath->tableDef)[j].field_num;
00686 
00687             if (dbxpath->tableDef[j].name)
00688                 free(dbxpath->tableDef[j].name);
00689 
00690             dbf = (dbxpath->tableDef)[j].field_def;
00691             for (i = 0; i < fnum; i++) {
00692                 free(dbf[i].name);
00693                 free(dbf[i].type);
00694             }
00695             free(dbf);
00696         }
00697         free(dbxpath->tableDef);
00698         dbxpath->tableDef = NULL;
00699 
00700         /* Removing Keywords */
00701         keywords_remove(c, KEYWORD_TABLE);
00702         keywords_remove(c, KEYWORD_FIELD);
00703     }
00704 }
00705 
00709 static int xp_DBget_table_num(DBConnection * c)
00710 {
00711     DBConnection_XPath *xpconn = (DBConnection_XPath *) (c->pvt);
00712     return xpconn->tableCount;
00713 }
00714 
00719 static DBTableDef *xp_DBget_table(DBConnection * c, int table)
00720 {
00721     DBConnection_XPath *xpconn = (DBConnection_XPath *) (c->pvt);
00722 
00723     if (table > 0) {
00724         fprintf(stderr, "Internal error (table number too big)...\n");
00725         return NULL;
00726     }
00727 
00728     if (xpconn->tableDef == NULL) {
00729         fprintf(stderr, "Internal error (searching a NULL table)...\n");
00730         return NULL;
00731     }
00732     else {
00733         return xpconn->tableDef + table;
00734     }
00735     return NULL;
00736 }
00737 
00740 DBConnection *xpath_dbconnection_new()
00741 {
00742     DBConnection *dbc = calloc(1, sizeof(DBConnection));
00743     DBConnection_XPath *pvtdata;
00744     int i;
00745 
00746     if (dbc) {
00747         dbc->DBdisconnect = xp_DBdisconnect;
00748         dbc->DBget_error_message = xp_DBget_error_message;
00749         dbc->DBget_db_name = xp_DBget_db_name;
00750         dbc->DBexecute_query = xp_DBexecute_query;
00751         dbc->DBget_query_status = xp_DBget_query_status;
00752         dbc->DBget_record_number = xp_DBget_record_number;
00753         dbc->DBget_field_number = xp_DBget_field_number;
00754         dbc->DBget_field_name = xp_DBget_field_name;
00755         dbc->DBget_field_value = xp_DBget_field_value;
00756         dbc->DBclear_result = xp_DBclear_result;
00757 
00758         /* Set up keywords */
00759         dbc->keylist = NULL;
00760         i = 0;
00761         while (xpathKeywords[i] != NULL)
00762             add_keyword((DBConnection *) dbc, xpathKeywords[i++],
00763                         KEYWORD_SQL);
00764 
00765         dbc->DBget_table_def = xp_DBget_table_def;
00766         dbc->DBfree_table_def = xp_DBfree_table_def;
00767         dbc->DBget_table_num = xp_DBget_table_num;
00768         dbc->DBget_table = xp_DBget_table;
00769 
00770         /* Setup private data. */
00771         pvtdata = calloc(1, sizeof(DBConnection_XPath));
00772         dbc->pvt = pvtdata;
00773         dbc->pvtlen = sizeof(DBConnection_XPath);
00774     }
00775     return dbc;
00776 }
00777 
00781 void dbconnection_xpath_set_filename(DBConnection * dbc, char *fn)
00782 {
00783     DBConnection_XPath *dbcxp;
00784 
00785     if (!dbc)
00786         return;
00787 
00788     dbcxp = (DBConnection_XPath *) (dbc->pvt);
00789     if (!dbcxp)
00790         return;
00791 
00792     if (dbcxp->filename)
00793         free(dbcxp->filename);
00794 
00795     dbcxp->filename = strdup(fn);
00796 }
00797 
00801 void xpath_set_error(DBConnection_XPath * dbc, char *s)
00802 {
00803     if (!dbc)
00804         return;
00805 
00806     if (dbc->errmsg)
00807         free(dbc->errmsg);
00808 
00809     dbc->errmsg = strdup(s);
00810 }
00811 
00816 int dbconnection_xpath_open_doc(DBConnection * dbc, char *fn)
00817 {
00818     DBConnection_XPath *dbcxp;
00819     xmlNodePtr cur;
00820 
00821     if (!dbc)
00822         return CONNECT_ERROR;
00823 
00824     dbcxp = (DBConnection_XPath *) (dbc->pvt);
00825 
00826     if (!dbcxp)
00827         return CONNECT_ERROR;
00828 
00829     dbconnection_xpath_set_filename(dbc, fn);
00830 
00831     dbcxp->doc = xmlParseFile(fn);
00832     if (dbcxp->doc == NULL) {
00833         xpath_set_error(dbcxp, "Document not parsed successfully.");
00834         xmlFreeDoc(dbcxp->doc);
00835         dbcxp->doc = NULL;
00836         return CONNECT_ERROR;
00837     }
00838 
00839     cur = xmlDocGetRootElement(dbcxp->doc);
00840     if (cur == NULL) {
00841         xpath_set_error(dbcxp, "Document empty");
00842         xmlFreeDoc(dbcxp->doc);
00843         dbcxp->doc = NULL;
00844         return CONNECT_ERROR;
00845     }
00846     return CONNECT_OK;
00847 }
00848 
00856 static int connect_callback(DBConnector * dbc, DBConnection ** ret)
00857 {
00859 #define DB_CONNECT_ERROR_S  "Database connection error : \n %s"
00860     char *xmlname;
00861     DBConnection *ret_my;
00862 
00863     /* Gets the results */
00864     xmlname = frm_get_value_by_name(dbc->db_frm, XMLFILE);
00865 
00866     /* Tests the results */
00867     if ((xmlname == NULL) || (strlen(xmlname) == 0)) {
00868         dbc->app_error_dialog("Connection Error",
00869                               "You need to provide a database name");
00870         return CONNECT_ERROR;
00871     }
00872 
00873     ret_my = xpath_dbconnection_new();
00874     if (!ret_my)
00875         return CONNECT_ERROR;
00876 
00877     ret_my->connector = dbc;
00878 
00879     /* All OK - set things up */
00880     status_push("Parsing XML...");
00881     if (dbconnection_xpath_open_doc(ret_my, xmlname) != CONNECT_OK)
00882         return CONNECT_ERROR;
00883 
00884     status_pop();
00885     *ret = ret_my;
00886     return CONNECT_OK;
00887 }
00888 
00892 DBConnector *register_XPath(void (*error_dialog) (char *, char *))
00893 {
00895 #define XPATH_TYPEKEY   "XPath"
00896     DBConnector *ret;
00897     FormField *fld;
00898 
00899     ret = dbconnector_new();
00900     if (ret == NULL)
00901         return NULL;
00902 
00903     ret->dbtype = XPATH_TYPEKEY;
00904 
00905     /* Prepares all the structures */
00906     ret->app_error_dialog = error_dialog;
00907     ret->db_connect_callback = connect_callback;
00908     ret->url_to_form = xp_DBurl_to_form;
00909     ret->form_to_url = xp_DBform_to_url;
00910 
00911     /* Creates the data-structure */
00912     ret->db_frm = frm_new(NULL);
00913     frm_set_title(ret->db_frm, "XPath");
00914     fld = frm_add_field(ret->db_frm, XMLFILE, NULL);
00915     fld_set_relevance(fld, FR_REQUIRED);
00916     fld_set_type(fld, 0, FT_FILENAME);
00917     fld_set_tip(fld, "The filename for the XML file (required)");
00918     return ret;
00919 }
00920 
00921 #endif

Generated on Sun May 9 19:19:16 2004 for GtkSQL by doxygen1.2.18