123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620 |
- /* glpsql.c */
- /***********************************************************************
- * This code is part of GLPK (GNU Linear Programming Kit).
- *
- * Author: Heinrich Schuchardt <xypron.glpk@gmx.de>.
- *
- * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- * 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
- * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
- * E-mail: <mao@gnu.org>.
- *
- * GLPK is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GLPK is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
- ***********************************************************************/
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include "glpmpl.h"
- #include "glpsql.h"
- #ifdef ODBC_DLNAME
- #define HAVE_ODBC
- #define libodbc ODBC_DLNAME
- #define h_odbc (get_env_ptr()->h_odbc)
- #endif
- #ifdef MYSQL_DLNAME
- #define HAVE_MYSQL
- #define libmysql MYSQL_DLNAME
- #define h_mysql (get_env_ptr()->h_mysql)
- #endif
- static void *db_iodbc_open_int(TABDCA *dca, int mode, const char
- **sqllines);
- static void *db_mysql_open_int(TABDCA *dca, int mode, const char
- **sqllines);
- /**********************************************************************/
- #if defined(HAVE_ODBC) || defined(HAVE_MYSQL)
- #define SQL_FIELD_MAX 100
- /* maximal field count */
- #define SQL_FDLEN_MAX 255
- /* maximal field length */
- /***********************************************************************
- * NAME
- *
- * args_concat - concatenate arguments
- *
- * SYNOPSIS
- *
- * static char **args_concat(TABDCA *dca);
- *
- * DESCRIPTION
- *
- * The arguments passed in dca are SQL statements. A SQL statement may
- * be split over multiple arguments. The last argument of a SQL
- * statement will be terminated with a semilocon. Each SQL statement is
- * merged into a single zero terminated string. Boundaries between
- * arguments are replaced by space.
- *
- * RETURNS
- *
- * Buffer with SQL statements */
- static char **args_concat(TABDCA *dca)
- {
- const char *arg;
- int i;
- int j;
- int j0;
- int j1;
- int len;
- int lentot;
- int narg;
- int nline = 0;
- void *ret;
- char **sqllines = NULL;
- narg = mpl_tab_num_args(dca);
- /* The SQL statements start with argument 3. */
- if (narg < 3)
- return NULL;
- /* Count the SQL statements */
- for (j = 3; j <= narg; j++)
- {
- arg = mpl_tab_get_arg(dca, j);
- len = strlen(arg);
- if (arg[len-1] == ';' || j == narg)
- nline ++;
- }
- /* Allocate string buffer. */
- sqllines = (char **) xmalloc((nline+1) * sizeof(char **));
- /* Join arguments */
- sqllines[0] = NULL;
- j0 = 3;
- i = 0;
- lentot = 0;
- for (j = 3; j <= narg; j++)
- {
- arg = mpl_tab_get_arg(dca, j);
- len = strlen(arg);
- lentot += len;
- if (arg[len-1] == ';' || j == narg)
- { /* Join arguments for a single SQL statement */
- sqllines[i] = xmalloc(lentot+1);
- sqllines[i+1] = NULL;
- sqllines[i][0] = 0x00;
- for (j1 = j0; j1 <= j; j1++)
- { if(j1>j0)
- strcat(sqllines[i], " ");
- strcat(sqllines[i], mpl_tab_get_arg(dca, j1));
- }
- len = strlen(sqllines[i]);
- if (sqllines[i][len-1] == ';')
- sqllines[i][len-1] = 0x00;
- j0 = j+1;
- i++;
- lentot = 0;
- }
- }
- return sqllines;
- }
- /***********************************************************************
- * NAME
- *
- * free_buffer - free multiline string buffer
- *
- * SYNOPSIS
- *
- * static void free_buffer(char **buf);
- *
- * DESCRIPTION
- *
- * buf is a list of strings terminated by NULL.
- * The memory for the strings and for the list is released. */
- static void free_buffer(char **buf)
- { int i;
- for(i = 0; buf[i] != NULL; i++)
- xfree(buf[i]);
- xfree(buf);
- }
- static int db_escaped_string_length(const char* from)
- /* length of escaped string */
- {
- int count;
- const char *pointer;
- for (pointer = from, count = 0; *pointer != (char) '\0'; pointer++,
- count++)
- {
- switch (*pointer)
- {
- case '\'':
- count++;
- break;
- }
- }
- return count;
- }
- static int db_escape_string (char *to, const char *from)
- /* escape string*/
- {
- const char *source = from;
- char *target = to;
- unsigned int remaining;
- remaining = strlen(from);
- if (to == NULL)
- to = (char *) (from + remaining);
- while (remaining > 0)
- {
- switch (*source)
- {
- case '\'':
- *target = '\'';
- target++;
- *target = '\'';
- break;
- default:
- *target = *source;
- }
- source++;
- target++;
- remaining--;
- }
- /* Write the terminating NUL character. */
- *target = '\0';
- return target - to;
- }
- static char *db_generate_select_stmt(TABDCA *dca)
- /* generate select statement */
- {
- char *arg;
- char const *field;
- char *query;
- int j;
- int narg;
- int nf;
- int total;
- total = 50;
- nf = mpl_tab_num_flds(dca);
- narg = mpl_tab_num_args(dca);
- for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
- {
- field = mpl_tab_get_name(dca, j);
- total += strlen(field);
- total += 2;
- }
- arg = (char *) mpl_tab_get_arg(dca, narg);
- total += strlen(arg);
- query = xmalloc( total * sizeof(char));
- strcpy (query, "SELECT ");
- for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
- {
- field = mpl_tab_get_name(dca, j);
- strcat(query, field);
- if ( j < nf )
- strcat(query, ", ");
- }
- strcat(query, " FROM ");
- strcat(query, arg);
- return query;
- }
- static char *db_generate_insert_stmt(TABDCA *dca)
- /* generate insert statement */
- {
- char *arg;
- char const *field;
- char *query;
- int j;
- int narg;
- int nf;
- int total;
- total = 50;
- nf = mpl_tab_num_flds(dca);
- narg = mpl_tab_num_args(dca);
- for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
- {
- field = mpl_tab_get_name(dca, j);
- total += strlen(field);
- total += 5;
- }
- arg = (char *) mpl_tab_get_arg(dca, narg);
- total += strlen(arg);
- query = xmalloc( (total+1) * sizeof(char));
- strcpy (query, "INSERT INTO ");
- strcat(query, arg);
- strcat(query, " ( ");
- for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
- {
- field = mpl_tab_get_name(dca, j);
- strcat(query, field);
- if ( j < nf )
- strcat(query, ", ");
- }
- strcat(query, " ) VALUES ( ");
- for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
- {
- strcat(query, "?");
- if ( j < nf )
- strcat(query, ", ");
- }
- strcat(query, " )");
- return query;
- }
- #endif
- /**********************************************************************/
- #ifndef HAVE_ODBC
- void *db_iodbc_open(TABDCA *dca, int mode)
- { xassert(dca == dca);
- xassert(mode == mode);
- xprintf("iODBC table driver not supported\n");
- return NULL;
- }
- int db_iodbc_read(TABDCA *dca, void *link)
- { xassert(dca != dca);
- xassert(link != link);
- return 0;
- }
- int db_iodbc_write(TABDCA *dca, void *link)
- { xassert(dca != dca);
- xassert(link != link);
- return 0;
- }
- int db_iodbc_close(TABDCA *dca, void *link)
- { xassert(dca != dca);
- xassert(link != link);
- return 0;
- }
- #else
- #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__)
- #include <windows.h>
- #endif
- #include <sql.h>
- #include <sqlext.h>
- struct db_odbc
- {
- int mode; /*'R' = Read, 'W' = Write*/
- SQLHDBC hdbc; /*connection handle*/
- SQLHENV henv; /*environment handle*/
- SQLHSTMT hstmt; /*statement handle*/
- SQLSMALLINT nresultcols; /* columns in result*/
- SQLULEN collen[SQL_FIELD_MAX+1];
- SQLLEN outlen[SQL_FIELD_MAX+1];
- SQLSMALLINT coltype[SQL_FIELD_MAX+1];
- SQLCHAR data[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1];
- SQLCHAR colname[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1];
- int isnumeric[SQL_FIELD_MAX+1];
- int nf;
- /* number of fields in the csv file */
- int ref[1+SQL_FIELD_MAX];
- /* ref[k] = k', if k-th field of the csv file corresponds to
- k'-th field in the table statement; if ref[k] = 0, k-th field
- of the csv file is ignored */
- SQLCHAR *query;
- /* query generated by db_iodbc_open */
- };
- SQLRETURN SQL_API dl_SQLAllocHandle (
- SQLSMALLINT HandleType,
- SQLHANDLE InputHandle,
- SQLHANDLE *OutputHandle)
- {
- typedef SQLRETURN SQL_API ep_SQLAllocHandle(
- SQLSMALLINT HandleType,
- SQLHANDLE InputHandle,
- SQLHANDLE *OutputHandle);
- ep_SQLAllocHandle *fn;
- fn = (ep_SQLAllocHandle *) xdlsym(h_odbc, "SQLAllocHandle");
- xassert(fn != NULL);
- return (*fn)(HandleType, InputHandle, OutputHandle);
- }
- SQLRETURN SQL_API dl_SQLBindCol (
- SQLHSTMT StatementHandle,
- SQLUSMALLINT ColumnNumber,
- SQLSMALLINT TargetType,
- SQLPOINTER TargetValue,
- SQLLEN BufferLength,
- SQLLEN *StrLen_or_Ind)
- {
- typedef SQLRETURN SQL_API ep_SQLBindCol(
- SQLHSTMT StatementHandle,
- SQLUSMALLINT ColumnNumber,
- SQLSMALLINT TargetType,
- SQLPOINTER TargetValue,
- SQLLEN BufferLength,
- SQLLEN *StrLen_or_Ind);
- ep_SQLBindCol *fn;
- fn = (ep_SQLBindCol *) xdlsym(h_odbc, "SQLBindCol");
- xassert(fn != NULL);
- return (*fn)(StatementHandle, ColumnNumber, TargetType,
- TargetValue, BufferLength, StrLen_or_Ind);
- }
- SQLRETURN SQL_API dl_SQLCloseCursor (
- SQLHSTMT StatementHandle)
- {
- typedef SQLRETURN SQL_API ep_SQLCloseCursor (
- SQLHSTMT StatementHandle);
- ep_SQLCloseCursor *fn;
- fn = (ep_SQLCloseCursor *) xdlsym(h_odbc, "SQLCloseCursor");
- xassert(fn != NULL);
- return (*fn)(StatementHandle);
- }
- SQLRETURN SQL_API dl_SQLDisconnect (
- SQLHDBC ConnectionHandle)
- {
- typedef SQLRETURN SQL_API ep_SQLDisconnect(
- SQLHDBC ConnectionHandle);
- ep_SQLDisconnect *fn;
- fn = (ep_SQLDisconnect *) xdlsym(h_odbc, "SQLDisconnect");
- xassert(fn != NULL);
- return (*fn)(ConnectionHandle);
- }
- SQLRETURN SQL_API dl_SQLDriverConnect (
- SQLHDBC hdbc,
- SQLHWND hwnd,
- SQLCHAR *szConnStrIn,
- SQLSMALLINT cbConnStrIn,
- SQLCHAR *szConnStrOut,
- SQLSMALLINT cbConnStrOutMax,
- SQLSMALLINT *pcbConnStrOut,
- SQLUSMALLINT fDriverCompletion)
- {
- typedef SQLRETURN SQL_API ep_SQLDriverConnect(
- SQLHDBC hdbc,
- SQLHWND hwnd,
- SQLCHAR * szConnStrIn,
- SQLSMALLINT cbConnStrIn,
- SQLCHAR * szConnStrOut,
- SQLSMALLINT cbConnStrOutMax,
- SQLSMALLINT * pcbConnStrOut,
- SQLUSMALLINT fDriverCompletion);
- ep_SQLDriverConnect *fn;
- fn = (ep_SQLDriverConnect *) xdlsym(h_odbc, "SQLDriverConnect");
- xassert(fn != NULL);
- return (*fn)(hdbc, hwnd, szConnStrIn, cbConnStrIn, szConnStrOut,
- cbConnStrOutMax, pcbConnStrOut, fDriverCompletion);
- }
- SQLRETURN SQL_API dl_SQLEndTran (
- SQLSMALLINT HandleType,
- SQLHANDLE Handle,
- SQLSMALLINT CompletionType)
- {
- typedef SQLRETURN SQL_API ep_SQLEndTran (
- SQLSMALLINT HandleType,
- SQLHANDLE Handle,
- SQLSMALLINT CompletionType);
- ep_SQLEndTran *fn;
- fn = (ep_SQLEndTran *) xdlsym(h_odbc, "SQLEndTran");
- xassert(fn != NULL);
- return (*fn)(HandleType, Handle, CompletionType);
- }
- SQLRETURN SQL_API dl_SQLExecDirect (
- SQLHSTMT StatementHandle,
- SQLCHAR * StatementText,
- SQLINTEGER TextLength)
- {
- typedef SQLRETURN SQL_API ep_SQLExecDirect (
- SQLHSTMT StatementHandle,
- SQLCHAR * StatementText,
- SQLINTEGER TextLength);
- ep_SQLExecDirect *fn;
- fn = (ep_SQLExecDirect *) xdlsym(h_odbc, "SQLExecDirect");
- xassert(fn != NULL);
- return (*fn)(StatementHandle, StatementText, TextLength);
- }
- SQLRETURN SQL_API dl_SQLFetch (
- SQLHSTMT StatementHandle)
- {
- typedef SQLRETURN SQL_API ep_SQLFetch (
- SQLHSTMT StatementHandle);
- ep_SQLFetch *fn;
- fn = (ep_SQLFetch*) xdlsym(h_odbc, "SQLFetch");
- xassert(fn != NULL);
- return (*fn)(StatementHandle);
- }
- SQLRETURN SQL_API dl_SQLFreeHandle (
- SQLSMALLINT HandleType,
- SQLHANDLE Handle)
- {
- typedef SQLRETURN SQL_API ep_SQLFreeHandle (
- SQLSMALLINT HandleType,
- SQLHANDLE Handle);
- ep_SQLFreeHandle *fn;
- fn = (ep_SQLFreeHandle *) xdlsym(h_odbc, "SQLFreeHandle");
- xassert(fn != NULL);
- return (*fn)(HandleType, Handle);
- }
- SQLRETURN SQL_API dl_SQLDescribeCol (
- SQLHSTMT StatementHandle,
- SQLUSMALLINT ColumnNumber,
- SQLCHAR * ColumnName,
- SQLSMALLINT BufferLength,
- SQLSMALLINT * NameLength,
- SQLSMALLINT * DataType,
- SQLULEN * ColumnSize,
- SQLSMALLINT * DecimalDigits,
- SQLSMALLINT * Nullable)
- {
- typedef SQLRETURN SQL_API ep_SQLDescribeCol (
- SQLHSTMT StatementHandle,
- SQLUSMALLINT ColumnNumber,
- SQLCHAR *ColumnName,
- SQLSMALLINT BufferLength,
- SQLSMALLINT *NameLength,
- SQLSMALLINT *DataType,
- SQLULEN *ColumnSize,
- SQLSMALLINT *DecimalDigits,
- SQLSMALLINT *Nullable);
- ep_SQLDescribeCol *fn;
- fn = (ep_SQLDescribeCol *) xdlsym(h_odbc, "SQLDescribeCol");
- xassert(fn != NULL);
- return (*fn)(StatementHandle, ColumnNumber, ColumnName,
- BufferLength, NameLength,
- DataType, ColumnSize, DecimalDigits, Nullable);
- }
- SQLRETURN SQL_API dl_SQLGetDiagRec (
- SQLSMALLINT HandleType,
- SQLHANDLE Handle,
- SQLSMALLINT RecNumber,
- SQLCHAR *Sqlstate,
- SQLINTEGER *NativeError,
- SQLCHAR *MessageText,
- SQLSMALLINT BufferLength,
- SQLSMALLINT *TextLength)
- {
- typedef SQLRETURN SQL_API ep_SQLGetDiagRec (
- SQLSMALLINT HandleType,
- SQLHANDLE Handle,
- SQLSMALLINT RecNumber,
- SQLCHAR *Sqlstate,
- SQLINTEGER *NativeError,
- SQLCHAR *MessageText,
- SQLSMALLINT BufferLength,
- SQLSMALLINT *TextLength);
- ep_SQLGetDiagRec *fn;
- fn = (ep_SQLGetDiagRec *) xdlsym(h_odbc, "SQLGetDiagRec");
- xassert(fn != NULL);
- return (*fn)(HandleType, Handle, RecNumber, Sqlstate,
- NativeError, MessageText, BufferLength, TextLength);
- }
- SQLRETURN SQL_API dl_SQLGetInfo (
- SQLHDBC ConnectionHandle,
- SQLUSMALLINT InfoType,
- SQLPOINTER InfoValue,
- SQLSMALLINT BufferLength,
- SQLSMALLINT *StringLength)
- {
- typedef SQLRETURN SQL_API ep_SQLGetInfo (
- SQLHDBC ConnectionHandle,
- SQLUSMALLINT InfoType,
- SQLPOINTER InfoValue,
- SQLSMALLINT BufferLength,
- SQLSMALLINT *StringLength);
- ep_SQLGetInfo *fn;
- fn = (ep_SQLGetInfo *) xdlsym(h_odbc, "SQLGetInfo");
- xassert(fn != NULL);
- return (*fn)(ConnectionHandle, InfoType, InfoValue, BufferLength,
- StringLength);
- }
- SQLRETURN SQL_API dl_SQLNumResultCols (
- SQLHSTMT StatementHandle,
- SQLSMALLINT *ColumnCount)
- {
- typedef SQLRETURN SQL_API ep_SQLNumResultCols (
- SQLHSTMT StatementHandle,
- SQLSMALLINT *ColumnCount);
- ep_SQLNumResultCols *fn;
- fn = (ep_SQLNumResultCols *) xdlsym(h_odbc, "SQLNumResultCols");
- xassert(fn != NULL);
- return (*fn)(StatementHandle, ColumnCount);
- }
- SQLRETURN SQL_API dl_SQLSetConnectAttr (
- SQLHDBC ConnectionHandle,
- SQLINTEGER Attribute,
- SQLPOINTER Value,
- SQLINTEGER StringLength)
- {
- typedef SQLRETURN SQL_API ep_SQLSetConnectAttr (
- SQLHDBC ConnectionHandle,
- SQLINTEGER Attribute,
- SQLPOINTER Value,
- SQLINTEGER StringLength);
- ep_SQLSetConnectAttr *fn;
- fn = (ep_SQLSetConnectAttr *) xdlsym(h_odbc, "SQLSetConnectAttr");
- xassert(fn != NULL);
- return (*fn)(ConnectionHandle, Attribute, Value, StringLength);
- }
- SQLRETURN SQL_API dl_SQLSetEnvAttr (
- SQLHENV EnvironmentHandle,
- SQLINTEGER Attribute,
- SQLPOINTER Value,
- SQLINTEGER StringLength)
- {
- typedef SQLRETURN SQL_API ep_SQLSetEnvAttr (
- SQLHENV EnvironmentHandle,
- SQLINTEGER Attribute,
- SQLPOINTER Value,
- SQLINTEGER StringLength);
- ep_SQLSetEnvAttr *fn;
- fn = (ep_SQLSetEnvAttr *) xdlsym(h_odbc, "SQLSetEnvAttr");
- xassert(fn != NULL);
- return (*fn)(EnvironmentHandle, Attribute, Value, StringLength);
- }
- static void extract_error(
- char *fn,
- SQLHANDLE handle,
- SQLSMALLINT type);
- static int is_numeric(
- SQLSMALLINT coltype);
- /***********************************************************************
- * NAME
- *
- * db_iodbc_open - open connection to ODBC data base
- *
- * SYNOPSIS
- *
- * #include "glpsql.h"
- * void *db_iodbc_open(TABDCA *dca, int mode);
- *
- * DESCRIPTION
- *
- * The routine db_iodbc_open opens a connection to an ODBC data base.
- * It then executes the sql statements passed.
- *
- * In the case of table read the SELECT statement is executed.
- *
- * In the case of table write the INSERT statement is prepared.
- * RETURNS
- *
- * The routine returns a pointer to data storage area created. */
- void *db_iodbc_open(TABDCA *dca, int mode)
- { void *ret;
- char **sqllines;
- sqllines = args_concat(dca);
- if (sqllines == NULL)
- { xprintf("Missing arguments in table statement.\n"
- "Please, supply table driver, dsn, and query.\n");
- return NULL;
- }
- ret = db_iodbc_open_int(dca, mode, (const char **) sqllines);
- free_buffer(sqllines);
- return ret;
- }
- static void *db_iodbc_open_int(TABDCA *dca, int mode, const char
- **sqllines)
- {
- struct db_odbc *sql;
- SQLRETURN ret;
- SQLCHAR FAR *dsn;
- SQLCHAR info[256];
- SQLSMALLINT colnamelen;
- SQLSMALLINT nullable;
- SQLSMALLINT scale;
- const char *arg;
- int narg;
- int i, j;
- int total;
- if (libodbc == NULL)
- {
- xprintf("No loader for shared ODBC library available\n");
- return NULL;
- }
- if (h_odbc == NULL)
- {
- h_odbc = xdlopen(libodbc);
- if (h_odbc == NULL)
- { xprintf("unable to open library %s\n", libodbc);
- xprintf("%s\n", xerrmsg());
- return NULL;
- }
- }
- sql = (struct db_odbc *) xmalloc(sizeof(struct db_odbc));
- if (sql == NULL)
- return NULL;
- sql->mode = mode;
- sql->hdbc = NULL;
- sql->henv = NULL;
- sql->hstmt = NULL;
- sql->query = NULL;
- narg = mpl_tab_num_args(dca);
- dsn = (SQLCHAR FAR *) mpl_tab_get_arg(dca, 2);
- /* allocate an environment handle */
- ret = dl_SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
- &(sql->henv));
- /* set attribute to enable application to run as ODBC 3.0
- application */
- ret = dl_SQLSetEnvAttr(sql->henv, SQL_ATTR_ODBC_VERSION,
- (void *) SQL_OV_ODBC3, 0);
- /* allocate a connection handle */
- ret = dl_SQLAllocHandle(SQL_HANDLE_DBC, sql->henv, &(sql->hdbc));
- /* connect */
- ret = dl_SQLDriverConnect(sql->hdbc, NULL, dsn, SQL_NTS, NULL, 0,
- NULL, SQL_DRIVER_COMPLETE);
- if (SQL_SUCCEEDED(ret))
- { /* output information about data base connection */
- xprintf("Connected to ");
- dl_SQLGetInfo(sql->hdbc, SQL_DBMS_NAME, (SQLPOINTER)info,
- sizeof(info), NULL);
- xprintf("%s ", info);
- dl_SQLGetInfo(sql->hdbc, SQL_DBMS_VER, (SQLPOINTER)info,
- sizeof(info), NULL);
- xprintf("%s - ", info);
- dl_SQLGetInfo(sql->hdbc, SQL_DATABASE_NAME, (SQLPOINTER)info,
- sizeof(info), NULL);
- xprintf("%s\n", info);
- }
- else
- { /* describe error */
- xprintf("Failed to connect\n");
- extract_error("SQLDriverConnect", sql->hdbc, SQL_HANDLE_DBC);
- dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
- xfree(sql);
- return NULL;
- }
- /* set AUTOCOMMIT on*/
- ret = dl_SQLSetConnectAttr(sql->hdbc, SQL_ATTR_AUTOCOMMIT,
- (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0);
- /* allocate a statement handle */
- ret = dl_SQLAllocHandle(SQL_HANDLE_STMT, sql->hdbc, &(sql->hstmt));
- /* initialization queries */
- for(j = 0; sqllines[j+1] != NULL; j++)
- {
- sql->query = (SQLCHAR *) sqllines[j];
- xprintf("%s\n", sql->query);
- ret = dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS);
- switch (ret)
- {
- case SQL_SUCCESS:
- case SQL_SUCCESS_WITH_INFO:
- case SQL_NO_DATA_FOUND:
- break;
- default:
- xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n",
- sql->query);
- extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT);
- dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
- dl_SQLDisconnect(sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
- xfree(sql);
- return NULL;
- }
- /* commit statement */
- dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT);
- }
- if ( sql->mode == 'R' )
- { sql->nf = mpl_tab_num_flds(dca);
- for(j = 0; sqllines[j] != NULL; j++)
- arg = sqllines[j];
- total = strlen(arg);
- if (total > 7 && 0 == strncmp(arg, "SELECT ", 7))
- {
- total = strlen(arg);
- sql->query = xmalloc( (total+1) * sizeof(char));
- strcpy (sql->query, arg);
- }
- else
- {
- sql->query = db_generate_select_stmt(dca);
- }
- xprintf("%s\n", sql->query);
- if (dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS) !=
- SQL_SUCCESS)
- {
- xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query);
- extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT);
- dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
- dl_SQLDisconnect(sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
- xfree(sql->query);
- xfree(sql);
- return NULL;
- }
- xfree(sql->query);
- /* determine number of result columns */
- ret = dl_SQLNumResultCols(sql->hstmt, &sql->nresultcols);
- total = sql->nresultcols;
- if (total > SQL_FIELD_MAX)
- { xprintf("db_iodbc_open: Too many fields (> %d) in query.\n"
- "\"%s\"\n", SQL_FIELD_MAX, sql->query);
- dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
- dl_SQLDisconnect(sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
- xfree(sql->query);
- return NULL;
- }
- for (i = 1; i <= total; i++)
- { /* return a set of attributes for a column */
- ret = dl_SQLDescribeCol(sql->hstmt, (SQLSMALLINT) i,
- sql->colname[i], SQL_FDLEN_MAX,
- &colnamelen, &(sql->coltype[i]), &(sql->collen[i]), &scale,
- &nullable);
- sql->isnumeric[i] = is_numeric(sql->coltype[i]);
- /* bind columns to program vars, converting all types to CHAR*/
- dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i],
- SQL_FDLEN_MAX, &(sql->outlen[i]));
- for (j = sql->nf; j >= 1; j--)
- { if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0)
- break;
- }
- sql->ref[i] = j;
- }
- }
- else if ( sql->mode == 'W' )
- { for(j = 0; sqllines[j] != NULL; j++)
- arg = sqllines[j];
- if ( NULL != strchr(arg, '?') )
- {
- total = strlen(arg);
- sql->query = xmalloc( (total+1) * sizeof(char));
- strcpy (sql->query, arg);
- }
- else
- {
- sql->query = db_generate_insert_stmt(dca);
- }
- xprintf("%s\n", sql->query);
- }
- return sql;
- }
- int db_iodbc_read(TABDCA *dca, void *link)
- {
- struct db_odbc *sql;
- SQLRETURN ret;
- char buf[SQL_FDLEN_MAX+1];
- int i;
- int len;
- double num;
- sql = (struct db_odbc *) link;
- xassert(sql != NULL);
- xassert(sql->mode == 'R');
- ret=dl_SQLFetch(sql->hstmt);
- if (ret== SQL_ERROR)
- return -1;
- if (ret== SQL_NO_DATA_FOUND)
- return -1; /*EOF*/
- for (i=1; i <= sql->nresultcols; i++)
- {
- if (sql->ref[i] > 0)
- {
- len = sql->outlen[i];
- if (len != SQL_NULL_DATA)
- {
- if (len > SQL_FDLEN_MAX)
- len = SQL_FDLEN_MAX;
- else if (len < 0)
- len = 0;
- strncpy(buf, (const char *) sql->data[i], len);
- buf[len] = 0x00;
- if (0 != (sql->isnumeric[i]))
- { strspx(buf); /* remove spaces*/
- if (str2num(buf, &num) != 0)
- { xprintf("'%s' cannot be converted to a number.\n",
- buf);
- return 1;
- }
- mpl_tab_set_num(dca, sql->ref[i], num);
- }
- else
- { mpl_tab_set_str(dca, sql->ref[i], strtrim(buf));
- }
- }
- }
- }
- return 0;
- }
- int db_iodbc_write(TABDCA *dca, void *link)
- {
- struct db_odbc *sql;
- char *part;
- char *query;
- char *template;
- char num[50];
- int k;
- int len;
- int nf;
- sql = (struct db_odbc *) link;
- xassert(sql != NULL);
- xassert(sql->mode == 'W');
- len = strlen(sql->query);
- template = (char *) xmalloc( (len + 1) * sizeof(char) );
- strcpy(template, sql->query);
- nf = mpl_tab_num_flds(dca);
- for (k = 1; k <= nf; k++)
- { switch (mpl_tab_get_type(dca, k))
- { case 'N':
- len += 20;
- break;
- case 'S':
- len += db_escaped_string_length(mpl_tab_get_str(dca, k));
- len += 2;
- break;
- default:
- xassert(dca != dca);
- }
- }
- query = xmalloc( (len + 1 ) * sizeof(char) );
- query[0] = 0x00;
- for (k = 1, part = strtok (template, "?"); (part != NULL);
- part = strtok (NULL, "?"), k++)
- {
- if (k > nf) break;
- strcat( query, part );
- switch (mpl_tab_get_type(dca, k))
- { case 'N':
- sprintf(num, "%-18g",mpl_tab_get_num(dca, k));
- strcat( query, num );
- break;
- case 'S':
- strcat( query, "'");
- db_escape_string( query + strlen(query),
- mpl_tab_get_str(dca, k) );
- strcat( query, "'");
- break;
- default:
- xassert(dca != dca);
- }
- }
- if (part != NULL)
- strcat(query, part);
- if (dl_SQLExecDirect(sql->hstmt, (SQLCHAR *) query, SQL_NTS)
- != SQL_SUCCESS)
- {
- xprintf("db_iodbc_write: Query\n\"%s\"\nfailed.\n", query);
- extract_error("SQLExecDirect", sql->hdbc, SQL_HANDLE_DBC);
- xfree(query);
- xfree(template);
- return 1;
- }
- xfree(query);
- xfree(template);
- return 0;
- }
- int db_iodbc_close(TABDCA *dca, void *link)
- {
- struct db_odbc *sql;
- sql = (struct db_odbc *) link;
- xassert(sql != NULL);
- /* Commit */
- if ( sql->mode == 'W' )
- dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT);
- if ( sql->mode == 'R' )
- dl_SQLCloseCursor(sql->hstmt);
- dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
- dl_SQLDisconnect(sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
- dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
- if ( sql->mode == 'W' )
- xfree(sql->query);
- xfree(sql);
- dca->link = NULL;
- return 0;
- }
- static void extract_error(
- char *fn,
- SQLHANDLE handle,
- SQLSMALLINT type)
- {
- SQLINTEGER i = 0;
- SQLINTEGER native;
- SQLCHAR state[ 7 ];
- SQLCHAR text[256];
- SQLSMALLINT len;
- SQLRETURN ret;
- xprintf("\nThe driver reported the following diagnostics whilst "
- "running %s\n", fn);
- do
- {
- ret = dl_SQLGetDiagRec(type, handle, ++i, state, &native, text,
- sizeof(text), &len );
- if (SQL_SUCCEEDED(ret))
- xprintf("%s:%ld:%ld:%s\n", state, i, native, text);
- }
- while( ret == SQL_SUCCESS );
- }
- static int is_numeric(SQLSMALLINT coltype)
- {
- int ret = 0;
- switch (coltype)
- {
- case SQL_DECIMAL:
- case SQL_NUMERIC:
- case SQL_SMALLINT:
- case SQL_INTEGER:
- case SQL_REAL:
- case SQL_FLOAT:
- case SQL_DOUBLE:
- case SQL_TINYINT:
- case SQL_BIGINT:
- ret = 1;
- break;
- }
- return ret;
- }
- #endif
- /**********************************************************************/
- #ifndef HAVE_MYSQL
- void *db_mysql_open(TABDCA *dca, int mode)
- { xassert(dca == dca);
- xassert(mode == mode);
- xprintf("MySQL table driver not supported\n");
- return NULL;
- }
- int db_mysql_read(TABDCA *dca, void *link)
- { xassert(dca != dca);
- xassert(link != link);
- return 0;
- }
- int db_mysql_write(TABDCA *dca, void *link)
- { xassert(dca != dca);
- xassert(link != link);
- return 0;
- }
- int db_mysql_close(TABDCA *dca, void *link)
- { xassert(dca != dca);
- xassert(link != link);
- return 0;
- }
- #else
- #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__)
- #include <windows.h>
- #endif
- #ifdef __CYGWIN__
- #define byte_defined 1
- #endif
- #include <my_global.h>
- #include <my_sys.h>
- #include <mysql.h>
- struct db_mysql
- {
- int mode; /*'R' = Read, 'W' = Write*/
- MYSQL *con; /*connection*/
- MYSQL_RES *res; /*result*/
- int nf;
- /* number of fields in the csv file */
- int ref[1+SQL_FIELD_MAX];
- /* ref[k] = k', if k-th field of the csv file corresponds to
- k'-th field in the table statement; if ref[k] = 0, k-th field
- of the csv file is ignored */
- char *query;
- /* query generated by db_mysql_open */
- };
- void STDCALL dl_mysql_close(MYSQL *sock)
- {
- typedef void STDCALL ep_mysql_close(MYSQL *sock);
- ep_mysql_close *fn;
- fn = (ep_mysql_close *) xdlsym(h_mysql, "mysql_close");
- xassert(fn != NULL);
- return (*fn)(sock);
- }
- const char * STDCALL dl_mysql_error(MYSQL *mysql)
- {
- typedef const char * STDCALL ep_mysql_error(MYSQL *mysql);
- ep_mysql_error *fn;
- fn = (ep_mysql_error *) xdlsym(h_mysql, "mysql_error");
- xassert(fn != NULL);
- return (*fn)(mysql);
- }
- MYSQL_FIELD * STDCALL dl_mysql_fetch_fields(MYSQL_RES *res)
- {
- typedef MYSQL_FIELD * STDCALL
- ep_mysql_fetch_fields(MYSQL_RES *res);
- ep_mysql_fetch_fields *fn;
- fn = (ep_mysql_fetch_fields *) xdlsym(h_mysql, "mysql_fetch_fields");
- xassert(fn != NULL);
- return (*fn)(res);
- }
- unsigned long * STDCALL dl_mysql_fetch_lengths(MYSQL_RES *result)
- {
- typedef unsigned long * STDCALL
- ep_mysql_fetch_lengths(MYSQL_RES *result);
- ep_mysql_fetch_lengths *fn;
- fn = (ep_mysql_fetch_lengths *) xdlsym(h_mysql,
- "mysql_fetch_lengths");
- xassert(fn != NULL);
- return (*fn)(result);
- }
- MYSQL_ROW STDCALL dl_mysql_fetch_row(MYSQL_RES *result)
- {
- typedef MYSQL_ROW STDCALL ep_mysql_fetch_row(MYSQL_RES *result);
- ep_mysql_fetch_row *fn;
- fn = (ep_mysql_fetch_row *) xdlsym(h_mysql, "mysql_fetch_row");
- xassert(fn != NULL);
- return (*fn)(result);
- }
- unsigned int STDCALL dl_mysql_field_count(MYSQL *mysql)
- {
- typedef unsigned int STDCALL ep_mysql_field_count(MYSQL *mysql);
- ep_mysql_field_count *fn;
- fn = (ep_mysql_field_count *) xdlsym(h_mysql, "mysql_field_count");
- xassert(fn != NULL);
- return (*fn)(mysql);
- }
- MYSQL * STDCALL dl_mysql_init(MYSQL *mysql)
- {
- typedef MYSQL * STDCALL ep_mysql_init(MYSQL *mysql);
- ep_mysql_init *fn;
- fn = (ep_mysql_init *) xdlsym(h_mysql, "mysql_init");
- xassert(fn != NULL);
- return (*fn)(mysql);
- }
- unsigned int STDCALL dl_mysql_num_fields(MYSQL_RES *res)
- {
- typedef unsigned int STDCALL ep_mysql_num_fields(MYSQL_RES *res);
- ep_mysql_num_fields *fn;
- fn = (ep_mysql_num_fields *) xdlsym(h_mysql, "mysql_num_fields");
- xassert(fn != NULL);
- return (*fn)(res);
- }
- int STDCALL dl_mysql_query(MYSQL *mysql, const char *q)
- {
- typedef int STDCALL ep_mysql_query(MYSQL *mysql, const char *q);
- ep_mysql_query *fn;
- fn = (ep_mysql_query *) xdlsym(h_mysql, "mysql_query");
- xassert(fn != NULL);
- return (*fn)(mysql, q);
- }
- MYSQL * STDCALL dl_mysql_real_connect(MYSQL *mysql, const char *host,
- const char *user,
- const char *passwd,
- const char *db,
- unsigned int port,
- const char *unix_socket,
- unsigned long clientflag)
- {
- typedef MYSQL * STDCALL ep_mysql_real_connect(MYSQL *mysql,
- const char *host,
- const char *user,
- const char *passwd,
- const char *db,
- unsigned int port,
- const char *unix_socket,
- unsigned long clientflag);
- ep_mysql_real_connect *fn;
- fn = (ep_mysql_real_connect *) xdlsym(h_mysql,
- "mysql_real_connect");
- xassert(fn != NULL);
- return (*fn)(mysql, host, user, passwd, db, port, unix_socket,
- clientflag);
- }
- MYSQL_RES * STDCALL dl_mysql_use_result(MYSQL *mysql)
- {
- typedef MYSQL_RES * STDCALL ep_mysql_use_result(MYSQL *mysql);
- ep_mysql_use_result *fn;
- fn = (ep_mysql_use_result *) xdlsym(h_mysql, "mysql_use_result");
- xassert(fn != NULL);
- return (*fn)(mysql);
- }
- /***********************************************************************
- * NAME
- *
- * db_mysql_open - open connection to ODBC data base
- *
- * SYNOPSIS
- *
- * #include "glpsql.h"
- * void *db_mysql_open(TABDCA *dca, int mode);
- *
- * DESCRIPTION
- *
- * The routine db_mysql_open opens a connection to a MySQL data base.
- * It then executes the sql statements passed.
- *
- * In the case of table read the SELECT statement is executed.
- *
- * In the case of table write the INSERT statement is prepared.
- * RETURNS
- *
- * The routine returns a pointer to data storage area created. */
- void *db_mysql_open(TABDCA *dca, int mode)
- { void *ret;
- char **sqllines;
- sqllines = args_concat(dca);
- if (sqllines == NULL)
- { xprintf("Missing arguments in table statement.\n"
- "Please, supply table driver, dsn, and query.\n");
- return NULL;
- }
- ret = db_mysql_open_int(dca, mode, (const char **) sqllines);
- free_buffer(sqllines);
- return ret;
- }
- static void *db_mysql_open_int(TABDCA *dca, int mode, const char
- **sqllines)
- {
- struct db_mysql *sql = NULL;
- char *arg = NULL;
- const char *field;
- MYSQL_FIELD *fields;
- char *keyword;
- char *value;
- char *query;
- char *dsn;
- /* "Server=[server_name];Database=[database_name];UID=[username];*/
- /* PWD=[password];Port=[port]"*/
- char *server = NULL; /* Server */
- char *user = NULL; /* UID */
- char *password = NULL; /* PWD */
- char *database = NULL; /* Database */
- unsigned int port = 0; /* Port */
- int narg;
- int i, j, total;
- if (libmysql == NULL)
- {
- xprintf("No loader for shared MySQL library available\n");
- return NULL;
- }
- if (h_mysql == NULL)
- {
- h_mysql = xdlopen(libmysql);
- if (h_mysql == NULL)
- { xprintf("unable to open library %s\n", libmysql);
- xprintf("%s\n", xerrmsg());
- return NULL;
- }
- }
- sql = (struct db_mysql *) xmalloc(sizeof(struct db_mysql));
- if (sql == NULL)
- return NULL;
- sql->mode = mode;
- sql->res = NULL;
- sql->query = NULL;
- sql->nf = mpl_tab_num_flds(dca);
- narg = mpl_tab_num_args(dca);
- if (narg < 3 )
- xprintf("MySQL driver: string list too short \n");
- /* get connection string*/
- dsn = (char *) mpl_tab_get_arg(dca, 2);
- /* copy connection string*/
- i = strlen(dsn);
- i++;
- arg = xmalloc(i * sizeof(char));
- strcpy(arg, dsn);
- /*tokenize connection string*/
- for (i = 1, keyword = strtok (arg, "="); (keyword != NULL);
- keyword = strtok (NULL, "="), i++)
- {
- value = strtok (NULL, ";");
- if (value==NULL)
- {
- xprintf("db_mysql_open: Missing value for keyword %s\n",
- keyword);
- xfree(arg);
- xfree(sql);
- return NULL;
- }
- if (0 == strcmp(keyword, "Server"))
- server = value;
- else if (0 == strcmp(keyword, "Database"))
- database = value;
- else if (0 == strcmp(keyword, "UID"))
- user = value;
- else if (0 == strcmp(keyword, "PWD"))
- password = value;
- else if (0 == strcmp(keyword, "Port"))
- port = (unsigned int) atol(value);
- }
- /* Connect to database */
- sql->con = dl_mysql_init(NULL);
- if (!dl_mysql_real_connect(sql->con, server, user, password, database,
- port, NULL, 0))
- {
- xprintf("db_mysql_open: Connect failed\n");
- xprintf("%s\n", dl_mysql_error(sql->con));
- xfree(arg);
- xfree(sql);
- return NULL;
- }
- xfree(arg);
- for(j = 0; sqllines[j+1] != NULL; j++)
- { query = (char *) sqllines[j];
- xprintf("%s\n", query);
- if (dl_mysql_query(sql->con, query))
- {
- xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query);
- xprintf("%s\n",dl_mysql_error(sql->con));
- dl_mysql_close(sql->con);
- xfree(sql);
- return NULL;
- }
- }
- if ( sql->mode == 'R' )
- { sql->nf = mpl_tab_num_flds(dca);
- for(j = 0; sqllines[j] != NULL; j++)
- arg = (char *) sqllines[j];
- total = strlen(arg);
- if (total > 7 && 0 == strncmp(arg, "SELECT ", 7))
- {
- total = strlen(arg);
- query = xmalloc( (total+1) * sizeof(char));
- strcpy (query, arg);
- }
- else
- {
- query = db_generate_select_stmt(dca);
- }
- xprintf("%s\n", query);
- if (dl_mysql_query(sql->con, query))
- {
- xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query);
- xprintf("%s\n",dl_mysql_error(sql->con));
- dl_mysql_close(sql->con);
- xfree(query);
- xfree(sql);
- return NULL;
- }
- xfree(query);
- sql->res = dl_mysql_use_result(sql->con);
- if (sql->res)
- {
- /* create references between query results and table fields*/
- total = dl_mysql_num_fields(sql->res);
- if (total > SQL_FIELD_MAX)
- { xprintf("db_mysql_open: Too many fields (> %d) in query.\n"
- "\"%s\"\n", SQL_FIELD_MAX, query);
- xprintf("%s\n",dl_mysql_error(sql->con));
- dl_mysql_close(sql->con);
- xfree(query);
- xfree(sql);
- return NULL;
- }
- fields = dl_mysql_fetch_fields(sql->res);
- for (i = 1; i <= total; i++)
- {
- for (j = sql->nf; j >= 1; j--)
- {
- if (strcmp(mpl_tab_get_name(dca, j), fields[i-1].name)
- == 0)
- break;
- }
- sql->ref[i] = j;
- }
- }
- else
- {
- if(dl_mysql_field_count(sql->con) == 0)
- {
- xprintf("db_mysql_open: Query was not a SELECT\n\"%s\"\n",
- query);
- xprintf("%s\n",dl_mysql_error(sql->con));
- xfree(query);
- xfree(sql);
- return NULL;
- }
- else
- {
- xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query);
- xprintf("%s\n",dl_mysql_error(sql->con));
- xfree(query);
- xfree(sql);
- return NULL;
- }
- }
- }
- else if ( sql->mode == 'W' )
- { for(j = 0; sqllines[j] != NULL; j++)
- arg = (char *) sqllines[j];
- if ( NULL != strchr(arg, '?') )
- {
- total = strlen(arg);
- query = xmalloc( (total+1) * sizeof(char));
- strcpy (query, arg);
- }
- else
- query = db_generate_insert_stmt(dca);
- sql->query = query;
- xprintf("%s\n", query);
- }
- return sql;
- }
- int db_mysql_read(TABDCA *dca, void *link)
- { struct db_mysql *sql;
- char buf[255+1];
- char **row;
- unsigned long *lengths;
- MYSQL_FIELD *fields;
- double num;
- int len;
- unsigned long num_fields;
- int i;
- sql = (struct db_mysql *) link;
- xassert(sql != NULL);
- xassert(sql->mode == 'R');
- if (NULL == sql->res)
- {
- xprintf("db_mysql_read: no result set available");
- return 1;
- }
- if (NULL==(row = (char **)dl_mysql_fetch_row(sql->res))) {
- return -1; /*EOF*/
- }
- lengths = dl_mysql_fetch_lengths(sql->res);
- fields = dl_mysql_fetch_fields(sql->res);
- num_fields = dl_mysql_num_fields(sql->res);
- for (i=1; i <= num_fields; i++)
- {
- if (row[i-1] != NULL)
- { len = (size_t) lengths[i-1];
- if (len > 255)
- len = 255;
- strncpy(buf, (const char *) row[i-1], len);
- buf[len] = 0x00;
- if (0 != (fields[i-1].flags & NUM_FLAG))
- { strspx(buf); /* remove spaces*/
- if (str2num(buf, &num) != 0)
- { xprintf("'%s' cannot be converted to a number.\n", buf);
- return 1;
- }
- if (sql->ref[i] > 0)
- mpl_tab_set_num(dca, sql->ref[i], num);
- }
- else
- { if (sql->ref[i] > 0)
- mpl_tab_set_str(dca, sql->ref[i], strtrim(buf));
- }
- }
- }
- return 0;
- }
- int db_mysql_write(TABDCA *dca, void *link)
- {
- struct db_mysql *sql;
- char *part;
- char *query;
- char *template;
- char num[50];
- int k;
- int len;
- int nf;
- sql = (struct db_mysql *) link;
- xassert(sql != NULL);
- xassert(sql->mode == 'W');
- len = strlen(sql->query);
- template = (char *) xmalloc( (len + 1) * sizeof(char) );
- strcpy(template, sql->query);
- nf = mpl_tab_num_flds(dca);
- for (k = 1; k <= nf; k++)
- { switch (mpl_tab_get_type(dca, k))
- { case 'N':
- len += 20;
- break;
- case 'S':
- len += db_escaped_string_length(mpl_tab_get_str(dca, k));
- len += 2;
- break;
- default:
- xassert(dca != dca);
- }
- }
- query = xmalloc( (len + 1 ) * sizeof(char) );
- query[0] = 0x00;
- for (k = 1, part = strtok (template, "?"); (part != NULL);
- part = strtok (NULL, "?"), k++)
- {
- if (k > nf) break;
- strcat( query, part );
- switch (mpl_tab_get_type(dca, k))
- { case 'N':
- sprintf(num, "%-18g",mpl_tab_get_num(dca, k));
- strcat( query, num );
- break;
- case 'S':
- strcat( query, "'");
- db_escape_string( query + strlen(query),
- mpl_tab_get_str(dca, k) );
- strcat( query, "'");
- break;
- default:
- xassert(dca != dca);
- }
- }
- if (part != NULL)
- strcat(query, part);
- if (dl_mysql_query(sql->con, query))
- {
- xprintf("db_mysql_write: Query\n\"%s\"\nfailed.\n", query);
- xprintf("%s\n",dl_mysql_error(sql->con));
- xfree(query);
- xfree(template);
- return 1;
- }
- xfree(query);
- xfree(template);
- return 0;
- }
- int db_mysql_close(TABDCA *dca, void *link)
- {
- struct db_mysql *sql;
- sql = (struct db_mysql *) link;
- xassert(sql != NULL);
- dl_mysql_close(sql->con);
- if ( sql->mode == 'W' )
- xfree(sql->query);
- xfree(sql);
- dca->link = NULL;
- return 0;
- }
- #endif
- /* eof */
|