~ubuntu-branches/ubuntu/edgy/psqlodbc/edgy

1 by Martin Pitt
Import upstream version 07.03.0200
1
/*-------
2
 * Module:			odbcapi30.c
3
 *
4
 * Description:		This module contains routines related to ODBC 3.0
5
 *			most of their implementations are temporary
6
 *			and must be rewritten properly.
7
 *			2001/07/23	inoue
8
 *
9
 * Classes:			n/a
10
 *
11
 * API functions:	SQLAllocHandle, SQLBindParam, SQLCloseCursor,
12
			SQLColAttribute, SQLCopyDesc, SQLEndTran,
13
			SQLFetchScroll, SQLFreeHandle, SQLGetDescField,
14
			SQLGetDescRec, SQLGetDiagField, SQLGetDiagRec,
15
			SQLGetEnvAttr, SQLGetConnectAttr, SQLGetStmtAttr,
16
			SQLSetConnectAttr, SQLSetDescField, SQLSetDescRec,
17
			SQLSetEnvAttr, SQLSetStmtAttr, SQLBulkOperations
18
 *-------
19
 */
20
21
#include "psqlodbc.h"
22
23
#if (ODBCVER >= 0x0300)
24
#include <stdio.h>
25
#include <string.h>
26
27
#include "environ.h"
28
#include "connection.h"
29
#include "statement.h"
30
#include "pgapifunc.h"
31
32
/*	SQLAllocConnect/SQLAllocEnv/SQLAllocStmt -> SQLAllocHandle */
33
RETCODE		SQL_API
34
SQLAllocHandle(SQLSMALLINT HandleType,
35
			   SQLHANDLE InputHandle, SQLHANDLE * OutputHandle)
36
{
37
	RETCODE		ret;
38
	ConnectionClass	*conn;
39
40
	mylog("[[SQLAllocHandle]]");
41
	switch (HandleType)
42
	{
43
		case SQL_HANDLE_ENV:
44
			ret = PGAPI_AllocEnv(OutputHandle);
45
			break;
46
		case SQL_HANDLE_DBC:
47
			ENTER_ENV_CS((EnvironmentClass *) InputHandle);
48
			ret = PGAPI_AllocConnect(InputHandle, OutputHandle);
49
			LEAVE_ENV_CS((EnvironmentClass *) InputHandle);
50
			break;
51
		case SQL_HANDLE_STMT:
52
			ENTER_CONN_CS((ConnectionClass *) InputHandle);
53
			ret = PGAPI_AllocStmt(InputHandle, OutputHandle);
54
			LEAVE_CONN_CS((ConnectionClass *) InputHandle);
55
			break;
56
		case SQL_HANDLE_DESC:
57
			conn = (ConnectionClass *) InputHandle;
58
			ENTER_CONN_CS(conn);
59
			CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "can't alloc Desc Handle yet"); 
60
			LEAVE_CONN_CS(conn);
61
			ret = SQL_ERROR;
62
			break;
63
		default:
64
			ret = SQL_ERROR;
65
			break;
66
	}
67
	return ret;
68
}
69
70
/*	SQLBindParameter/SQLSetParam -> SQLBindParam */
71
RETCODE		SQL_API
72
SQLBindParam(HSTMT StatementHandle,
73
			 SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
74
			 SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision,
75
			 SQLSMALLINT ParameterScale, PTR ParameterValue,
76
			 SQLINTEGER *StrLen_or_Ind)
77
{
78
	RETCODE			ret;
79
	int			BufferLength = 512;		/* Is it OK ? */
80
81
	mylog("[[SQLBindParam]]");
82
	ENTER_STMT_CS((StatementClass *) StatementHandle);
83
	SC_clear_error((StatementClass *) StatementHandle);
84
	ret = PGAPI_BindParameter(StatementHandle, ParameterNumber, SQL_PARAM_INPUT, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValue, BufferLength, StrLen_or_Ind);
85
	LEAVE_STMT_CS((StatementClass *) StatementHandle);
86
	return ret;
87
}
88
89
/*	New function */
90
RETCODE		SQL_API
91
SQLCloseCursor(HSTMT StatementHandle)
92
{
93
	RETCODE	ret;
94
95
	mylog("[[SQLCloseCursor]]");
96
	ENTER_STMT_CS((StatementClass *) StatementHandle);
97
	SC_clear_error((StatementClass *) StatementHandle);
98
	ret = PGAPI_FreeStmt(StatementHandle, SQL_CLOSE);
99
	LEAVE_STMT_CS((StatementClass *) StatementHandle);
100
	return ret;
101
}
102
103
/*	SQLColAttributes -> SQLColAttribute */
104
RETCODE		SQL_API
105
SQLColAttribute(HSTMT StatementHandle,
106
				SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier,
107
				PTR CharacterAttribute, SQLSMALLINT BufferLength,
108
				SQLSMALLINT *StringLength, PTR NumericAttribute)
109
{
110
	RETCODE	ret;
111
112
	mylog("[[SQLColAttribute]]");
113
	ENTER_STMT_CS((StatementClass *) StatementHandle);
114
	SC_clear_error((StatementClass *) StatementHandle);
115
	ret = PGAPI_ColAttributes(StatementHandle, ColumnNumber,
116
					   FieldIdentifier, CharacterAttribute, BufferLength,
117
							   StringLength, NumericAttribute);
118
	LEAVE_STMT_CS((StatementClass *) StatementHandle);
119
	return ret;
120
}
121
122
static HSTMT
123
descHandleFromStatementHandle(HSTMT StatementHandle, SQLINTEGER descType) 
124
{
125
	switch (descType)
126
	{
127
		case SQL_ATTR_APP_ROW_DESC:		/* 10010 */
128
			return StatementHandle;	/* this is bogus */
129
		case SQL_ATTR_APP_PARAM_DESC:	/* 10011 */
130
			return (HSTMT) ((SQLUINTEGER) StatementHandle + 1) ; /* this is bogus */
131
		case SQL_ATTR_IMP_ROW_DESC:		/* 10012 */
132
			return (HSTMT) ((SQLUINTEGER) StatementHandle + 2); /* this is bogus */
133
		case SQL_ATTR_IMP_PARAM_DESC:	/* 10013 */
134
			return (HSTMT) ((SQLUINTEGER) StatementHandle + 3); /* this is bogus */
135
	}
136
	return (HSTMT) 0;
137
}
138
static HSTMT
139
statementHandleFromDescHandle(HSTMT DescHandle, SQLINTEGER *descType) 
140
{
141
	SQLUINTEGER res = (SQLUINTEGER) DescHandle % 4;
142
	switch (res)
143
	{
144
		case 0: *descType = SQL_ATTR_APP_ROW_DESC; /* 10010 */
145
			break;
146
		case 1: *descType = SQL_ATTR_APP_PARAM_DESC; /* 10011 */
147
			break;
148
		case 2: *descType = SQL_ATTR_IMP_ROW_DESC; /* 10012 */
149
			break;
150
		case 3: *descType = SQL_ATTR_IMP_PARAM_DESC; /* 10013 */
151
			break;
152
	}
153
	return (HSTMT) ((SQLUINTEGER) DescHandle - res);
154
}
155
156
/*	new function */
157
RETCODE		SQL_API
158
SQLCopyDesc(SQLHDESC SourceDescHandle,
159
			SQLHDESC TargetDescHandle)
160
{
161
	mylog("[[SQLCopyDesc]]\n");
162
	mylog("Error not implemented\n");
163
	return SQL_ERROR;
164
}
165
166
/*	SQLTransact -> SQLEndTran */
167
RETCODE		SQL_API
168
SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle,
169
		   SQLSMALLINT CompletionType)
170
{
171
	RETCODE	ret;
172
173
	mylog("[[SQLEndTran]]");
174
	switch (HandleType)
175
	{
176
		case SQL_HANDLE_ENV:
177
			ENTER_ENV_CS((EnvironmentClass *) Handle);
178
			ret = PGAPI_Transact(Handle, SQL_NULL_HDBC, CompletionType);
179
			LEAVE_ENV_CS((EnvironmentClass *) Handle);
180
			break;
181
		case SQL_HANDLE_DBC:
182
			ENTER_CONN_CS((ConnectionClass *) Handle);
183
			CC_clear_error((ConnectionClass *) Handle);
184
			ret = PGAPI_Transact(SQL_NULL_HENV, Handle, CompletionType);
185
			LEAVE_CONN_CS((ConnectionClass *) Handle);
186
			break;
187
		default:
188
			ret = SQL_ERROR;
189
			break;
190
	}
191
	return ret;
192
}
193
194
/*	SQLExtendedFetch -> SQLFetchScroll */
195
RETCODE		SQL_API
196
SQLFetchScroll(HSTMT StatementHandle,
197
			   SQLSMALLINT FetchOrientation, SQLINTEGER FetchOffset)
198
{
199
	CSTR func = "SQLFetchScroll";
200
	StatementClass *stmt = (StatementClass *) StatementHandle;
201
	RETCODE		ret = SQL_SUCCESS;
202
	IRDFields	*irdopts = SC_get_IRD(stmt);
203
	SQLUSMALLINT *rowStatusArray = irdopts->rowStatusArray;
204
	SQLINTEGER *pcRow = irdopts->rowsFetched, bkmarkoff = 0;
205
206
	mylog("[[%s]] %d,%d\n", func, FetchOrientation, FetchOffset);
207
	ENTER_STMT_CS(stmt);
208
	SC_clear_error(stmt);
209
	if (FetchOrientation == SQL_FETCH_BOOKMARK)
210
	{
211
		if (stmt->options.bookmark_ptr)
212
		{
213
			bkmarkoff = FetchOffset;
214
			FetchOffset = *((Int4 *) stmt->options.bookmark_ptr);
215
mylog("bookmark=%u FetchOffset = %d\n", FetchOffset, bkmarkoff);
216
		}
217
		else
218
		{
219
			SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Bookmark isn't specifed yet");
220
			SC_log_error(func, "", stmt);
221
			ret = SQL_ERROR;
222
		}
223
	}
224
	if (SQL_SUCCESS == ret)
225
	{
226
		ARDFields	*opts = SC_get_ARD(stmt);
227
228
		ret = PGAPI_ExtendedFetch(StatementHandle, FetchOrientation, FetchOffset,
229
				pcRow, rowStatusArray, bkmarkoff, opts->size_of_rowset);
230
		stmt->transition_status = 6;
231
	}
232
	LEAVE_STMT_CS(stmt);
233
	if (ret != SQL_SUCCESS)
234
		mylog("%s return = %d\n", func, ret);
235
	return ret;
236
}
237
238
/*	SQLFree(Connect/Env/Stmt) -> SQLFreeHandle */
239
RETCODE		SQL_API
240
SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
241
{
242
	RETCODE		ret;
243
	mylog("[[SQLFreeHandle]]");
244
	switch (HandleType)
245
	{
246
		case SQL_HANDLE_ENV:
247
			ret = PGAPI_FreeEnv(Handle);
248
			break;
249
		case SQL_HANDLE_DBC:
250
			ret = PGAPI_FreeConnect(Handle);
251
			break;
252
		case SQL_HANDLE_STMT:
253
			ret = PGAPI_FreeStmt(Handle, SQL_DROP);
254
			break;
255
		default:
256
			ret = SQL_ERROR;
257
			break;
258
	}
259
	return ret;
260
}
261
262
/*	new function */
263
RETCODE		SQL_API
264
SQLGetDescField(SQLHDESC DescriptorHandle,
265
				SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
266
				PTR Value, SQLINTEGER BufferLength,
267
				SQLINTEGER *StringLength)
268
{
269
	RETCODE	ret;
270
271
	mylog("[[SQLGetDescField]]\n");
272
	ret = PGAPI_GetDescField(DescriptorHandle, RecNumber, FieldIdentifier,
273
			Value, BufferLength, StringLength);
274
	return ret;
275
}
276
277
/*	new function */
278
RETCODE		SQL_API
279
SQLGetDescRec(SQLHDESC DescriptorHandle,
280
			  SQLSMALLINT RecNumber, SQLCHAR *Name,
281
			  SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
282
			  SQLSMALLINT *Type, SQLSMALLINT *SubType,
283
			  SQLINTEGER *Length, SQLSMALLINT *Precision,
284
			  SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
285
{
286
	mylog("[[SQLGetDescRec]]\n");
287
	mylog("Error not implemented\n");
288
	return SQL_ERROR;
289
}
290
291
/*	new function */
292
RETCODE		SQL_API
293
SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
294
				SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
295
				PTR DiagInfo, SQLSMALLINT BufferLength,
296
				SQLSMALLINT *StringLength)
297
{
298
	RETCODE	ret;
299
300
	mylog("[[SQLGetDiagField]] Handle=(%u,%x) Rec=%d Id=%d\n", HandleType, Handle, RecNumber, DiagIdentifier);
301
	ret = PGAPI_GetDiagField(HandleType, Handle, RecNumber, DiagIdentifier,
302
				DiagInfo, BufferLength, StringLength);
303
	return ret;
304
}
305
306
/*	SQLError -> SQLDiagRec */
307
RETCODE		SQL_API
308
SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
309
			  SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
310
			  SQLINTEGER *NativeError, SQLCHAR *MessageText,
311
			  SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
312
{
313
	RETCODE	ret;
314
315
	mylog("[[SQLGetDiagRec]]\n");
316
	ret = PGAPI_GetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
317
			NativeError, MessageText, BufferLength, TextLength);
318
	return ret;
319
}
320
321
/*	new function */
322
RETCODE		SQL_API
323
SQLGetEnvAttr(HENV EnvironmentHandle,
324
			  SQLINTEGER Attribute, PTR Value,
325
			  SQLINTEGER BufferLength, SQLINTEGER *StringLength)
326
{
327
	RETCODE	ret;
328
	EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
329
330
	mylog("[[SQLGetEnvAttr]] %d\n", Attribute);
331
	ENTER_ENV_CS(env);
332
	ret = SQL_SUCCESS;
333
	switch (Attribute)
334
	{
335
		case SQL_ATTR_CONNECTION_POOLING:
336
			*((unsigned int *) Value) = EN_is_pooling(env) ? SQL_CP_ONE_PER_DRIVER : SQL_CP_OFF;
337
			break;
338
		case SQL_ATTR_CP_MATCH:
339
			*((unsigned int *) Value) = SQL_CP_RELAXED_MATCH;
340
			break;
341
		case SQL_ATTR_ODBC_VERSION:
342
			*((unsigned int *) Value) = EN_is_odbc2(env) ? SQL_OV_ODBC2 : SQL_OV_ODBC3;
343
			break;
344
		case SQL_ATTR_OUTPUT_NTS:
345
			*((unsigned int *) Value) = SQL_TRUE;
346
			break;
347
		default:
348
			env->errornumber = CONN_INVALID_ARGUMENT_NO;
349
			ret = SQL_ERROR;
350
	}
351
	LEAVE_ENV_CS(env);
352
	return ret;
353
}
354
355
/*	SQLGetConnectOption -> SQLGetconnectAttr */
356
RETCODE		SQL_API
357
SQLGetConnectAttr(HDBC ConnectionHandle,
358
				  SQLINTEGER Attribute, PTR Value,
359
				  SQLINTEGER BufferLength, SQLINTEGER *StringLength)
360
{
361
	RETCODE	ret;
362
363
	mylog("[[SQLGetConnectAttr]] %d\n", Attribute);
364
	ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
365
	CC_clear_error((ConnectionClass *) ConnectionHandle);
366
	ret = PGAPI_GetConnectAttr(ConnectionHandle, Attribute,Value,
367
			BufferLength, StringLength);
368
	LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
369
	return ret;
370
}
371
372
/*	SQLGetStmtOption -> SQLGetStmtAttr */
373
RETCODE		SQL_API
374
SQLGetStmtAttr(HSTMT StatementHandle,
375
			   SQLINTEGER Attribute, PTR Value,
376
			   SQLINTEGER BufferLength, SQLINTEGER *StringLength)
377
{
378
	RETCODE	ret;
379
	CSTR func = "SQLGetStmtAttr";
380
381
	mylog("[[%s]] Handle=%u %d\n", func, StatementHandle, Attribute);
382
	ENTER_STMT_CS((StatementClass *) StatementHandle);
383
	SC_clear_error((StatementClass *) StatementHandle);
384
	ret = PGAPI_GetStmtAttr(StatementHandle, Attribute, Value,
385
			BufferLength, StringLength);
386
	LEAVE_STMT_CS((StatementClass *) StatementHandle);
387
	return ret;
388
}
389
390
/*	SQLSetConnectOption -> SQLSetConnectAttr */
391
RETCODE		SQL_API
392
SQLSetConnectAttr(HDBC ConnectionHandle,
393
				  SQLINTEGER Attribute, PTR Value,
394
				  SQLINTEGER StringLength)
395
{
396
	RETCODE	ret;
397
	ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
398
399
	mylog("[[SQLSetConnectAttr]] %d\n", Attribute);
400
	ENTER_CONN_CS(conn);
401
	CC_clear_error(conn);
402
	ret = PGAPI_SetConnectAttr(ConnectionHandle, Attribute, Value,
403
				  StringLength);
404
	LEAVE_CONN_CS(conn);
405
	return ret;
406
}
407
408
/*	new function */
409
RETCODE		SQL_API
410
SQLSetDescField(SQLHDESC DescriptorHandle,
411
				SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
412
				PTR Value, SQLINTEGER BufferLength)
413
{
414
	RETCODE		ret;
415
416
	mylog("[[SQLSetDescField]] h=%u rec=%d field=%d val=%x\n", DescriptorHandle, RecNumber, FieldIdentifier, Value);
417
	ret = PGAPI_SetDescField(DescriptorHandle, RecNumber, FieldIdentifier,
418
				Value, BufferLength);
419
	return ret;
420
}
421
422
/*	new fucntion */
423
RETCODE		SQL_API
424
SQLSetDescRec(SQLHDESC DescriptorHandle,
425
			  SQLSMALLINT RecNumber, SQLSMALLINT Type,
426
			  SQLSMALLINT SubType, SQLINTEGER Length,
427
			  SQLSMALLINT Precision, SQLSMALLINT Scale,
428
			  PTR Data, SQLINTEGER *StringLength,
429
			  SQLINTEGER *Indicator)
430
{
431
	CSTR func = "SQLSetDescRec";
432
433
	mylog("[[SQLSetDescRec]]\n");
434
	mylog("Error not implemented\n");
435
	return SQL_ERROR;
436
}
437
438
/*	new function */
439
RETCODE		SQL_API
440
SQLSetEnvAttr(HENV EnvironmentHandle,
441
			  SQLINTEGER Attribute, PTR Value,
442
			  SQLINTEGER StringLength)
443
{
444
	RETCODE	ret;
445
	EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
446
447
	mylog("[[SQLSetEnvAttr]] att=%d,%u\n", Attribute, Value);
448
	ENTER_ENV_CS(env);
449
	switch (Attribute)
450
	{
451
		case SQL_ATTR_CONNECTION_POOLING:
452
			switch ((SQLUINTEGER) Value)
453
			{
454
			 	case SQL_CP_OFF:
455
					EN_unset_pooling(env);
456
					ret = SQL_SUCCESS;
457
					break;
458
#if defined(WIN_MULTITHREAD_SUPPORT) || defined(POSIX_MULTITHREAD_SUPPORT)
459
				case SQL_CP_ONE_PER_DRIVER:
460
					EN_set_pooling(env);
461
					ret = SQL_SUCCESS;
462
					break;
463
#endif /* WIN_MULTITHREAD_SUPPORT */
464
				default:
465
					ret = SQL_SUCCESS_WITH_INFO;
466
			}
467
			break;
468
		case SQL_ATTR_CP_MATCH:
469
			/* *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH; */
470
			ret = SQL_SUCCESS;
471
			break;
472
		case SQL_ATTR_ODBC_VERSION:
473
			if ((SQLUINTEGER) Value == SQL_OV_ODBC2)
474
				EN_set_odbc2(env);
475
			else
476
				EN_set_odbc3(env);
477
			ret = SQL_SUCCESS;
478
			break;
479
		case SQL_ATTR_OUTPUT_NTS:
480
			if ((SQLUINTEGER) Value == SQL_TRUE)
481
				ret = SQL_SUCCESS;
482
			else
483
				ret = SQL_SUCCESS_WITH_INFO;
484
	
485
			break;
486
		default:
487
			env->errornumber = CONN_INVALID_ARGUMENT_NO;
488
			ret = SQL_ERROR;
489
	}
490
	if (SQL_SUCCESS_WITH_INFO == ret)
491
	{
492
		env->errornumber = CONN_OPTION_VALUE_CHANGED;
493
		env->errormsg = "SetEnv changed to ";
494
	}
495
	LEAVE_ENV_CS(env);
496
	return ret;
497
}
498
499
/*	SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */
500
RETCODE		SQL_API
501
SQLSetStmtAttr(HSTMT StatementHandle,
502
			   SQLINTEGER Attribute, PTR Value,
503
			   SQLINTEGER StringLength)
504
{
505
	CSTR func = "SQLSetStmtAttr";
506
	StatementClass *stmt = (StatementClass *) StatementHandle;
507
	RETCODE	ret;
508
509
	mylog("[[%s]] Handle=%u %d,%u\n", func, StatementHandle, Attribute, Value);
510
	ENTER_STMT_CS(stmt);
511
	SC_clear_error(stmt);
512
	ret = PGAPI_SetStmtAttr(StatementHandle, Attribute, Value, StringLength);
513
	LEAVE_STMT_CS(stmt);
514
	return ret;
515
}
516
517
#define SQL_FUNC_ESET(pfExists, uwAPI) \
518
		(*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) \
519
			|= (1 << ((uwAPI) & 0x000F)) \
520
				)
521
RETCODE		SQL_API
522
PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
523
{
524
	ConnectionClass	*conn = (ConnectionClass *) hdbc;
525
	ConnInfo	*ci = &(conn->connInfo);
526
527
	CC_clear_error(conn);
528
	if (fFunction != SQL_API_ODBC3_ALL_FUNCTIONS)
529
		return SQL_ERROR;
530
	memset(pfExists, 0, sizeof(UWORD) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
531
532
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCCONNECT); 1 deprecated */
533
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCENV); 2 deprecated */
534
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCSTMT); 3 deprecated */
535
536
	/*
537
	 * for (i = SQL_API_SQLBINDCOL; i <= 23; i++) SQL_FUNC_ESET(pfExists,
538
	 * i);
539
	 */
540
	SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDCOL);		/* 4 */
541
	SQL_FUNC_ESET(pfExists, SQL_API_SQLCANCEL); /* 5 */
542
	SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLATTRIBUTE);	/* 6 */
543
	SQL_FUNC_ESET(pfExists, SQL_API_SQLCONNECT);		/* 7 */
544
	SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBECOL);	/* 8 */
545
	SQL_FUNC_ESET(pfExists, SQL_API_SQLDISCONNECT);		/* 9 */
546
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLERROR);  10 deprecated */
547
	SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECDIRECT);		/* 11 */
548
	SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECUTE);		/* 12 */
549
	SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCH);	/* 13 */
550
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREECONNECT); 14 deprecated */
551
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEENV); 15 deprecated */
552
	SQL_FUNC_ESET(pfExists, SQL_API_SQLFREESTMT);		/* 16 */
553
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCURSORNAME);	/* 17 */
554
	SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMRESULTCOLS);	/* 18 */
555
	SQL_FUNC_ESET(pfExists, SQL_API_SQLPREPARE);		/* 19 */
556
	SQL_FUNC_ESET(pfExists, SQL_API_SQLROWCOUNT);		/* 20 */
557
	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCURSORNAME);	/* 21 */
558
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPARAM); 22 deprecated */
559
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLTRANSACT); 23 deprecated */
560
561
	/*
562
	 * for (i = 40; i < SQL_API_SQLEXTENDEDFETCH; i++)
563
	 * SQL_FUNC_ESET(pfExists, i);
564
	 */
565
	SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNS);		/* 40 */
566
	SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERCONNECT);	/* 41 */
567
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTOPTION); 42 deprecated */
568
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDATA);		/* 43 */
569
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETFUNCTIONS);	/* 44 */
570
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETINFO);		/* 45 */
571
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTOPTION); 46 deprecated */
572
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETTYPEINFO);	/* 47 */
573
	SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMDATA);		/* 48 */
574
	SQL_FUNC_ESET(pfExists, SQL_API_SQLPUTDATA);		/* 49 */
575
576
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50 deprecated */
577
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTOPTION); 51 deprecated */
578
	SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS);	/* 52 */
579
	SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS);		/* 53 */
580
	SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */
581
	if (ci->drivers.lie)
582
		SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT); /* 55 not implemented yet */
583
	if (ci->drivers.lie)
584
		SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 not implemented yet */ 
585
	SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES);	/* 57 */
586
	if (ci->drivers.lie)
587
		SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM); /* 58 not properly implemented */
588
	SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); /* 59 deprecated ? */
589
590
	/*
591
	 * for (++i; i < SQL_API_SQLBINDPARAMETER; i++)
592
	 * SQL_FUNC_ESET(pfExists, i);
593
	 */
594
	SQL_FUNC_ESET(pfExists, SQL_API_SQLFOREIGNKEYS);	/* 60 */
595
	SQL_FUNC_ESET(pfExists, SQL_API_SQLMORERESULTS);	/* 61 */
596
	SQL_FUNC_ESET(pfExists, SQL_API_SQLNATIVESQL);		/* 62 */
597
	SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMPARAMS);		/* 63 */
598
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */
599
	SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS);	/* 65 */
600
	SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS);	/* 66 */ 
601
	SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURES);		/* 67 */
602
	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS);		/* 68 */
603
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); 69 deprecated */
604
	SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES);		/* 70 */
605
	/* SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS); */	/* 71 */
606
	SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER);	/* 72 */
607
608
	SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCHANDLE);	/* 1001 */
609
	SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAM);		/* 1002 */
610
	SQL_FUNC_ESET(pfExists, SQL_API_SQLCLOSECURSOR);	/* 1003 */
611
	if (ci->drivers.lie)
612
		SQL_FUNC_ESET(pfExists, SQL_API_SQLCOPYDESC); /* 1004 not implemented yet */
613
	SQL_FUNC_ESET(pfExists, SQL_API_SQLENDTRAN);		/* 1005 */
614
	SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEHANDLE);		/* 1006 */
615
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTATTR);	/* 1007 */
616
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCFIELD); 	/* 1008 */
617
	if (ci->drivers.lie)
618
	{
619
		SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC); /* 1009 not implemented yet */
620
	}
621
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGFIELD); /* 1010 minimal implementation */
622
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGREC);		/* 1011 */
623
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETENVATTR);		/* 1012 */
624
	SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTATTR);	/* 1014 */
625
	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR);	/* 1016 */
626
	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD);	/* 1017 */
627
	if (ci->drivers.lie)
628
	{
629
		SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC); /* 1018 not implemented yet */
630
	}
631
	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETENVATTR);		/* 1019 */
632
	SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR);	/* 1020 */
633
	SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL);	/* 1021 */
634
	if (ci->updatable_cursors)
635
		SQL_FUNC_ESET(pfExists, SQL_API_SQLBULKOPERATIONS);	/* 24 */
636
637
	return SQL_SUCCESS;
638
}
639
640
RETCODE	SQL_API
641
SQLBulkOperations(HSTMT hstmt, SQLSMALLINT operation)
642
{
643
	RETCODE	ret;
644
	CSTR func = "SQLBulkOperations";
645
	StatementClass	*stmt = (StatementClass *) hstmt;
646
647
	ENTER_STMT_CS(stmt);
648
#ifndef	DRIVER_CURSOR_IMPLEMENT
649
	SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR,
650
	"driver must be compiled with the DRIVER_CURSOR_IMPLEMENT option");
651
	SC_log_error(func, "", stmt);
652
	ret = SQL_ERROR;
653
#else
654
	mylog("[[%s]] Handle=%u %d\n", func, hstmt, operation);
655
	SC_clear_error((StatementClass *) hstmt);
656
	ret = PGAPI_BulkOperations(hstmt, operation);
657
#endif /* DRIVER_CURSOR_IMPLEMENT */
658
	LEAVE_STMT_CS(stmt);
659
	return ret;
660
}	
661
#endif /* ODBCVER >= 0x0300 */