/
tdsodbc.h
543 lines (482 loc) · 15.5 KB
/
tdsodbc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Brian Bruns
* Copyright (C) 2004, 2005, 2006, 2007 Frediano Ziglio
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _sql_h_
#define _sql_h_
#include "tds.h"
#if defined(UNIXODBC) || defined(TDS_NO_DM)
#include <sql.h>
#include <sqlext.h>
#ifdef UNIXODBC
#include <odbcinst.h>
#endif
#else /* IODBC */
#include <isql.h>
#include <isqlext.h>
#ifdef HAVE_IODBCINST_H
#include <iodbcinst.h>
#endif /* HAVE_IODBCINST_H */
#endif
#ifndef HAVE_SQLLEN
#ifndef SQLULEN
#define SQLULEN SQLUINTEGER
#endif
#ifndef SQLLEN
#define SQLLEN SQLINTEGER
#endif
#endif
#ifndef HAVE_SQLSETPOSIROW
#define SQLSETPOSIROW SQLUSMALLINT
#endif
#ifndef HAVE_SQLROWOFFSET
#define SQLROWOFFSET SQLLEN
#endif
#ifndef HAVE_SQLROWSETSIZE
#define SQLROWSETSIZE SQLULEN
#endif
#ifdef __cplusplus
extern "C"
{
#if 0
}
#endif
#endif
/* $Id: tdsodbc.h,v 1.103.2.2 2009-12-22 20:16:01 freddy77 Exp $ */
#if defined(__GNUC__) && __GNUC__ >= 4
#pragma GCC visibility push(hidden)
#define ODBC_API SQL_API __attribute__((externally_visible))
#else
#define ODBC_API SQL_API
#endif
#define ODBC_MAX(a,b) ( (a) > (b) ? (a) : (b) )
#define ODBC_MIN(a,b) ( (a) < (b) ? (a) : (b) )
struct _sql_error
{
const char *msg;
char state2[6];
char state3[6];
TDS_UINT native;
char *server;
int linenum;
int msgstate;
};
struct _sql_errors
{
SQLRETURN lastrc;
int num_errors;
struct _sql_error *errs;
char ranked;
};
#if ENABLE_EXTRA_CHECKS
void odbc_check_struct_extra(void *p);
#define ODBC_RETURN(handle, rc) \
do { odbc_check_struct_extra(handle); return (handle->errs.lastrc = (rc)); } while(0)
#define ODBC_RETURN_(handle) \
do { odbc_check_struct_extra(handle); return handle->errs.lastrc; } while(0)
#else
#define ODBC_RETURN(handle, rc) \
do { return (handle->errs.lastrc = (rc)); } while(0)
#define ODBC_RETURN_(handle) \
do { return handle->errs.lastrc; } while(0)
#endif
/** reset errors */
void odbc_errs_reset(struct _sql_errors *errs);
/** add an error to list */
void odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg);
/** Add an error to list. This functions is for error that came from server */
void odbc_errs_add_rdbms(struct _sql_errors *errs, TDS_UINT native, const char *sqlstate, const char *msg, int linenum,
int msgstate, const char *server);
struct _dheader
{
SQLSMALLINT sql_desc_alloc_type;
SQLINTEGER sql_desc_bind_type;
SQLULEN sql_desc_array_size;
/* TODO SQLLEN ?? see http://support.microsoft.com/default.aspx?scid=kb;en-us;298678 */
SQLSMALLINT sql_desc_count;
SQLUSMALLINT *sql_desc_array_status_ptr;
SQLULEN *sql_desc_rows_processed_ptr;
SQLLEN *sql_desc_bind_offset_ptr;
};
struct _drecord
{
SQLUINTEGER sql_desc_auto_unique_value;
DSTR sql_desc_base_column_name;
DSTR sql_desc_base_table_name;
SQLINTEGER sql_desc_case_sensitive;
DSTR sql_desc_catalog_name;
SQLSMALLINT sql_desc_concise_type;
SQLPOINTER sql_desc_data_ptr;
SQLSMALLINT sql_desc_datetime_interval_code;
SQLINTEGER sql_desc_datetime_interval_precision;
SQLLEN sql_desc_display_size;
SQLSMALLINT sql_desc_fixed_prec_scale;
SQLLEN *sql_desc_indicator_ptr;
DSTR sql_desc_label;
SQLULEN sql_desc_length;
/* this point to a constant buffer, do not free or modify */
const char *sql_desc_literal_prefix;
/* this point to a constant buffer, do not free or modify */
const char *sql_desc_literal_suffix;
DSTR sql_desc_local_type_name;
DSTR sql_desc_name;
SQLSMALLINT sql_desc_nullable;
SQLINTEGER sql_desc_num_prec_radix;
SQLLEN sql_desc_octet_length;
SQLLEN *sql_desc_octet_length_ptr;
SQLSMALLINT sql_desc_parameter_type;
SQLSMALLINT sql_desc_precision;
SQLSMALLINT sql_desc_rowver;
SQLSMALLINT sql_desc_scale;
DSTR sql_desc_schema_name;
SQLSMALLINT sql_desc_searchable;
DSTR sql_desc_table_name;
SQLSMALLINT sql_desc_type;
/* this point to a constant buffer, do not free or modify */
const char *sql_desc_type_name;
SQLSMALLINT sql_desc_unnamed;
SQLSMALLINT sql_desc_unsigned;
SQLSMALLINT sql_desc_updatable;
};
struct _hdesc
{
SQLSMALLINT htype; /* do not reorder this field */
int type;
SQLHANDLE parent;
struct _dheader header;
struct _drecord *records;
struct _sql_errors errs;
};
typedef struct _hdesc TDS_DESC;
#define DESC_IRD 1
#define DESC_IPD 2
#define DESC_ARD 3
#define DESC_APD 4
struct _heattr
{
SQLUINTEGER connection_pooling;
SQLUINTEGER cp_match;
SQLINTEGER odbc_version;
SQLINTEGER output_nts;
};
struct _hchk
{
SQLSMALLINT htype; /* do not reorder this field */
};
struct _henv
{
SQLSMALLINT htype; /* do not reorder this field */
TDSCONTEXT *tds_ctx;
struct _sql_errors errs;
struct _heattr attr;
};
struct _hcattr
{
SQLUINTEGER access_mode;
SQLUINTEGER async_enable;
SQLUINTEGER auto_ipd;
SQLUINTEGER autocommit;
SQLUINTEGER connection_dead;
SQLUINTEGER connection_timeout;
DSTR current_catalog;
SQLUINTEGER login_timeout;
SQLUINTEGER metadata_id;
SQLUINTEGER odbc_cursors;
SQLUINTEGER packet_size;
SQLHWND quite_mode;
DSTR translate_lib;
SQLUINTEGER translate_option;
SQLUINTEGER txn_isolation;
SQLUINTEGER cursor_type;
#ifdef TDS_NO_DM
SQLUINTEGER trace;
DSTR tracefile;
#endif
};
#define TDS_MAX_APP_DESC 100
struct _hstmt;
struct _hdbc
{
SQLSMALLINT htype; /* do not reorder this field */
struct _henv *env;
TDSSOCKET *tds_socket;
DSTR dsn;
DSTR server; /* aka Instance */
/**
* Statement executing. This should be set AFTER sending query
* to avoid race condition and assure to not overwrite it if
* another statement is executing a query.
*/
struct _hstmt *current_statement;
/** list of all statements allocated from this connection */
struct _hstmt *stmt_list;
struct _sql_errors errs;
struct _hcattr attr;
/** descriptors associated to connection */
TDS_DESC *uad[TDS_MAX_APP_DESC];
/** <>0 if server handle cursors */
unsigned int cursor_support;
TDS_INT default_query_timeout;
};
struct _hsattr
{
/* TODO remove IRD, ARD, IPD, APD from statement, do not duplicate */
/* TDS_DESC *app_row_desc; */
/* TDS_DESC *app_param_desc; */
SQLUINTEGER async_enable;
SQLUINTEGER concurrency;
SQLUINTEGER cursor_scrollable;
SQLUINTEGER cursor_sensitivity;
SQLUINTEGER cursor_type;
SQLUINTEGER enable_auto_ipd;
SQLPOINTER fetch_bookmark_ptr;
SQLULEN keyset_size;
SQLULEN max_length;
SQLULEN max_rows;
SQLUINTEGER metadata_id;
SQLUINTEGER noscan;
/* apd->sql_desc_bind_offset_ptr */
/* SQLUINTEGER *param_bind_offset_ptr; */
/* apd->sql_desc_bind_type */
/* SQLUINTEGER param_bind_type; */
/* apd->sql_desc_array_status_ptr */
/* SQLUSMALLINT *param_operation_ptr; */
/* ipd->sql_desc_array_status_ptr */
/* SQLUSMALLINT *param_status_ptr; */
/* ipd->sql_desc_rows_processed_ptr */
/* SQLUSMALLINT *params_processed_ptr; */
/* apd->sql_desc_array_size */
/* SQLUINTEGER paramset_size; */
SQLUINTEGER query_timeout;
SQLUINTEGER retrieve_data;
/* ard->sql_desc_bind_offset_ptr */
/* SQLUINTEGER *row_bind_offset_ptr; */
/* ard->sql_desc_array_size */
/* SQLUINTEGER row_array_size; */
/* ard->sql_desc_bind_type */
/* SQLUINTEGER row_bind_type; */
SQLULEN row_number;
/* ard->sql_desc_array_status_ptr */
/* SQLUINTEGER *row_operation_ptr; */
/* ird->sql_desc_array_status_ptr */
/* SQLUINTEGER *row_status_ptr; */
/* ird->sql_desc_rows_processed_ptr */
/* SQLUINTEGER *rows_fetched_ptr; */
SQLUINTEGER simulate_cursor;
SQLUINTEGER use_bookmarks;
/* SQLGetStmtAttr only */
/* TDS_DESC *imp_row_desc; */
/* TDS_DESC *imp_param_desc; */
};
typedef enum
{
NOT_IN_ROW,
IN_NORMAL_ROW,
IN_COMPUTE_ROW,
AFTER_COMPUTE_ROW,
PRE_NORMAL_ROW
} TDS_ODBC_ROW_STATUS;
typedef enum
{
ODBC_SPECIAL_NONE = 0,
ODBC_SPECIAL_GETTYPEINFO = 1,
ODBC_SPECIAL_COLUMNS = 2,
ODBC_SPECIAL_PROCEDURECOLUMNS = 3,
ODBC_SPECIAL_SPECIALCOLUMNS = 4
} TDS_ODBC_SPECIAL_ROWS;
struct _hstmt
{
SQLSMALLINT htype; /* do not reorder this field */
struct _hdbc *dbc;
/** query to execute */
char *query;
/** next in list */
struct _hstmt *next;
/** previous in list */
struct _hstmt *prev;
/* begin prepared query stuff */
char *prepared_query;
unsigned prepared_query_is_func:1;
unsigned prepared_query_is_rpc:1;
unsigned need_reprepare:1;
unsigned param_data_called:1;
/* end prepared query stuff */
/** parameters saved */
TDSPARAMINFO *params;
/** last valid parameter in params, it's a ODBC index (from 1 relative to descriptor) */
int param_num;
/** position in prepared query to check parameters, used only in RPC */
char *prepared_pos;
unsigned int curr_param_row, num_param_rows;
/** number of parameter in current query */
unsigned int param_count;
int row;
/** row count to return */
TDS_INT8 row_count;
/** status of row, it can happen that this flag mark that we are still parsing row, this it's normal */
TDS_ODBC_ROW_STATUS row_status;
/* do NOT free dynamic, free from socket or attach to connection */
TDSDYNAMIC *dyn;
struct _sql_errors errs;
TDS_DESC *ard, *ird, *apd, *ipd;
TDS_DESC *orig_ard, *orig_apd;
SQLULEN sql_rowset_size;
struct _hsattr attr;
DSTR cursor_name; /* auto generated cursor name */
TDS_ODBC_SPECIAL_ROWS special_row;
/* do NOT free cursor, free from socket or attach to connection */
TDSCURSOR *cursor;
unsigned char cancel_sent;
};
typedef struct _henv TDS_ENV;
typedef struct _hdbc TDS_DBC;
typedef struct _hstmt TDS_STMT;
typedef struct _hchk TDS_CHK;
#define IS_HENV(x) (((TDS_CHK *)x)->htype == SQL_HANDLE_ENV)
#define IS_HDBC(x) (((TDS_CHK *)x)->htype == SQL_HANDLE_DBC)
#define IS_HSTMT(x) (((TDS_CHK *)x)->htype == SQL_HANDLE_STMT)
#define IS_HDESC(x) (((TDS_CHK *)x)->htype == SQL_HANDLE_DESC)
/* fix a bug in MingW headers */
#ifdef __MINGW32__
#if SQL_INTERVAL_YEAR == (100 + SQL_CODE_SECOND)
#undef SQL_INTERVAL_YEAR
#undef SQL_INTERVAL_MONTH
#undef SQL_INTERVAL_DAY
#undef SQL_INTERVAL_HOUR
#undef SQL_INTERVAL_MINUTE
#undef SQL_INTERVAL_SECOND
#undef SQL_INTERVAL_YEAR_TO_MONTH
#undef SQL_INTERVAL_DAY_TO_HOUR
#undef SQL_INTERVAL_DAY_TO_MINUTE
#undef SQL_INTERVAL_DAY_TO_SECOND
#undef SQL_INTERVAL_HOUR_TO_MINUTE
#undef SQL_INTERVAL_HOUR_TO_SECOND
#undef SQL_INTERVAL_MINUTE_TO_SECOND
#define SQL_INTERVAL_YEAR (100 + SQL_CODE_YEAR)
#define SQL_INTERVAL_MONTH (100 + SQL_CODE_MONTH)
#define SQL_INTERVAL_DAY (100 + SQL_CODE_DAY)
#define SQL_INTERVAL_HOUR (100 + SQL_CODE_HOUR)
#define SQL_INTERVAL_MINUTE (100 + SQL_CODE_MINUTE)
#define SQL_INTERVAL_SECOND (100 + SQL_CODE_SECOND)
#define SQL_INTERVAL_YEAR_TO_MONTH (100 + SQL_CODE_YEAR_TO_MONTH)
#define SQL_INTERVAL_DAY_TO_HOUR (100 + SQL_CODE_DAY_TO_HOUR)
#define SQL_INTERVAL_DAY_TO_MINUTE (100 + SQL_CODE_DAY_TO_MINUTE)
#define SQL_INTERVAL_DAY_TO_SECOND (100 + SQL_CODE_DAY_TO_SECOND)
#define SQL_INTERVAL_HOUR_TO_MINUTE (100 + SQL_CODE_HOUR_TO_MINUTE)
#define SQL_INTERVAL_HOUR_TO_SECOND (100 + SQL_CODE_HOUR_TO_SECOND)
#define SQL_INTERVAL_MINUTE_TO_SECOND (100 + SQL_CODE_MINUTE_TO_SECOND)
#endif
#endif
#ifdef WIN32
BOOL get_login_info(HWND hwndParent, TDSCONNECTION * connection);
#endif
/*
* connectparams.h
*/
/**
* Parses a connection string for SQLDriverConnect().
* \param connect_string point to connection string
* \param connect_string_end point to end of connection string
* \param connection structure where to store informations
* \return 0 if error, 1 otherwise
*/
int odbc_parse_connect_string(const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection);
int odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection);
/*
* convert_tds2sql.c
*/
TDS_INT convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
/*
* descriptor.c
*/
TDS_DESC *desc_alloc(SQLHANDLE parent, int desc_type, int alloc_type);
SQLRETURN desc_free(TDS_DESC * desc);
SQLRETURN desc_alloc_records(TDS_DESC * desc, unsigned count);
SQLRETURN desc_copy(TDS_DESC * dest, TDS_DESC * src);
SQLRETURN desc_free_records(TDS_DESC * desc);
/*
* odbc.c
*/
SQLRETURN _SQLRowCount(SQLHSTMT hstmt, SQLLEN FAR * pcrow);
/*
* odbc_checks.h
*/
#if ENABLE_EXTRA_CHECKS
/* macro */
#define CHECK_ENV_EXTRA(env) odbc_check_env_extra(env)
#define CHECK_DBC_EXTRA(dbc) odbc_check_dbc_extra(dbc)
#define CHECK_STMT_EXTRA(stmt) odbc_check_stmt_extra(stmt)
#define CHECK_DESC_EXTRA(desc) odbc_check_desc_extra(desc)
/* declarations*/
void odbc_check_env_extra(TDS_ENV * env);
void odbc_check_dbc_extra(TDS_DBC * dbc);
void odbc_check_stmt_extra(TDS_STMT * stmt);
void odbc_check_desc_extra(TDS_DESC * desc);
#else
/* macro */
#define CHECK_ENV_EXTRA(env)
#define CHECK_DBC_EXTRA(dbc)
#define CHECK_STMT_EXTRA(stmt)
#define CHECK_DESC_EXTRA(desc)
#endif
/*
* odbc_util.h
*/
int odbc_set_stmt_query(struct _hstmt *stmt, const char *sql, int sql_len);
int odbc_set_stmt_prepared_query(struct _hstmt *stmt, const char *sql, int sql_len);
void odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row);
void odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row);
SQLSMALLINT odbc_server_to_sql_type(int col_type, int col_size);
int odbc_sql_to_c_type_default(int sql_type);
int odbc_sql_to_server_type(TDSSOCKET * tds, int sql_type);
int odbc_c_to_server_type(int c_type);
void odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver);
SQLINTEGER odbc_sql_to_displaysize(int sqltype, TDSCOLUMN *col);
int odbc_get_string_size(int size, SQLCHAR * str);
void odbc_rdbms_version(TDSSOCKET * tds_socket, char *pversion_string);
SQLINTEGER odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_ixd, const TDS_DESC* axd, unsigned int n_row);
SQLRETURN odbc_set_string(SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len);
SQLRETURN odbc_set_string_i(SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len);
SQLSMALLINT odbc_get_concise_sql_type(SQLSMALLINT type, SQLSMALLINT interval);
SQLRETURN odbc_set_concise_sql_type(SQLSMALLINT concise_type, struct _drecord *drec, int check_only);
SQLSMALLINT odbc_get_concise_c_type(SQLSMALLINT type, SQLSMALLINT interval);
SQLRETURN odbc_set_concise_c_type(SQLSMALLINT concise_type, struct _drecord *drec, int check_only);
SQLLEN odbc_get_octet_len(int c_type, const struct _drecord *drec);
/*
* prepare_query.c
*/
SQLRETURN prepare_call(struct _hstmt *stmt);
SQLRETURN native_sql(struct _hdbc *dbc, char *s);
int parse_prepared_query(struct _hstmt *stmt, int compute_row);
int start_parse_prepared_query(struct _hstmt *stmt, int compute_row);
int continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN StrLen_or_Ind);
const char *parse_const_param(const char * s, TDS_SERVER_TYPE *type);
/*
* sql2tds.c
*/
SQLRETURN sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _drecord *drec_axd, TDSCOLUMN *curcol, int compute_row, const TDS_DESC* axd, unsigned int n_row);
#if defined(__GNUC__) && __GNUC__ >= 4
#pragma GCC visibility pop
#endif
#ifdef __cplusplus
#if 0
{
#endif
}
#endif
#endif