Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : /*
14 : * This code was created by Peter Harvey (mostly during Christmas 98/99).
15 : * This code is LGPL. Please ensure that this message remains in future
16 : * distributions and uses of this code (thats about all I get out of it).
17 : * - Peter Harvey pharvey@codebydesign.com
18 : *
19 : * This file has been modified for the MonetDB project. See the file
20 : * Copyright in this directory for more information.
21 : */
22 :
23 : /********************************************************************
24 : * SQLSetPos()
25 : * CLI Compliance: ODBC
26 : *
27 : * Author: Martin van Dinther, Sjoerd Mullender
28 : * Date : 30 aug 2002
29 : *
30 : ********************************************************************/
31 :
32 : #include "ODBCGlobal.h"
33 : #include "ODBCStmt.h"
34 :
35 : #ifdef ODBCDEBUG
36 : static char *
37 0 : translateOperation(SQLUSMALLINT Operation)
38 : {
39 0 : switch (Operation) {
40 : case SQL_POSITION:
41 : return "SQL_POSITION";
42 0 : case SQL_REFRESH:
43 0 : return "SQL_REFRESH";
44 0 : case SQL_UPDATE:
45 0 : return "SQL_UPDATE";
46 0 : case SQL_DELETE:
47 0 : return "SQL_DELETE";
48 0 : default:
49 0 : return "unknown";
50 : }
51 : }
52 :
53 : static char *
54 0 : translateLockType(SQLUSMALLINT LockType)
55 : {
56 0 : switch (LockType) {
57 : case SQL_LOCK_NO_CHANGE:
58 : return "SQL_LOCK_NO_CHANGE";
59 0 : case SQL_LOCK_EXCLUSIVE:
60 0 : return "SQL_LOCK_EXCLUSIVE";
61 0 : case SQL_LOCK_UNLOCK:
62 0 : return "SQL_LOCK_UNLOCK";
63 0 : default:
64 0 : return "unknown";
65 : }
66 : }
67 : #endif
68 :
69 : SQLRETURN SQL_API
70 : SQLSetPos(SQLHSTMT StatementHandle,
71 : SQLSETPOSIROW RowNumber,
72 : SQLUSMALLINT Operation,
73 : SQLUSMALLINT LockType)
74 : {
75 0 : ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
76 :
77 : #ifdef ODBCDEBUG
78 0 : ODBCLOG("SQLSetPos %p " ULENFMT " %s %s\n",
79 : StatementHandle, ULENCAST RowNumber,
80 : translateOperation(Operation), translateLockType(LockType));
81 : #endif
82 :
83 0 : if (!isValidStmt(stmt))
84 : return SQL_INVALID_HANDLE;
85 :
86 0 : clearStmtErrors(stmt);
87 :
88 : /* check the parameter values */
89 :
90 0 : if (stmt->State < EXECUTED0) {
91 : /* Function sequence error */
92 0 : addStmtError(stmt, "HY010", NULL, 0);
93 0 : return SQL_ERROR;
94 : }
95 0 : if (stmt->State <= EXECUTED1) {
96 : /* Invalid cursor state */
97 0 : addStmtError(stmt, "24000", NULL, 0);
98 0 : return SQL_ERROR;
99 : }
100 :
101 0 : if (RowNumber > (SQLSETPOSIROW) stmt->rowSetSize) {
102 : /* Row value out of range */
103 0 : addStmtError(stmt, "HY107", NULL, 0);
104 0 : return SQL_ERROR;
105 : }
106 :
107 0 : if (stmt->cursorType == SQL_CURSOR_FORWARD_ONLY) {
108 : /* Invalid cursor position */
109 0 : addStmtError(stmt, "HY109", NULL, 0);
110 0 : return SQL_ERROR;
111 : }
112 :
113 0 : switch (LockType) {
114 : case SQL_LOCK_NO_CHANGE:
115 : /* the only value that we support */
116 0 : break;
117 0 : case SQL_LOCK_EXCLUSIVE:
118 : case SQL_LOCK_UNLOCK:
119 : /* Optional feature not implemented */
120 0 : addStmtError(stmt, "HYC00", NULL, 0);
121 0 : return SQL_ERROR;
122 0 : default:
123 : /* Invalid attribute/option identifier */
124 0 : addStmtError(stmt, "HY092", NULL, 0);
125 0 : return SQL_ERROR;
126 : }
127 :
128 0 : switch (Operation) {
129 0 : case SQL_POSITION:
130 0 : if (RowNumber == 0) {
131 : /* If RowNumber is 0, the operation applies to every
132 : * row in the rowset.
133 : * In this case set it to the first row, so 1.
134 : */
135 : RowNumber = 1;
136 : }
137 0 : if (mapi_seek_row(stmt->hdl, stmt->startRow + RowNumber - 1,
138 : MAPI_SEEK_SET) != MOK) {
139 : /* Invalid cursor position */
140 0 : addStmtError(stmt, "HY109", NULL, 0);
141 0 : return SQL_ERROR;
142 : }
143 0 : stmt->currentRow = stmt->startRow + RowNumber - 1;
144 0 : switch (mapi_fetch_row(stmt->hdl)) {
145 : case MOK:
146 0 : break;
147 0 : case MTIMEOUT:
148 : /* Connection timeout expired */
149 0 : addStmtError(stmt, "HYT01", NULL, 0);
150 0 : return SQL_ERROR;
151 0 : default:
152 : /* Invalid cursor position */
153 0 : addStmtError(stmt, "HY109", NULL, 0);
154 0 : return SQL_ERROR;
155 : }
156 0 : stmt->currentRow++;
157 0 : break;
158 0 : case SQL_REFRESH:
159 : case SQL_UPDATE:
160 : case SQL_DELETE:
161 : /* Optional feature not implemented */
162 0 : addStmtError(stmt, "HYC00", NULL, 0);
163 0 : return SQL_ERROR;
164 0 : default:
165 : /* Invalid attribute/option identifier */
166 0 : addStmtError(stmt, "HY092", NULL, 0);
167 0 : return SQL_ERROR;
168 : }
169 :
170 0 : return SQL_SUCCESS;
171 : }
|