Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0b644ad

Browse files
author
Byron Nikolaidis
committed
Update 06-40-0004 -- Add Bookmark support!
1 parent 97b88f1 commit 0b644ad

File tree

9 files changed

+187
-61
lines changed

9 files changed

+187
-61
lines changed

src/interfaces/odbc/bind.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,6 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
162162
return SQL_INVALID_HANDLE;
163163
}
164164

165-
if (icol < 1) {
166-
/* currently we do not support bookmarks */
167-
stmt->errormsg = "Bookmarks are not currently supported.";
168-
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
169-
SC_log_error(func, "", stmt);
170-
return SQL_ERROR;
171-
}
172165

173166
SC_clear_error(stmt);
174167

@@ -179,6 +172,28 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
179172
return SQL_ERROR;
180173
}
181174

175+
/* If the bookmark column is being bound, then just save it */
176+
if (icol == 0) {
177+
178+
if (rgbValue == NULL) {
179+
stmt->bookmark.buffer = NULL;
180+
stmt->bookmark.used = NULL;
181+
}
182+
else {
183+
/* Make sure it is the bookmark data type */
184+
if ( fCType != SQL_C_BOOKMARK) {
185+
stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
186+
stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
187+
SC_log_error(func, "", stmt);
188+
return SQL_ERROR;
189+
}
190+
191+
stmt->bookmark.buffer = rgbValue;
192+
stmt->bookmark.used = pcbValue;
193+
}
194+
return SQL_SUCCESS;
195+
}
196+
182197
// allocate enough bindings if not already done
183198
// Most likely, execution of a statement would have setup the
184199
// necessary bindings. But some apps call BindCol before any

src/interfaces/odbc/environ.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ int status;
190190
case STMT_VALUE_OUT_OF_RANGE:
191191
strcpy(szSqlState, "22003");
192192
break;
193+
194+
case STMT_OPERATION_INVALID:
195+
strcpy(szSqlState, "S1011");
196+
break;
197+
193198
default:
194199
strcpy(szSqlState, "S1000");
195200
// also a general error

src/interfaces/odbc/info.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ RETCODE result;
107107
break;
108108

109109
case SQL_BOOKMARK_PERSISTENCE: /* ODBC 2.0 */
110-
len = 4;
111-
value = 0;
110+
/* very simple bookmark support */
111+
len = 4;
112+
value = globals.use_declarefetch ? 0 : (SQL_BP_SCROLL);
112113
break;
113114

114115
case SQL_COLUMN_ALIAS: /* ODBC 2.0 */
@@ -221,7 +222,8 @@ RETCODE result;
221222
SQL_FD_FETCH_LAST |
222223
SQL_FD_FETCH_PRIOR |
223224
SQL_FD_FETCH_ABSOLUTE |
224-
SQL_FD_FETCH_RELATIVE);
225+
SQL_FD_FETCH_RELATIVE |
226+
SQL_FD_FETCH_BOOKMARK);
225227
break;
226228

227229
case SQL_FILE_USAGE: /* ODBC 2.0 */

src/interfaces/odbc/options.c

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "environ.h"
3333
#include "connection.h"
3434
#include "statement.h"
35+
#include "qresult.h"
3536

3637

3738
extern GLOBAL_VALUES globals;
@@ -189,7 +190,6 @@ char changed = FALSE;
189190
if (conn) conn->stmtOptions.rowset_size = vParam;
190191
if (stmt) stmt->options.rowset_size = vParam;
191192

192-
193193
break;
194194

195195
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
@@ -205,18 +205,11 @@ char changed = FALSE;
205205
}
206206
return SQL_ERROR;
207207

208-
case SQL_USE_BOOKMARKS: /* NOT SUPPORTED */
209-
if (stmt) {
210-
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
211-
stmt->errormsg = "Driver does not support (SET) using bookmarks.";
212-
SC_log_error(func, "", stmt);
213-
}
214-
if (conn) {
215-
conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
216-
conn->errormsg = "Driver does not support (SET) using bookmarks.";
217-
CC_log_error(func, "", conn);
218-
}
219-
return SQL_ERROR;
208+
case SQL_USE_BOOKMARKS:
209+
210+
if (stmt) stmt->options.use_bookmarks = vParam;
211+
if (conn) conn->stmtOptions.use_bookmarks = vParam;
212+
break;
220213

221214
default:
222215
{
@@ -507,6 +500,7 @@ RETCODE SQL_API SQLGetStmtOption(
507500
{
508501
static char *func="SQLGetStmtOption";
509502
StatementClass *stmt = (StatementClass *) hstmt;
503+
QResultClass *res;
510504

511505
mylog("%s: entering...\n", func);
512506

@@ -520,15 +514,39 @@ StatementClass *stmt = (StatementClass *) hstmt;
520514
}
521515

522516
switch(fOption) {
523-
case SQL_GET_BOOKMARK:/* NOT SUPPORTED */
524-
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
525-
stmt->errormsg = "Driver does not support getting bookmarks.";
526-
SC_log_error(func, "", stmt);
527-
return SQL_ERROR;
528-
break;
529-
517+
case SQL_GET_BOOKMARK:
530518
case SQL_ROW_NUMBER:
531-
*((SDWORD *) pvParam) = stmt->currTuple + 1;
519+
520+
res = stmt->result;
521+
522+
if ( stmt->manual_result || ! globals.use_declarefetch) {
523+
// make sure we're positioned on a valid row
524+
if((stmt->currTuple < 0) ||
525+
(stmt->currTuple >= QR_get_num_tuples(res))) {
526+
stmt->errormsg = "Not positioned on a valid row.";
527+
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
528+
SC_log_error(func, "", stmt);
529+
return SQL_ERROR;
530+
}
531+
}
532+
else {
533+
if (stmt->currTuple == -1 || ! res || ! res->tupleField) {
534+
stmt->errormsg = "Not positioned on a valid row.";
535+
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
536+
SC_log_error(func, "", stmt);
537+
return SQL_ERROR;
538+
}
539+
}
540+
541+
if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF) {
542+
stmt->errormsg = "Operation invalid because use bookmarks not enabled.";
543+
stmt->errornumber = STMT_OPERATION_INVALID;
544+
SC_log_error(func, "", stmt);
545+
return SQL_ERROR;
546+
}
547+
548+
*((UDWORD *) pvParam) = SC_get_bookmark(stmt);
549+
532550
break;
533551

534552
case SQL_ASYNC_ENABLE: /* NOT SUPPORTED */
@@ -583,8 +601,8 @@ StatementClass *stmt = (StatementClass *) hstmt;
583601
*((SDWORD *) pvParam) = SQL_SC_NON_UNIQUE;
584602
break;
585603

586-
case SQL_USE_BOOKMARKS:/* NOT SUPPORTED */
587-
*((SDWORD *) pvParam) = SQL_UB_OFF;
604+
case SQL_USE_BOOKMARKS:
605+
*((SDWORD *) pvParam) = stmt->options.use_bookmarks;
588606
break;
589607

590608
default:

src/interfaces/odbc/psqlodbc.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ typedef UInt4 Oid;
3939

4040
#define DRIVERNAME "PostgreSQL ODBC"
4141
#define DBMS_NAME "PostgreSQL"
42-
#define DBMS_VERSION "06.40.0003 PostgreSQL 6.4"
43-
#define POSTGRESDRIVERVERSION "06.40.0003"
42+
#define DBMS_VERSION "06.40.0004 PostgreSQL 6.4"
43+
#define POSTGRESDRIVERVERSION "06.40.0004"
4444

4545
#ifdef WIN32
4646
#define DRIVER_FILE_NAME "PSQLODBC.DLL"
@@ -137,6 +137,7 @@ typedef struct StatementOptions_ {
137137
int scroll_concurrency;
138138
int retrieve_data;
139139
int bind_size; /* size of each structure if using Row Binding */
140+
int use_bookmarks;
140141
} StatementOptions;
141142

142143
/* Used to pass extra query info to send_query */

src/interfaces/odbc/psqlodbc.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ END
204204
//
205205

206206
VS_VERSION_INFO VERSIONINFO
207-
FILEVERSION 6,40,0,3
208-
PRODUCTVERSION 6,40,0,3
207+
FILEVERSION 6,40,0,4
208+
PRODUCTVERSION 6,40,0,4
209209
FILEFLAGSMASK 0x3L
210210
#ifdef _DEBUG
211211
FILEFLAGS 0x1L
@@ -223,12 +223,12 @@ BEGIN
223223
VALUE "Comments", "PostgreSQL ODBC driver for Windows 95\0"
224224
VALUE "CompanyName", "Insight Distribution Systems\0"
225225
VALUE "FileDescription", "PostgreSQL Driver\0"
226-
VALUE "FileVersion", " 6.40.0003\0"
226+
VALUE "FileVersion", " 6.40.0004\0"
227227
VALUE "InternalName", "psqlodbc\0"
228228
VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft� is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0"
229229
VALUE "OriginalFilename", "psqlodbc.dll\0"
230230
VALUE "ProductName", "Microsoft Open Database Connectivity\0"
231-
VALUE "ProductVersion", " 6.40.0003\0"
231+
VALUE "ProductVersion", " 6.40.0004\0"
232232
END
233233
END
234234
BLOCK "VarFileInfo"

src/interfaces/odbc/results.c

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ int num_cols, num_rows;
610610
Int4 field_type;
611611
void *value;
612612
int result;
613-
613+
char get_bookmark = FALSE;
614614

615615
mylog("SQLGetData: enter, stmt=%u\n", stmt);
616616

@@ -635,24 +635,41 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
635635
}
636636

637637
if (icol == 0) {
638-
stmt->errormsg = "Bookmarks are not currently supported.";
639-
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
640-
SC_log_error(func, "", stmt);
641-
return SQL_ERROR;
642-
}
643638

644-
// use zero-based column numbers
645-
icol--;
639+
if (stmt->options.use_bookmarks == SQL_UB_OFF) {
640+
stmt->errornumber = STMT_COLNUM_ERROR;
641+
stmt->errormsg = "Attempt to retrieve bookmark with bookmark usage disabled";
642+
SC_log_error(func, "", stmt);
643+
return SQL_ERROR;
644+
}
645+
646+
/* Make sure it is the bookmark data type */
647+
if (fCType != SQL_C_BOOKMARK) {
648+
stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK";
649+
stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE;
650+
SC_log_error(func, "", stmt);
651+
return SQL_ERROR;
652+
}
653+
654+
get_bookmark = TRUE;
646655

647-
// make sure the column number is valid
648-
num_cols = QR_NumResultCols(res);
649-
if (icol >= num_cols) {
650-
stmt->errormsg = "Invalid column number.";
651-
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
652-
SC_log_error(func, "", stmt);
653-
return SQL_ERROR;
654656
}
655657

658+
else {
659+
660+
// use zero-based column numbers
661+
icol--;
662+
663+
// make sure the column number is valid
664+
num_cols = QR_NumResultCols(res);
665+
if (icol >= num_cols) {
666+
stmt->errormsg = "Invalid column number.";
667+
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
668+
SC_log_error(func, "", stmt);
669+
return SQL_ERROR;
670+
}
671+
}
672+
656673
if ( stmt->manual_result || ! globals.use_declarefetch) {
657674
// make sure we're positioned on a valid row
658675
num_rows = QR_get_num_tuples(res);
@@ -664,13 +681,16 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
664681
return SQL_ERROR;
665682
}
666683
mylog(" num_rows = %d\n", num_rows);
667-
if ( stmt->manual_result) {
668-
value = QR_get_value_manual(res, stmt->currTuple, icol);
669-
}
670-
else {
671-
value = QR_get_value_backend_row(res, stmt->currTuple, icol);
684+
685+
if ( ! get_bookmark) {
686+
if ( stmt->manual_result) {
687+
value = QR_get_value_manual(res, stmt->currTuple, icol);
688+
}
689+
else {
690+
value = QR_get_value_backend_row(res, stmt->currTuple, icol);
691+
}
692+
mylog(" value = '%s'\n", value);
672693
}
673-
mylog(" value = '%s'\n", value);
674694
}
675695
else { /* its a SOCKET result (backend data) */
676696
if (stmt->currTuple == -1 || ! res || ! res->tupleField) {
@@ -680,11 +700,21 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
680700
return SQL_ERROR;
681701
}
682702

683-
value = QR_get_value_backend(res, icol);
703+
if ( ! get_bookmark)
704+
value = QR_get_value_backend(res, icol);
684705

685706
mylog(" socket: value = '%s'\n", value);
686707
}
687708

709+
if ( get_bookmark) {
710+
*((UDWORD *) rgbValue) = SC_get_bookmark(stmt);
711+
712+
if (pcbValue)
713+
*pcbValue = 4;
714+
715+
return SQL_SUCCESS;
716+
}
717+
688718
field_type = QR_get_field_type(res, icol);
689719

690720
mylog("**** SQLGetData: icol = %d, fCType = %d, field_type = %d, value = '%s'\n", icol, fCType, field_type, value);
@@ -761,6 +791,14 @@ mylog("SQLFetch: stmt = %u, stmt->result= %u\n", stmt, stmt->result);
761791
return SQL_ERROR;
762792
}
763793

794+
/* Not allowed to bind a bookmark column when using SQLFetch. */
795+
if ( stmt->bookmark.buffer) {
796+
stmt->errornumber = STMT_COLNUM_ERROR;
797+
stmt->errormsg = "Not allowed to bind a bookmark column when using SQLFetch";
798+
SC_log_error(func, "", stmt);
799+
return SQL_ERROR;
800+
}
801+
764802
if (stmt->status == STMT_EXECUTING) {
765803
stmt->errormsg = "Can't fetch while statement is still executing.";
766804
stmt->errornumber = STMT_SEQUENCE_ERROR;
@@ -831,6 +869,14 @@ mylog("SQLExtendedFetch: stmt=%u\n", stmt);
831869
return SQL_ERROR;
832870
}
833871

872+
/* If a bookmark colunmn is bound but bookmark usage is off, then error */
873+
if (stmt->bookmark.buffer && stmt->options.use_bookmarks == SQL_UB_OFF) {
874+
stmt->errornumber = STMT_COLNUM_ERROR;
875+
stmt->errormsg = "Attempt to retrieve bookmark with bookmark usage disabled";
876+
SC_log_error(func, "", stmt);
877+
return SQL_ERROR;
878+
}
879+
834880
if (stmt->status == STMT_EXECUTING) {
835881
stmt->errormsg = "Can't fetch while statement is still executing.";
836882
stmt->errornumber = STMT_SEQUENCE_ERROR;
@@ -950,6 +996,11 @@ mylog("SQLExtendedFetch: stmt=%u\n", stmt);
950996

951997
break;
952998

999+
case SQL_FETCH_BOOKMARK:
1000+
1001+
stmt->rowset_start = irow - 1;
1002+
break;
1003+
9531004
default:
9541005
SC_log_error(func, "Unsupported SQLExtendedFetch Direction", stmt);
9551006
return SQL_ERROR;

0 commit comments

Comments
 (0)