lemon-project-template-glpk
diff deps/glpk/src/glpsql.c @ 9:33de93886c88
Import GLPK 4.47
author | Alpar Juttner <alpar@cs.elte.hu> |
---|---|
date | Sun, 06 Nov 2011 20:59:10 +0100 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/deps/glpk/src/glpsql.c Sun Nov 06 20:59:10 2011 +0100 1.3 @@ -0,0 +1,1631 @@ 1.4 +/* glpsql.c */ 1.5 + 1.6 +/*********************************************************************** 1.7 +* This code is part of GLPK (GNU Linear Programming Kit). 1.8 +* 1.9 +* Author: Heinrich Schuchardt <xypron.glpk@gmx.de>. 1.10 +* 1.11 +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 1.12 +* 2009, 2010 Andrew Makhorin, Department for Applied Informatics, 1.13 +* Moscow Aviation Institute, Moscow, Russia. All rights reserved. 1.14 +* E-mail: <mao@gnu.org>. 1.15 +* 1.16 +* GLPK is free software: you can redistribute it and/or modify it 1.17 +* under the terms of the GNU General Public License as published by 1.18 +* the Free Software Foundation, either version 3 of the License, or 1.19 +* (at your option) any later version. 1.20 +* 1.21 +* GLPK is distributed in the hope that it will be useful, but WITHOUT 1.22 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1.23 +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 1.24 +* License for more details. 1.25 +* 1.26 +* You should have received a copy of the GNU General Public License 1.27 +* along with GLPK. If not, see <http://www.gnu.org/licenses/>. 1.28 +***********************************************************************/ 1.29 + 1.30 +#ifdef HAVE_CONFIG_H 1.31 +#include <config.h> 1.32 +#endif 1.33 + 1.34 +#include "glpmpl.h" 1.35 +#include "glpsql.h" 1.36 + 1.37 +#ifdef ODBC_DLNAME 1.38 +#define HAVE_ODBC 1.39 +#define libodbc ODBC_DLNAME 1.40 +#define h_odbc (get_env_ptr()->h_odbc) 1.41 +#endif 1.42 + 1.43 +#ifdef MYSQL_DLNAME 1.44 +#define HAVE_MYSQL 1.45 +#define libmysql MYSQL_DLNAME 1.46 +#define h_mysql (get_env_ptr()->h_mysql) 1.47 +#endif 1.48 + 1.49 +static void *db_iodbc_open_int(TABDCA *dca, int mode, const char 1.50 + **sqllines); 1.51 +static void *db_mysql_open_int(TABDCA *dca, int mode, const char 1.52 + **sqllines); 1.53 + 1.54 +/**********************************************************************/ 1.55 + 1.56 +#if defined(HAVE_ODBC) || defined(HAVE_MYSQL) 1.57 + 1.58 +#define SQL_FIELD_MAX 100 1.59 +/* maximal field count */ 1.60 + 1.61 +#define SQL_FDLEN_MAX 255 1.62 +/* maximal field length */ 1.63 + 1.64 +/*********************************************************************** 1.65 +* NAME 1.66 +* 1.67 +* args_concat - concatenate arguments 1.68 +* 1.69 +* SYNOPSIS 1.70 +* 1.71 +* static char **args_concat(TABDCA *dca); 1.72 +* 1.73 +* DESCRIPTION 1.74 +* 1.75 +* The arguments passed in dca are SQL statements. A SQL statement may 1.76 +* be split over multiple arguments. The last argument of a SQL 1.77 +* statement will be terminated with a semilocon. Each SQL statement is 1.78 +* merged into a single zero terminated string. Boundaries between 1.79 +* arguments are replaced by space. 1.80 +* 1.81 +* RETURNS 1.82 +* 1.83 +* Buffer with SQL statements */ 1.84 + 1.85 +static char **args_concat(TABDCA *dca) 1.86 +{ 1.87 + const char *arg; 1.88 + int i; 1.89 + int j; 1.90 + int j0; 1.91 + int j1; 1.92 + int len; 1.93 + int lentot; 1.94 + int narg; 1.95 + int nline = 0; 1.96 + void *ret; 1.97 + char **sqllines = NULL; 1.98 + 1.99 + narg = mpl_tab_num_args(dca); 1.100 + /* The SQL statements start with argument 3. */ 1.101 + if (narg < 3) 1.102 + return NULL; 1.103 + /* Count the SQL statements */ 1.104 + for (j = 3; j <= narg; j++) 1.105 + { 1.106 + arg = mpl_tab_get_arg(dca, j); 1.107 + len = strlen(arg); 1.108 + if (arg[len-1] == ';' || j == narg) 1.109 + nline ++; 1.110 + } 1.111 + /* Allocate string buffer. */ 1.112 + sqllines = (char **) xmalloc((nline+1) * sizeof(char **)); 1.113 + /* Join arguments */ 1.114 + sqllines[0] = NULL; 1.115 + j0 = 3; 1.116 + i = 0; 1.117 + lentot = 0; 1.118 + for (j = 3; j <= narg; j++) 1.119 + { 1.120 + arg = mpl_tab_get_arg(dca, j); 1.121 + len = strlen(arg); 1.122 + /* add length of part */ 1.123 + lentot += len; 1.124 + /* add length of space separating parts or 0x00 at end of SQL 1.125 + statement */ 1.126 + lentot++; 1.127 + if (arg[len-1] == ';' || j == narg) 1.128 + { /* Join arguments for a single SQL statement */ 1.129 + sqllines[i] = xmalloc(lentot); 1.130 + sqllines[i+1] = NULL; 1.131 + sqllines[i][0] = 0x00; 1.132 + for (j1 = j0; j1 <= j; j1++) 1.133 + { if(j1>j0) 1.134 + strcat(sqllines[i], " "); 1.135 + strcat(sqllines[i], mpl_tab_get_arg(dca, j1)); 1.136 + } 1.137 + len = strlen(sqllines[i]); 1.138 + if (sqllines[i][len-1] == ';') 1.139 + sqllines[i][len-1] = 0x00; 1.140 + j0 = j+1; 1.141 + i++; 1.142 + lentot = 0; 1.143 + } 1.144 + } 1.145 + return sqllines; 1.146 +} 1.147 + 1.148 +/*********************************************************************** 1.149 +* NAME 1.150 +* 1.151 +* free_buffer - free multiline string buffer 1.152 +* 1.153 +* SYNOPSIS 1.154 +* 1.155 +* static void free_buffer(char **buf); 1.156 +* 1.157 +* DESCRIPTION 1.158 +* 1.159 +* buf is a list of strings terminated by NULL. 1.160 +* The memory for the strings and for the list is released. */ 1.161 + 1.162 +static void free_buffer(char **buf) 1.163 +{ int i; 1.164 + 1.165 + for(i = 0; buf[i] != NULL; i++) 1.166 + xfree(buf[i]); 1.167 + xfree(buf); 1.168 +} 1.169 + 1.170 +static int db_escaped_string_length(const char* from) 1.171 +/* length of escaped string */ 1.172 +{ 1.173 + int count; 1.174 + const char *pointer; 1.175 + 1.176 + for (pointer = from, count = 0; *pointer != (char) '\0'; pointer++, 1.177 + count++) 1.178 + { 1.179 + switch (*pointer) 1.180 + { 1.181 + case '\'': 1.182 + count++; 1.183 + break; 1.184 + } 1.185 + } 1.186 + 1.187 + return count; 1.188 +} 1.189 + 1.190 +static int db_escape_string (char *to, const char *from) 1.191 +/* escape string*/ 1.192 +{ 1.193 + const char *source = from; 1.194 + char *target = to; 1.195 + unsigned int remaining; 1.196 + 1.197 + remaining = strlen(from); 1.198 + 1.199 + if (to == NULL) 1.200 + to = (char *) (from + remaining); 1.201 + 1.202 + while (remaining > 0) 1.203 + { 1.204 + switch (*source) 1.205 + { 1.206 + case '\'': 1.207 + *target = '\''; 1.208 + target++; 1.209 + *target = '\''; 1.210 + break; 1.211 + 1.212 + default: 1.213 + *target = *source; 1.214 + } 1.215 + source++; 1.216 + target++; 1.217 + remaining--; 1.218 + } 1.219 + 1.220 + /* Write the terminating NUL character. */ 1.221 + *target = '\0'; 1.222 + 1.223 + return target - to; 1.224 +} 1.225 + 1.226 +static char *db_generate_select_stmt(TABDCA *dca) 1.227 +/* generate select statement */ 1.228 +{ 1.229 + char *arg; 1.230 + char const *field; 1.231 + char *query; 1.232 + int j; 1.233 + int narg; 1.234 + int nf; 1.235 + int total; 1.236 + 1.237 + total = 50; 1.238 + nf = mpl_tab_num_flds(dca); 1.239 + narg = mpl_tab_num_args(dca); 1.240 + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) 1.241 + { 1.242 + field = mpl_tab_get_name(dca, j); 1.243 + total += strlen(field); 1.244 + total += 2; 1.245 + } 1.246 + arg = (char *) mpl_tab_get_arg(dca, narg); 1.247 + total += strlen(arg); 1.248 + query = xmalloc( total * sizeof(char)); 1.249 + strcpy (query, "SELECT "); 1.250 + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) 1.251 + { 1.252 + field = mpl_tab_get_name(dca, j); 1.253 + strcat(query, field); 1.254 + if ( j < nf ) 1.255 + strcat(query, ", "); 1.256 + } 1.257 + strcat(query, " FROM "); 1.258 + strcat(query, arg); 1.259 + return query; 1.260 +} 1.261 + 1.262 +static char *db_generate_insert_stmt(TABDCA *dca) 1.263 +/* generate insert statement */ 1.264 +{ 1.265 + char *arg; 1.266 + char const *field; 1.267 + char *query; 1.268 + int j; 1.269 + int narg; 1.270 + int nf; 1.271 + int total; 1.272 + 1.273 + total = 50; 1.274 + nf = mpl_tab_num_flds(dca); 1.275 + narg = mpl_tab_num_args(dca); 1.276 + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) 1.277 + { 1.278 + field = mpl_tab_get_name(dca, j); 1.279 + total += strlen(field); 1.280 + total += 5; 1.281 + } 1.282 + arg = (char *) mpl_tab_get_arg(dca, narg); 1.283 + total += strlen(arg); 1.284 + query = xmalloc( (total+1) * sizeof(char)); 1.285 + strcpy (query, "INSERT INTO "); 1.286 + strcat(query, arg); 1.287 + strcat(query, " ( "); 1.288 + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) 1.289 + { 1.290 + field = mpl_tab_get_name(dca, j); 1.291 + strcat(query, field); 1.292 + if ( j < nf ) 1.293 + strcat(query, ", "); 1.294 + } 1.295 + strcat(query, " ) VALUES ( "); 1.296 + for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++) 1.297 + { 1.298 + strcat(query, "?"); 1.299 + if ( j < nf ) 1.300 + strcat(query, ", "); 1.301 + } 1.302 + strcat(query, " )"); 1.303 + return query; 1.304 +} 1.305 + 1.306 +#endif 1.307 + 1.308 +/**********************************************************************/ 1.309 + 1.310 +#ifndef HAVE_ODBC 1.311 + 1.312 +void *db_iodbc_open(TABDCA *dca, int mode) 1.313 +{ xassert(dca == dca); 1.314 + xassert(mode == mode); 1.315 + xprintf("iODBC table driver not supported\n"); 1.316 + return NULL; 1.317 +} 1.318 + 1.319 +int db_iodbc_read(TABDCA *dca, void *link) 1.320 +{ xassert(dca != dca); 1.321 + xassert(link != link); 1.322 + return 0; 1.323 +} 1.324 + 1.325 +int db_iodbc_write(TABDCA *dca, void *link) 1.326 +{ xassert(dca != dca); 1.327 + xassert(link != link); 1.328 + return 0; 1.329 +} 1.330 + 1.331 +int db_iodbc_close(TABDCA *dca, void *link) 1.332 +{ xassert(dca != dca); 1.333 + xassert(link != link); 1.334 + return 0; 1.335 +} 1.336 + 1.337 +#else 1.338 + 1.339 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__) 1.340 +#include <windows.h> 1.341 +#endif 1.342 + 1.343 +#include <sql.h> 1.344 +#include <sqlext.h> 1.345 + 1.346 +struct db_odbc 1.347 +{ 1.348 + int mode; /*'R' = Read, 'W' = Write*/ 1.349 + SQLHDBC hdbc; /*connection handle*/ 1.350 + SQLHENV henv; /*environment handle*/ 1.351 + SQLHSTMT hstmt; /*statement handle*/ 1.352 + SQLSMALLINT nresultcols; /* columns in result*/ 1.353 + SQLULEN collen[SQL_FIELD_MAX+1]; 1.354 + SQLLEN outlen[SQL_FIELD_MAX+1]; 1.355 + SQLSMALLINT coltype[SQL_FIELD_MAX+1]; 1.356 + SQLCHAR data[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1]; 1.357 + SQLCHAR colname[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1]; 1.358 + int isnumeric[SQL_FIELD_MAX+1]; 1.359 + int nf; 1.360 + /* number of fields in the csv file */ 1.361 + int ref[1+SQL_FIELD_MAX]; 1.362 + /* ref[k] = k', if k-th field of the csv file corresponds to 1.363 + k'-th field in the table statement; if ref[k] = 0, k-th field 1.364 + of the csv file is ignored */ 1.365 + SQLCHAR *query; 1.366 + /* query generated by db_iodbc_open */ 1.367 +}; 1.368 + 1.369 +SQLRETURN SQL_API dl_SQLAllocHandle ( 1.370 + SQLSMALLINT HandleType, 1.371 + SQLHANDLE InputHandle, 1.372 + SQLHANDLE *OutputHandle) 1.373 +{ 1.374 + typedef SQLRETURN SQL_API ep_SQLAllocHandle( 1.375 + SQLSMALLINT HandleType, 1.376 + SQLHANDLE InputHandle, 1.377 + SQLHANDLE *OutputHandle); 1.378 + 1.379 + ep_SQLAllocHandle *fn; 1.380 + fn = (ep_SQLAllocHandle *) xdlsym(h_odbc, "SQLAllocHandle"); 1.381 + xassert(fn != NULL); 1.382 + return (*fn)(HandleType, InputHandle, OutputHandle); 1.383 +} 1.384 + 1.385 +SQLRETURN SQL_API dl_SQLBindCol ( 1.386 + SQLHSTMT StatementHandle, 1.387 + SQLUSMALLINT ColumnNumber, 1.388 + SQLSMALLINT TargetType, 1.389 + SQLPOINTER TargetValue, 1.390 + SQLLEN BufferLength, 1.391 + SQLLEN *StrLen_or_Ind) 1.392 +{ 1.393 + typedef SQLRETURN SQL_API ep_SQLBindCol( 1.394 + SQLHSTMT StatementHandle, 1.395 + SQLUSMALLINT ColumnNumber, 1.396 + SQLSMALLINT TargetType, 1.397 + SQLPOINTER TargetValue, 1.398 + SQLLEN BufferLength, 1.399 + SQLLEN *StrLen_or_Ind); 1.400 + ep_SQLBindCol *fn; 1.401 + fn = (ep_SQLBindCol *) xdlsym(h_odbc, "SQLBindCol"); 1.402 + xassert(fn != NULL); 1.403 + return (*fn)(StatementHandle, ColumnNumber, TargetType, 1.404 + TargetValue, BufferLength, StrLen_or_Ind); 1.405 +} 1.406 + 1.407 +SQLRETURN SQL_API dl_SQLCloseCursor ( 1.408 + SQLHSTMT StatementHandle) 1.409 +{ 1.410 + typedef SQLRETURN SQL_API ep_SQLCloseCursor ( 1.411 + SQLHSTMT StatementHandle); 1.412 + 1.413 + ep_SQLCloseCursor *fn; 1.414 + fn = (ep_SQLCloseCursor *) xdlsym(h_odbc, "SQLCloseCursor"); 1.415 + xassert(fn != NULL); 1.416 + return (*fn)(StatementHandle); 1.417 +} 1.418 + 1.419 + 1.420 +SQLRETURN SQL_API dl_SQLDisconnect ( 1.421 + SQLHDBC ConnectionHandle) 1.422 +{ 1.423 + typedef SQLRETURN SQL_API ep_SQLDisconnect( 1.424 + SQLHDBC ConnectionHandle); 1.425 + 1.426 + ep_SQLDisconnect *fn; 1.427 + fn = (ep_SQLDisconnect *) xdlsym(h_odbc, "SQLDisconnect"); 1.428 + xassert(fn != NULL); 1.429 + return (*fn)(ConnectionHandle); 1.430 +} 1.431 + 1.432 +SQLRETURN SQL_API dl_SQLDriverConnect ( 1.433 + SQLHDBC hdbc, 1.434 + SQLHWND hwnd, 1.435 + SQLCHAR *szConnStrIn, 1.436 + SQLSMALLINT cbConnStrIn, 1.437 + SQLCHAR *szConnStrOut, 1.438 + SQLSMALLINT cbConnStrOutMax, 1.439 + SQLSMALLINT *pcbConnStrOut, 1.440 + SQLUSMALLINT fDriverCompletion) 1.441 +{ 1.442 + typedef SQLRETURN SQL_API ep_SQLDriverConnect( 1.443 + SQLHDBC hdbc, 1.444 + SQLHWND hwnd, 1.445 + SQLCHAR * szConnStrIn, 1.446 + SQLSMALLINT cbConnStrIn, 1.447 + SQLCHAR * szConnStrOut, 1.448 + SQLSMALLINT cbConnStrOutMax, 1.449 + SQLSMALLINT * pcbConnStrOut, 1.450 + SQLUSMALLINT fDriverCompletion); 1.451 + 1.452 + ep_SQLDriverConnect *fn; 1.453 + fn = (ep_SQLDriverConnect *) xdlsym(h_odbc, "SQLDriverConnect"); 1.454 + xassert(fn != NULL); 1.455 + return (*fn)(hdbc, hwnd, szConnStrIn, cbConnStrIn, szConnStrOut, 1.456 + cbConnStrOutMax, pcbConnStrOut, fDriverCompletion); 1.457 +} 1.458 + 1.459 +SQLRETURN SQL_API dl_SQLEndTran ( 1.460 + SQLSMALLINT HandleType, 1.461 + SQLHANDLE Handle, 1.462 + SQLSMALLINT CompletionType) 1.463 +{ 1.464 + typedef SQLRETURN SQL_API ep_SQLEndTran ( 1.465 + SQLSMALLINT HandleType, 1.466 + SQLHANDLE Handle, 1.467 + SQLSMALLINT CompletionType); 1.468 + 1.469 + ep_SQLEndTran *fn; 1.470 + fn = (ep_SQLEndTran *) xdlsym(h_odbc, "SQLEndTran"); 1.471 + xassert(fn != NULL); 1.472 + return (*fn)(HandleType, Handle, CompletionType); 1.473 +} 1.474 + 1.475 +SQLRETURN SQL_API dl_SQLExecDirect ( 1.476 + SQLHSTMT StatementHandle, 1.477 + SQLCHAR * StatementText, 1.478 + SQLINTEGER TextLength) 1.479 +{ 1.480 + typedef SQLRETURN SQL_API ep_SQLExecDirect ( 1.481 + SQLHSTMT StatementHandle, 1.482 + SQLCHAR * StatementText, 1.483 + SQLINTEGER TextLength); 1.484 + 1.485 + ep_SQLExecDirect *fn; 1.486 + fn = (ep_SQLExecDirect *) xdlsym(h_odbc, "SQLExecDirect"); 1.487 + xassert(fn != NULL); 1.488 + return (*fn)(StatementHandle, StatementText, TextLength); 1.489 +} 1.490 + 1.491 +SQLRETURN SQL_API dl_SQLFetch ( 1.492 + SQLHSTMT StatementHandle) 1.493 +{ 1.494 + typedef SQLRETURN SQL_API ep_SQLFetch ( 1.495 + SQLHSTMT StatementHandle); 1.496 + 1.497 + ep_SQLFetch *fn; 1.498 + fn = (ep_SQLFetch*) xdlsym(h_odbc, "SQLFetch"); 1.499 + xassert(fn != NULL); 1.500 + return (*fn)(StatementHandle); 1.501 +} 1.502 + 1.503 +SQLRETURN SQL_API dl_SQLFreeHandle ( 1.504 + SQLSMALLINT HandleType, 1.505 + SQLHANDLE Handle) 1.506 +{ 1.507 + typedef SQLRETURN SQL_API ep_SQLFreeHandle ( 1.508 + SQLSMALLINT HandleType, 1.509 + SQLHANDLE Handle); 1.510 + 1.511 + ep_SQLFreeHandle *fn; 1.512 + fn = (ep_SQLFreeHandle *) xdlsym(h_odbc, "SQLFreeHandle"); 1.513 + xassert(fn != NULL); 1.514 + return (*fn)(HandleType, Handle); 1.515 +} 1.516 + 1.517 +SQLRETURN SQL_API dl_SQLDescribeCol ( 1.518 + SQLHSTMT StatementHandle, 1.519 + SQLUSMALLINT ColumnNumber, 1.520 + SQLCHAR * ColumnName, 1.521 + SQLSMALLINT BufferLength, 1.522 + SQLSMALLINT * NameLength, 1.523 + SQLSMALLINT * DataType, 1.524 + SQLULEN * ColumnSize, 1.525 + SQLSMALLINT * DecimalDigits, 1.526 + SQLSMALLINT * Nullable) 1.527 +{ 1.528 + typedef SQLRETURN SQL_API ep_SQLDescribeCol ( 1.529 + SQLHSTMT StatementHandle, 1.530 + SQLUSMALLINT ColumnNumber, 1.531 + SQLCHAR *ColumnName, 1.532 + SQLSMALLINT BufferLength, 1.533 + SQLSMALLINT *NameLength, 1.534 + SQLSMALLINT *DataType, 1.535 + SQLULEN *ColumnSize, 1.536 + SQLSMALLINT *DecimalDigits, 1.537 + SQLSMALLINT *Nullable); 1.538 + 1.539 + ep_SQLDescribeCol *fn; 1.540 + fn = (ep_SQLDescribeCol *) xdlsym(h_odbc, "SQLDescribeCol"); 1.541 + xassert(fn != NULL); 1.542 + return (*fn)(StatementHandle, ColumnNumber, ColumnName, 1.543 + BufferLength, NameLength, 1.544 + DataType, ColumnSize, DecimalDigits, Nullable); 1.545 +} 1.546 + 1.547 +SQLRETURN SQL_API dl_SQLGetDiagRec ( 1.548 + SQLSMALLINT HandleType, 1.549 + SQLHANDLE Handle, 1.550 + SQLSMALLINT RecNumber, 1.551 + SQLCHAR *Sqlstate, 1.552 + SQLINTEGER *NativeError, 1.553 + SQLCHAR *MessageText, 1.554 + SQLSMALLINT BufferLength, 1.555 + SQLSMALLINT *TextLength) 1.556 +{ 1.557 + typedef SQLRETURN SQL_API ep_SQLGetDiagRec ( 1.558 + SQLSMALLINT HandleType, 1.559 + SQLHANDLE Handle, 1.560 + SQLSMALLINT RecNumber, 1.561 + SQLCHAR *Sqlstate, 1.562 + SQLINTEGER *NativeError, 1.563 + SQLCHAR *MessageText, 1.564 + SQLSMALLINT BufferLength, 1.565 + SQLSMALLINT *TextLength); 1.566 + 1.567 + ep_SQLGetDiagRec *fn; 1.568 + fn = (ep_SQLGetDiagRec *) xdlsym(h_odbc, "SQLGetDiagRec"); 1.569 + xassert(fn != NULL); 1.570 + return (*fn)(HandleType, Handle, RecNumber, Sqlstate, 1.571 + NativeError, MessageText, BufferLength, TextLength); 1.572 +} 1.573 + 1.574 +SQLRETURN SQL_API dl_SQLGetInfo ( 1.575 + SQLHDBC ConnectionHandle, 1.576 + SQLUSMALLINT InfoType, 1.577 + SQLPOINTER InfoValue, 1.578 + SQLSMALLINT BufferLength, 1.579 + SQLSMALLINT *StringLength) 1.580 +{ 1.581 + typedef SQLRETURN SQL_API ep_SQLGetInfo ( 1.582 + SQLHDBC ConnectionHandle, 1.583 + SQLUSMALLINT InfoType, 1.584 + SQLPOINTER InfoValue, 1.585 + SQLSMALLINT BufferLength, 1.586 + SQLSMALLINT *StringLength); 1.587 + 1.588 + ep_SQLGetInfo *fn; 1.589 + fn = (ep_SQLGetInfo *) xdlsym(h_odbc, "SQLGetInfo"); 1.590 + xassert(fn != NULL); 1.591 + return (*fn)(ConnectionHandle, InfoType, InfoValue, BufferLength, 1.592 + StringLength); 1.593 +} 1.594 + 1.595 +SQLRETURN SQL_API dl_SQLNumResultCols ( 1.596 + SQLHSTMT StatementHandle, 1.597 + SQLSMALLINT *ColumnCount) 1.598 +{ 1.599 + typedef SQLRETURN SQL_API ep_SQLNumResultCols ( 1.600 + SQLHSTMT StatementHandle, 1.601 + SQLSMALLINT *ColumnCount); 1.602 + 1.603 + ep_SQLNumResultCols *fn; 1.604 + fn = (ep_SQLNumResultCols *) xdlsym(h_odbc, "SQLNumResultCols"); 1.605 + xassert(fn != NULL); 1.606 + return (*fn)(StatementHandle, ColumnCount); 1.607 +} 1.608 + 1.609 +SQLRETURN SQL_API dl_SQLSetConnectAttr ( 1.610 + SQLHDBC ConnectionHandle, 1.611 + SQLINTEGER Attribute, 1.612 + SQLPOINTER Value, 1.613 + SQLINTEGER StringLength) 1.614 +{ 1.615 + typedef SQLRETURN SQL_API ep_SQLSetConnectAttr ( 1.616 + SQLHDBC ConnectionHandle, 1.617 + SQLINTEGER Attribute, 1.618 + SQLPOINTER Value, 1.619 + SQLINTEGER StringLength); 1.620 + 1.621 + ep_SQLSetConnectAttr *fn; 1.622 + fn = (ep_SQLSetConnectAttr *) xdlsym(h_odbc, "SQLSetConnectAttr"); 1.623 + xassert(fn != NULL); 1.624 + return (*fn)(ConnectionHandle, Attribute, Value, StringLength); 1.625 +} 1.626 + 1.627 +SQLRETURN SQL_API dl_SQLSetEnvAttr ( 1.628 + SQLHENV EnvironmentHandle, 1.629 + SQLINTEGER Attribute, 1.630 + SQLPOINTER Value, 1.631 + SQLINTEGER StringLength) 1.632 +{ 1.633 + typedef SQLRETURN SQL_API ep_SQLSetEnvAttr ( 1.634 + SQLHENV EnvironmentHandle, 1.635 + SQLINTEGER Attribute, 1.636 + SQLPOINTER Value, 1.637 + SQLINTEGER StringLength); 1.638 + 1.639 + ep_SQLSetEnvAttr *fn; 1.640 + fn = (ep_SQLSetEnvAttr *) xdlsym(h_odbc, "SQLSetEnvAttr"); 1.641 + xassert(fn != NULL); 1.642 + return (*fn)(EnvironmentHandle, Attribute, Value, StringLength); 1.643 +} 1.644 + 1.645 +static void extract_error( 1.646 + char *fn, 1.647 + SQLHANDLE handle, 1.648 + SQLSMALLINT type); 1.649 + 1.650 +static int is_numeric( 1.651 + SQLSMALLINT coltype); 1.652 + 1.653 +/*********************************************************************** 1.654 +* NAME 1.655 +* 1.656 +* db_iodbc_open - open connection to ODBC data base 1.657 +* 1.658 +* SYNOPSIS 1.659 +* 1.660 +* #include "glpsql.h" 1.661 +* void *db_iodbc_open(TABDCA *dca, int mode); 1.662 +* 1.663 +* DESCRIPTION 1.664 +* 1.665 +* The routine db_iodbc_open opens a connection to an ODBC data base. 1.666 +* It then executes the sql statements passed. 1.667 +* 1.668 +* In the case of table read the SELECT statement is executed. 1.669 +* 1.670 +* In the case of table write the INSERT statement is prepared. 1.671 +* RETURNS 1.672 +* 1.673 +* The routine returns a pointer to data storage area created. */ 1.674 +void *db_iodbc_open(TABDCA *dca, int mode) 1.675 +{ void *ret; 1.676 + char **sqllines; 1.677 + 1.678 + sqllines = args_concat(dca); 1.679 + if (sqllines == NULL) 1.680 + { xprintf("Missing arguments in table statement.\n" 1.681 + "Please, supply table driver, dsn, and query.\n"); 1.682 + return NULL; 1.683 + } 1.684 + ret = db_iodbc_open_int(dca, mode, (const char **) sqllines); 1.685 + free_buffer(sqllines); 1.686 + return ret; 1.687 +} 1.688 + 1.689 +static void *db_iodbc_open_int(TABDCA *dca, int mode, const char 1.690 + **sqllines) 1.691 +{ 1.692 + struct db_odbc *sql; 1.693 + SQLRETURN ret; 1.694 + SQLCHAR FAR *dsn; 1.695 + SQLCHAR info[256]; 1.696 + SQLSMALLINT colnamelen; 1.697 + SQLSMALLINT nullable; 1.698 + SQLSMALLINT scale; 1.699 + const char *arg; 1.700 + int narg; 1.701 + int i, j; 1.702 + int total; 1.703 + 1.704 + if (libodbc == NULL) 1.705 + { 1.706 + xprintf("No loader for shared ODBC library available\n"); 1.707 + return NULL; 1.708 + } 1.709 + 1.710 + if (h_odbc == NULL) 1.711 + { 1.712 + h_odbc = xdlopen(libodbc); 1.713 + if (h_odbc == NULL) 1.714 + { xprintf("unable to open library %s\n", libodbc); 1.715 + xprintf("%s\n", xerrmsg()); 1.716 + return NULL; 1.717 + } 1.718 + } 1.719 + 1.720 + sql = (struct db_odbc *) xmalloc(sizeof(struct db_odbc)); 1.721 + if (sql == NULL) 1.722 + return NULL; 1.723 + 1.724 + sql->mode = mode; 1.725 + sql->hdbc = NULL; 1.726 + sql->henv = NULL; 1.727 + sql->hstmt = NULL; 1.728 + sql->query = NULL; 1.729 + narg = mpl_tab_num_args(dca); 1.730 + 1.731 + dsn = (SQLCHAR FAR *) mpl_tab_get_arg(dca, 2); 1.732 + /* allocate an environment handle */ 1.733 + ret = dl_SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, 1.734 + &(sql->henv)); 1.735 + /* set attribute to enable application to run as ODBC 3.0 1.736 + application */ 1.737 + ret = dl_SQLSetEnvAttr(sql->henv, SQL_ATTR_ODBC_VERSION, 1.738 + (void *) SQL_OV_ODBC3, 0); 1.739 + /* allocate a connection handle */ 1.740 + ret = dl_SQLAllocHandle(SQL_HANDLE_DBC, sql->henv, &(sql->hdbc)); 1.741 + /* connect */ 1.742 + ret = dl_SQLDriverConnect(sql->hdbc, NULL, dsn, SQL_NTS, NULL, 0, 1.743 + NULL, SQL_DRIVER_COMPLETE); 1.744 + if (SQL_SUCCEEDED(ret)) 1.745 + { /* output information about data base connection */ 1.746 + xprintf("Connected to "); 1.747 + dl_SQLGetInfo(sql->hdbc, SQL_DBMS_NAME, (SQLPOINTER)info, 1.748 + sizeof(info), NULL); 1.749 + xprintf("%s ", info); 1.750 + dl_SQLGetInfo(sql->hdbc, SQL_DBMS_VER, (SQLPOINTER)info, 1.751 + sizeof(info), NULL); 1.752 + xprintf("%s - ", info); 1.753 + dl_SQLGetInfo(sql->hdbc, SQL_DATABASE_NAME, (SQLPOINTER)info, 1.754 + sizeof(info), NULL); 1.755 + xprintf("%s\n", info); 1.756 + } 1.757 + else 1.758 + { /* describe error */ 1.759 + xprintf("Failed to connect\n"); 1.760 + extract_error("SQLDriverConnect", sql->hdbc, SQL_HANDLE_DBC); 1.761 + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); 1.762 + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); 1.763 + xfree(sql); 1.764 + return NULL; 1.765 + } 1.766 + /* set AUTOCOMMIT on*/ 1.767 + ret = dl_SQLSetConnectAttr(sql->hdbc, SQL_ATTR_AUTOCOMMIT, 1.768 + (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0); 1.769 + /* allocate a statement handle */ 1.770 + ret = dl_SQLAllocHandle(SQL_HANDLE_STMT, sql->hdbc, &(sql->hstmt)); 1.771 + 1.772 + /* initialization queries */ 1.773 + for(j = 0; sqllines[j+1] != NULL; j++) 1.774 + { 1.775 + sql->query = (SQLCHAR *) sqllines[j]; 1.776 + xprintf("%s\n", sql->query); 1.777 + ret = dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS); 1.778 + switch (ret) 1.779 + { 1.780 + case SQL_SUCCESS: 1.781 + case SQL_SUCCESS_WITH_INFO: 1.782 + case SQL_NO_DATA_FOUND: 1.783 + break; 1.784 + default: 1.785 + xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", 1.786 + sql->query); 1.787 + extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); 1.788 + dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); 1.789 + dl_SQLDisconnect(sql->hdbc); 1.790 + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); 1.791 + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); 1.792 + xfree(sql); 1.793 + return NULL; 1.794 + } 1.795 + /* commit statement */ 1.796 + dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); 1.797 + } 1.798 + 1.799 + if ( sql->mode == 'R' ) 1.800 + { sql->nf = mpl_tab_num_flds(dca); 1.801 + for(j = 0; sqllines[j] != NULL; j++) 1.802 + arg = sqllines[j]; 1.803 + total = strlen(arg); 1.804 + if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) 1.805 + { 1.806 + total = strlen(arg); 1.807 + sql->query = xmalloc( (total+1) * sizeof(char)); 1.808 + strcpy (sql->query, arg); 1.809 + } 1.810 + else 1.811 + { 1.812 + sql->query = db_generate_select_stmt(dca); 1.813 + } 1.814 + xprintf("%s\n", sql->query); 1.815 + if (dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS) != 1.816 + SQL_SUCCESS) 1.817 + { 1.818 + xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query); 1.819 + extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT); 1.820 + dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); 1.821 + dl_SQLDisconnect(sql->hdbc); 1.822 + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); 1.823 + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); 1.824 + xfree(sql->query); 1.825 + xfree(sql); 1.826 + return NULL; 1.827 + } 1.828 + xfree(sql->query); 1.829 + /* determine number of result columns */ 1.830 + ret = dl_SQLNumResultCols(sql->hstmt, &sql->nresultcols); 1.831 + total = sql->nresultcols; 1.832 + if (total > SQL_FIELD_MAX) 1.833 + { xprintf("db_iodbc_open: Too many fields (> %d) in query.\n" 1.834 + "\"%s\"\n", SQL_FIELD_MAX, sql->query); 1.835 + dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); 1.836 + dl_SQLDisconnect(sql->hdbc); 1.837 + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); 1.838 + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); 1.839 + xfree(sql->query); 1.840 + return NULL; 1.841 + } 1.842 + for (i = 1; i <= total; i++) 1.843 + { /* return a set of attributes for a column */ 1.844 + ret = dl_SQLDescribeCol(sql->hstmt, (SQLSMALLINT) i, 1.845 + sql->colname[i], SQL_FDLEN_MAX, 1.846 + &colnamelen, &(sql->coltype[i]), &(sql->collen[i]), &scale, 1.847 + &nullable); 1.848 + sql->isnumeric[i] = is_numeric(sql->coltype[i]); 1.849 + /* bind columns to program vars, converting all types to CHAR*/ 1.850 + if (sql->isnumeric[i]) 1.851 + { dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, sql->data[i], 1.852 + SQL_FDLEN_MAX, &(sql->outlen[i])); 1.853 + } else 1.854 + { dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i], 1.855 + SQL_FDLEN_MAX, &(sql->outlen[i])); 1.856 + } 1.857 + for (j = sql->nf; j >= 1; j--) 1.858 + { if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0) 1.859 + break; 1.860 + } 1.861 + sql->ref[i] = j; 1.862 + } 1.863 + } 1.864 + else if ( sql->mode == 'W' ) 1.865 + { for(j = 0; sqllines[j] != NULL; j++) 1.866 + arg = sqllines[j]; 1.867 + if ( NULL != strchr(arg, '?') ) 1.868 + { 1.869 + total = strlen(arg); 1.870 + sql->query = xmalloc( (total+1) * sizeof(char)); 1.871 + strcpy (sql->query, arg); 1.872 + } 1.873 + else 1.874 + { 1.875 + sql->query = db_generate_insert_stmt(dca); 1.876 + } 1.877 + xprintf("%s\n", sql->query); 1.878 + } 1.879 + return sql; 1.880 +} 1.881 + 1.882 +int db_iodbc_read(TABDCA *dca, void *link) 1.883 +{ 1.884 + struct db_odbc *sql; 1.885 + SQLRETURN ret; 1.886 + char buf[SQL_FDLEN_MAX+1]; 1.887 + int i; 1.888 + int len; 1.889 + double num; 1.890 + 1.891 + sql = (struct db_odbc *) link; 1.892 + 1.893 + xassert(sql != NULL); 1.894 + xassert(sql->mode == 'R'); 1.895 + 1.896 + ret=dl_SQLFetch(sql->hstmt); 1.897 + if (ret== SQL_ERROR) 1.898 + return -1; 1.899 + if (ret== SQL_NO_DATA_FOUND) 1.900 + return -1; /*EOF*/ 1.901 + for (i=1; i <= sql->nresultcols; i++) 1.902 + { 1.903 + if (sql->ref[i] > 0) 1.904 + { 1.905 + len = sql->outlen[i]; 1.906 + if (len != SQL_NULL_DATA) 1.907 + { 1.908 + if (sql->isnumeric[i]) 1.909 + { mpl_tab_set_num(dca, sql->ref[i], 1.910 + *((const double *) sql->data[i])); 1.911 + } 1.912 + else 1.913 + { if (len > SQL_FDLEN_MAX) 1.914 + len = SQL_FDLEN_MAX; 1.915 + else if (len < 0) 1.916 + len = 0; 1.917 + strncpy(buf, (const char *) sql->data[i], len); 1.918 + buf[len] = 0x00; 1.919 + mpl_tab_set_str(dca, sql->ref[i], strtrim(buf)); 1.920 + } 1.921 + } 1.922 + } 1.923 + } 1.924 + return 0; 1.925 +} 1.926 + 1.927 +int db_iodbc_write(TABDCA *dca, void *link) 1.928 +{ 1.929 + struct db_odbc *sql; 1.930 + char *part; 1.931 + char *query; 1.932 + char *template; 1.933 + char num[50]; 1.934 + int k; 1.935 + int len; 1.936 + int nf; 1.937 + 1.938 + sql = (struct db_odbc *) link; 1.939 + xassert(sql != NULL); 1.940 + xassert(sql->mode == 'W'); 1.941 + 1.942 + len = strlen(sql->query); 1.943 + template = (char *) xmalloc( (len + 1) * sizeof(char) ); 1.944 + strcpy(template, sql->query); 1.945 + 1.946 + nf = mpl_tab_num_flds(dca); 1.947 + for (k = 1; k <= nf; k++) 1.948 + { switch (mpl_tab_get_type(dca, k)) 1.949 + { case 'N': 1.950 + len += 20; 1.951 + break; 1.952 + case 'S': 1.953 + len += db_escaped_string_length(mpl_tab_get_str(dca, k)); 1.954 + len += 2; 1.955 + break; 1.956 + default: 1.957 + xassert(dca != dca); 1.958 + } 1.959 + } 1.960 + query = xmalloc( (len + 1 ) * sizeof(char) ); 1.961 + query[0] = 0x00; 1.962 + for (k = 1, part = strtok (template, "?"); (part != NULL); 1.963 + part = strtok (NULL, "?"), k++) 1.964 + { 1.965 + if (k > nf) break; 1.966 + strcat( query, part ); 1.967 + switch (mpl_tab_get_type(dca, k)) 1.968 + { case 'N': 1.969 +#if 0 /* 02/XI-2010 by xypron */ 1.970 + sprintf(num, "%-18g",mpl_tab_get_num(dca, k)); 1.971 +#else 1.972 + sprintf(num, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); 1.973 +#endif 1.974 + strcat( query, num ); 1.975 + break; 1.976 + case 'S': 1.977 + strcat( query, "'"); 1.978 + db_escape_string( query + strlen(query), 1.979 + mpl_tab_get_str(dca, k) ); 1.980 + strcat( query, "'"); 1.981 + break; 1.982 + default: 1.983 + xassert(dca != dca); 1.984 + } 1.985 + } 1.986 + if (part != NULL) 1.987 + strcat(query, part); 1.988 + if (dl_SQLExecDirect(sql->hstmt, (SQLCHAR *) query, SQL_NTS) 1.989 + != SQL_SUCCESS) 1.990 + { 1.991 + xprintf("db_iodbc_write: Query\n\"%s\"\nfailed.\n", query); 1.992 + extract_error("SQLExecDirect", sql->hdbc, SQL_HANDLE_DBC); 1.993 + xfree(query); 1.994 + xfree(template); 1.995 + return 1; 1.996 + } 1.997 + 1.998 + xfree(query); 1.999 + xfree(template); 1.1000 + return 0; 1.1001 +} 1.1002 + 1.1003 +int db_iodbc_close(TABDCA *dca, void *link) 1.1004 +{ 1.1005 + struct db_odbc *sql; 1.1006 + 1.1007 + sql = (struct db_odbc *) link; 1.1008 + xassert(sql != NULL); 1.1009 + /* Commit */ 1.1010 + if ( sql->mode == 'W' ) 1.1011 + dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT); 1.1012 + if ( sql->mode == 'R' ) 1.1013 + dl_SQLCloseCursor(sql->hstmt); 1.1014 + 1.1015 + dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt); 1.1016 + dl_SQLDisconnect(sql->hdbc); 1.1017 + dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc); 1.1018 + dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv); 1.1019 + if ( sql->mode == 'W' ) 1.1020 + xfree(sql->query); 1.1021 + xfree(sql); 1.1022 + dca->link = NULL; 1.1023 + return 0; 1.1024 +} 1.1025 + 1.1026 +static void extract_error( 1.1027 + char *fn, 1.1028 + SQLHANDLE handle, 1.1029 + SQLSMALLINT type) 1.1030 +{ 1.1031 + SQLINTEGER i = 0; 1.1032 + SQLINTEGER native; 1.1033 + SQLCHAR state[ 7 ]; 1.1034 + SQLCHAR text[256]; 1.1035 + SQLSMALLINT len; 1.1036 + SQLRETURN ret; 1.1037 + 1.1038 + xprintf("\nThe driver reported the following diagnostics whilst " 1.1039 + "running %s\n", fn); 1.1040 + 1.1041 + do 1.1042 + { 1.1043 + ret = dl_SQLGetDiagRec(type, handle, ++i, state, &native, text, 1.1044 + sizeof(text), &len ); 1.1045 + if (SQL_SUCCEEDED(ret)) 1.1046 + xprintf("%s:%ld:%ld:%s\n", state, i, native, text); 1.1047 + } 1.1048 + while( ret == SQL_SUCCESS ); 1.1049 +} 1.1050 + 1.1051 +static int is_numeric(SQLSMALLINT coltype) 1.1052 +{ 1.1053 + int ret = 0; 1.1054 + switch (coltype) 1.1055 + { 1.1056 + case SQL_DECIMAL: 1.1057 + case SQL_NUMERIC: 1.1058 + case SQL_SMALLINT: 1.1059 + case SQL_INTEGER: 1.1060 + case SQL_REAL: 1.1061 + case SQL_FLOAT: 1.1062 + case SQL_DOUBLE: 1.1063 + case SQL_TINYINT: 1.1064 + case SQL_BIGINT: 1.1065 + ret = 1; 1.1066 + break; 1.1067 + } 1.1068 + return ret; 1.1069 +} 1.1070 + 1.1071 +#endif 1.1072 + 1.1073 +/**********************************************************************/ 1.1074 + 1.1075 +#ifndef HAVE_MYSQL 1.1076 + 1.1077 +void *db_mysql_open(TABDCA *dca, int mode) 1.1078 +{ xassert(dca == dca); 1.1079 + xassert(mode == mode); 1.1080 + xprintf("MySQL table driver not supported\n"); 1.1081 + return NULL; 1.1082 +} 1.1083 + 1.1084 +int db_mysql_read(TABDCA *dca, void *link) 1.1085 +{ xassert(dca != dca); 1.1086 + xassert(link != link); 1.1087 + return 0; 1.1088 +} 1.1089 + 1.1090 +int db_mysql_write(TABDCA *dca, void *link) 1.1091 +{ xassert(dca != dca); 1.1092 + xassert(link != link); 1.1093 + return 0; 1.1094 +} 1.1095 + 1.1096 +int db_mysql_close(TABDCA *dca, void *link) 1.1097 +{ xassert(dca != dca); 1.1098 + xassert(link != link); 1.1099 + return 0; 1.1100 +} 1.1101 + 1.1102 +#else 1.1103 + 1.1104 +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__) 1.1105 +#include <windows.h> 1.1106 +#endif 1.1107 + 1.1108 +#ifdef __CYGWIN__ 1.1109 +#define byte_defined 1 1.1110 +#endif 1.1111 + 1.1112 +#include <my_global.h> 1.1113 +#include <my_sys.h> 1.1114 +#include <mysql.h> 1.1115 + 1.1116 +struct db_mysql 1.1117 +{ 1.1118 + int mode; /*'R' = Read, 'W' = Write*/ 1.1119 + MYSQL *con; /*connection*/ 1.1120 + MYSQL_RES *res; /*result*/ 1.1121 + int nf; 1.1122 + /* number of fields in the csv file */ 1.1123 + int ref[1+SQL_FIELD_MAX]; 1.1124 + /* ref[k] = k', if k-th field of the csv file corresponds to 1.1125 + k'-th field in the table statement; if ref[k] = 0, k-th field 1.1126 + of the csv file is ignored */ 1.1127 + char *query; 1.1128 + /* query generated by db_mysql_open */ 1.1129 +}; 1.1130 + 1.1131 +void STDCALL dl_mysql_close(MYSQL *sock) 1.1132 +{ 1.1133 + typedef void STDCALL ep_mysql_close(MYSQL *sock); 1.1134 + 1.1135 + ep_mysql_close *fn; 1.1136 + fn = (ep_mysql_close *) xdlsym(h_mysql, "mysql_close"); 1.1137 + xassert(fn != NULL); 1.1138 + return (*fn)(sock); 1.1139 +} 1.1140 + 1.1141 +const char * STDCALL dl_mysql_error(MYSQL *mysql) 1.1142 +{ 1.1143 + typedef const char * STDCALL ep_mysql_error(MYSQL *mysql); 1.1144 + 1.1145 + ep_mysql_error *fn; 1.1146 + fn = (ep_mysql_error *) xdlsym(h_mysql, "mysql_error"); 1.1147 + xassert(fn != NULL); 1.1148 + return (*fn)(mysql); 1.1149 +} 1.1150 + 1.1151 +MYSQL_FIELD * STDCALL dl_mysql_fetch_fields(MYSQL_RES *res) 1.1152 +{ 1.1153 + typedef MYSQL_FIELD * STDCALL 1.1154 + ep_mysql_fetch_fields(MYSQL_RES *res); 1.1155 + 1.1156 + ep_mysql_fetch_fields *fn; 1.1157 + fn = (ep_mysql_fetch_fields *) xdlsym(h_mysql, "mysql_fetch_fields"); 1.1158 + xassert(fn != NULL); 1.1159 + return (*fn)(res); 1.1160 +} 1.1161 + 1.1162 +unsigned long * STDCALL dl_mysql_fetch_lengths(MYSQL_RES *result) 1.1163 +{ 1.1164 + typedef unsigned long * STDCALL 1.1165 + ep_mysql_fetch_lengths(MYSQL_RES *result); 1.1166 + 1.1167 + ep_mysql_fetch_lengths *fn; 1.1168 + fn = (ep_mysql_fetch_lengths *) xdlsym(h_mysql, 1.1169 + "mysql_fetch_lengths"); 1.1170 + xassert(fn != NULL); 1.1171 + return (*fn)(result); 1.1172 +} 1.1173 + 1.1174 +MYSQL_ROW STDCALL dl_mysql_fetch_row(MYSQL_RES *result) 1.1175 +{ 1.1176 + typedef MYSQL_ROW STDCALL ep_mysql_fetch_row(MYSQL_RES *result); 1.1177 + 1.1178 + ep_mysql_fetch_row *fn; 1.1179 + fn = (ep_mysql_fetch_row *) xdlsym(h_mysql, "mysql_fetch_row"); 1.1180 + xassert(fn != NULL); 1.1181 + return (*fn)(result); 1.1182 +} 1.1183 + 1.1184 +unsigned int STDCALL dl_mysql_field_count(MYSQL *mysql) 1.1185 +{ 1.1186 + typedef unsigned int STDCALL ep_mysql_field_count(MYSQL *mysql); 1.1187 + 1.1188 + ep_mysql_field_count *fn; 1.1189 + fn = (ep_mysql_field_count *) xdlsym(h_mysql, "mysql_field_count"); 1.1190 + xassert(fn != NULL); 1.1191 + return (*fn)(mysql); 1.1192 +} 1.1193 + 1.1194 +MYSQL * STDCALL dl_mysql_init(MYSQL *mysql) 1.1195 +{ 1.1196 + typedef MYSQL * STDCALL ep_mysql_init(MYSQL *mysql); 1.1197 + 1.1198 + ep_mysql_init *fn; 1.1199 + fn = (ep_mysql_init *) xdlsym(h_mysql, "mysql_init"); 1.1200 + xassert(fn != NULL); 1.1201 + return (*fn)(mysql); 1.1202 +} 1.1203 + 1.1204 +unsigned int STDCALL dl_mysql_num_fields(MYSQL_RES *res) 1.1205 +{ 1.1206 + typedef unsigned int STDCALL ep_mysql_num_fields(MYSQL_RES *res); 1.1207 + 1.1208 + ep_mysql_num_fields *fn; 1.1209 + fn = (ep_mysql_num_fields *) xdlsym(h_mysql, "mysql_num_fields"); 1.1210 + xassert(fn != NULL); 1.1211 + return (*fn)(res); 1.1212 +} 1.1213 + 1.1214 +int STDCALL dl_mysql_query(MYSQL *mysql, const char *q) 1.1215 +{ 1.1216 + typedef int STDCALL ep_mysql_query(MYSQL *mysql, const char *q); 1.1217 + 1.1218 + ep_mysql_query *fn; 1.1219 + fn = (ep_mysql_query *) xdlsym(h_mysql, "mysql_query"); 1.1220 + xassert(fn != NULL); 1.1221 + return (*fn)(mysql, q); 1.1222 +} 1.1223 + 1.1224 +MYSQL * STDCALL dl_mysql_real_connect(MYSQL *mysql, const char *host, 1.1225 + const char *user, 1.1226 + const char *passwd, 1.1227 + const char *db, 1.1228 + unsigned int port, 1.1229 + const char *unix_socket, 1.1230 + unsigned long clientflag) 1.1231 +{ 1.1232 + typedef MYSQL * STDCALL ep_mysql_real_connect(MYSQL *mysql, 1.1233 + const char *host, 1.1234 + const char *user, 1.1235 + const char *passwd, 1.1236 + const char *db, 1.1237 + unsigned int port, 1.1238 + const char *unix_socket, 1.1239 + unsigned long clientflag); 1.1240 + 1.1241 + ep_mysql_real_connect *fn; 1.1242 + fn = (ep_mysql_real_connect *) xdlsym(h_mysql, 1.1243 + "mysql_real_connect"); 1.1244 + xassert(fn != NULL); 1.1245 + return (*fn)(mysql, host, user, passwd, db, port, unix_socket, 1.1246 + clientflag); 1.1247 +} 1.1248 + 1.1249 +MYSQL_RES * STDCALL dl_mysql_use_result(MYSQL *mysql) 1.1250 +{ 1.1251 + typedef MYSQL_RES * STDCALL ep_mysql_use_result(MYSQL *mysql); 1.1252 + ep_mysql_use_result *fn; 1.1253 + fn = (ep_mysql_use_result *) xdlsym(h_mysql, "mysql_use_result"); 1.1254 + xassert(fn != NULL); 1.1255 + return (*fn)(mysql); 1.1256 +} 1.1257 + 1.1258 +/*********************************************************************** 1.1259 +* NAME 1.1260 +* 1.1261 +* db_mysql_open - open connection to ODBC data base 1.1262 +* 1.1263 +* SYNOPSIS 1.1264 +* 1.1265 +* #include "glpsql.h" 1.1266 +* void *db_mysql_open(TABDCA *dca, int mode); 1.1267 +* 1.1268 +* DESCRIPTION 1.1269 +* 1.1270 +* The routine db_mysql_open opens a connection to a MySQL data base. 1.1271 +* It then executes the sql statements passed. 1.1272 +* 1.1273 +* In the case of table read the SELECT statement is executed. 1.1274 +* 1.1275 +* In the case of table write the INSERT statement is prepared. 1.1276 +* RETURNS 1.1277 +* 1.1278 +* The routine returns a pointer to data storage area created. */ 1.1279 + 1.1280 +void *db_mysql_open(TABDCA *dca, int mode) 1.1281 +{ void *ret; 1.1282 + char **sqllines; 1.1283 + 1.1284 + sqllines = args_concat(dca); 1.1285 + if (sqllines == NULL) 1.1286 + { xprintf("Missing arguments in table statement.\n" 1.1287 + "Please, supply table driver, dsn, and query.\n"); 1.1288 + return NULL; 1.1289 + } 1.1290 + ret = db_mysql_open_int(dca, mode, (const char **) sqllines); 1.1291 + free_buffer(sqllines); 1.1292 + return ret; 1.1293 +} 1.1294 + 1.1295 +static void *db_mysql_open_int(TABDCA *dca, int mode, const char 1.1296 + **sqllines) 1.1297 +{ 1.1298 + struct db_mysql *sql = NULL; 1.1299 + char *arg = NULL; 1.1300 + const char *field; 1.1301 + MYSQL_FIELD *fields; 1.1302 + char *keyword; 1.1303 + char *value; 1.1304 + char *query; 1.1305 + char *dsn; 1.1306 +/* "Server=[server_name];Database=[database_name];UID=[username];*/ 1.1307 +/* PWD=[password];Port=[port]"*/ 1.1308 + char *server = NULL; /* Server */ 1.1309 + char *user = NULL; /* UID */ 1.1310 + char *password = NULL; /* PWD */ 1.1311 + char *database = NULL; /* Database */ 1.1312 + unsigned int port = 0; /* Port */ 1.1313 + int narg; 1.1314 + int i, j, total; 1.1315 + 1.1316 + if (libmysql == NULL) 1.1317 + { 1.1318 + xprintf("No loader for shared MySQL library available\n"); 1.1319 + return NULL; 1.1320 + } 1.1321 + 1.1322 + if (h_mysql == NULL) 1.1323 + { 1.1324 + h_mysql = xdlopen(libmysql); 1.1325 + if (h_mysql == NULL) 1.1326 + { xprintf("unable to open library %s\n", libmysql); 1.1327 + xprintf("%s\n", xerrmsg()); 1.1328 + return NULL; 1.1329 + } 1.1330 + } 1.1331 + 1.1332 + sql = (struct db_mysql *) xmalloc(sizeof(struct db_mysql)); 1.1333 + if (sql == NULL) 1.1334 + return NULL; 1.1335 + sql->mode = mode; 1.1336 + sql->res = NULL; 1.1337 + sql->query = NULL; 1.1338 + sql->nf = mpl_tab_num_flds(dca); 1.1339 + 1.1340 + narg = mpl_tab_num_args(dca); 1.1341 + if (narg < 3 ) 1.1342 + xprintf("MySQL driver: string list too short \n"); 1.1343 + 1.1344 + /* get connection string*/ 1.1345 + dsn = (char *) mpl_tab_get_arg(dca, 2); 1.1346 + /* copy connection string*/ 1.1347 + i = strlen(dsn); 1.1348 + i++; 1.1349 + arg = xmalloc(i * sizeof(char)); 1.1350 + strcpy(arg, dsn); 1.1351 + /*tokenize connection string*/ 1.1352 + for (i = 1, keyword = strtok (arg, "="); (keyword != NULL); 1.1353 + keyword = strtok (NULL, "="), i++) 1.1354 + { 1.1355 + value = strtok (NULL, ";"); 1.1356 + if (value==NULL) 1.1357 + { 1.1358 + xprintf("db_mysql_open: Missing value for keyword %s\n", 1.1359 + keyword); 1.1360 + xfree(arg); 1.1361 + xfree(sql); 1.1362 + return NULL; 1.1363 + } 1.1364 + if (0 == strcmp(keyword, "Server")) 1.1365 + server = value; 1.1366 + else if (0 == strcmp(keyword, "Database")) 1.1367 + database = value; 1.1368 + else if (0 == strcmp(keyword, "UID")) 1.1369 + user = value; 1.1370 + else if (0 == strcmp(keyword, "PWD")) 1.1371 + password = value; 1.1372 + else if (0 == strcmp(keyword, "Port")) 1.1373 + port = (unsigned int) atol(value); 1.1374 + } 1.1375 + /* Connect to database */ 1.1376 + sql->con = dl_mysql_init(NULL); 1.1377 + if (!dl_mysql_real_connect(sql->con, server, user, password, database, 1.1378 + port, NULL, 0)) 1.1379 + { 1.1380 + xprintf("db_mysql_open: Connect failed\n"); 1.1381 + xprintf("%s\n", dl_mysql_error(sql->con)); 1.1382 + xfree(arg); 1.1383 + xfree(sql); 1.1384 + return NULL; 1.1385 + } 1.1386 + xfree(arg); 1.1387 + 1.1388 + for(j = 0; sqllines[j+1] != NULL; j++) 1.1389 + { query = (char *) sqllines[j]; 1.1390 + xprintf("%s\n", query); 1.1391 + if (dl_mysql_query(sql->con, query)) 1.1392 + { 1.1393 + xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); 1.1394 + xprintf("%s\n",dl_mysql_error(sql->con)); 1.1395 + dl_mysql_close(sql->con); 1.1396 + xfree(sql); 1.1397 + return NULL; 1.1398 + } 1.1399 + } 1.1400 + 1.1401 + if ( sql->mode == 'R' ) 1.1402 + { sql->nf = mpl_tab_num_flds(dca); 1.1403 + for(j = 0; sqllines[j] != NULL; j++) 1.1404 + arg = (char *) sqllines[j]; 1.1405 + total = strlen(arg); 1.1406 + if (total > 7 && 0 == strncmp(arg, "SELECT ", 7)) 1.1407 + { 1.1408 + total = strlen(arg); 1.1409 + query = xmalloc( (total+1) * sizeof(char)); 1.1410 + strcpy (query, arg); 1.1411 + } 1.1412 + else 1.1413 + { 1.1414 + query = db_generate_select_stmt(dca); 1.1415 + } 1.1416 + xprintf("%s\n", query); 1.1417 + if (dl_mysql_query(sql->con, query)) 1.1418 + { 1.1419 + xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); 1.1420 + xprintf("%s\n",dl_mysql_error(sql->con)); 1.1421 + dl_mysql_close(sql->con); 1.1422 + xfree(query); 1.1423 + xfree(sql); 1.1424 + return NULL; 1.1425 + } 1.1426 + xfree(query); 1.1427 + sql->res = dl_mysql_use_result(sql->con); 1.1428 + if (sql->res) 1.1429 + { 1.1430 + /* create references between query results and table fields*/ 1.1431 + total = dl_mysql_num_fields(sql->res); 1.1432 + if (total > SQL_FIELD_MAX) 1.1433 + { xprintf("db_mysql_open: Too many fields (> %d) in query.\n" 1.1434 + "\"%s\"\n", SQL_FIELD_MAX, query); 1.1435 + xprintf("%s\n",dl_mysql_error(sql->con)); 1.1436 + dl_mysql_close(sql->con); 1.1437 + xfree(query); 1.1438 + xfree(sql); 1.1439 + return NULL; 1.1440 + } 1.1441 + fields = dl_mysql_fetch_fields(sql->res); 1.1442 + for (i = 1; i <= total; i++) 1.1443 + { 1.1444 + for (j = sql->nf; j >= 1; j--) 1.1445 + { 1.1446 + if (strcmp(mpl_tab_get_name(dca, j), fields[i-1].name) 1.1447 + == 0) 1.1448 + break; 1.1449 + } 1.1450 + sql->ref[i] = j; 1.1451 + } 1.1452 + } 1.1453 + else 1.1454 + { 1.1455 + if(dl_mysql_field_count(sql->con) == 0) 1.1456 + { 1.1457 + xprintf("db_mysql_open: Query was not a SELECT\n\"%s\"\n", 1.1458 + query); 1.1459 + xprintf("%s\n",dl_mysql_error(sql->con)); 1.1460 + xfree(query); 1.1461 + xfree(sql); 1.1462 + return NULL; 1.1463 + } 1.1464 + else 1.1465 + { 1.1466 + xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query); 1.1467 + xprintf("%s\n",dl_mysql_error(sql->con)); 1.1468 + xfree(query); 1.1469 + xfree(sql); 1.1470 + return NULL; 1.1471 + } 1.1472 + } 1.1473 + } 1.1474 + else if ( sql->mode == 'W' ) 1.1475 + { for(j = 0; sqllines[j] != NULL; j++) 1.1476 + arg = (char *) sqllines[j]; 1.1477 + if ( NULL != strchr(arg, '?') ) 1.1478 + { 1.1479 + total = strlen(arg); 1.1480 + query = xmalloc( (total+1) * sizeof(char)); 1.1481 + strcpy (query, arg); 1.1482 + } 1.1483 + else 1.1484 + query = db_generate_insert_stmt(dca); 1.1485 + sql->query = query; 1.1486 + xprintf("%s\n", query); 1.1487 + } 1.1488 + return sql; 1.1489 +} 1.1490 + 1.1491 +int db_mysql_read(TABDCA *dca, void *link) 1.1492 +{ struct db_mysql *sql; 1.1493 + char buf[255+1]; 1.1494 + char **row; 1.1495 + unsigned long *lengths; 1.1496 + MYSQL_FIELD *fields; 1.1497 + double num; 1.1498 + int len; 1.1499 + unsigned long num_fields; 1.1500 + int i; 1.1501 + 1.1502 + sql = (struct db_mysql *) link; 1.1503 + 1.1504 + xassert(sql != NULL); 1.1505 + xassert(sql->mode == 'R'); 1.1506 + if (NULL == sql->res) 1.1507 + { 1.1508 + xprintf("db_mysql_read: no result set available"); 1.1509 + return 1; 1.1510 + } 1.1511 + if (NULL==(row = (char **)dl_mysql_fetch_row(sql->res))) { 1.1512 + return -1; /*EOF*/ 1.1513 + } 1.1514 + lengths = dl_mysql_fetch_lengths(sql->res); 1.1515 + fields = dl_mysql_fetch_fields(sql->res); 1.1516 + num_fields = dl_mysql_num_fields(sql->res); 1.1517 + for (i=1; i <= num_fields; i++) 1.1518 + { 1.1519 + if (row[i-1] != NULL) 1.1520 + { len = (size_t) lengths[i-1]; 1.1521 + if (len > 255) 1.1522 + len = 255; 1.1523 + strncpy(buf, (const char *) row[i-1], len); 1.1524 + buf[len] = 0x00; 1.1525 + if (0 != (fields[i-1].flags & NUM_FLAG)) 1.1526 + { strspx(buf); /* remove spaces*/ 1.1527 + if (str2num(buf, &num) != 0) 1.1528 + { xprintf("'%s' cannot be converted to a number.\n", buf); 1.1529 + return 1; 1.1530 + } 1.1531 + if (sql->ref[i] > 0) 1.1532 + mpl_tab_set_num(dca, sql->ref[i], num); 1.1533 + } 1.1534 + else 1.1535 + { if (sql->ref[i] > 0) 1.1536 + mpl_tab_set_str(dca, sql->ref[i], strtrim(buf)); 1.1537 + } 1.1538 + } 1.1539 + } 1.1540 + return 0; 1.1541 +} 1.1542 + 1.1543 +int db_mysql_write(TABDCA *dca, void *link) 1.1544 +{ 1.1545 + struct db_mysql *sql; 1.1546 + char *part; 1.1547 + char *query; 1.1548 + char *template; 1.1549 + char num[50]; 1.1550 + int k; 1.1551 + int len; 1.1552 + int nf; 1.1553 + 1.1554 + sql = (struct db_mysql *) link; 1.1555 + xassert(sql != NULL); 1.1556 + xassert(sql->mode == 'W'); 1.1557 + 1.1558 + len = strlen(sql->query); 1.1559 + template = (char *) xmalloc( (len + 1) * sizeof(char) ); 1.1560 + strcpy(template, sql->query); 1.1561 + 1.1562 + nf = mpl_tab_num_flds(dca); 1.1563 + for (k = 1; k <= nf; k++) 1.1564 + { switch (mpl_tab_get_type(dca, k)) 1.1565 + { case 'N': 1.1566 + len += 20; 1.1567 + break; 1.1568 + case 'S': 1.1569 + len += db_escaped_string_length(mpl_tab_get_str(dca, k)); 1.1570 + len += 2; 1.1571 + break; 1.1572 + default: 1.1573 + xassert(dca != dca); 1.1574 + } 1.1575 + } 1.1576 + query = xmalloc( (len + 1 ) * sizeof(char) ); 1.1577 + query[0] = 0x00; 1.1578 + for (k = 1, part = strtok (template, "?"); (part != NULL); 1.1579 + part = strtok (NULL, "?"), k++) 1.1580 + { 1.1581 + if (k > nf) break; 1.1582 + strcat( query, part ); 1.1583 + switch (mpl_tab_get_type(dca, k)) 1.1584 + { case 'N': 1.1585 +#if 0 /* 02/XI-2010 by xypron */ 1.1586 + sprintf(num, "%-18g",mpl_tab_get_num(dca, k)); 1.1587 +#else 1.1588 + sprintf(num, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k)); 1.1589 +#endif 1.1590 + strcat( query, num ); 1.1591 + break; 1.1592 + case 'S': 1.1593 + strcat( query, "'"); 1.1594 + db_escape_string( query + strlen(query), 1.1595 + mpl_tab_get_str(dca, k) ); 1.1596 + strcat( query, "'"); 1.1597 + break; 1.1598 + default: 1.1599 + xassert(dca != dca); 1.1600 + } 1.1601 + } 1.1602 + if (part != NULL) 1.1603 + strcat(query, part); 1.1604 + if (dl_mysql_query(sql->con, query)) 1.1605 + { 1.1606 + xprintf("db_mysql_write: Query\n\"%s\"\nfailed.\n", query); 1.1607 + xprintf("%s\n",dl_mysql_error(sql->con)); 1.1608 + xfree(query); 1.1609 + xfree(template); 1.1610 + return 1; 1.1611 + } 1.1612 + 1.1613 + xfree(query); 1.1614 + xfree(template); 1.1615 + return 0; 1.1616 + } 1.1617 + 1.1618 +int db_mysql_close(TABDCA *dca, void *link) 1.1619 +{ 1.1620 + struct db_mysql *sql; 1.1621 + 1.1622 + sql = (struct db_mysql *) link; 1.1623 + xassert(sql != NULL); 1.1624 + dl_mysql_close(sql->con); 1.1625 + if ( sql->mode == 'W' ) 1.1626 + xfree(sql->query); 1.1627 + xfree(sql); 1.1628 + dca->link = NULL; 1.1629 + return 0; 1.1630 +} 1.1631 + 1.1632 +#endif 1.1633 + 1.1634 +/* eof */