duitxnquery.c File Reference


Detailed Description

Implementation of SQL Query Handler.

Author:
Copyright (C) 2002,2004 Linas Vepstas <linas@linas.org>

Definition in file duitxnquery.c.

#include "config.h"
#include <string.h>
#include <glib.h>
#include "builder.h"
#include "estron.h"
#include "dui-initdb.h"
#include "duifield.h"
#include "duifield-sql.h"
#include "duifieldmap.h"
#include "duifilter.h"
#include "duiresolver.h"
#include "duitxnquery.h"
#include "perr.h"

Go to the source code of this file.

Enumerations

enum  MetaQueryType { QUERY_NONE, QUERY_SIMPLE, QUERY_TABLES, QUERY_FIELDS }

Functions

static void dui_txnquery_init (DuiTxnQuery *q)
DuiTxnQuery * dui_txnquery_new (void)
void dui_txnquery_destroy (DuiTxnQuery *q)
void dui_txnquery_set_database (DuiTxnQuery *q, DuiDatabase *db)
void dui_txnquery_set_tablename (DuiTxnQuery *qry, const gchar *tablename)
void dui_txnquery_set_querytype (DuiTxnQuery *qry, const gchar *sql_querytype)
void dui_txnquery_set_table (DuiTxnQuery *qry, DuiField *tabfld, const gchar *sql_querytype)
void dui_txnquery_add_term (DuiTxnQuery *qry, DuiFieldMap *fm)
void dui_txnquery_add_source_match_term (DuiTxnQuery *qry, DuiFieldMap *fm)
DuiFieldMap * dui_txnquery_get_source_match_term (DuiTxnQuery *qry)
void dui_txnquery_set_resolver (DuiTxnQuery *qry, DuiResolver *res)
void dui_txnquery_do_realize (DuiTxnQuery *qry)
void dui_txnquery_connect (DuiTxnQuery *qry)
static DuiDBRecordSet * dui_txnquery_run_one_query (DuiTxnQuery *qry)
DuiDBRecordSet * dui_txnquery_run (DuiTxnQuery *qry)
DuiDBRecordSet * dui_txnquery_rerun_last_query (DuiTxnQuery *qry)


Function Documentation

static DuiDBRecordSet* dui_txnquery_run_one_query ( DuiTxnQuery *  qry  )  [static]

< Database table column

< match to database column

< match to database column

Definition at line 356 of file duitxnquery.c.

00357 {
00358     DuiDBRecordSet *recs = NULL;
00359     if (!qry) return NULL;
00360 
00361     ENTER ("(qry=%p)", qry);
00362     switch (qry->meta_qtype)
00363     {
00364         case QUERY_NONE: break;
00365         case QUERY_SIMPLE: break;
00366         case QUERY_TABLES:
00367             if (qry->db_conn)
00368             {
00369                 recs = dui_connection_tables(qry->db_conn);
00370                 return recs;
00371             }
00372             break;
00373         case QUERY_FIELDS:
00374             if ((qry->db_conn) && (qry->table->get_field_value))
00375             {
00376                 const char * table;
00377                 table = qry->table->get_field_value(qry->table);
00378                 PINFO ("perform fields query with table=\'%s\'", table);
00379                 recs = dui_connection_table_columns(qry->db_conn, table);
00380                 return recs;
00381             }
00382             break;
00383     }
00384 
00385     /* If we have data we need to query, then do the query.  */
00386     if (qry->sql_builder)
00387     {
00388         GList *node;
00389         SqlBuilder *dupe;
00390         short broken_select = 0;
00391         short wild_select = 1;
00392 
00393         g_free (qry->query_string);
00394         qry->query_string = NULL;
00395 
00396         /* Make a copy of the query, which might be holding statically
00397          * compiled 'SELECT term FROM table' in it.  These static terms
00398          * were added with the dui_txnquery_add_term() routine above.
00399          * We append dynamic terms below, dynamic in that we need the
00400          * values for the INSERT, UPDATE and WHERE terms.
00401          *
00402          * Note also: if the sql_builder is empty, then there MUST be
00403          * some insert/update terms; alternately, if the sql_builder
00404          * is not empty, there must NOT be any insert/update terms,
00405          * else bad SQL will be generated.
00406          */
00407         dupe = sql_builder_copy (qry->sql_builder);
00408 
00409         /* Loop, looking for INSERT/UPDATE terms */
00410         for (node = qry->terms; node; node=node->next)
00411         {
00412             DuiFieldMap *fm = node->data;
00413             const char * fieldval;
00414             if ((!DUI_FIELD_IS_TYPE(&fm->target,DUI_FIELD_SQL)) &&
00415                 (!DUI_FIELD_IS_TYPE(&fm->target,DUI_FIELD_WHERE))) continue;
00416 
00417             fieldval = dui_field_map_get_value (fm);
00418             if ((NULL == fieldval) && ((SQL_INSERT == qry->qtype) ||
00419                                        (SQL_UPDATE == qry->qtype)))
00420             {
00421                 PERR ("Null field value for insert/update not allowed, field=%s\n",
00422                        fm->target.fieldname);
00423                 sql_builder_destroy (dupe);
00424                 return NULL;
00425             }
00426             sql_builder_set_str (dupe, fm->target.fieldname, fieldval);
00427             PINFO ("insert/update %s=%s", fm->target.fieldname, fieldval);
00428         }
00429 
00430         /* Loop again, this time for where terms */
00431         for (node = qry->terms; node; node=node->next)
00432         {
00433             DuiFieldMap *fm = node->data;
00434             const char * fieldval;
00435 
00436             if (!DUI_FIELD_IS_TYPE(&fm->target,DUI_FIELD_WHERE)) continue;
00437             wild_select = 0;
00438 
00439             fieldval = dui_field_map_get_value (fm);
00440             PINFO ("where (%s %s %s)", fm->target.fieldname,
00441                             dui_field_where_get_op(&fm->target), fieldval);
00442             /* fields left blank don't match anything */
00443             fieldval = whitespace_filter (fieldval);
00444             if (fieldval)
00445             {
00446                 /* Do not use 'where' term when inserting;
00447                  * This was already picked up above. */
00448                 if (SQL_INSERT != qry->qtype)
00449                 {
00450                     sql_builder_where_str (dupe,
00451                        fm->target.fieldname,
00452                         fieldval, dui_field_where_get_op(&fm->target));
00453                 }
00454             }
00455             else
00456             {
00457                 broken_select = 1;
00458             }
00459         }
00460 
00461         if (NULL == qry->db_conn)
00462         {
00463             /* Now get the database too */
00464             if (NULL == qry->database)
00465             {
00466                 PERR ("Can't perform query, no database specified!\n");
00467                 sql_builder_destroy (dupe);
00468                 return NULL;
00469             }
00470             qry->db_conn = dui_database_do_realize (qry->database);
00471         }
00472 
00473         /* Perform the query only if its an intentional wild-card
00474          * or has valid WHERE terms.  Goal is to try to prevent
00475          * stupid DUI XML file errors from doing a global clobber.
00476          * (e.g. an unintentional wildcard delete, because some
00477          * value for the where clause couldn't be found.)
00478          */
00479         if (wild_select || !broken_select || (SQL_SELECT == qry->qtype))
00480         {
00481             const gchar * stmt;
00482 
00483             /* Get the sql statement string */
00484             stmt = sql_builder_query (dupe);
00485             qry->query_string = g_strdup (stmt);
00486 
00487             /* Now run the query */
00488             if (qry->db_conn)
00489             {
00490                 recs = dui_connection_exec(qry->db_conn, stmt);
00491             }
00492         }
00493         else
00494         {
00495             PERR ("Can't perform query, missing WHERE term (%d %d)",
00496                    wild_select, broken_select);
00497             sql_builder_destroy (dupe);
00498             return NULL;
00499         }
00500         sql_builder_destroy (dupe);
00501     }
00502     else
00503     {
00504         PERR ("Failed to specify table for query");
00505     }
00506 
00507     LEAVE(" got recs=%p for query=\"%s\"\n", recs, qry->query_string);
00508 
00509     return recs;
00510 }


Generated on Tue Apr 29 21:27:53 2008 for estron by  doxygen 1.5.5