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