lemon-project-template-glpk
view deps/glpk/src/glpsql.c @ 11:4fc6ad2fb8a6
Test GLPK in src/main.cc
author | Alpar Juttner <alpar@cs.elte.hu> |
---|---|
date | Sun, 06 Nov 2011 21:43:29 +0100 |
parents | |
children |
line source
1 /* glpsql.c */
3 /***********************************************************************
4 * This code is part of GLPK (GNU Linear Programming Kit).
5 *
6 * Author: Heinrich Schuchardt <xypron.glpk@gmx.de>.
7 *
8 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
9 * 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
10 * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
11 * E-mail: <mao@gnu.org>.
12 *
13 * GLPK is free software: you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * GLPK is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
21 * License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
25 ***********************************************************************/
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
31 #include "glpmpl.h"
32 #include "glpsql.h"
34 #ifdef ODBC_DLNAME
35 #define HAVE_ODBC
36 #define libodbc ODBC_DLNAME
37 #define h_odbc (get_env_ptr()->h_odbc)
38 #endif
40 #ifdef MYSQL_DLNAME
41 #define HAVE_MYSQL
42 #define libmysql MYSQL_DLNAME
43 #define h_mysql (get_env_ptr()->h_mysql)
44 #endif
46 static void *db_iodbc_open_int(TABDCA *dca, int mode, const char
47 **sqllines);
48 static void *db_mysql_open_int(TABDCA *dca, int mode, const char
49 **sqllines);
51 /**********************************************************************/
53 #if defined(HAVE_ODBC) || defined(HAVE_MYSQL)
55 #define SQL_FIELD_MAX 100
56 /* maximal field count */
58 #define SQL_FDLEN_MAX 255
59 /* maximal field length */
61 /***********************************************************************
62 * NAME
63 *
64 * args_concat - concatenate arguments
65 *
66 * SYNOPSIS
67 *
68 * static char **args_concat(TABDCA *dca);
69 *
70 * DESCRIPTION
71 *
72 * The arguments passed in dca are SQL statements. A SQL statement may
73 * be split over multiple arguments. The last argument of a SQL
74 * statement will be terminated with a semilocon. Each SQL statement is
75 * merged into a single zero terminated string. Boundaries between
76 * arguments are replaced by space.
77 *
78 * RETURNS
79 *
80 * Buffer with SQL statements */
82 static char **args_concat(TABDCA *dca)
83 {
84 const char *arg;
85 int i;
86 int j;
87 int j0;
88 int j1;
89 int len;
90 int lentot;
91 int narg;
92 int nline = 0;
93 void *ret;
94 char **sqllines = NULL;
96 narg = mpl_tab_num_args(dca);
97 /* The SQL statements start with argument 3. */
98 if (narg < 3)
99 return NULL;
100 /* Count the SQL statements */
101 for (j = 3; j <= narg; j++)
102 {
103 arg = mpl_tab_get_arg(dca, j);
104 len = strlen(arg);
105 if (arg[len-1] == ';' || j == narg)
106 nline ++;
107 }
108 /* Allocate string buffer. */
109 sqllines = (char **) xmalloc((nline+1) * sizeof(char **));
110 /* Join arguments */
111 sqllines[0] = NULL;
112 j0 = 3;
113 i = 0;
114 lentot = 0;
115 for (j = 3; j <= narg; j++)
116 {
117 arg = mpl_tab_get_arg(dca, j);
118 len = strlen(arg);
119 /* add length of part */
120 lentot += len;
121 /* add length of space separating parts or 0x00 at end of SQL
122 statement */
123 lentot++;
124 if (arg[len-1] == ';' || j == narg)
125 { /* Join arguments for a single SQL statement */
126 sqllines[i] = xmalloc(lentot);
127 sqllines[i+1] = NULL;
128 sqllines[i][0] = 0x00;
129 for (j1 = j0; j1 <= j; j1++)
130 { if(j1>j0)
131 strcat(sqllines[i], " ");
132 strcat(sqllines[i], mpl_tab_get_arg(dca, j1));
133 }
134 len = strlen(sqllines[i]);
135 if (sqllines[i][len-1] == ';')
136 sqllines[i][len-1] = 0x00;
137 j0 = j+1;
138 i++;
139 lentot = 0;
140 }
141 }
142 return sqllines;
143 }
145 /***********************************************************************
146 * NAME
147 *
148 * free_buffer - free multiline string buffer
149 *
150 * SYNOPSIS
151 *
152 * static void free_buffer(char **buf);
153 *
154 * DESCRIPTION
155 *
156 * buf is a list of strings terminated by NULL.
157 * The memory for the strings and for the list is released. */
159 static void free_buffer(char **buf)
160 { int i;
162 for(i = 0; buf[i] != NULL; i++)
163 xfree(buf[i]);
164 xfree(buf);
165 }
167 static int db_escaped_string_length(const char* from)
168 /* length of escaped string */
169 {
170 int count;
171 const char *pointer;
173 for (pointer = from, count = 0; *pointer != (char) '\0'; pointer++,
174 count++)
175 {
176 switch (*pointer)
177 {
178 case '\'':
179 count++;
180 break;
181 }
182 }
184 return count;
185 }
187 static int db_escape_string (char *to, const char *from)
188 /* escape string*/
189 {
190 const char *source = from;
191 char *target = to;
192 unsigned int remaining;
194 remaining = strlen(from);
196 if (to == NULL)
197 to = (char *) (from + remaining);
199 while (remaining > 0)
200 {
201 switch (*source)
202 {
203 case '\'':
204 *target = '\'';
205 target++;
206 *target = '\'';
207 break;
209 default:
210 *target = *source;
211 }
212 source++;
213 target++;
214 remaining--;
215 }
217 /* Write the terminating NUL character. */
218 *target = '\0';
220 return target - to;
221 }
223 static char *db_generate_select_stmt(TABDCA *dca)
224 /* generate select statement */
225 {
226 char *arg;
227 char const *field;
228 char *query;
229 int j;
230 int narg;
231 int nf;
232 int total;
234 total = 50;
235 nf = mpl_tab_num_flds(dca);
236 narg = mpl_tab_num_args(dca);
237 for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
238 {
239 field = mpl_tab_get_name(dca, j);
240 total += strlen(field);
241 total += 2;
242 }
243 arg = (char *) mpl_tab_get_arg(dca, narg);
244 total += strlen(arg);
245 query = xmalloc( total * sizeof(char));
246 strcpy (query, "SELECT ");
247 for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
248 {
249 field = mpl_tab_get_name(dca, j);
250 strcat(query, field);
251 if ( j < nf )
252 strcat(query, ", ");
253 }
254 strcat(query, " FROM ");
255 strcat(query, arg);
256 return query;
257 }
259 static char *db_generate_insert_stmt(TABDCA *dca)
260 /* generate insert statement */
261 {
262 char *arg;
263 char const *field;
264 char *query;
265 int j;
266 int narg;
267 int nf;
268 int total;
270 total = 50;
271 nf = mpl_tab_num_flds(dca);
272 narg = mpl_tab_num_args(dca);
273 for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
274 {
275 field = mpl_tab_get_name(dca, j);
276 total += strlen(field);
277 total += 5;
278 }
279 arg = (char *) mpl_tab_get_arg(dca, narg);
280 total += strlen(arg);
281 query = xmalloc( (total+1) * sizeof(char));
282 strcpy (query, "INSERT INTO ");
283 strcat(query, arg);
284 strcat(query, " ( ");
285 for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
286 {
287 field = mpl_tab_get_name(dca, j);
288 strcat(query, field);
289 if ( j < nf )
290 strcat(query, ", ");
291 }
292 strcat(query, " ) VALUES ( ");
293 for (j=1; j <= nf && j <= SQL_FIELD_MAX; j++)
294 {
295 strcat(query, "?");
296 if ( j < nf )
297 strcat(query, ", ");
298 }
299 strcat(query, " )");
300 return query;
301 }
303 #endif
305 /**********************************************************************/
307 #ifndef HAVE_ODBC
309 void *db_iodbc_open(TABDCA *dca, int mode)
310 { xassert(dca == dca);
311 xassert(mode == mode);
312 xprintf("iODBC table driver not supported\n");
313 return NULL;
314 }
316 int db_iodbc_read(TABDCA *dca, void *link)
317 { xassert(dca != dca);
318 xassert(link != link);
319 return 0;
320 }
322 int db_iodbc_write(TABDCA *dca, void *link)
323 { xassert(dca != dca);
324 xassert(link != link);
325 return 0;
326 }
328 int db_iodbc_close(TABDCA *dca, void *link)
329 { xassert(dca != dca);
330 xassert(link != link);
331 return 0;
332 }
334 #else
336 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__)
337 #include <windows.h>
338 #endif
340 #include <sql.h>
341 #include <sqlext.h>
343 struct db_odbc
344 {
345 int mode; /*'R' = Read, 'W' = Write*/
346 SQLHDBC hdbc; /*connection handle*/
347 SQLHENV henv; /*environment handle*/
348 SQLHSTMT hstmt; /*statement handle*/
349 SQLSMALLINT nresultcols; /* columns in result*/
350 SQLULEN collen[SQL_FIELD_MAX+1];
351 SQLLEN outlen[SQL_FIELD_MAX+1];
352 SQLSMALLINT coltype[SQL_FIELD_MAX+1];
353 SQLCHAR data[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1];
354 SQLCHAR colname[SQL_FIELD_MAX+1][SQL_FDLEN_MAX+1];
355 int isnumeric[SQL_FIELD_MAX+1];
356 int nf;
357 /* number of fields in the csv file */
358 int ref[1+SQL_FIELD_MAX];
359 /* ref[k] = k', if k-th field of the csv file corresponds to
360 k'-th field in the table statement; if ref[k] = 0, k-th field
361 of the csv file is ignored */
362 SQLCHAR *query;
363 /* query generated by db_iodbc_open */
364 };
366 SQLRETURN SQL_API dl_SQLAllocHandle (
367 SQLSMALLINT HandleType,
368 SQLHANDLE InputHandle,
369 SQLHANDLE *OutputHandle)
370 {
371 typedef SQLRETURN SQL_API ep_SQLAllocHandle(
372 SQLSMALLINT HandleType,
373 SQLHANDLE InputHandle,
374 SQLHANDLE *OutputHandle);
376 ep_SQLAllocHandle *fn;
377 fn = (ep_SQLAllocHandle *) xdlsym(h_odbc, "SQLAllocHandle");
378 xassert(fn != NULL);
379 return (*fn)(HandleType, InputHandle, OutputHandle);
380 }
382 SQLRETURN SQL_API dl_SQLBindCol (
383 SQLHSTMT StatementHandle,
384 SQLUSMALLINT ColumnNumber,
385 SQLSMALLINT TargetType,
386 SQLPOINTER TargetValue,
387 SQLLEN BufferLength,
388 SQLLEN *StrLen_or_Ind)
389 {
390 typedef SQLRETURN SQL_API ep_SQLBindCol(
391 SQLHSTMT StatementHandle,
392 SQLUSMALLINT ColumnNumber,
393 SQLSMALLINT TargetType,
394 SQLPOINTER TargetValue,
395 SQLLEN BufferLength,
396 SQLLEN *StrLen_or_Ind);
397 ep_SQLBindCol *fn;
398 fn = (ep_SQLBindCol *) xdlsym(h_odbc, "SQLBindCol");
399 xassert(fn != NULL);
400 return (*fn)(StatementHandle, ColumnNumber, TargetType,
401 TargetValue, BufferLength, StrLen_or_Ind);
402 }
404 SQLRETURN SQL_API dl_SQLCloseCursor (
405 SQLHSTMT StatementHandle)
406 {
407 typedef SQLRETURN SQL_API ep_SQLCloseCursor (
408 SQLHSTMT StatementHandle);
410 ep_SQLCloseCursor *fn;
411 fn = (ep_SQLCloseCursor *) xdlsym(h_odbc, "SQLCloseCursor");
412 xassert(fn != NULL);
413 return (*fn)(StatementHandle);
414 }
417 SQLRETURN SQL_API dl_SQLDisconnect (
418 SQLHDBC ConnectionHandle)
419 {
420 typedef SQLRETURN SQL_API ep_SQLDisconnect(
421 SQLHDBC ConnectionHandle);
423 ep_SQLDisconnect *fn;
424 fn = (ep_SQLDisconnect *) xdlsym(h_odbc, "SQLDisconnect");
425 xassert(fn != NULL);
426 return (*fn)(ConnectionHandle);
427 }
429 SQLRETURN SQL_API dl_SQLDriverConnect (
430 SQLHDBC hdbc,
431 SQLHWND hwnd,
432 SQLCHAR *szConnStrIn,
433 SQLSMALLINT cbConnStrIn,
434 SQLCHAR *szConnStrOut,
435 SQLSMALLINT cbConnStrOutMax,
436 SQLSMALLINT *pcbConnStrOut,
437 SQLUSMALLINT fDriverCompletion)
438 {
439 typedef SQLRETURN SQL_API ep_SQLDriverConnect(
440 SQLHDBC hdbc,
441 SQLHWND hwnd,
442 SQLCHAR * szConnStrIn,
443 SQLSMALLINT cbConnStrIn,
444 SQLCHAR * szConnStrOut,
445 SQLSMALLINT cbConnStrOutMax,
446 SQLSMALLINT * pcbConnStrOut,
447 SQLUSMALLINT fDriverCompletion);
449 ep_SQLDriverConnect *fn;
450 fn = (ep_SQLDriverConnect *) xdlsym(h_odbc, "SQLDriverConnect");
451 xassert(fn != NULL);
452 return (*fn)(hdbc, hwnd, szConnStrIn, cbConnStrIn, szConnStrOut,
453 cbConnStrOutMax, pcbConnStrOut, fDriverCompletion);
454 }
456 SQLRETURN SQL_API dl_SQLEndTran (
457 SQLSMALLINT HandleType,
458 SQLHANDLE Handle,
459 SQLSMALLINT CompletionType)
460 {
461 typedef SQLRETURN SQL_API ep_SQLEndTran (
462 SQLSMALLINT HandleType,
463 SQLHANDLE Handle,
464 SQLSMALLINT CompletionType);
466 ep_SQLEndTran *fn;
467 fn = (ep_SQLEndTran *) xdlsym(h_odbc, "SQLEndTran");
468 xassert(fn != NULL);
469 return (*fn)(HandleType, Handle, CompletionType);
470 }
472 SQLRETURN SQL_API dl_SQLExecDirect (
473 SQLHSTMT StatementHandle,
474 SQLCHAR * StatementText,
475 SQLINTEGER TextLength)
476 {
477 typedef SQLRETURN SQL_API ep_SQLExecDirect (
478 SQLHSTMT StatementHandle,
479 SQLCHAR * StatementText,
480 SQLINTEGER TextLength);
482 ep_SQLExecDirect *fn;
483 fn = (ep_SQLExecDirect *) xdlsym(h_odbc, "SQLExecDirect");
484 xassert(fn != NULL);
485 return (*fn)(StatementHandle, StatementText, TextLength);
486 }
488 SQLRETURN SQL_API dl_SQLFetch (
489 SQLHSTMT StatementHandle)
490 {
491 typedef SQLRETURN SQL_API ep_SQLFetch (
492 SQLHSTMT StatementHandle);
494 ep_SQLFetch *fn;
495 fn = (ep_SQLFetch*) xdlsym(h_odbc, "SQLFetch");
496 xassert(fn != NULL);
497 return (*fn)(StatementHandle);
498 }
500 SQLRETURN SQL_API dl_SQLFreeHandle (
501 SQLSMALLINT HandleType,
502 SQLHANDLE Handle)
503 {
504 typedef SQLRETURN SQL_API ep_SQLFreeHandle (
505 SQLSMALLINT HandleType,
506 SQLHANDLE Handle);
508 ep_SQLFreeHandle *fn;
509 fn = (ep_SQLFreeHandle *) xdlsym(h_odbc, "SQLFreeHandle");
510 xassert(fn != NULL);
511 return (*fn)(HandleType, Handle);
512 }
514 SQLRETURN SQL_API dl_SQLDescribeCol (
515 SQLHSTMT StatementHandle,
516 SQLUSMALLINT ColumnNumber,
517 SQLCHAR * ColumnName,
518 SQLSMALLINT BufferLength,
519 SQLSMALLINT * NameLength,
520 SQLSMALLINT * DataType,
521 SQLULEN * ColumnSize,
522 SQLSMALLINT * DecimalDigits,
523 SQLSMALLINT * Nullable)
524 {
525 typedef SQLRETURN SQL_API ep_SQLDescribeCol (
526 SQLHSTMT StatementHandle,
527 SQLUSMALLINT ColumnNumber,
528 SQLCHAR *ColumnName,
529 SQLSMALLINT BufferLength,
530 SQLSMALLINT *NameLength,
531 SQLSMALLINT *DataType,
532 SQLULEN *ColumnSize,
533 SQLSMALLINT *DecimalDigits,
534 SQLSMALLINT *Nullable);
536 ep_SQLDescribeCol *fn;
537 fn = (ep_SQLDescribeCol *) xdlsym(h_odbc, "SQLDescribeCol");
538 xassert(fn != NULL);
539 return (*fn)(StatementHandle, ColumnNumber, ColumnName,
540 BufferLength, NameLength,
541 DataType, ColumnSize, DecimalDigits, Nullable);
542 }
544 SQLRETURN SQL_API dl_SQLGetDiagRec (
545 SQLSMALLINT HandleType,
546 SQLHANDLE Handle,
547 SQLSMALLINT RecNumber,
548 SQLCHAR *Sqlstate,
549 SQLINTEGER *NativeError,
550 SQLCHAR *MessageText,
551 SQLSMALLINT BufferLength,
552 SQLSMALLINT *TextLength)
553 {
554 typedef SQLRETURN SQL_API ep_SQLGetDiagRec (
555 SQLSMALLINT HandleType,
556 SQLHANDLE Handle,
557 SQLSMALLINT RecNumber,
558 SQLCHAR *Sqlstate,
559 SQLINTEGER *NativeError,
560 SQLCHAR *MessageText,
561 SQLSMALLINT BufferLength,
562 SQLSMALLINT *TextLength);
564 ep_SQLGetDiagRec *fn;
565 fn = (ep_SQLGetDiagRec *) xdlsym(h_odbc, "SQLGetDiagRec");
566 xassert(fn != NULL);
567 return (*fn)(HandleType, Handle, RecNumber, Sqlstate,
568 NativeError, MessageText, BufferLength, TextLength);
569 }
571 SQLRETURN SQL_API dl_SQLGetInfo (
572 SQLHDBC ConnectionHandle,
573 SQLUSMALLINT InfoType,
574 SQLPOINTER InfoValue,
575 SQLSMALLINT BufferLength,
576 SQLSMALLINT *StringLength)
577 {
578 typedef SQLRETURN SQL_API ep_SQLGetInfo (
579 SQLHDBC ConnectionHandle,
580 SQLUSMALLINT InfoType,
581 SQLPOINTER InfoValue,
582 SQLSMALLINT BufferLength,
583 SQLSMALLINT *StringLength);
585 ep_SQLGetInfo *fn;
586 fn = (ep_SQLGetInfo *) xdlsym(h_odbc, "SQLGetInfo");
587 xassert(fn != NULL);
588 return (*fn)(ConnectionHandle, InfoType, InfoValue, BufferLength,
589 StringLength);
590 }
592 SQLRETURN SQL_API dl_SQLNumResultCols (
593 SQLHSTMT StatementHandle,
594 SQLSMALLINT *ColumnCount)
595 {
596 typedef SQLRETURN SQL_API ep_SQLNumResultCols (
597 SQLHSTMT StatementHandle,
598 SQLSMALLINT *ColumnCount);
600 ep_SQLNumResultCols *fn;
601 fn = (ep_SQLNumResultCols *) xdlsym(h_odbc, "SQLNumResultCols");
602 xassert(fn != NULL);
603 return (*fn)(StatementHandle, ColumnCount);
604 }
606 SQLRETURN SQL_API dl_SQLSetConnectAttr (
607 SQLHDBC ConnectionHandle,
608 SQLINTEGER Attribute,
609 SQLPOINTER Value,
610 SQLINTEGER StringLength)
611 {
612 typedef SQLRETURN SQL_API ep_SQLSetConnectAttr (
613 SQLHDBC ConnectionHandle,
614 SQLINTEGER Attribute,
615 SQLPOINTER Value,
616 SQLINTEGER StringLength);
618 ep_SQLSetConnectAttr *fn;
619 fn = (ep_SQLSetConnectAttr *) xdlsym(h_odbc, "SQLSetConnectAttr");
620 xassert(fn != NULL);
621 return (*fn)(ConnectionHandle, Attribute, Value, StringLength);
622 }
624 SQLRETURN SQL_API dl_SQLSetEnvAttr (
625 SQLHENV EnvironmentHandle,
626 SQLINTEGER Attribute,
627 SQLPOINTER Value,
628 SQLINTEGER StringLength)
629 {
630 typedef SQLRETURN SQL_API ep_SQLSetEnvAttr (
631 SQLHENV EnvironmentHandle,
632 SQLINTEGER Attribute,
633 SQLPOINTER Value,
634 SQLINTEGER StringLength);
636 ep_SQLSetEnvAttr *fn;
637 fn = (ep_SQLSetEnvAttr *) xdlsym(h_odbc, "SQLSetEnvAttr");
638 xassert(fn != NULL);
639 return (*fn)(EnvironmentHandle, Attribute, Value, StringLength);
640 }
642 static void extract_error(
643 char *fn,
644 SQLHANDLE handle,
645 SQLSMALLINT type);
647 static int is_numeric(
648 SQLSMALLINT coltype);
650 /***********************************************************************
651 * NAME
652 *
653 * db_iodbc_open - open connection to ODBC data base
654 *
655 * SYNOPSIS
656 *
657 * #include "glpsql.h"
658 * void *db_iodbc_open(TABDCA *dca, int mode);
659 *
660 * DESCRIPTION
661 *
662 * The routine db_iodbc_open opens a connection to an ODBC data base.
663 * It then executes the sql statements passed.
664 *
665 * In the case of table read the SELECT statement is executed.
666 *
667 * In the case of table write the INSERT statement is prepared.
668 * RETURNS
669 *
670 * The routine returns a pointer to data storage area created. */
671 void *db_iodbc_open(TABDCA *dca, int mode)
672 { void *ret;
673 char **sqllines;
675 sqllines = args_concat(dca);
676 if (sqllines == NULL)
677 { xprintf("Missing arguments in table statement.\n"
678 "Please, supply table driver, dsn, and query.\n");
679 return NULL;
680 }
681 ret = db_iodbc_open_int(dca, mode, (const char **) sqllines);
682 free_buffer(sqllines);
683 return ret;
684 }
686 static void *db_iodbc_open_int(TABDCA *dca, int mode, const char
687 **sqllines)
688 {
689 struct db_odbc *sql;
690 SQLRETURN ret;
691 SQLCHAR FAR *dsn;
692 SQLCHAR info[256];
693 SQLSMALLINT colnamelen;
694 SQLSMALLINT nullable;
695 SQLSMALLINT scale;
696 const char *arg;
697 int narg;
698 int i, j;
699 int total;
701 if (libodbc == NULL)
702 {
703 xprintf("No loader for shared ODBC library available\n");
704 return NULL;
705 }
707 if (h_odbc == NULL)
708 {
709 h_odbc = xdlopen(libodbc);
710 if (h_odbc == NULL)
711 { xprintf("unable to open library %s\n", libodbc);
712 xprintf("%s\n", xerrmsg());
713 return NULL;
714 }
715 }
717 sql = (struct db_odbc *) xmalloc(sizeof(struct db_odbc));
718 if (sql == NULL)
719 return NULL;
721 sql->mode = mode;
722 sql->hdbc = NULL;
723 sql->henv = NULL;
724 sql->hstmt = NULL;
725 sql->query = NULL;
726 narg = mpl_tab_num_args(dca);
728 dsn = (SQLCHAR FAR *) mpl_tab_get_arg(dca, 2);
729 /* allocate an environment handle */
730 ret = dl_SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
731 &(sql->henv));
732 /* set attribute to enable application to run as ODBC 3.0
733 application */
734 ret = dl_SQLSetEnvAttr(sql->henv, SQL_ATTR_ODBC_VERSION,
735 (void *) SQL_OV_ODBC3, 0);
736 /* allocate a connection handle */
737 ret = dl_SQLAllocHandle(SQL_HANDLE_DBC, sql->henv, &(sql->hdbc));
738 /* connect */
739 ret = dl_SQLDriverConnect(sql->hdbc, NULL, dsn, SQL_NTS, NULL, 0,
740 NULL, SQL_DRIVER_COMPLETE);
741 if (SQL_SUCCEEDED(ret))
742 { /* output information about data base connection */
743 xprintf("Connected to ");
744 dl_SQLGetInfo(sql->hdbc, SQL_DBMS_NAME, (SQLPOINTER)info,
745 sizeof(info), NULL);
746 xprintf("%s ", info);
747 dl_SQLGetInfo(sql->hdbc, SQL_DBMS_VER, (SQLPOINTER)info,
748 sizeof(info), NULL);
749 xprintf("%s - ", info);
750 dl_SQLGetInfo(sql->hdbc, SQL_DATABASE_NAME, (SQLPOINTER)info,
751 sizeof(info), NULL);
752 xprintf("%s\n", info);
753 }
754 else
755 { /* describe error */
756 xprintf("Failed to connect\n");
757 extract_error("SQLDriverConnect", sql->hdbc, SQL_HANDLE_DBC);
758 dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
759 dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
760 xfree(sql);
761 return NULL;
762 }
763 /* set AUTOCOMMIT on*/
764 ret = dl_SQLSetConnectAttr(sql->hdbc, SQL_ATTR_AUTOCOMMIT,
765 (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0);
766 /* allocate a statement handle */
767 ret = dl_SQLAllocHandle(SQL_HANDLE_STMT, sql->hdbc, &(sql->hstmt));
769 /* initialization queries */
770 for(j = 0; sqllines[j+1] != NULL; j++)
771 {
772 sql->query = (SQLCHAR *) sqllines[j];
773 xprintf("%s\n", sql->query);
774 ret = dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS);
775 switch (ret)
776 {
777 case SQL_SUCCESS:
778 case SQL_SUCCESS_WITH_INFO:
779 case SQL_NO_DATA_FOUND:
780 break;
781 default:
782 xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n",
783 sql->query);
784 extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT);
785 dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
786 dl_SQLDisconnect(sql->hdbc);
787 dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
788 dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
789 xfree(sql);
790 return NULL;
791 }
792 /* commit statement */
793 dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT);
794 }
796 if ( sql->mode == 'R' )
797 { sql->nf = mpl_tab_num_flds(dca);
798 for(j = 0; sqllines[j] != NULL; j++)
799 arg = sqllines[j];
800 total = strlen(arg);
801 if (total > 7 && 0 == strncmp(arg, "SELECT ", 7))
802 {
803 total = strlen(arg);
804 sql->query = xmalloc( (total+1) * sizeof(char));
805 strcpy (sql->query, arg);
806 }
807 else
808 {
809 sql->query = db_generate_select_stmt(dca);
810 }
811 xprintf("%s\n", sql->query);
812 if (dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS) !=
813 SQL_SUCCESS)
814 {
815 xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query);
816 extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT);
817 dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
818 dl_SQLDisconnect(sql->hdbc);
819 dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
820 dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
821 xfree(sql->query);
822 xfree(sql);
823 return NULL;
824 }
825 xfree(sql->query);
826 /* determine number of result columns */
827 ret = dl_SQLNumResultCols(sql->hstmt, &sql->nresultcols);
828 total = sql->nresultcols;
829 if (total > SQL_FIELD_MAX)
830 { xprintf("db_iodbc_open: Too many fields (> %d) in query.\n"
831 "\"%s\"\n", SQL_FIELD_MAX, sql->query);
832 dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
833 dl_SQLDisconnect(sql->hdbc);
834 dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
835 dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
836 xfree(sql->query);
837 return NULL;
838 }
839 for (i = 1; i <= total; i++)
840 { /* return a set of attributes for a column */
841 ret = dl_SQLDescribeCol(sql->hstmt, (SQLSMALLINT) i,
842 sql->colname[i], SQL_FDLEN_MAX,
843 &colnamelen, &(sql->coltype[i]), &(sql->collen[i]), &scale,
844 &nullable);
845 sql->isnumeric[i] = is_numeric(sql->coltype[i]);
846 /* bind columns to program vars, converting all types to CHAR*/
847 if (sql->isnumeric[i])
848 { dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, sql->data[i],
849 SQL_FDLEN_MAX, &(sql->outlen[i]));
850 } else
851 { dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i],
852 SQL_FDLEN_MAX, &(sql->outlen[i]));
853 }
854 for (j = sql->nf; j >= 1; j--)
855 { if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0)
856 break;
857 }
858 sql->ref[i] = j;
859 }
860 }
861 else if ( sql->mode == 'W' )
862 { for(j = 0; sqllines[j] != NULL; j++)
863 arg = sqllines[j];
864 if ( NULL != strchr(arg, '?') )
865 {
866 total = strlen(arg);
867 sql->query = xmalloc( (total+1) * sizeof(char));
868 strcpy (sql->query, arg);
869 }
870 else
871 {
872 sql->query = db_generate_insert_stmt(dca);
873 }
874 xprintf("%s\n", sql->query);
875 }
876 return sql;
877 }
879 int db_iodbc_read(TABDCA *dca, void *link)
880 {
881 struct db_odbc *sql;
882 SQLRETURN ret;
883 char buf[SQL_FDLEN_MAX+1];
884 int i;
885 int len;
886 double num;
888 sql = (struct db_odbc *) link;
890 xassert(sql != NULL);
891 xassert(sql->mode == 'R');
893 ret=dl_SQLFetch(sql->hstmt);
894 if (ret== SQL_ERROR)
895 return -1;
896 if (ret== SQL_NO_DATA_FOUND)
897 return -1; /*EOF*/
898 for (i=1; i <= sql->nresultcols; i++)
899 {
900 if (sql->ref[i] > 0)
901 {
902 len = sql->outlen[i];
903 if (len != SQL_NULL_DATA)
904 {
905 if (sql->isnumeric[i])
906 { mpl_tab_set_num(dca, sql->ref[i],
907 *((const double *) sql->data[i]));
908 }
909 else
910 { if (len > SQL_FDLEN_MAX)
911 len = SQL_FDLEN_MAX;
912 else if (len < 0)
913 len = 0;
914 strncpy(buf, (const char *) sql->data[i], len);
915 buf[len] = 0x00;
916 mpl_tab_set_str(dca, sql->ref[i], strtrim(buf));
917 }
918 }
919 }
920 }
921 return 0;
922 }
924 int db_iodbc_write(TABDCA *dca, void *link)
925 {
926 struct db_odbc *sql;
927 char *part;
928 char *query;
929 char *template;
930 char num[50];
931 int k;
932 int len;
933 int nf;
935 sql = (struct db_odbc *) link;
936 xassert(sql != NULL);
937 xassert(sql->mode == 'W');
939 len = strlen(sql->query);
940 template = (char *) xmalloc( (len + 1) * sizeof(char) );
941 strcpy(template, sql->query);
943 nf = mpl_tab_num_flds(dca);
944 for (k = 1; k <= nf; k++)
945 { switch (mpl_tab_get_type(dca, k))
946 { case 'N':
947 len += 20;
948 break;
949 case 'S':
950 len += db_escaped_string_length(mpl_tab_get_str(dca, k));
951 len += 2;
952 break;
953 default:
954 xassert(dca != dca);
955 }
956 }
957 query = xmalloc( (len + 1 ) * sizeof(char) );
958 query[0] = 0x00;
959 for (k = 1, part = strtok (template, "?"); (part != NULL);
960 part = strtok (NULL, "?"), k++)
961 {
962 if (k > nf) break;
963 strcat( query, part );
964 switch (mpl_tab_get_type(dca, k))
965 { case 'N':
966 #if 0 /* 02/XI-2010 by xypron */
967 sprintf(num, "%-18g",mpl_tab_get_num(dca, k));
968 #else
969 sprintf(num, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k));
970 #endif
971 strcat( query, num );
972 break;
973 case 'S':
974 strcat( query, "'");
975 db_escape_string( query + strlen(query),
976 mpl_tab_get_str(dca, k) );
977 strcat( query, "'");
978 break;
979 default:
980 xassert(dca != dca);
981 }
982 }
983 if (part != NULL)
984 strcat(query, part);
985 if (dl_SQLExecDirect(sql->hstmt, (SQLCHAR *) query, SQL_NTS)
986 != SQL_SUCCESS)
987 {
988 xprintf("db_iodbc_write: Query\n\"%s\"\nfailed.\n", query);
989 extract_error("SQLExecDirect", sql->hdbc, SQL_HANDLE_DBC);
990 xfree(query);
991 xfree(template);
992 return 1;
993 }
995 xfree(query);
996 xfree(template);
997 return 0;
998 }
1000 int db_iodbc_close(TABDCA *dca, void *link)
1001 {
1002 struct db_odbc *sql;
1004 sql = (struct db_odbc *) link;
1005 xassert(sql != NULL);
1006 /* Commit */
1007 if ( sql->mode == 'W' )
1008 dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT);
1009 if ( sql->mode == 'R' )
1010 dl_SQLCloseCursor(sql->hstmt);
1012 dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
1013 dl_SQLDisconnect(sql->hdbc);
1014 dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
1015 dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
1016 if ( sql->mode == 'W' )
1017 xfree(sql->query);
1018 xfree(sql);
1019 dca->link = NULL;
1020 return 0;
1021 }
1023 static void extract_error(
1024 char *fn,
1025 SQLHANDLE handle,
1026 SQLSMALLINT type)
1027 {
1028 SQLINTEGER i = 0;
1029 SQLINTEGER native;
1030 SQLCHAR state[ 7 ];
1031 SQLCHAR text[256];
1032 SQLSMALLINT len;
1033 SQLRETURN ret;
1035 xprintf("\nThe driver reported the following diagnostics whilst "
1036 "running %s\n", fn);
1038 do
1039 {
1040 ret = dl_SQLGetDiagRec(type, handle, ++i, state, &native, text,
1041 sizeof(text), &len );
1042 if (SQL_SUCCEEDED(ret))
1043 xprintf("%s:%ld:%ld:%s\n", state, i, native, text);
1044 }
1045 while( ret == SQL_SUCCESS );
1046 }
1048 static int is_numeric(SQLSMALLINT coltype)
1049 {
1050 int ret = 0;
1051 switch (coltype)
1052 {
1053 case SQL_DECIMAL:
1054 case SQL_NUMERIC:
1055 case SQL_SMALLINT:
1056 case SQL_INTEGER:
1057 case SQL_REAL:
1058 case SQL_FLOAT:
1059 case SQL_DOUBLE:
1060 case SQL_TINYINT:
1061 case SQL_BIGINT:
1062 ret = 1;
1063 break;
1064 }
1065 return ret;
1066 }
1068 #endif
1070 /**********************************************************************/
1072 #ifndef HAVE_MYSQL
1074 void *db_mysql_open(TABDCA *dca, int mode)
1075 { xassert(dca == dca);
1076 xassert(mode == mode);
1077 xprintf("MySQL table driver not supported\n");
1078 return NULL;
1079 }
1081 int db_mysql_read(TABDCA *dca, void *link)
1082 { xassert(dca != dca);
1083 xassert(link != link);
1084 return 0;
1085 }
1087 int db_mysql_write(TABDCA *dca, void *link)
1088 { xassert(dca != dca);
1089 xassert(link != link);
1090 return 0;
1091 }
1093 int db_mysql_close(TABDCA *dca, void *link)
1094 { xassert(dca != dca);
1095 xassert(link != link);
1096 return 0;
1097 }
1099 #else
1101 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WOE__)
1102 #include <windows.h>
1103 #endif
1105 #ifdef __CYGWIN__
1106 #define byte_defined 1
1107 #endif
1109 #include <my_global.h>
1110 #include <my_sys.h>
1111 #include <mysql.h>
1113 struct db_mysql
1114 {
1115 int mode; /*'R' = Read, 'W' = Write*/
1116 MYSQL *con; /*connection*/
1117 MYSQL_RES *res; /*result*/
1118 int nf;
1119 /* number of fields in the csv file */
1120 int ref[1+SQL_FIELD_MAX];
1121 /* ref[k] = k', if k-th field of the csv file corresponds to
1122 k'-th field in the table statement; if ref[k] = 0, k-th field
1123 of the csv file is ignored */
1124 char *query;
1125 /* query generated by db_mysql_open */
1126 };
1128 void STDCALL dl_mysql_close(MYSQL *sock)
1129 {
1130 typedef void STDCALL ep_mysql_close(MYSQL *sock);
1132 ep_mysql_close *fn;
1133 fn = (ep_mysql_close *) xdlsym(h_mysql, "mysql_close");
1134 xassert(fn != NULL);
1135 return (*fn)(sock);
1136 }
1138 const char * STDCALL dl_mysql_error(MYSQL *mysql)
1139 {
1140 typedef const char * STDCALL ep_mysql_error(MYSQL *mysql);
1142 ep_mysql_error *fn;
1143 fn = (ep_mysql_error *) xdlsym(h_mysql, "mysql_error");
1144 xassert(fn != NULL);
1145 return (*fn)(mysql);
1146 }
1148 MYSQL_FIELD * STDCALL dl_mysql_fetch_fields(MYSQL_RES *res)
1149 {
1150 typedef MYSQL_FIELD * STDCALL
1151 ep_mysql_fetch_fields(MYSQL_RES *res);
1153 ep_mysql_fetch_fields *fn;
1154 fn = (ep_mysql_fetch_fields *) xdlsym(h_mysql, "mysql_fetch_fields");
1155 xassert(fn != NULL);
1156 return (*fn)(res);
1157 }
1159 unsigned long * STDCALL dl_mysql_fetch_lengths(MYSQL_RES *result)
1160 {
1161 typedef unsigned long * STDCALL
1162 ep_mysql_fetch_lengths(MYSQL_RES *result);
1164 ep_mysql_fetch_lengths *fn;
1165 fn = (ep_mysql_fetch_lengths *) xdlsym(h_mysql,
1166 "mysql_fetch_lengths");
1167 xassert(fn != NULL);
1168 return (*fn)(result);
1169 }
1171 MYSQL_ROW STDCALL dl_mysql_fetch_row(MYSQL_RES *result)
1172 {
1173 typedef MYSQL_ROW STDCALL ep_mysql_fetch_row(MYSQL_RES *result);
1175 ep_mysql_fetch_row *fn;
1176 fn = (ep_mysql_fetch_row *) xdlsym(h_mysql, "mysql_fetch_row");
1177 xassert(fn != NULL);
1178 return (*fn)(result);
1179 }
1181 unsigned int STDCALL dl_mysql_field_count(MYSQL *mysql)
1182 {
1183 typedef unsigned int STDCALL ep_mysql_field_count(MYSQL *mysql);
1185 ep_mysql_field_count *fn;
1186 fn = (ep_mysql_field_count *) xdlsym(h_mysql, "mysql_field_count");
1187 xassert(fn != NULL);
1188 return (*fn)(mysql);
1189 }
1191 MYSQL * STDCALL dl_mysql_init(MYSQL *mysql)
1192 {
1193 typedef MYSQL * STDCALL ep_mysql_init(MYSQL *mysql);
1195 ep_mysql_init *fn;
1196 fn = (ep_mysql_init *) xdlsym(h_mysql, "mysql_init");
1197 xassert(fn != NULL);
1198 return (*fn)(mysql);
1199 }
1201 unsigned int STDCALL dl_mysql_num_fields(MYSQL_RES *res)
1202 {
1203 typedef unsigned int STDCALL ep_mysql_num_fields(MYSQL_RES *res);
1205 ep_mysql_num_fields *fn;
1206 fn = (ep_mysql_num_fields *) xdlsym(h_mysql, "mysql_num_fields");
1207 xassert(fn != NULL);
1208 return (*fn)(res);
1209 }
1211 int STDCALL dl_mysql_query(MYSQL *mysql, const char *q)
1212 {
1213 typedef int STDCALL ep_mysql_query(MYSQL *mysql, const char *q);
1215 ep_mysql_query *fn;
1216 fn = (ep_mysql_query *) xdlsym(h_mysql, "mysql_query");
1217 xassert(fn != NULL);
1218 return (*fn)(mysql, q);
1219 }
1221 MYSQL * STDCALL dl_mysql_real_connect(MYSQL *mysql, const char *host,
1222 const char *user,
1223 const char *passwd,
1224 const char *db,
1225 unsigned int port,
1226 const char *unix_socket,
1227 unsigned long clientflag)
1228 {
1229 typedef MYSQL * STDCALL ep_mysql_real_connect(MYSQL *mysql,
1230 const char *host,
1231 const char *user,
1232 const char *passwd,
1233 const char *db,
1234 unsigned int port,
1235 const char *unix_socket,
1236 unsigned long clientflag);
1238 ep_mysql_real_connect *fn;
1239 fn = (ep_mysql_real_connect *) xdlsym(h_mysql,
1240 "mysql_real_connect");
1241 xassert(fn != NULL);
1242 return (*fn)(mysql, host, user, passwd, db, port, unix_socket,
1243 clientflag);
1244 }
1246 MYSQL_RES * STDCALL dl_mysql_use_result(MYSQL *mysql)
1247 {
1248 typedef MYSQL_RES * STDCALL ep_mysql_use_result(MYSQL *mysql);
1249 ep_mysql_use_result *fn;
1250 fn = (ep_mysql_use_result *) xdlsym(h_mysql, "mysql_use_result");
1251 xassert(fn != NULL);
1252 return (*fn)(mysql);
1253 }
1255 /***********************************************************************
1256 * NAME
1257 *
1258 * db_mysql_open - open connection to ODBC data base
1259 *
1260 * SYNOPSIS
1261 *
1262 * #include "glpsql.h"
1263 * void *db_mysql_open(TABDCA *dca, int mode);
1264 *
1265 * DESCRIPTION
1266 *
1267 * The routine db_mysql_open opens a connection to a MySQL data base.
1268 * It then executes the sql statements passed.
1269 *
1270 * In the case of table read the SELECT statement is executed.
1271 *
1272 * In the case of table write the INSERT statement is prepared.
1273 * RETURNS
1274 *
1275 * The routine returns a pointer to data storage area created. */
1277 void *db_mysql_open(TABDCA *dca, int mode)
1278 { void *ret;
1279 char **sqllines;
1281 sqllines = args_concat(dca);
1282 if (sqllines == NULL)
1283 { xprintf("Missing arguments in table statement.\n"
1284 "Please, supply table driver, dsn, and query.\n");
1285 return NULL;
1286 }
1287 ret = db_mysql_open_int(dca, mode, (const char **) sqllines);
1288 free_buffer(sqllines);
1289 return ret;
1290 }
1292 static void *db_mysql_open_int(TABDCA *dca, int mode, const char
1293 **sqllines)
1294 {
1295 struct db_mysql *sql = NULL;
1296 char *arg = NULL;
1297 const char *field;
1298 MYSQL_FIELD *fields;
1299 char *keyword;
1300 char *value;
1301 char *query;
1302 char *dsn;
1303 /* "Server=[server_name];Database=[database_name];UID=[username];*/
1304 /* PWD=[password];Port=[port]"*/
1305 char *server = NULL; /* Server */
1306 char *user = NULL; /* UID */
1307 char *password = NULL; /* PWD */
1308 char *database = NULL; /* Database */
1309 unsigned int port = 0; /* Port */
1310 int narg;
1311 int i, j, total;
1313 if (libmysql == NULL)
1314 {
1315 xprintf("No loader for shared MySQL library available\n");
1316 return NULL;
1317 }
1319 if (h_mysql == NULL)
1320 {
1321 h_mysql = xdlopen(libmysql);
1322 if (h_mysql == NULL)
1323 { xprintf("unable to open library %s\n", libmysql);
1324 xprintf("%s\n", xerrmsg());
1325 return NULL;
1326 }
1327 }
1329 sql = (struct db_mysql *) xmalloc(sizeof(struct db_mysql));
1330 if (sql == NULL)
1331 return NULL;
1332 sql->mode = mode;
1333 sql->res = NULL;
1334 sql->query = NULL;
1335 sql->nf = mpl_tab_num_flds(dca);
1337 narg = mpl_tab_num_args(dca);
1338 if (narg < 3 )
1339 xprintf("MySQL driver: string list too short \n");
1341 /* get connection string*/
1342 dsn = (char *) mpl_tab_get_arg(dca, 2);
1343 /* copy connection string*/
1344 i = strlen(dsn);
1345 i++;
1346 arg = xmalloc(i * sizeof(char));
1347 strcpy(arg, dsn);
1348 /*tokenize connection string*/
1349 for (i = 1, keyword = strtok (arg, "="); (keyword != NULL);
1350 keyword = strtok (NULL, "="), i++)
1351 {
1352 value = strtok (NULL, ";");
1353 if (value==NULL)
1354 {
1355 xprintf("db_mysql_open: Missing value for keyword %s\n",
1356 keyword);
1357 xfree(arg);
1358 xfree(sql);
1359 return NULL;
1360 }
1361 if (0 == strcmp(keyword, "Server"))
1362 server = value;
1363 else if (0 == strcmp(keyword, "Database"))
1364 database = value;
1365 else if (0 == strcmp(keyword, "UID"))
1366 user = value;
1367 else if (0 == strcmp(keyword, "PWD"))
1368 password = value;
1369 else if (0 == strcmp(keyword, "Port"))
1370 port = (unsigned int) atol(value);
1371 }
1372 /* Connect to database */
1373 sql->con = dl_mysql_init(NULL);
1374 if (!dl_mysql_real_connect(sql->con, server, user, password, database,
1375 port, NULL, 0))
1376 {
1377 xprintf("db_mysql_open: Connect failed\n");
1378 xprintf("%s\n", dl_mysql_error(sql->con));
1379 xfree(arg);
1380 xfree(sql);
1381 return NULL;
1382 }
1383 xfree(arg);
1385 for(j = 0; sqllines[j+1] != NULL; j++)
1386 { query = (char *) sqllines[j];
1387 xprintf("%s\n", query);
1388 if (dl_mysql_query(sql->con, query))
1389 {
1390 xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query);
1391 xprintf("%s\n",dl_mysql_error(sql->con));
1392 dl_mysql_close(sql->con);
1393 xfree(sql);
1394 return NULL;
1395 }
1396 }
1398 if ( sql->mode == 'R' )
1399 { sql->nf = mpl_tab_num_flds(dca);
1400 for(j = 0; sqllines[j] != NULL; j++)
1401 arg = (char *) sqllines[j];
1402 total = strlen(arg);
1403 if (total > 7 && 0 == strncmp(arg, "SELECT ", 7))
1404 {
1405 total = strlen(arg);
1406 query = xmalloc( (total+1) * sizeof(char));
1407 strcpy (query, arg);
1408 }
1409 else
1410 {
1411 query = db_generate_select_stmt(dca);
1412 }
1413 xprintf("%s\n", query);
1414 if (dl_mysql_query(sql->con, query))
1415 {
1416 xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query);
1417 xprintf("%s\n",dl_mysql_error(sql->con));
1418 dl_mysql_close(sql->con);
1419 xfree(query);
1420 xfree(sql);
1421 return NULL;
1422 }
1423 xfree(query);
1424 sql->res = dl_mysql_use_result(sql->con);
1425 if (sql->res)
1426 {
1427 /* create references between query results and table fields*/
1428 total = dl_mysql_num_fields(sql->res);
1429 if (total > SQL_FIELD_MAX)
1430 { xprintf("db_mysql_open: Too many fields (> %d) in query.\n"
1431 "\"%s\"\n", SQL_FIELD_MAX, query);
1432 xprintf("%s\n",dl_mysql_error(sql->con));
1433 dl_mysql_close(sql->con);
1434 xfree(query);
1435 xfree(sql);
1436 return NULL;
1437 }
1438 fields = dl_mysql_fetch_fields(sql->res);
1439 for (i = 1; i <= total; i++)
1440 {
1441 for (j = sql->nf; j >= 1; j--)
1442 {
1443 if (strcmp(mpl_tab_get_name(dca, j), fields[i-1].name)
1444 == 0)
1445 break;
1446 }
1447 sql->ref[i] = j;
1448 }
1449 }
1450 else
1451 {
1452 if(dl_mysql_field_count(sql->con) == 0)
1453 {
1454 xprintf("db_mysql_open: Query was not a SELECT\n\"%s\"\n",
1455 query);
1456 xprintf("%s\n",dl_mysql_error(sql->con));
1457 xfree(query);
1458 xfree(sql);
1459 return NULL;
1460 }
1461 else
1462 {
1463 xprintf("db_mysql_open: Query\n\"%s\"\nfailed.\n", query);
1464 xprintf("%s\n",dl_mysql_error(sql->con));
1465 xfree(query);
1466 xfree(sql);
1467 return NULL;
1468 }
1469 }
1470 }
1471 else if ( sql->mode == 'W' )
1472 { for(j = 0; sqllines[j] != NULL; j++)
1473 arg = (char *) sqllines[j];
1474 if ( NULL != strchr(arg, '?') )
1475 {
1476 total = strlen(arg);
1477 query = xmalloc( (total+1) * sizeof(char));
1478 strcpy (query, arg);
1479 }
1480 else
1481 query = db_generate_insert_stmt(dca);
1482 sql->query = query;
1483 xprintf("%s\n", query);
1484 }
1485 return sql;
1486 }
1488 int db_mysql_read(TABDCA *dca, void *link)
1489 { struct db_mysql *sql;
1490 char buf[255+1];
1491 char **row;
1492 unsigned long *lengths;
1493 MYSQL_FIELD *fields;
1494 double num;
1495 int len;
1496 unsigned long num_fields;
1497 int i;
1499 sql = (struct db_mysql *) link;
1501 xassert(sql != NULL);
1502 xassert(sql->mode == 'R');
1503 if (NULL == sql->res)
1504 {
1505 xprintf("db_mysql_read: no result set available");
1506 return 1;
1507 }
1508 if (NULL==(row = (char **)dl_mysql_fetch_row(sql->res))) {
1509 return -1; /*EOF*/
1510 }
1511 lengths = dl_mysql_fetch_lengths(sql->res);
1512 fields = dl_mysql_fetch_fields(sql->res);
1513 num_fields = dl_mysql_num_fields(sql->res);
1514 for (i=1; i <= num_fields; i++)
1515 {
1516 if (row[i-1] != NULL)
1517 { len = (size_t) lengths[i-1];
1518 if (len > 255)
1519 len = 255;
1520 strncpy(buf, (const char *) row[i-1], len);
1521 buf[len] = 0x00;
1522 if (0 != (fields[i-1].flags & NUM_FLAG))
1523 { strspx(buf); /* remove spaces*/
1524 if (str2num(buf, &num) != 0)
1525 { xprintf("'%s' cannot be converted to a number.\n", buf);
1526 return 1;
1527 }
1528 if (sql->ref[i] > 0)
1529 mpl_tab_set_num(dca, sql->ref[i], num);
1530 }
1531 else
1532 { if (sql->ref[i] > 0)
1533 mpl_tab_set_str(dca, sql->ref[i], strtrim(buf));
1534 }
1535 }
1536 }
1537 return 0;
1538 }
1540 int db_mysql_write(TABDCA *dca, void *link)
1541 {
1542 struct db_mysql *sql;
1543 char *part;
1544 char *query;
1545 char *template;
1546 char num[50];
1547 int k;
1548 int len;
1549 int nf;
1551 sql = (struct db_mysql *) link;
1552 xassert(sql != NULL);
1553 xassert(sql->mode == 'W');
1555 len = strlen(sql->query);
1556 template = (char *) xmalloc( (len + 1) * sizeof(char) );
1557 strcpy(template, sql->query);
1559 nf = mpl_tab_num_flds(dca);
1560 for (k = 1; k <= nf; k++)
1561 { switch (mpl_tab_get_type(dca, k))
1562 { case 'N':
1563 len += 20;
1564 break;
1565 case 'S':
1566 len += db_escaped_string_length(mpl_tab_get_str(dca, k));
1567 len += 2;
1568 break;
1569 default:
1570 xassert(dca != dca);
1571 }
1572 }
1573 query = xmalloc( (len + 1 ) * sizeof(char) );
1574 query[0] = 0x00;
1575 for (k = 1, part = strtok (template, "?"); (part != NULL);
1576 part = strtok (NULL, "?"), k++)
1577 {
1578 if (k > nf) break;
1579 strcat( query, part );
1580 switch (mpl_tab_get_type(dca, k))
1581 { case 'N':
1582 #if 0 /* 02/XI-2010 by xypron */
1583 sprintf(num, "%-18g",mpl_tab_get_num(dca, k));
1584 #else
1585 sprintf(num, "%.*g", DBL_DIG, mpl_tab_get_num(dca, k));
1586 #endif
1587 strcat( query, num );
1588 break;
1589 case 'S':
1590 strcat( query, "'");
1591 db_escape_string( query + strlen(query),
1592 mpl_tab_get_str(dca, k) );
1593 strcat( query, "'");
1594 break;
1595 default:
1596 xassert(dca != dca);
1597 }
1598 }
1599 if (part != NULL)
1600 strcat(query, part);
1601 if (dl_mysql_query(sql->con, query))
1602 {
1603 xprintf("db_mysql_write: Query\n\"%s\"\nfailed.\n", query);
1604 xprintf("%s\n",dl_mysql_error(sql->con));
1605 xfree(query);
1606 xfree(template);
1607 return 1;
1608 }
1610 xfree(query);
1611 xfree(template);
1612 return 0;
1613 }
1615 int db_mysql_close(TABDCA *dca, void *link)
1616 {
1617 struct db_mysql *sql;
1619 sql = (struct db_mysql *) link;
1620 xassert(sql != NULL);
1621 dl_mysql_close(sql->con);
1622 if ( sql->mode == 'W' )
1623 xfree(sql->query);
1624 xfree(sql);
1625 dca->link = NULL;
1626 return 0;
1627 }
1629 #endif
1631 /* eof */