My favorites | Sign in
Project Home Downloads Wiki Issues Source
Repository:
Checkout   Browse   Changes   Clones  
Changes to /src/cursor.cpp
c278e74e4434 vs. b2dfac9a0b88 Compare: vs.  Format:
Revision b2dfac9a0b88
Go to: 
Sign in to write a code review
/src/cursor.cpp   c278e74e4434 /src/cursor.cpp   b2dfac9a0b88
1 1
2 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 2 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
3 // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 3 // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
4 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 4 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
5 // permit persons to whom the Software is furnished to do so. 5 // permit persons to whom the Software is furnished to do so.
6 // 6 //
7 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 7 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
8 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 8 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
9 // OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 9 // OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
10 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 11
12 // Note: This project has gone from C++ (when it was ported from pypgdb) to C, back to C++ (where it will stay). If 12 // Note: This project has gone from C++ (when it was ported from pypgdb) to C, back to C++ (where it will stay). If
13 // you are making modifications, feel free to move variable declarations from the top of functions to where they are 13 // you are making modifications, feel free to move variable declarations from the top of functions to where they are
14 // actually used. 14 // actually used.
15 15
16 #include "pyodbc.h" 16 #include "pyodbc.h"
17 #include "cursor.h" 17 #include "cursor.h"
18 #include "pyodbcmodule.h" 18 #include "pyodbcmodule.h"
19 #include "connection.h" 19 #include "connection.h"
20 #include "row.h" 20 #include "row.h"
21 #include "buffer.h" 21 #include "buffer.h"
22 #include "params.h" 22 #include "params.h"
23 #include "errors.h" 23 #include "errors.h"
24 #include "getdata.h" 24 #include "getdata.h"
25 #include "dbspecific.h" 25 #include "dbspecific.h"
26 #include "sqlwchar.h" 26 #include "sqlwchar.h"
27 #include <datetime.h> 27 #include <datetime.h>
28 28
29 enum 29 enum
30 { 30 {
31 CURSOR_REQUIRE_CNXN = 0x00000001, 31 CURSOR_REQUIRE_CNXN = 0x00000001,
32 CURSOR_REQUIRE_OPEN = 0x00000003, // includes _CNXN 32 CURSOR_REQUIRE_OPEN = 0x00000003, // includes _CNXN
33 CURSOR_REQUIRE_RESULTS = 0x00000007, // includes _OPEN 33 CURSOR_REQUIRE_RESULTS = 0x00000007, // includes _OPEN
34 CURSOR_RAISE_ERROR = 0x00000010, 34 CURSOR_RAISE_ERROR = 0x00000010,
35 }; 35 };
36 36
37 inline bool 37 inline bool StatementIsValid(Cursor* cursor)
38 StatementIsValid(Cursor* cursor)
39 { 38 {
40 return cursor->cnxn != 0 && ((Connection*)cursor->cnxn)->hdbc != SQL_NULL_HANDLE && cursor->hstmt != SQL_NULL_HANDLE; 39 return cursor->cnxn != 0 && ((Connection*)cursor->cnxn)->hdbc != SQL_NULL_HANDLE && cursor->hstmt != SQL_NULL_HANDLE;
41 } 40 }
42 41
43 extern PyTypeObject CursorType; 42 extern PyTypeObject CursorType;
44 43
45 inline bool 44 inline bool Cursor_Check(PyObject* o)
46 Cursor_Check(PyObject* o)
47 { 45 {
48 return o != 0 && Py_TYPE(o) == &CursorType; 46 return o != 0 && Py_TYPE(o) == &CursorType;
49 } 47 }
50 48
51 49 static Cursor* Cursor_Validate(PyObject* obj, DWORD flags)
52 Cursor* Cursor_Validate(PyObject* obj, DWORD flags)
53 { 50 {
54 // Validates that a PyObject is a Cursor (like Cursor_Check) and optionally some other requirements controlled by 51 // Validates that a PyObject is a Cursor (like Cursor_Check) and optionally some other requirements controlled by
55 // `flags`. If valid and all requirements (from the flags) are met, the cursor is returned, cast to Cursor*. 52 // `flags`. If valid and all requirements (from the flags) are met, the cursor is returned, cast to Cursor*.
56 // Otherwise zero is returned. 53 // Otherwise zero is returned.
57 // 54 //
58 // Designed to be used at the top of methods to convert the PyObject pointer and perform necessary checks. 55 // Designed to be used at the top of methods to convert the PyObject pointer and perform necessary checks.
59 // 56 //
60 // Valid flags are from the CURSOR_ enum above. Note that unless CURSOR_RAISE_ERROR is supplied, an exception 57 // Valid flags are from the CURSOR_ enum above. Note that unless CURSOR_RAISE_ERROR is supplied, an exception
61 // will not be set. (When deallocating, we really don't want an exception.) 58 // will not be set. (When deallocating, we really don't want an exception.)
62 59
63 Connection* cnxn = 0; 60 Connection* cnxn = 0;
64 Cursor* cursor = 0; 61 Cursor* cursor = 0;
65 62
66 if (!Cursor_Check(obj)) 63 if (!Cursor_Check(obj))
67 { 64 {
68 if (flags & CURSOR_RAISE_ERROR) 65 if (flags & CURSOR_RAISE_ERROR)
69 PyErr_SetString(ProgrammingError, "Invalid cursor object."); 66 PyErr_SetString(ProgrammingError, "Invalid cursor object.");
70 return 0; 67 return 0;
71 } 68 }
72 69
73 cursor = (Cursor*)obj; 70 cursor = (Cursor*)obj;
74 cnxn = (Connection*)cursor->cnxn; 71 cnxn = (Connection*)cursor->cnxn;
75 72
76 if (cnxn == 0) 73 if (cnxn == 0)
77 { 74 {
78 if (flags & CURSOR_RAISE_ERROR) 75 if (flags & CURSOR_RAISE_ERROR)
79 PyErr_SetString(ProgrammingError, "Attempt to use a closed cursor."); 76 PyErr_SetString(ProgrammingError, "Attempt to use a closed cursor.");
80 return 0; 77 return 0;
81 } 78 }
82 79
83 if (IsSet(flags, CURSOR_REQUIRE_OPEN)) 80 if (IsSet(flags, CURSOR_REQUIRE_OPEN))
84 { 81 {
85 if (cursor->hstmt == SQL_NULL_HANDLE) 82 if (cursor->hstmt == SQL_NULL_HANDLE)
86 { 83 {
87 if (flags & CURSOR_RAISE_ERROR) 84 if (flags & CURSOR_RAISE_ERROR)
88 PyErr_SetString(ProgrammingError, "Attempt to use a closed cursor."); 85 PyErr_SetString(ProgrammingError, "Attempt to use a closed cursor.");
89 return 0; 86 return 0;
90 } 87 }
91 88
92 if (cnxn->hdbc == SQL_NULL_HANDLE) 89 if (cnxn->hdbc == SQL_NULL_HANDLE)
93 { 90 {
94 if (flags & CURSOR_RAISE_ERROR) 91 if (flags & CURSOR_RAISE_ERROR)
95 PyErr_SetString(ProgrammingError, "The cursor's connection has been closed."); 92 PyErr_SetString(ProgrammingError, "The cursor's connection has been closed.");
96 return 0; 93 return 0;
97 } 94 }
98 } 95 }
99 96
100 if (IsSet(flags, CURSOR_REQUIRE_RESULTS) && cursor->colinfos == 0) 97 if (IsSet(flags, CURSOR_REQUIRE_RESULTS) && cursor->colinfos == 0)
101 { 98 {
102 if (flags & CURSOR_RAISE_ERROR) 99 if (flags & CURSOR_RAISE_ERROR)
103 PyErr_SetString(ProgrammingError, "No results. Previous SQL was not a query."); 100 PyErr_SetString(ProgrammingError, "No results. Previous SQL was not a query.");
104 return 0; 101 return 0;
105 } 102 }
106 103
107 return cursor; 104 return cursor;
108 } 105 }
109 106
110 107
111 inline bool IsNumericType(SQLSMALLINT sqltype) 108 inline bool IsNumericType(SQLSMALLINT sqltype)
112 { 109 {
113 switch (sqltype) 110 switch (sqltype)
114 { 111 {
115 case SQL_DECIMAL: 112 case SQL_DECIMAL:
116 case SQL_NUMERIC: 113 case SQL_NUMERIC:
117 case SQL_REAL: 114 case SQL_REAL:
118 case SQL_FLOAT: 115 case SQL_FLOAT:
119 case SQL_DOUBLE: 116 case SQL_DOUBLE:
120 case SQL_SMALLINT: 117 case SQL_SMALLINT:
121 case SQL_INTEGER: 118 case SQL_INTEGER:
122 case SQL_TINYINT: 119 case SQL_TINYINT:
123 case SQL_BIGINT: 120 case SQL_BIGINT:
124 return true; 121 return true;
125 } 122 }
126 123
127 return false; 124 return false;
128 } 125 }
129 126
130 127
131 PyObject* PythonTypeFromSqlType(Cursor* cur, const SQLCHAR* name, SQLSMALLINT type, bool unicode_results) 128 static PyObject* PythonTypeFromSqlType(Cursor* cur, const SQLCHAR* name, SQLSMALLINT type, bool unicode_results)
132 { 129 {
133 // Returns a type object ('int', 'str', etc.) for the given ODBC C type. This is used to populate 130 // Returns a type object ('int', 'str', etc.) for the given ODBC C type. This is used to populate
134 // Cursor.description with the type of Python object that will be returned for each column. 131 // Cursor.description with the type of Python object that will be returned for each column.
135 // 132 //
136 // name 133 // name
137 // The name of the column, only used to create error messages. 134 // The name of the column, only used to create error messages.
138 // 135 //
139 // type 136 // type
140 // The ODBC C type (SQL_C_CHAR, etc.) of the column. 137 // The ODBC C type (SQL_C_CHAR, etc.) of the column.
141 // 138 //
142 // The returned object does not have its reference count incremented! 139 // The returned object does not have its reference count incremented!
143 140
144 int conv_index = GetUserConvIndex(cur, type); 141 int conv_index = GetUserConvIndex(cur, type);
145 if (conv_index != -1) 142 if (conv_index != -1)
146 return (PyObject*)&PyString_Type; 143 return (PyObject*)&PyString_Type;
147 144
148 PyObject* pytype = 0; 145 PyObject* pytype = 0;
149 146
150 switch (type) 147 switch (type)
151 { 148 {
152 case SQL_CHAR: 149 case SQL_CHAR:
153 case SQL_VARCHAR: 150 case SQL_VARCHAR:
154 case SQL_LONGVARCHAR: 151 case SQL_LONGVARCHAR:
155 case SQL_GUID: 152 case SQL_GUID:
156 case SQL_SS_XML: 153 case SQL_SS_XML:
157 if (unicode_results) 154 if (unicode_results)
158 pytype = (PyObject*)&PyUnicode_Type; 155 pytype = (PyObject*)&PyUnicode_Type;
159 else 156 else
160 pytype = (PyObject*)&PyString_Type; 157 pytype = (PyObject*)&PyString_Type;
161 break; 158 break;
162 159
163 case SQL_DECIMAL: 160 case SQL_DECIMAL:
164 case SQL_NUMERIC: 161 case SQL_NUMERIC:
165 pytype = (PyObject*)decimal_type; 162 pytype = (PyObject*)decimal_type;
166 break; 163 break;
167 164
168 case SQL_REAL: 165 case SQL_REAL:
169 case SQL_FLOAT: 166 case SQL_FLOAT:
170 case SQL_DOUBLE: 167 case SQL_DOUBLE:
171 pytype = (PyObject*)&PyFloat_Type; 168 pytype = (PyObject*)&PyFloat_Type;
172 break; 169 break;
173 170
174 case SQL_SMALLINT: 171 case SQL_SMALLINT:
175 case SQL_INTEGER: 172 case SQL_INTEGER:
176 case SQL_TINYINT: 173 case SQL_TINYINT:
177 pytype = (PyObject*)&PyInt_Type; 174 pytype = (PyObject*)&PyInt_Type;
178 break; 175 break;
179 176
180 case SQL_TYPE_DATE: 177 case SQL_TYPE_DATE:
181 pytype = (PyObject*)PyDateTimeAPI->DateType; 178 pytype = (PyObject*)PyDateTimeAPI->DateType;
182 break; 179 break;
183 180
184 case SQL_TYPE_TIME: 181 case SQL_TYPE_TIME:
185 case SQL_SS_TIME2: // SQL Server 2008+ 182 case SQL_SS_TIME2: // SQL Server 2008+
186 pytype = (PyObject*)PyDateTimeAPI->TimeType; 183 pytype = (PyObject*)PyDateTimeAPI->TimeType;
187 break; 184 break;
188 185
189 case SQL_TYPE_TIMESTAMP: 186 case SQL_TYPE_TIMESTAMP:
190 pytype = (PyObject*)PyDateTimeAPI->DateTimeType; 187 pytype = (PyObject*)PyDateTimeAPI->DateTimeType;
191 break; 188 break;
192 189
193 case SQL_BIGINT: 190 case SQL_BIGINT:
194 pytype = (PyObject*)&PyLong_Type; 191 pytype = (PyObject*)&PyLong_Type;
195 break; 192 break;
196 193
197 case SQL_BIT: 194 case SQL_BIT:
198 pytype = (PyObject*)&PyBool_Type; 195 pytype = (PyObject*)&PyBool_Type;
199 break; 196 break;
200 197
201 case SQL_BINARY: 198 case SQL_BINARY:
202 case SQL_VARBINARY: 199 case SQL_VARBINARY:
203 case SQL_LONGVARBINARY: 200 case SQL_LONGVARBINARY:
204 #if PY_MAJOR_VERSION >= 3 201 #if PY_MAJOR_VERSION >= 3
205 pytype = (PyObject*)&PyBytes_Type; 202 pytype = (PyObject*)&PyBytes_Type;
206 #else 203 #else
207 pytype = (PyObject*)&PyBuffer_Type; 204 pytype = (PyObject*)&PyBuffer_Type;
208 #endif 205 #endif
209 break; 206 break;
210 207
211 208
212 case SQL_WCHAR: 209 case SQL_WCHAR:
213 case SQL_WVARCHAR: 210 case SQL_WVARCHAR:
214 case SQL_WLONGVARCHAR: 211 case SQL_WLONGVARCHAR:
215 pytype = (PyObject*)&PyUnicode_Type; 212 pytype = (PyObject*)&PyUnicode_Type;
216 break; 213 break;
217 214
218 default: 215 default:
219 return RaiseErrorV(0, 0, "ODBC data type %d is not supported. Cannot read column %s.", type, (const char*)name); 216 return RaiseErrorV(0, 0, "ODBC data type %d is not supported. Cannot read column %s.", type, (const char*)name);
220 } 217 }
221 218
222 Py_INCREF(pytype); 219 Py_INCREF(pytype);
223 return pytype; 220 return pytype;
224 } 221 }
225 222
226 223
227 static bool 224 static bool create_name_map(Cursor* cur, SQLSMALLINT field_count, bool lower)
228 create_name_map(Cursor* cur, SQLSMALLINT field_count, bool lower)
229 { 225 {
230 // Called after an execute to construct the map shared by rows. 226 // Called after an execute to construct the map shared by rows.
231 227
232 bool success = false; 228 bool success = false;
233 PyObject *desc = 0, *colmap = 0, *colinfo = 0, *type = 0, *index = 0, *nullable_obj=0; 229 PyObject *desc = 0, *colmap = 0, *colinfo = 0, *type = 0, *index = 0, *nullable_obj=0;
234 SQLRETURN ret; 230 SQLRETURN ret;
235 231
236 I(cur->hstmt != SQL_NULL_HANDLE && cur->colinfos != 0); 232 I(cur->hstmt != SQL_NULL_HANDLE && cur->colinfos != 0);
237 233
238 // These are the values we expect after free_results. If this function fails, we do not modify any members, so 234 // These are the values we expect after free_results. If this function fails, we do not modify any members, so
239 // they should be set to something Cursor_close can deal with. 235 // they should be set to something Cursor_close can deal with.
240 I(cur->description == Py_None); 236 I(cur->description == Py_None);
241 I(cur->map_name_to_index == 0); 237 I(cur->map_name_to_index == 0);
242 238
243 if (cur->cnxn->hdbc == SQL_NULL_HANDLE) 239 if (cur->cnxn->hdbc == SQL_NULL_HANDLE)
244 { 240 {
245 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed."); 241 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
246 return false; 242 return false;
247 } 243 }
248 244
249 desc = PyTuple_New((Py_ssize_t)field_count); 245 desc = PyTuple_New((Py_ssize_t)field_count);
250 colmap = PyDict_New(); 246 colmap = PyDict_New();
251 if (!desc || !colmap) 247 if (!desc || !colmap)
252 goto done; 248 goto done;
253 249
254 for (int i = 0; i < field_count; i++) 250 for (int i = 0; i < field_count; i++)
255 { 251 {
256 SQLCHAR name[300]; 252 SQLCHAR name[300];
257 SQLSMALLINT nDataType; 253 SQLSMALLINT nDataType;
258 SQLULEN nColSize; // precision 254 SQLULEN nColSize; // precision
259 SQLSMALLINT cDecimalDigits; // scale 255 SQLSMALLINT cDecimalDigits; // scale
260 SQLSMALLINT nullable; 256 SQLSMALLINT nullable;
261 257
262 Py_BEGIN_ALLOW_THREADS 258 Py_BEGIN_ALLOW_THREADS
263 ret = SQLDescribeCol(cur->hstmt, (SQLUSMALLINT)(i + 1), name, _countof(name), 0, &nDataType, &nColSize, &cDecimalDigits, &nullable); 259 ret = SQLDescribeCol(cur->hstmt, (SQLUSMALLINT)(i + 1), name, _countof(name), 0, &nDataType, &nColSize, &cDecimalDigits, &nullable);
264 Py_END_ALLOW_THREADS 260 Py_END_ALLOW_THREADS
265 261
266 if (cur->cnxn->hdbc == SQL_NULL_HANDLE) 262 if (cur->cnxn->hdbc == SQL_NULL_HANDLE)
267 { 263 {
268 // The connection was closed by another thread in the ALLOW_THREADS block above. 264 // The connection was closed by another thread in the ALLOW_THREADS block above.
269 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed."); 265 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
270 goto done; 266 goto done;
271 } 267 }
272 268
273 if (!SQL_SUCCEEDED(ret)) 269 if (!SQL_SUCCEEDED(ret))
274 { 270 {
275 RaiseErrorFromHandle("SQLDescribeCol", cur->cnxn->hdbc, cur->hstmt); 271 RaiseErrorFromHandle("SQLDescribeCol", cur->cnxn->hdbc, cur->hstmt);
276 goto done; 272 goto done;
277 } 273 }
278 274
279 TRACE("Col %d: type=%d colsize=%d\n", (i+1), (int)nDataType, (int)nColSize); 275 TRACE("Col %d: type=%d colsize=%d\n", (i+1), (int)nDataType, (int)nColSize);
280 276
281 if (lower) 277 if (lower)
282 _strlwr((char*)name); 278 _strlwr((char*)name);
283 279
284 type = PythonTypeFromSqlType(cur, name, nDataType, cur->cnxn->unicode_results); 280 type = PythonTypeFromSqlType(cur, name, nDataType, cur->cnxn->unicode_results);
285 if (!type) 281 if (!type)
286 goto done; 282 goto done;
287 283
288 switch (nullable) 284 switch (nullable)
289 { 285 {
290 case SQL_NO_NULLS: 286 case SQL_NO_NULLS:
291 nullable_obj = Py_False; 287 nullable_obj = Py_False;
292 break; 288 break;
293 case SQL_NULLABLE: 289 case SQL_NULLABLE:
294 nullable_obj = Py_True; 290 nullable_obj = Py_True;
295 break; 291 break;
296 case SQL_NULLABLE_UNKNOWN: 292 case SQL_NULLABLE_UNKNOWN:
297 default: 293 default:
298 nullable_obj = Py_None; 294 nullable_obj = Py_None;
299 break; 295 break;
300 } 296 }
301 297
302 // The Oracle ODBC driver has a bug (I call it) that it returns a data size of 0 when a numeric value is 298 // The Oracle ODBC driver has a bug (I call it) that it returns a data size of 0 when a numeric value is
303 // retrieved from a UNION: http://support.microsoft.com/?scid=kb%3Ben-us%3B236786&x=13&y=6 299 // retrieved from a UNION: http://support.microsoft.com/?scid=kb%3Ben-us%3B236786&x=13&y=6
304 // 300 //
305 // Unfortunately, I don't have a test system for this yet, so I'm *trying* something. (Not a good sign.) If 301 // Unfortunately, I don't have a test system for this yet, so I'm *trying* something. (Not a good sign.) If
306 // the size is zero and it appears to be a numeric type, we'll try to come up with our own length using any 302 // the size is zero and it appears to be a numeric type, we'll try to come up with our own length using any
307 // other data we can get. 303 // other data we can get.
308 304
309 if (nColSize == 0 && IsNumericType(nDataType)) 305 if (nColSize == 0 && IsNumericType(nDataType))
310 { 306 {
311 // I'm not sure how 307 // I'm not sure how
312 if (cDecimalDigits != 0) 308 if (cDecimalDigits != 0)
313 { 309 {
314 nColSize = (SQLUINTEGER)(cDecimalDigits + 3); 310 nColSize = (SQLUINTEGER)(cDecimalDigits + 3);
315 } 311 }
316 else 312 else
317 { 313 {
318 // I'm not sure if this is a good idea, but ... 314 // I'm not sure if this is a good idea, but ...
319 nColSize = 42; 315 nColSize = 42;
320 } 316 }
321 } 317 }
322 318
323 colinfo = Py_BuildValue("(sOOiiiO)", 319 colinfo = Py_BuildValue("(sOOiiiO)",
324 (char*)name, 320 (char*)name,
325 type, // type_code 321 type, // type_code
326 Py_None, // display size 322 Py_None, // display size
327 (int)nColSize, // internal_size 323 (int)nColSize, // internal_size
328 (int)nColSize, // precision 324 (int)nColSize, // precision
329 (int)cDecimalDigits, // scale 325 (int)cDecimalDigits, // scale
330 nullable_obj); // null_ok 326 nullable_obj); // null_ok
331 if (!colinfo) 327 if (!colinfo)
332 goto done; 328 goto done;
333 329
334 330
335 nullable_obj = 0; 331 nullable_obj = 0;
336 332
337 index = PyInt_FromLong(i); 333 index = PyInt_FromLong(i);
338 if (!index) 334 if (!index)
339 goto done; 335 goto done;
340 336
341 PyDict_SetItemString(colmap, (const char*)name, index); 337 PyDict_SetItemString(colmap, (const char*)name, index);
342 Py_DECREF(index); // SetItemString increments 338 Py_DECREF(index); // SetItemString increments
343 index = 0; 339 index = 0;
344 340
345 PyTuple_SET_ITEM(desc, i, colinfo); 341 PyTuple_SET_ITEM(desc, i, colinfo);
346 colinfo = 0; // reference stolen by SET_ITEM 342 colinfo = 0; // reference stolen by SET_ITEM
347 } 343 }
348 344
349 Py_XDECREF(cur->description); 345 Py_XDECREF(cur->description);
350 cur->description = desc; 346 cur->description = desc;
351 desc = 0; 347 desc = 0;
352 cur->map_name_to_index = colmap; 348 cur->map_name_to_index = colmap;
353 colmap = 0; 349 colmap = 0;
354 350
355 success = true; 351 success = true;
356 352
357 done: 353 done:
358 Py_XDECREF(nullable_obj); 354 Py_XDECREF(nullable_obj);
359 Py_XDECREF(desc); 355 Py_XDECREF(desc);
360 Py_XDECREF(colmap); 356 Py_XDECREF(colmap);
361 Py_XDECREF(index); 357 Py_XDECREF(index);
362 Py_XDECREF(colinfo); 358 Py_XDECREF(colinfo);
363 359
364 return success; 360 return success;
365 } 361 }
366 362
367 enum free_results_type 363 enum free_results_type
368 { 364 {
369 FREE_STATEMENT, 365 FREE_STATEMENT,
370 KEEP_STATEMENT 366 KEEP_STATEMENT
371 }; 367 };
372 368
373 static bool 369 static bool free_results(Cursor* self, free_results_type free_statement)
374 free_results(Cursor* self, free_results_type free_statement)
375 { 370 {
376 // Internal function called any time we need to free the memory associated with query results. It is safe to call 371 // Internal function called any time we need to free the memory associated with query results. It is safe to call
377 // this even when a query has not been executed. 372 // this even when a query has not been executed.
378 373
379 // If we ran out of memory, it is possible that we have a cursor but colinfos is zero. However, we should be 374 // If we ran out of memory, it is possible that we have a cursor but colinfos is zero. However, we should be
380 // deleting this object, so the cursor will be freed when the HSTMT is destroyed. */ 375 // deleting this object, so the cursor will be freed when the HSTMT is destroyed. */
381 376
382 if (self->colinfos) 377 if (self->colinfos)
383 { 378 {
384 pyodbc_free(self->colinfos); 379 pyodbc_free(self->colinfos);
385 self->colinfos = 0; 380 self->colinfos = 0;
386 } 381 }
387 382
388 if (StatementIsValid(self)) 383 if (StatementIsValid(self))
389 { 384 {
390 if (free_statement == FREE_STATEMENT) 385 if (free_statement == FREE_STATEMENT)
391 { 386 {
392 Py_BEGIN_ALLOW_THREADS 387 Py_BEGIN_ALLOW_THREADS
393 SQLFreeStmt(self->hstmt, SQL_CLOSE); 388 SQLFreeStmt(self->hstmt, SQL_CLOSE);
394 Py_END_ALLOW_THREADS; 389 Py_END_ALLOW_THREADS;
395 } 390 }
396 else 391 else
397 { 392 {
398 Py_BEGIN_ALLOW_THREADS 393 Py_BEGIN_ALLOW_THREADS
399 SQLFreeStmt(self->hstmt, SQL_UNBIND); 394 SQLFreeStmt(self->hstmt, SQL_UNBIND);
400 SQLFreeStmt(self->hstmt, SQL_RESET_PARAMS); 395 SQLFreeStmt(self->hstmt, SQL_RESET_PARAMS);
401 Py_END_ALLOW_THREADS; 396 Py_END_ALLOW_THREADS;
402 } 397 }
403 398
404 if (self->cnxn->hdbc == SQL_NULL_HANDLE) 399 if (self->cnxn->hdbc == SQL_NULL_HANDLE)
405 { 400 {
406 // The connection was closed by another thread in the ALLOW_THREADS block above. 401 // The connection was closed by another thread in the ALLOW_THREADS block above.
407 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed."); 402 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
408 return false; 403 return false;
409 } 404 }
410 } 405 }
411 406
412 if (self->description != Py_None) 407 if (self->description != Py_None)
413 { 408 {
414 Py_DECREF(self->description); 409 Py_DECREF(self->description);
415 self->description = Py_None; 410 self->description = Py_None;
416 Py_INCREF(Py_None); 411 Py_INCREF(Py_None);
417 } 412 }
418 413
419 if (self->map_name_to_index) 414 if (self->map_name_to_index)
420 { 415 {
421 Py_DECREF(self->map_name_to_index); 416 Py_DECREF(self->map_name_to_index);
422 self->map_name_to_index = 0; 417 self->map_name_to_index = 0;
423 } 418 }
424 419
425 self->rowcount = -1; 420 self->rowcount = -1;
426 421
427 return true; 422 return true;
428 } 423 }
429 424
430 425
431 static void 426 static void closeimpl(Cursor* cur)
432 closeimpl(Cursor* cur)
433 { 427 {
434 // An internal function for the shared 'closing' code used by Cursor_close and Cursor_dealloc. 428 // An internal function for the shared 'closing' code used by Cursor_close and Cursor_dealloc.
435 // 429 //
436 // This method releases the GIL lock while closing, so verify the HDBC still exists if you use it. 430 // This method releases the GIL lock while closing, so verify the HDBC still exists if you use it.
437 431
438 free_results(cur, FREE_STATEMENT); 432 free_results(cur, FREE_STATEMENT);
439 433
440 FreeParameterInfo(cur); 434 FreeParameterInfo(cur);
441 FreeParameterData(cur); 435 FreeParameterData(cur);
442 436
443 if (StatementIsValid(cur)) 437 if (StatementIsValid(cur))
444 { 438 {
445 HSTMT hstmt = cur->hstmt; 439 HSTMT hstmt = cur->hstmt;
446 cur->hstmt = SQL_NULL_HANDLE; 440 cur->hstmt = SQL_NULL_HANDLE;
447 Py_BEGIN_ALLOW_THREADS 441 Py_BEGIN_ALLOW_THREADS
448 SQLFreeHandle(SQL_HANDLE_STMT, hstmt); 442 SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
449 Py_END_ALLOW_THREADS 443 Py_END_ALLOW_THREADS
450 } 444 }
451 445
452 446
453 Py_XDECREF(cur->pPreparedSQL); 447 Py_XDECREF(cur->pPreparedSQL);
454 Py_XDECREF(cur->description); 448 Py_XDECREF(cur->description);
455 Py_XDECREF(cur->map_name_to_index); 449 Py_XDECREF(cur->map_name_to_index);
456 Py_XDECREF(cur->cnxn); 450 Py_XDECREF(cur->cnxn);
457 451
458 cur->pPreparedSQL = 0; 452 cur->pPreparedSQL = 0;
459 cur->description = 0; 453 cur->description = 0;
460 cur->map_name_to_index = 0; 454 cur->map_name_to_index = 0;
461 cur->cnxn = 0; 455 cur->cnxn = 0;
462 } 456 }
463 457
464 static char close_doc[] = 458 static char close_doc[] =
465 "Close the cursor now (rather than whenever __del__ is called). The cursor will\n" 459 "Close the cursor now (rather than whenever __del__ is called). The cursor will\n"
466 "be unusable from this point forward; a ProgrammingError exception will be\n" 460 "be unusable from this point forward; a ProgrammingError exception will be\n"
467 "raised if any operation is attempted with the cursor."; 461 "raised if any operation is attempted with the cursor.";
468 462
469 static PyObject* 463 static PyObject* Cursor_close(PyObject* self, PyObject* args)
470 Cursor_close(PyObject* self, PyObject* args)
471 { 464 {
472 UNUSED(args); 465 UNUSED(args);
473 466
474 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR); 467 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR);
475 if (!cursor) 468 if (!cursor)
476 return 0; 469 return 0;
477 470
478 closeimpl(cursor); 471 closeimpl(cursor);
479 472
480 Py_INCREF(Py_None); 473 Py_INCREF(Py_None);
481 return Py_None; 474 return Py_None;
482 } 475 }
483 476
484 static void 477 static void Cursor_dealloc(Cursor* cursor)
485 Cursor_dealloc(Cursor* cursor)
486 { 478 {
487 if (Cursor_Validate((PyObject*)cursor, CURSOR_REQUIRE_CNXN)) 479 if (Cursor_Validate((PyObject*)cursor, CURSOR_REQUIRE_CNXN))
488 { 480 {
489 closeimpl(cursor); 481 closeimpl(cursor);
490 } 482 }
491 483
492 PyObject_Del(cursor); 484 PyObject_Del(cursor);
493 } 485 }
494 486
495 487
496 488 bool InitColumnInfo(Cursor* cursor, SQLUSMALLINT iCol, ColumnInfo* pinfo)
497 bool
498 InitColumnInfo(Cursor* cursor, SQLUSMALLINT iCol, ColumnInfo* pinfo)
499 { 489 {
500 // Initializes ColumnInfo from result set metadata. 490 // Initializes ColumnInfo from result set metadata.
501 491
502 SQLRETURN ret; 492 SQLRETURN ret;
503 493
504 // REVIEW: This line fails on OS/X with the FileMaker driver : http://www.filemaker.com/support/updaters/xdbc_odbc_mac.html 494 // REVIEW: This line fails on OS/X with the FileMaker driver : http://www.filemaker.com/support/updaters/xdbc_odbc_mac.html
505 // 495 //
506 // I suspect the problem is that it doesn't allow NULLs in some of the parameters, so I'm going to supply them all 496 // I suspect the problem is that it doesn't allow NULLs in some of the parameters, so I'm going to supply them all
507 // to see what happens. 497 // to see what happens.
508 498
509 SQLCHAR ColumnName[200]; 499 SQLCHAR ColumnName[200];
510 SQLSMALLINT BufferLength = _countof(ColumnName); 500 SQLSMALLINT BufferLength = _countof(ColumnName);
511 SQLSMALLINT NameLength = 0; 501 SQLSMALLINT NameLength = 0;
512 SQLSMALLINT DataType = 0; 502 SQLSMALLINT DataType = 0;
513 SQLULEN ColumnSize = 0; 503 SQLULEN ColumnSize = 0;
514 SQLSMALLINT DecimalDigits = 0; 504 SQLSMALLINT DecimalDigits = 0;
515 SQLSMALLINT Nullable = 0; 505 SQLSMALLINT Nullable = 0;
516 506
517 Py_BEGIN_ALLOW_THREADS 507 Py_BEGIN_ALLOW_THREADS
518 ret = SQLDescribeCol(cursor->hstmt, iCol, 508 ret = SQLDescribeCol(cursor->hstmt, iCol,
519 ColumnName, 509 ColumnName,
520 BufferLength, 510 BufferLength,
521 &NameLength, 511 &NameLength,
522 &DataType, 512 &DataType,
523 &ColumnSize, 513 &ColumnSize,
524 &DecimalDigits, 514 &DecimalDigits,
525 &Nullable); 515 &Nullable);
526 Py_END_ALLOW_THREADS 516 Py_END_ALLOW_THREADS
527 517
528 pinfo->sql_type = DataType; 518 pinfo->sql_type = DataType;
529 pinfo->column_size = ColumnSize; 519 pinfo->column_size = ColumnSize;
530 520
531 if (cursor->cnxn->hdbc == SQL_NULL_HANDLE) 521 if (cursor->cnxn->hdbc == SQL_NULL_HANDLE)
532 { 522 {
533 // The connection was closed by another thread in the ALLOW_THREADS block above. 523 // The connection was closed by another thread in the ALLOW_THREADS block above.
534 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed."); 524 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
535 return false; 525 return false;
536 } 526 }
537 527
538 if (!SQL_SUCCEEDED(ret)) 528 if (!SQL_SUCCEEDED(ret))
539 { 529 {
540 RaiseErrorFromHandle("SQLDescribeCol", cursor->cnxn->hdbc, cursor->hstmt); 530 RaiseErrorFromHandle("SQLDescribeCol", cursor->cnxn->hdbc, cursor->hstmt);
541 return false; 531 return false;
542 } 532 }
543 533
544 // If it is an integer type, determine if it is signed or unsigned. The buffer size is the same but we'll need to 534 // If it is an integer type, determine if it is signed or unsigned. The buffer size is the same but we'll need to
545 // know when we convert to a Python integer. 535 // know when we convert to a Python integer.
546 536
547 switch (pinfo->sql_type) 537 switch (pinfo->sql_type)
548 { 538 {
549 case SQL_TINYINT: 539 case SQL_TINYINT:
550 case SQL_SMALLINT: 540 case SQL_SMALLINT:
551 case SQL_INTEGER: 541 case SQL_INTEGER:
552 case SQL_BIGINT: 542 case SQL_BIGINT:
553 { 543 {
554 SQLLEN f; 544 SQLLEN f;
555 Py_BEGIN_ALLOW_THREADS 545 Py_BEGIN_ALLOW_THREADS
556 ret = SQLColAttribute(cursor->hstmt, iCol, SQL_DESC_UNSIGNED, 0, 0, 0, &f); 546 ret = SQLColAttribute(cursor->hstmt, iCol, SQL_DESC_UNSIGNED, 0, 0, 0, &f);
557 Py_END_ALLOW_THREADS 547 Py_END_ALLOW_THREADS
558 548
559 if (cursor->cnxn->hdbc == SQL_NULL_HANDLE) 549 if (cursor->cnxn->hdbc == SQL_NULL_HANDLE)
560 { 550 {
561 // The connection was closed by another thread in the ALLOW_THREADS block above. 551 // The connection was closed by another thread in the ALLOW_THREADS block above.
562 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed."); 552 RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
563 return false; 553 return false;
564 } 554 }
565 555
566 if (!SQL_SUCCEEDED(ret)) 556 if (!SQL_SUCCEEDED(ret))
567 { 557 {
568 RaiseErrorFromHandle("SQLColAttribute", cursor->cnxn->hdbc, cursor->hstmt); 558 RaiseErrorFromHandle("SQLColAttribute", cursor->cnxn->hdbc, cursor->hstmt);
569 return false; 559 return false;
570 } 560 }
571 pinfo->is_unsigned = (f == SQL_TRUE); 561 pinfo->is_unsigned = (f == SQL_TRUE);
572 break; 562 break;
573 } 563 }
574 564
575 default: 565 default:
576 pinfo->is_unsigned = false; 566 pinfo->is_unsigned = false;
577 } 567 }
578 568
579 return true; 569 return true;
580 } 570 }
581 571
582 572
583 static bool 573 static bool PrepareResults(Cursor* cur, int cCols)
584 PrepareResults(Cursor* cur, int cCols)
585 { 574 {
586 // Called after a SELECT has been executed to perform pre-fetch work. 575 // Called after a SELECT has been executed to perform pre-fetch work.
587 // 576 //
588 // Allocates the ColumnInfo structures describing the returned data. 577 // Allocates the ColumnInfo structures describing the returned data.
589 578
590 int i; 579 int i;
591 I(cur->colinfos == 0); 580 I(cur->colinfos == 0);
592 581
593 cur->colinfos = (ColumnInfo*)pyodbc_malloc(sizeof(ColumnInfo) * cCols); 582 cur->colinfos = (ColumnInfo*)pyodbc_malloc(sizeof(ColumnInfo) * cCols);
594 if (cur->colinfos == 0) 583 if (cur->colinfos == 0)
595 { 584 {
596 PyErr_NoMemory(); 585 PyErr_NoMemory();
597 return false; 586 return false;
598 } 587 }
599 588
600 for (i = 0; i < cCols; i++) 589 for (i = 0; i < cCols; i++)
601 { 590 {
602 if (!InitColumnInfo(cur, (SQLUSMALLINT)(i + 1), &cur->colinfos[i])) 591 if (!InitColumnInfo(cur, (SQLUSMALLINT)(i + 1), &cur->colinfos[i]))
603 { 592 {
604 pyodbc_free(cur->colinfos); 593 pyodbc_free(cur->colinfos);
605 cur->colinfos = 0; 594 cur->colinfos = 0;
606 return false; 595 return false;
607 } 596 }
608 } 597 }
609 598
610 return true; 599 return true;
611 } 600 }
612 601
613 static PyObject* 602
614 execute(Cursor* cur, PyObject* pSql, PyObject* params, bool skip_first) 603 static PyObject* execute(Cursor* cur, PyObject* pSql, PyObject* params, bool skip_first)
615 { 604 {
616 // Internal function to execute SQL, called by .execute and .executemany. 605 // Internal function to execute SQL, called by .execute and .executemany.
617 // 606 //
618 // pSql 607 // pSql
619 // A PyString, PyUnicode, or derived object containing the SQL. 608 // A PyString, PyUnicode, or derived object containing the SQL.
620 // 609 //
621 // params 610 // params
622 // Pointer to an optional sequence of parameters, and possibly the SQL statement (see skip_first): 611 // Pointer to an optional sequence of parameters, and possibly the SQL statement (see skip_first):
623 // (SQL, param1, param2) or (param1, param2). 612 // (SQL, param1, param2) or (param1, param2).
624 // 613 //
625 // skip_first 614 // skip_first
626 // If true, the first element in `params` is ignored. (It will be the SQL statement and `params` will be the 615 // If true, the first element in `params` is ignored. (It will be the SQL statement and `params` will be the
627 // entire tuple passed to Cursor.execute.) Otherwise all of the params are used. (This case occurs when called 616 // entire tuple passed to Cursor.execute.) Otherwise all of the params are used. (This case occurs when called
628 // from Cursor.executemany, in which case the sequences do not contain the SQL statement.) Ignored if params is 617 // from Cursor.executemany, in which case the sequences do not contain the SQL statement.) Ignored if params is
629 // zero. 618 // zero.
630 619
631 if (params) 620 if (params)
632 { 621 {
633 if (!PyTuple_Check(params) && !PyList_Check(params) && !Row_Check(params)) 622 if (!PyTuple_Check(params) && !PyList_Check(params) && !Row_Check(params))
634 return RaiseErrorV(0, PyExc_TypeError, "Params must be in a list, tuple, or Row"); 623 return RaiseErrorV(0, PyExc_TypeError, "Params must be in a list, tuple, or Row");
635 } 624 }
636 625
637 // Normalize the parameter variables. 626 // Normalize the parameter variables.
638 627
639 int params_offset = skip_first ? 1 : 0; 628 int params_offset = skip_first ? 1 : 0;
640 Py_ssize_t cParams = params == 0 ? 0 : PySequence_Length(params) - params_offset; 629 Py_ssize_t cParams = params == 0 ? 0 : PySequence_Length(params) - params_offset;
641 630
642 SQLRETURN ret = 0; 631 SQLRETURN ret = 0;
643 632
644 free_results(cur, FREE_STATEMENT); 633 free_results(cur, FREE_STATEMENT);
645 634
646 const char* szLastFunction = ""; 635 const char* szLastFunction = "";
647 636
648 if (cParams > 0) 637 if (cParams > 0)
649 { 638 {
650 // There are parameters, so we'll need to prepare the SQL statement and bind the parameters. (We need to 639 // There are parameters, so we'll need to prepare the SQL statement and bind the parameters. (We need to
651 // prepare the statement because we can't bind a NULL (None) object without knowing the target datatype. There 640 // prepare the statement because we can't bind a NULL (None) object without knowing the target datatype. There
652 // is no one data type that always maps to the others (no, not even varchar)). 641 // is no one data type that always maps to the others (no, not even varchar)).
653 642
654 if (!PrepareAndBind(cur, pSql, params, skip_first)) 643 if (!PrepareAndBind(cur, pSql, params, skip_first))
655 return 0; 644 return 0;
656 645
657 szLastFunction = "SQLExecute"; 646 szLastFunction = "SQLExecute";
658 Py_BEGIN_ALLOW_THREADS 647 Py_BEGIN_ALLOW_THREADS
659 ret = SQLExecute(cur->hstmt); 648 ret = SQLExecute(cur->hstmt);
660 Py_END_ALLOW_THREADS 649 Py_END_ALLOW_THREADS
661 } 650 }
662 else 651 else
663 { 652 {
664 // REVIEW: Why don't we always prepare? It is highly unlikely that a user would need to execute the same SQL 653 // REVIEW: Why don't we always prepare? It is highly unlikely that a user would need to execute the same SQL
665 // repeatedly if it did not have parameters, so we are not losing performance, but it would simplify the code. 654 // repeatedly if it did not have parameters, so we are not losing performance, but it would simplify the code.
666 655
667 Py_XDECREF(cur->pPreparedSQL); 656 Py_XDECREF(cur->pPreparedSQL);
668 cur->pPreparedSQL = 0; 657 cur->pPreparedSQL = 0;
669 658
670 szLastFunction = "SQLExecDirect"; 659 szLastFunction = "SQLExecDirect";
671 #if PY_MAJOR_VERSION < 3 660 #if PY_MAJOR_VERSION < 3
672 if (PyString_Check(pSql)) 661 if (PyString_Check(pSql))
673 { 662 {
674 Py_BEGIN_ALLOW_THREADS 663 Py_BEGIN_ALLOW_THREADS
675 ret = SQLExecDirect(cur->hstmt, (SQLCHAR*)PyString_AS_STRING(pSql), SQL_NTS); 664 ret = SQLExecDirect(cur->hstmt, (SQLCHAR*)PyString_AS_STRING(pSql), SQL_NTS);
676 Py_END_ALLOW_THREADS 665 Py_END_ALLOW_THREADS
677 } 666 }
678 else 667 else
679 #endif 668 #endif
680 { 669 {
681 SQLWChar query(pSql); 670 SQLWChar query(pSql);
682 if (!query) 671 if (!query)
683 return 0; 672 return 0;
684 Py_BEGIN_ALLOW_THREADS 673 Py_BEGIN_ALLOW_THREADS
685 ret = SQLExecDirectW(cur->hstmt, query, SQL_NTS); 674 ret = SQLExecDirectW(cur->hstmt, query, SQL_NTS);
686 Py_END_ALLOW_THREADS 675 Py_END_ALLOW_THREADS
687 } 676 }
688 } 677 }
689 678
690 if (cur->cnxn->hdbc == SQL_NULL_HANDLE) 679 if (cur->cnxn->hdbc == SQL_NULL_HANDLE)
691 { 680 {
692 // The connection was closed by another thread in the ALLOW_THREADS block above. 681 // The connection was closed by another thread in the ALLOW_THREADS block above.
693 682
694 FreeParameterData(cur); 683 FreeParameterData(cur);
695 684
696 return RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed."); 685 return RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
697 } 686 }
698 687
699 if (!SQL_SUCCEEDED(ret) && ret != SQL_NEED_DATA && ret != SQL_NO_DATA) 688 if (!SQL_SUCCEEDED(ret) && ret != SQL_NEED_DATA && ret != SQL_NO_DATA)
700 { 689 {
701 // We could try dropping through the while and if below, but if there is an error, we need to raise it before 690 // We could try dropping through the while and if below, but if there is an error, we need to raise it before
702 // FreeParameterData calls more ODBC functions. 691 // FreeParameterData calls more ODBC functions.
703 return RaiseErrorFromHandle("SQLExecDirectW", cur->cnxn->hdbc, cur->hstmt); 692 return RaiseErrorFromHandle("SQLExecDirectW", cur->cnxn->hdbc, cur->hstmt);
704 } 693 }
705 694
706 while (ret == SQL_NEED_DATA) 695 while (ret == SQL_NEED_DATA)
707 { 696 {
708 // We have bound a PyObject* using SQL_LEN_DATA_AT_EXEC, so ODBC is asking us for the data now. We gave the 697 // We have bound a PyObject* using SQL_LEN_DATA_AT_EXEC, so ODBC is asking us for the data now. We gave the
709 // PyObject pointer to ODBC in SQLBindParameter -- SQLParamData below gives the pointer back to us. 698 // PyObject pointer to ODBC in SQLBindParameter -- SQLParamData below gives the pointer back to us.
710 699
711 szLastFunction = "SQLParamData"; 700 szLastFunction = "SQLParamData";
712 PyObject* pParam; 701 PyObject* pParam;
713 Py_BEGIN_ALLOW_THREADS 702 Py_BEGIN_ALLOW_THREADS
714 ret = SQLParamData(cur->hstmt, (SQLPOINTER*)&pParam); 703 ret = SQLParamData(cur->hstmt, (SQLPOINTER*)&pParam);
715 Py_END_ALLOW_THREADS 704 Py_END_ALLOW_THREADS
716 705
717 if (ret != SQL_NEED_DATA && ret != SQL_NO_DATA && !SQL_SUCCEEDED(ret)) 706 if (ret != SQL_NEED_DATA && ret != SQL_NO_DATA && !SQL_SUCCEEDED(ret))
718 return RaiseErrorFromHandle("SQLParamData", cur->cnxn->hdbc, cur->hstmt); 707 return RaiseErrorFromHandle("SQLParamData", cur->cnxn->hdbc, cur->hstmt);
719 708
720 TRACE("SQLParamData() --> %d\n", ret); 709 TRACE("SQLParamData() --> %d\n", ret);
721 710
722 if (ret == SQL_NEED_DATA) 711 if (ret == SQL_NEED_DATA)
723 { 712 {
724 szLastFunction = "SQLPutData"; 713 szLastFunction = "SQLPutData";
725 if (PyUnicode_Check(pParam)) 714 if (PyUnicode_Check(pParam))
726 { 715 {
727 SQLWChar wchar(pParam); // Will convert to SQLWCHAR if necessary. 716 SQLWChar wchar(pParam); // Will convert to SQLWCHAR if necessary.
728 717
729 Py_ssize_t offset = 0; // in characters 718 Py_ssize_t offset = 0; // in characters
730 Py_ssize_t length = wchar.size(); // in characters 719 Py_ssize_t length = wchar.size(); // in characters
731 720
732 while (offset < length) 721 while (offset < length)
733 { 722 {
734 SQLLEN remaining = min(cur->cnxn->varchar_maxlength, length - offset); 723 SQLLEN remaining = min(cur->cnxn->varchar_maxlength, length - offset);
735 Py_BEGIN_ALLOW_THREADS 724 Py_BEGIN_ALLOW_THREADS
736 ret = SQLPutData(cur->hstmt, (SQLPOINTER)wchar[offset], (SQLLEN)(remaining * sizeof(SQLWCHAR))); 725 ret = SQLPutData(cur->hstmt, (SQLPOINTER)wchar[offset], (SQLLEN)(remaining * sizeof(SQLWCHAR)));
737 Py_END_ALLOW_THREADS 726 Py_END_ALLOW_THREADS
738 if (!SQL_SUCCEEDED(ret)) 727 if (!SQL_SUCCEEDED(ret))
739 return RaiseErrorFromHandle("SQLPutData", cur->cnxn->hdbc, cur->hstmt); 728 return RaiseErrorFromHandle("SQLPutData", cur->cnxn->hdbc, cur->hstmt);
740 offset += remaining; 729 offset += remaining;
741 } 730 }
742 } 731 }
743 else if (PyBytes_Check(pParam)) 732 else if (PyBytes_Check(pParam))
744 { 733 {
745 const char* p = PyBytes_AS_STRING(pParam); 734 const char* p = PyBytes_AS_STRING(pParam);
746 SQLLEN offset = 0; 735 SQLLEN offset = 0;
747 SQLLEN cb = (SQLLEN)PyBytes_GET_SIZE(pParam); 736 SQLLEN cb = (SQLLEN)PyBytes_GET_SIZE(pParam);
748 while (offset < cb) 737 while (offset < cb)
749 { 738 {
750 SQLLEN remaining = min(cur->cnxn->varchar_maxlength, cb - offset); 739 SQLLEN remaining = min(cur->cnxn->varchar_maxlength, cb - offset);
751 TRACE("SQLPutData [%d] (%d) %s\n", offset, remaining, &p[offset]); 740 TRACE("SQLPutData [%d] (%d) %s\n", offset, remaining, &p[offset]);
752 Py_BEGIN_ALLOW_THREADS 741 Py_BEGIN_ALLOW_THREADS
753 ret = SQLPutData(cur->hstmt, (SQLPOINTER)&p[offset], remaining); 742 ret = SQLPutData(cur->hstmt, (SQLPOINTER)&p[offset], remaining);
754 Py_END_ALLOW_THREADS 743 Py_END_ALLOW_THREADS
755 if (!SQL_SUCCEEDED(ret)) 744 if (!SQL_SUCCEEDED(ret))
756 return RaiseErrorFromHandle("SQLPutData", cur->cnxn->hdbc, cur->hstmt); 745 return RaiseErrorFromHandle("SQLPutData", cur->cnxn->hdbc, cur->hstmt);
757 offset += remaining; 746 offset += remaining;
758 } 747 }
759 } 748 }
760 #if PY_VERSION_HEX >= 0x02060000 749 #if PY_VERSION_HEX >= 0x02060000
761 else if (PyByteArray_Check(pParam)) 750 else if (PyByteArray_Check(pParam))
762 { 751 {
763 const char* p = PyByteArray_AS_STRING(pParam); 752 const char* p = PyByteArray_AS_STRING(pParam);
764 SQLLEN offset = 0; 753 SQLLEN offset = 0;
765 SQLLEN cb = (SQLLEN)PyByteArray_GET_SIZE(pParam); 754 SQLLEN cb = (SQLLEN)PyByteArray_GET_SIZE(pParam);
766 while (offset < cb) 755 while (offset < cb)
767 { 756 {
768 SQLLEN remaining = min(cur->cnxn->varchar_maxlength, cb - offset); 757 SQLLEN remaining = min(cur->cnxn->varchar_maxlength, cb - offset);
769 TRACE("SQLPutData [%d] (%d) %s\n", offset, remaining, &p[offset]); 758 TRACE("SQLPutData [%d] (%d) %s\n", offset, remaining, &p[offset]);
770 Py_BEGIN_ALLOW_THREADS 759 Py_BEGIN_ALLOW_THREADS
771 ret = SQLPutData(cur->hstmt, (SQLPOINTER)&p[offset], remaining); 760 ret = SQLPutData(cur->hstmt, (SQLPOINTER)&p[offset], remaining);
772 Py_END_ALLOW_THREADS 761 Py_END_ALLOW_THREADS
773 if (!SQL_SUCCEEDED(ret)) 762 if (!SQL_SUCCEEDED(ret))
774 return RaiseErrorFromHandle("SQLPutData", cur->cnxn->hdbc, cur->hstmt); 763 return RaiseErrorFromHandle("SQLPutData", cur->cnxn->hdbc, cur->hstmt);
775 offset += remaining; 764 offset += remaining;
776 } 765 }
777 } 766 }
778 #endif 767 #endif
779 #if PY_MAJOR_VERSION < 3 768 #if PY_MAJOR_VERSION < 3
780 else if (PyBuffer_Check(pParam)) 769 else if (PyBuffer_Check(pParam))
781 { 770 {
782 // Buffers can have multiple segments, so we might need multiple writes. Looping through buffers isn't 771 // Buffers can have multiple segments, so we might need multiple writes. Looping through buffers isn't
783 // difficult, but we've wrapped it up in an iterator object to keep this loop simple. 772 // difficult, but we've wrapped it up in an iterator object to keep this loop simple.
784 773
785 BufferSegmentIterator it(pParam); 774 BufferSegmentIterator it(pParam);
786 byte* pb; 775 byte* pb;
787 SQLLEN cb; 776 SQLLEN cb;
788 while (it.Next(pb, cb)) 777 while (it.Next(pb, cb))
789 { 778 {
790 Py_BEGIN_ALLOW_THREADS 779 Py_BEGIN_ALLOW_THREADS
791 ret = SQLPutData(cur->hstmt, pb, cb); 780 ret = SQLPutData(cur->hstmt, pb, cb);
792 Py_END_ALLOW_THREADS 781 Py_END_ALLOW_THREADS
793 if (!SQL_SUCCEEDED(ret)) 782 if (!SQL_SUCCEEDED(ret))
794 return RaiseErrorFromHandle("SQLPutData", cur->cnxn->hdbc, cur->hstmt); 783 return RaiseErrorFromHandle("SQLPutData", cur->cnxn->hdbc, cur->hstmt);
795 } 784 }
796 } 785 }
797 #endif 786 #endif
798 ret = SQL_NEED_DATA; 787 ret = SQL_NEED_DATA;
799 } 788 }
800 } 789 }
801 790
802 FreeParameterData(cur); 791 FreeParameterData(cur);
803 792
804 if (ret == SQL_NO_DATA) 793 if (ret == SQL_NO_DATA)
805 { 794 {
806 // Example: A delete statement that did not delete anything. 795 // Example: A delete statement that did not delete anything.
807 cur->rowcount = 0; 796 cur->rowcount = 0;
808 Py_INCREF(cur); 797 Py_INCREF(cur);
809 return (PyObject*)cur; 798 return (PyObject*)cur;
810 } 799 }
811 800
812 if (!SQL_SUCCEEDED(ret)) 801 if (!SQL_SUCCEEDED(ret))
813 return RaiseErrorFromHandle(szLastFunction, cur->cnxn->hdbc, cur->hstmt); 802 return RaiseErrorFromHandle(szLastFunction, cur->cnxn->hdbc, cur->hstmt);
814 803
815 SQLLEN cRows = -1; 804 SQLLEN cRows = -1;
816 Py_BEGIN_ALLOW_THREADS 805 Py_BEGIN_ALLOW_THREADS
817 ret = SQLRowCount(cur->hstmt, &cRows); 806 ret = SQLRowCount(cur->hstmt, &cRows);
818 Py_END_ALLOW_THREADS 807 Py_END_ALLOW_THREADS
819 if (!SQL_SUCCEEDED(ret)) 808 if (!SQL_SUCCEEDED(ret))
820 return RaiseErrorFromHandle("SQLRowCount", cur->cnxn->hdbc, cur->hstmt); 809 return RaiseErrorFromHandle("SQLRowCount", cur->cnxn->hdbc, cur->hstmt);
821 810
822 cur->rowcount = (int)cRows; 811 cur->rowcount = (int)cRows;
823 812
824 TRACE("SQLRowCount: %d\n", cRows); 813 TRACE("SQLRowCount: %d\n", cRows);
825 814
826 SQLSMALLINT cCols = 0; 815 SQLSMALLINT cCols = 0;
827 Py_BEGIN_ALLOW_THREADS 816 Py_BEGIN_ALLOW_THREADS
828 ret = SQLNumResultCols(cur->hstmt, &cCols); 817 ret = SQLNumResultCols(cur->hstmt, &cCols);
829 Py_END_ALLOW_THREADS 818 Py_END_ALLOW_THREADS
830 if (!SQL_SUCCEEDED(ret)) 819 if (!SQL_SUCCEEDED(ret))
831 { 820 {
832 // Note: The SQL Server driver sometimes returns HY007 here if multiple statements (separated by ;) were 821 // Note: The SQL Server driver sometimes returns HY007 here if multiple statements (separated by ;) were
833 // submitted. This is not documented, but I've seen it with multiple successful inserts. 822 // submitted. This is not documented, but I've seen it with multiple successful inserts.
834 823
835 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 824 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
836 } 825 }
837 826
838 TRACE("SQLNumResultCols: %d\n", cCols); 827 TRACE("SQLNumResultCols: %d\n", cCols);
839 828
840 if (cur->cnxn->hdbc == SQL_NULL_HANDLE) 829 if (cur->cnxn->hdbc == SQL_NULL_HANDLE)
841 { 830 {
842 // The connection was closed by another thread in the ALLOW_THREADS block above. 831 // The connection was closed by another thread in the ALLOW_THREADS block above.
843 return RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed."); 832 return RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
844 } 833 }
845 834
846 if (!SQL_SUCCEEDED(ret)) 835 if (!SQL_SUCCEEDED(ret))
847 return RaiseErrorFromHandle("SQLRowCount", cur->cnxn->hdbc, cur->hstmt); 836 return RaiseErrorFromHandle("SQLRowCount", cur->cnxn->hdbc, cur->hstmt);
848 837
849 if (cCols != 0) 838 if (cCols != 0)
850 { 839 {
851 // A result set was created. 840 // A result set was created.
852 841
853 if (!PrepareResults(cur, cCols)) 842 if (!PrepareResults(cur, cCols))
854 return 0; 843 return 0;
855 844
856 if (!create_name_map(cur, cCols, lowercase())) 845 if (!create_name_map(cur, cCols, lowercase()))
857 return 0; 846 return 0;
858 } 847 }
859 848
860 Py_INCREF(cur); 849 Py_INCREF(cur);
861 return (PyObject*)cur; 850 return (PyObject*)cur;
862 } 851 }
852
863 853
864 inline bool IsSequence(PyObject* p) 854 inline bool IsSequence(PyObject* p)
865 { 855 {
866 // Used to determine if the first parameter of execute is a collection of SQL parameters or is a SQL parameter 856 // Used to determine if the first parameter of execute is a collection of SQL parameters or is a SQL parameter
867 // itself. If the first parameter is a list, tuple, or Row object, then we consider it a collection. Anything 857 // itself. If the first parameter is a list, tuple, or Row object, then we consider it a collection. Anything
868 // else, including other sequences (e.g. bytearray), are considered SQL parameters. 858 // else, including other sequences (e.g. bytearray), are considered SQL parameters.
869 859
870 return PyList_Check(p) || PyTuple_Check(p) || Row_Check(p); 860 return PyList_Check(p) || PyTuple_Check(p) || Row_Check(p);
871 } 861 }
862
872 863
873 static char execute_doc[] = 864 static char execute_doc[] =
874 "C.execute(sql, [params]) --> Cursor\n" 865 "C.execute(sql, [params]) --> Cursor\n"
875 "\n" 866 "\n"
876 "Prepare and execute a database query or command.\n" 867 "Prepare and execute a database query or command.\n"
877 "\n" 868 "\n"
878 "Parameters may be provided as a sequence (as specified by the DB API) or\n" 869 "Parameters may be provided as a sequence (as specified by the DB API) or\n"
879 "simply passed in one after another (non-standard):\n" 870 "simply passed in one after another (non-standard):\n"
880 "\n" 871 "\n"
881 " cursor.execute(sql, (param1, param2))\n" 872 " cursor.execute(sql, (param1, param2))\n"
882 "\n" 873 "\n"
883 " or\n" 874 " or\n"
884 "\n" 875 "\n"
885 " cursor.execute(sql, param1, param2)\n"; 876 " cursor.execute(sql, param1, param2)\n";
886 877
887 PyObject* Cursor_execute(PyObject* self, PyObject* args) 878 PyObject* Cursor_execute(PyObject* self, PyObject* args)
888 { 879 {
889 Py_ssize_t cParams = PyTuple_Size(args) - 1; 880 Py_ssize_t cParams = PyTuple_Size(args) - 1;
890 881
891 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR); 882 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR);
892 if (!cursor) 883 if (!cursor)
893 return 0; 884 return 0;
894 885
895 if (cParams < 0) 886 if (cParams < 0)
896 { 887 {
897 PyErr_SetString(PyExc_TypeError, "execute() takes at least 1 argument (0 given)"); 888 PyErr_SetString(PyExc_TypeError, "execute() takes at least 1 argument (0 given)");
898 return 0; 889 return 0;
899 } 890 }
900 891
901 PyObject* pSql = PyTuple_GET_ITEM(args, 0); 892 PyObject* pSql = PyTuple_GET_ITEM(args, 0);
902 893
903 if (!PyString_Check(pSql) && !PyUnicode_Check(pSql)) 894 if (!PyString_Check(pSql) && !PyUnicode_Check(pSql))
904 { 895 {
905 PyErr_SetString(PyExc_TypeError, "The first argument to execute must be a string or unicode query."); 896 PyErr_SetString(PyExc_TypeError, "The first argument to execute must be a string or unicode query.");
906 return 0; 897 return 0;
907 } 898 }
908 899
909 // Figure out if there were parameters and how they were passed. Our optional parameter passing complicates this slightly. 900 // Figure out if there were parameters and how they were passed. Our optional parameter passing complicates this slightly.
910 901
911 bool skip_first = false; 902 bool skip_first = false;
912 PyObject *params = 0; 903 PyObject *params = 0;
913 if (cParams == 1 && IsSequence(PyTuple_GET_ITEM(args, 1))) 904 if (cParams == 1 && IsSequence(PyTuple_GET_ITEM(args, 1)))
914 { 905 {
915 // There is a single argument and it is a sequence, so we must treat it as a sequence of parameters. (This is 906 // There is a single argument and it is a sequence, so we must treat it as a sequence of parameters. (This is
916 // the normal Cursor.execute behavior.) 907 // the normal Cursor.execute behavior.)
917 908
918 params = PyTuple_GET_ITEM(args, 1); 909 params = PyTuple_GET_ITEM(args, 1);
919 skip_first = false; 910 skip_first = false;
920 } 911 }
921 else if (cParams > 0) 912 else if (cParams > 0)
922 { 913 {
923 params = args; 914 params = args;
924 skip_first = true; 915 skip_first = true;
925 } 916 }
926 917
927 // Execute. 918 // Execute.
928 919
929 return execute(cursor, pSql, params, skip_first); 920 return execute(cursor, pSql, params, skip_first);
930 } 921 }
931 922
932 static PyObject* 923
933 Cursor_executemany(PyObject* self, PyObject* args) 924 static PyObject* Cursor_executemany(PyObject* self, PyObject* args)
934 { 925 {
935 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR); 926 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR);
936 if (!cursor) 927 if (!cursor)
937 return 0; 928 return 0;
938 929
939 cursor->rowcount = -1; 930 cursor->rowcount = -1;
940 931
941 PyObject *pSql, *param_seq; 932 PyObject *pSql, *param_seq;
942 if (!PyArg_ParseTuple(args, "OO", &pSql, &param_seq)) 933 if (!PyArg_ParseTuple(args, "OO", &pSql, &param_seq))
943 return 0; 934 return 0;
944 935
945 if (!PyString_Check(pSql) && !PyUnicode_Check(pSql)) 936 if (!PyString_Check(pSql) && !PyUnicode_Check(pSql))
946 { 937 {
947 PyErr_SetString(PyExc_TypeError, "The first argument to execute must be a string or unicode query."); 938 PyErr_SetString(PyExc_TypeError, "The first argument to execute must be a string or unicode query.");
948 return 0; 939 return 0;
949 } 940 }
950 941
951 if (!IsSequence(param_seq)) 942 if (!IsSequence(param_seq))
952 { 943 {
953 PyErr_SetString(ProgrammingError, "The second parameter to executemany must be a sequence."); 944 PyErr_SetString(ProgrammingError, "The second parameter to executemany must be a sequence.");
954 return 0; 945 return 0;
955 } 946 }
956 947
957 Py_ssize_t c = PySequence_Size(param_seq); 948 Py_ssize_t c = PySequence_Size(param_seq);
958 949
959 if (c == 0) 950 if (c == 0)
960 { 951 {
961 PyErr_SetString(ProgrammingError, "The second parameter to executemany must not be empty."); 952 PyErr_SetString(ProgrammingError, "The second parameter to executemany must not be empty.");
962 return 0; 953 return 0;
963 } 954 }
964 955
965 for (Py_ssize_t i = 0; i < c; i++) 956 for (Py_ssize_t i = 0; i < c; i++)
966 { 957 {
967 PyObject* params = PySequence_GetItem(param_seq, i); 958 PyObject* params = PySequence_GetItem(param_seq, i);
968 PyObject* result = execute(cursor, pSql, params, false); 959 PyObject* result = execute(cursor, pSql, params, false);
969 bool success = result != 0; 960 bool success = result != 0;
970 Py_XDECREF(result); 961 Py_XDECREF(result);
971 Py_DECREF(params); 962 Py_DECREF(params);
972 if (!success) 963 if (!success)
973 { 964 {
974 cursor->rowcount = -1; 965 cursor->rowcount = -1;
975 return 0; 966 return 0;
976 } 967 }
977 } 968 }
978 969
979 cursor->rowcount = -1; 970 cursor->rowcount = -1;
980 Py_RETURN_NONE; 971 Py_RETURN_NONE;
981 } 972 }
982 973
983 974
984 static PyObject* 975 static PyObject* Cursor_fetch(Cursor* cur)
985 Cursor_fetch(Cursor* cur)
986 { 976 {
987 // Internal function to fetch a single row and construct a Row object from it. Used by all of the fetching 977 // Internal function to fetch a single row and construct a Row object from it. Used by all of the fetching
988 // functions. 978 // functions.
989 // 979 //
990 // Returns a Row object if successful. If there are no more rows, zero is returned. If an error occurs, an 980 // Returns a Row object if successful. If there are no more rows, zero is returned. If an error occurs, an
991 // exception is set and zero is returned. (To differentiate between the last two, use PyErr_Occurred.) 981 // exception is set and zero is returned. (To differentiate between the last two, use PyErr_Occurred.)
992 982
993 SQLRETURN ret = 0; 983 SQLRETURN ret = 0;
994 Py_ssize_t field_count, i; 984 Py_ssize_t field_count, i;
995 PyObject** apValues; 985 PyObject** apValues;
996 986
997 Py_BEGIN_ALLOW_THREADS 987 Py_BEGIN_ALLOW_THREADS
998 ret = SQLFetch(cur->hstmt); 988 ret = SQLFetch(cur->hstmt);
999 Py_END_ALLOW_THREADS 989 Py_END_ALLOW_THREADS
1000 990
1001 if (cur->cnxn->hdbc == SQL_NULL_HANDLE) 991 if (cur->cnxn->hdbc == SQL_NULL_HANDLE)
1002 { 992 {
1003 // The connection was closed by another thread in the ALLOW_THREADS block above. 993 // The connection was closed by another thread in the ALLOW_THREADS block above.
1004 return RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed."); 994 return RaiseErrorV(0, ProgrammingError, "The cursor's connection was closed.");
1005 } 995 }
1006 996
1007 if (ret == SQL_NO_DATA) 997 if (ret == SQL_NO_DATA)
1008 return 0; 998 return 0;
1009 999
1010 if (!SQL_SUCCEEDED(ret)) 1000 if (!SQL_SUCCEEDED(ret))
1011 return RaiseErrorFromHandle("SQLFetch", cur->cnxn->hdbc, cur->hstmt); 1001 return RaiseErrorFromHandle("SQLFetch", cur->cnxn->hdbc, cur->hstmt);
1012 1002
1013 field_count = PyTuple_GET_SIZE(cur->description); 1003 field_count = PyTuple_GET_SIZE(cur->description);
1014 1004
1015 apValues = (PyObject**)pyodbc_malloc(sizeof(PyObject*) * field_count); 1005 apValues = (PyObject**)pyodbc_malloc(sizeof(PyObject*) * field_count);
1016 1006
1017 if (apValues == 0) 1007 if (apValues == 0)
1018 return PyErr_NoMemory(); 1008 return PyErr_NoMemory();
1019 1009
1020 for (i = 0; i < field_count; i++) 1010 for (i = 0; i < field_count; i++)
1021 { 1011 {
1022 PyObject* value = GetData(cur, i); 1012 PyObject* value = GetData(cur, i);
1023 1013
1024 if (!value) 1014 if (!value)
1025 { 1015 {
1026 FreeRowValues(i, apValues); 1016 FreeRowValues(i, apValues);
1027 return 0; 1017 return 0;
1028 } 1018 }
1029 1019
1030 apValues[i] = value; 1020 apValues[i] = value;
1031 } 1021 }
1032 1022
1033 return (PyObject*)Row_New(cur->description, cur->map_name_to_index, field_count, apValues); 1023 return (PyObject*)Row_New(cur->description, cur->map_name_to_index, field_count, apValues);
1034 } 1024 }
1035 1025
1036 1026
1037 static PyObject* 1027 static PyObject* Cursor_fetchlist(Cursor* cur, Py_ssize_t max)
1038 Cursor_fetchlist(Cursor* cur, Py_ssize_t max)
1039 { 1028 {
1040 // max 1029 // max
1041 // The maximum number of rows to fetch. If -1, fetch all rows. 1030 // The maximum number of rows to fetch. If -1, fetch all rows.
1042 // 1031 //
1043 // Returns a list of Rows. If there are no rows, an empty list is returned. 1032 // Returns a list of Rows. If there are no rows, an empty list is returned.
1044 1033
1045 PyObject* results; 1034 PyObject* results;
1046 PyObject* row; 1035 PyObject* row;
1047 1036
1048 results = PyList_New(0); 1037 results = PyList_New(0);
1049 if (!results) 1038 if (!results)
1050 return 0; 1039 return 0;
1051 1040
1052 while (max == -1 || max > 0) 1041 while (max == -1 || max > 0)
1053 { 1042 {
1054 row = Cursor_fetch(cur); 1043 row = Cursor_fetch(cur);
1055 1044
1056 if (!row) 1045 if (!row)
1057 { 1046 {
1058 if (PyErr_Occurred()) 1047 if (PyErr_Occurred())
1059 { 1048 {
1060 Py_DECREF(results); 1049 Py_DECREF(results);
1061 return 0; 1050 return 0;
1062 } 1051 }
1063 break; 1052 break;
1064 } 1053 }
1065 1054
1066 PyList_Append(results, row); 1055 PyList_Append(results, row);
1067 Py_DECREF(row); 1056 Py_DECREF(row);
1068 1057
1069 if (max != -1) 1058 if (max != -1)
1070 max--; 1059 max--;
1071 } 1060 }
1072 1061
1073 return results; 1062 return results;
1074 } 1063 }
1075 1064
1076 static PyObject* 1065
1077 Cursor_iter(PyObject* self) 1066 static PyObject* Cursor_iter(PyObject* self)
1078 { 1067 {
1079 Py_INCREF(self); 1068 Py_INCREF(self);
1080 return self; 1069 return self;
1081 } 1070 }
1082 1071
1083 1072
1084 static PyObject* 1073 static PyObject* Cursor_iternext(PyObject* self)
1085 Cursor_iternext(PyObject* self)
1086 { 1074 {
1087 // Implements the iterator protocol for cursors. Fetches the next row. Returns zero without setting an exception 1075 // Implements the iterator protocol for cursors. Fetches the next row. Returns zero without setting an exception
1088 // when there are no rows. 1076 // when there are no rows.
1089 1077
1090 PyObject* result; 1078 PyObject* result;
1091 1079
1092 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR); 1080 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR);
1093 1081
1094 if (!cursor) 1082 if (!cursor)
1095 return 0; 1083 return 0;
1096 1084
1097 result = Cursor_fetch(cursor); 1085 result = Cursor_fetch(cursor);
1098 1086
1099 return result; 1087 return result;
1100 } 1088 }
1101 1089
1102 static PyObject* 1090
1103 Cursor_fetchone(PyObject* self, PyObject* args) 1091 static PyObject* Cursor_fetchone(PyObject* self, PyObject* args)
1104 { 1092 {
1105 UNUSED(args); 1093 UNUSED(args);
1106 1094
1107 PyObject* row; 1095 PyObject* row;
1108 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR); 1096 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR);
1109 if (!cursor) 1097 if (!cursor)
1110 return 0; 1098 return 0;
1111 1099
1112 row = Cursor_fetch(cursor); 1100 row = Cursor_fetch(cursor);
1113 1101
1114 if (!row) 1102 if (!row)
1115 { 1103 {
1116 if (PyErr_Occurred()) 1104 if (PyErr_Occurred())
1117 return 0; 1105 return 0;
1118 Py_RETURN_NONE; 1106 Py_RETURN_NONE;
1119 } 1107 }
1120 1108
1121 return row; 1109 return row;
1122 } 1110 }
1123 1111
1124 static PyObject* 1112
1125 Cursor_fetchall(PyObject* self, PyObject* args) 1113 static PyObject* Cursor_fetchall(PyObject* self, PyObject* args)
1126 { 1114 {
1127 UNUSED(args); 1115 UNUSED(args);
1128 1116
1129 PyObject* result; 1117 PyObject* result;
1130 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR); 1118 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR);
1131 if (!cursor) 1119 if (!cursor)
1132 return 0; 1120 return 0;
1133 1121
1134 result = Cursor_fetchlist(cursor, -1); 1122 result = Cursor_fetchlist(cursor, -1);
1135 1123
1136 return result; 1124 return result;
1137 } 1125 }
1138 1126
1139 static PyObject* 1127
1140 Cursor_fetchmany(PyObject* self, PyObject* args) 1128 static PyObject* Cursor_fetchmany(PyObject* self, PyObject* args)
1141 { 1129 {
1142 long rows; 1130 long rows;
1143 PyObject* result; 1131 PyObject* result;
1144 1132
1145 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR); 1133 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR);
1146 if (!cursor) 1134 if (!cursor)
1147 return 0; 1135 return 0;
1148 1136
1149 rows = cursor->arraysize; 1137 rows = cursor->arraysize;
1150 if (!PyArg_ParseTuple(args, "|l", &rows)) 1138 if (!PyArg_ParseTuple(args, "|l", &rows))
1151 return 0; 1139 return 0;
1152 1140
1153 result = Cursor_fetchlist(cursor, rows); 1141 result = Cursor_fetchlist(cursor, rows);
1154 1142
1155 return result; 1143 return result;
1156 } 1144 }
1145
1157 1146
1158 static char tables_doc[] = 1147 static char tables_doc[] =
1159 "C.tables(table=None, catalog=None, schema=None, tableType=None) --> self\n" 1148 "C.tables(table=None, catalog=None, schema=None, tableType=None) --> self\n"
1160 "\n" 1149 "\n"
1161 "Executes SQLTables and creates a results set of tables defined in the data\n" 1150 "Executes SQLTables and creates a results set of tables defined in the data\n"
1162 "source.\n" 1151 "source.\n"
1163 "\n" 1152 "\n"
1164 "The table, catalog, and schema interpret the '_' and '%' characters as\n" 1153 "The table, catalog, and schema interpret the '_' and '%' characters as\n"
1165 "wildcards. The escape character is driver specific, so use\n" 1154 "wildcards. The escape character is driver specific, so use\n"
1166 "`Connection.searchescape`.\n" 1155 "`Connection.searchescape`.\n"
1167 "\n" 1156 "\n"
1168 "Each row fetched has the following columns:\n" 1157 "Each row fetched has the following columns:\n"
1169 " 0) table_cat: The catalog name.\n" 1158 " 0) table_cat: The catalog name.\n"
1170 " 1) table_schem: The schema name.\n" 1159 " 1) table_schem: The schema name.\n"
1171 " 2) table_name: The table name.\n" 1160 " 2) table_name: The table name.\n"
1172 " 3) table_type: One of 'TABLE', 'VIEW', SYSTEM TABLE', 'GLOBAL TEMPORARY'\n" 1161 " 3) table_type: One of 'TABLE', 'VIEW', SYSTEM TABLE', 'GLOBAL TEMPORARY'\n"
1173 " 'LOCAL TEMPORARY', 'ALIAS', 'SYNONYM', or a data source-specific type name."; 1162 " 'LOCAL TEMPORARY', 'ALIAS', 'SYNONYM', or a data source-specific type name.";
1174 1163
1175 char* Cursor_tables_kwnames[] = { "table", "catalog", "schema", "tableType", 0 }; 1164 char* Cursor_tables_kwnames[] = { "table", "catalog", "schema", "tableType", 0 };
1176 1165
1177 static PyObject* 1166 static PyObject* Cursor_tables(PyObject* self, PyObject* args, PyObject* kwargs)
1178 Cursor_tables(PyObject* self, PyObject* args, PyObject* kwargs)
1179 { 1167 {
1180 const char* szCatalog = 0; 1168 const char* szCatalog = 0;
1181 const char* szSchema = 0; 1169 const char* szSchema = 0;
1182 const char* szTableName = 0; 1170 const char* szTableName = 0;
1183 const char* szTableType = 0; 1171 const char* szTableType = 0;
1184 1172
1185 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssss", Cursor_tables_kwnames, &szTableName, &szCatalog, &szSchema, &szTableType)) 1173 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssss", Cursor_tables_kwnames, &szTableName, &szCatalog, &szSchema, &szTableType))
1186 return 0; 1174 return 0;
1187 1175
1188 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1176 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1189 1177
1190 if (!free_results(cur, FREE_STATEMENT)) 1178 if (!free_results(cur, FREE_STATEMENT))
1191 return 0; 1179 return 0;
1192 1180
1193 SQLRETURN ret = 0; 1181 SQLRETURN ret = 0;
1194 1182
1195 Py_BEGIN_ALLOW_THREADS 1183 Py_BEGIN_ALLOW_THREADS
1196 ret = SQLTables(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, 1184 ret = SQLTables(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS,
1197 (SQLCHAR*)szTableName, SQL_NTS, (SQLCHAR*)szTableType, SQL_NTS); 1185 (SQLCHAR*)szTableName, SQL_NTS, (SQLCHAR*)szTableType, SQL_NTS);
1198 Py_END_ALLOW_THREADS 1186 Py_END_ALLOW_THREADS
1199 1187
1200 if (!SQL_SUCCEEDED(ret)) 1188 if (!SQL_SUCCEEDED(ret))
1201 return RaiseErrorFromHandle("SQLTables", cur->cnxn->hdbc, cur->hstmt); 1189 return RaiseErrorFromHandle("SQLTables", cur->cnxn->hdbc, cur->hstmt);
1202 1190
1203 SQLSMALLINT cCols; 1191 SQLSMALLINT cCols;
1204 Py_BEGIN_ALLOW_THREADS 1192 Py_BEGIN_ALLOW_THREADS
1205 ret = SQLNumResultCols(cur->hstmt, &cCols); 1193 ret = SQLNumResultCols(cur->hstmt, &cCols);
1206 Py_END_ALLOW_THREADS 1194 Py_END_ALLOW_THREADS
1207 if (!SQL_SUCCEEDED(ret)) 1195 if (!SQL_SUCCEEDED(ret))
1208 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1196 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1209 1197
1210 if (!PrepareResults(cur, cCols)) 1198 if (!PrepareResults(cur, cCols))
1211 return 0; 1199 return 0;
1212 1200
1213 if (!create_name_map(cur, cCols, true)) 1201 if (!create_name_map(cur, cCols, true))
1214 return 0; 1202 return 0;
1215 1203
1216 // Return the cursor so the results can be iterated over directly. 1204 // Return the cursor so the results can be iterated over directly.
1217 Py_INCREF(cur); 1205 Py_INCREF(cur);
1218 return (PyObject*)cur; 1206 return (PyObject*)cur;
1219 } 1207 }
1220 1208
1221 1209
1222 static char columns_doc[] = 1210 static char columns_doc[] =
1223 "C.columns(table=None, catalog=None, schema=None, column=None)\n\n" 1211 "C.columns(table=None, catalog=None, schema=None, column=None)\n\n"
1224 "Creates a results set of column names in specified tables by executing the ODBC SQLColumns function.\n" 1212 "Creates a results set of column names in specified tables by executing the ODBC SQLColumns function.\n"
1225 "Each row fetched has the following columns:\n" 1213 "Each row fetched has the following columns:\n"
1226 " 0) table_cat\n" 1214 " 0) table_cat\n"
1227 " 1) table_schem\n" 1215 " 1) table_schem\n"
1228 " 2) table_name\n" 1216 " 2) table_name\n"
1229 " 3) column_name\n" 1217 " 3) column_name\n"
1230 " 4) data_type\n" 1218 " 4) data_type\n"
1231 " 5) type_name\n" 1219 " 5) type_name\n"
1232 " 6) column_size\n" 1220 " 6) column_size\n"
1233 " 7) buffer_length\n" 1221 " 7) buffer_length\n"
1234 " 8) decimal_digits\n" 1222 " 8) decimal_digits\n"
1235 " 9) num_prec_radix\n" 1223 " 9) num_prec_radix\n"
1236 " 10) nullable\n" 1224 " 10) nullable\n"
1237 " 11) remarks\n" 1225 " 11) remarks\n"
1238 " 12) column_def\n" 1226 " 12) column_def\n"
1239 " 13) sql_data_type\n" 1227 " 13) sql_data_type\n"
1240 " 14) sql_datetime_sub\n" 1228 " 14) sql_datetime_sub\n"
1241 " 15) char_octet_length\n" 1229 " 15) char_octet_length\n"
1242 " 16) ordinal_position\n" 1230 " 16) ordinal_position\n"
1243 " 17) is_nullable"; 1231 " 17) is_nullable";
1244 1232
1245 char* Cursor_column_kwnames[] = { "table", "catalog", "schema", "column", 0 }; 1233 char* Cursor_column_kwnames[] = { "table", "catalog", "schema", "column", 0 };
1246 1234
1247 static PyObject* 1235 static PyObject* Cursor_columns(PyObject* self, PyObject* args, PyObject* kwargs)
1248 Cursor_columns(PyObject* self, PyObject* args, PyObject* kwargs)
1249 { 1236 {
1250 const char* szCatalog = 0; 1237 const char* szCatalog = 0;
1251 const char* szSchema = 0; 1238 const char* szSchema = 0;
1252 const char* szTable = 0; 1239 const char* szTable = 0;
1253 const char* szColumn = 0; 1240 const char* szColumn = 0;
1254 1241
1255 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssss", Cursor_column_kwnames, &szTable, &szCatalog, &szSchema, &szColumn)) 1242 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssss", Cursor_column_kwnames, &szTable, &szCatalog, &szSchema, &szColumn))
1256 return 0; 1243 return 0;
1257 1244
1258 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1245 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1259 1246
1260 if (!free_results(cur, FREE_STATEMENT)) 1247 if (!free_results(cur, FREE_STATEMENT))
1261 return 0; 1248 return 0;
1262 1249
1263 SQLRETURN ret = 0; 1250 SQLRETURN ret = 0;
1264 1251
1265 Py_BEGIN_ALLOW_THREADS 1252 Py_BEGIN_ALLOW_THREADS
1266 ret = SQLColumns(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS, (SQLCHAR*)szColumn, SQL_NTS); 1253 ret = SQLColumns(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS, (SQLCHAR*)szColumn, SQL_NTS);
1267 Py_END_ALLOW_THREADS 1254 Py_END_ALLOW_THREADS
1268 1255
1269 if (!SQL_SUCCEEDED(ret)) 1256 if (!SQL_SUCCEEDED(ret))
1270 return RaiseErrorFromHandle("SQLColumns", cur->cnxn->hdbc, cur->hstmt); 1257 return RaiseErrorFromHandle("SQLColumns", cur->cnxn->hdbc, cur->hstmt);
1271 1258
1272 SQLSMALLINT cCols; 1259 SQLSMALLINT cCols;
1273 Py_BEGIN_ALLOW_THREADS 1260 Py_BEGIN_ALLOW_THREADS
1274 ret = SQLNumResultCols(cur->hstmt, &cCols); 1261 ret = SQLNumResultCols(cur->hstmt, &cCols);
1275 Py_END_ALLOW_THREADS 1262 Py_END_ALLOW_THREADS
1276 if (!SQL_SUCCEEDED(ret)) 1263 if (!SQL_SUCCEEDED(ret))
1277 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1264 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1278 1265
1279 if (!PrepareResults(cur, cCols)) 1266 if (!PrepareResults(cur, cCols))
1280 return 0; 1267 return 0;
1281 1268
1282 if (!create_name_map(cur, cCols, true)) 1269 if (!create_name_map(cur, cCols, true))
1283 return 0; 1270 return 0;
1284 1271
1285 // Return the cursor so the results can be iterated over directly. 1272 // Return the cursor so the results can be iterated over directly.
1286 Py_INCREF(cur); 1273 Py_INCREF(cur);
1287 return (PyObject*)cur; 1274 return (PyObject*)cur;
1288 } 1275 }
1289 1276
1290 1277
1291 static char statistics_doc[] = 1278 static char statistics_doc[] =
1292 "C.statistics(catalog=None, schema=None, unique=False, quick=True) --> self\n\n" 1279 "C.statistics(catalog=None, schema=None, unique=False, quick=True) --> self\n\n"
1293 "Creates a results set of statistics about a single table and the indexes associated with \n" 1280 "Creates a results set of statistics about a single table and the indexes associated with \n"
1294 "the table by executing SQLStatistics.\n" 1281 "the table by executing SQLStatistics.\n"
1295 "unique\n" 1282 "unique\n"
1296 " If True, only unique indexes are retured. Otherwise all indexes are returned.\n" 1283 " If True, only unique indexes are retured. Otherwise all indexes are returned.\n"
1297 "quick\n" 1284 "quick\n"
1298 " If True, CARDINALITY and PAGES are returned only if they are readily available\n" 1285 " If True, CARDINALITY and PAGES are returned only if they are readily available\n"
1299 " from the server\n" 1286 " from the server\n"
1300 "\n" 1287 "\n"
1301 "Each row fetched has the following columns:\n\n" 1288 "Each row fetched has the following columns:\n\n"
1302 " 0) table_cat\n" 1289 " 0) table_cat\n"
1303 " 1) table_schem\n" 1290 " 1) table_schem\n"
1304 " 2) table_name\n" 1291 " 2) table_name\n"
1305 " 3) non_unique\n" 1292 " 3) non_unique\n"
1306 " 4) index_qualifier\n" 1293 " 4) index_qualifier\n"
1307 " 5) index_name\n" 1294 " 5) index_name\n"
1308 " 6) type\n" 1295 " 6) type\n"
1309 " 7) ordinal_position\n" 1296 " 7) ordinal_position\n"
1310 " 8) column_name\n" 1297 " 8) column_name\n"
1311 " 9) asc_or_desc\n" 1298 " 9) asc_or_desc\n"
1312 " 10) cardinality\n" 1299 " 10) cardinality\n"
1313 " 11) pages\n" 1300 " 11) pages\n"
1314 " 12) filter_condition"; 1301 " 12) filter_condition";
1315 1302
1316 char* Cursor_statistics_kwnames[] = { "table", "catalog", "schema", "unique", "quick", 0 }; 1303 char* Cursor_statistics_kwnames[] = { "table", "catalog", "schema", "unique", "quick", 0 };
1317 1304
1318 static PyObject* 1305 static PyObject* Cursor_statistics(PyObject* self, PyObject* args, PyObject* kwargs)
1319 Cursor_statistics(PyObject* self, PyObject* args, PyObject* kwargs)
1320 { 1306 {
1321 const char* szCatalog = 0; 1307 const char* szCatalog = 0;
1322 const char* szSchema = 0; 1308 const char* szSchema = 0;
1323 const char* szTable = 0; 1309 const char* szTable = 0;
1324 PyObject* pUnique = Py_False; 1310 PyObject* pUnique = Py_False;
1325 PyObject* pQuick = Py_True; 1311 PyObject* pQuick = Py_True;
1326 1312
1327 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ssOO", Cursor_statistics_kwnames, &szTable, &szCatalog, &szSchema, 1313 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ssOO", Cursor_statistics_kwnames, &szTable, &szCatalog, &szSchema,
1328 &pUnique, &pQuick)) 1314 &pUnique, &pQuick))
1329 return 0; 1315 return 0;
1330 1316
1331 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1317 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1332 1318
1333 if (!free_results(cur, FREE_STATEMENT)) 1319 if (!free_results(cur, FREE_STATEMENT))
1334 return 0; 1320 return 0;
1335 1321
1336 SQLUSMALLINT nUnique = (SQLUSMALLINT)(PyObject_IsTrue(pUnique) ? SQL_INDEX_UNIQUE : SQL_INDEX_ALL); 1322 SQLUSMALLINT nUnique = (SQLUSMALLINT)(PyObject_IsTrue(pUnique) ? SQL_INDEX_UNIQUE : SQL_INDEX_ALL);
1337 SQLUSMALLINT nReserved = (SQLUSMALLINT)(PyObject_IsTrue(pQuick) ? SQL_QUICK : SQL_ENSURE); 1323 SQLUSMALLINT nReserved = (SQLUSMALLINT)(PyObject_IsTrue(pQuick) ? SQL_QUICK : SQL_ENSURE);
1338 1324
1339 SQLRETURN ret = 0; 1325 SQLRETURN ret = 0;
1340 1326
1341 Py_BEGIN_ALLOW_THREADS 1327 Py_BEGIN_ALLOW_THREADS
1342 ret = SQLStatistics(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS, 1328 ret = SQLStatistics(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS,
1343 nUnique, nReserved); 1329 nUnique, nReserved);
1344 Py_END_ALLOW_THREADS 1330 Py_END_ALLOW_THREADS
1345 1331
1346 if (!SQL_SUCCEEDED(ret)) 1332 if (!SQL_SUCCEEDED(ret))
1347 return RaiseErrorFromHandle("SQLStatistics", cur->cnxn->hdbc, cur->hstmt); 1333 return RaiseErrorFromHandle("SQLStatistics", cur->cnxn->hdbc, cur->hstmt);
1348 1334
1349 SQLSMALLINT cCols; 1335 SQLSMALLINT cCols;
1350 Py_BEGIN_ALLOW_THREADS 1336 Py_BEGIN_ALLOW_THREADS
1351 ret = SQLNumResultCols(cur->hstmt, &cCols); 1337 ret = SQLNumResultCols(cur->hstmt, &cCols);
1352 Py_END_ALLOW_THREADS 1338 Py_END_ALLOW_THREADS
1353 if (!SQL_SUCCEEDED(ret)) 1339 if (!SQL_SUCCEEDED(ret))
1354 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1340 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1355 1341
1356 if (!PrepareResults(cur, cCols)) 1342 if (!PrepareResults(cur, cCols))
1357 return 0; 1343 return 0;
1358 1344
1359 if (!create_name_map(cur, cCols, true)) 1345 if (!create_name_map(cur, cCols, true))
1360 return 0; 1346 return 0;
1361 1347
1362 // Return the cursor so the results can be iterated over directly. 1348 // Return the cursor so the results can be iterated over directly.
1363 Py_INCREF(cur); 1349 Py_INCREF(cur);
1364 return (PyObject*)cur; 1350 return (PyObject*)cur;
1365 } 1351 }
1366 1352
1367 1353
1368 static char rowIdColumns_doc[] = 1354 static char rowIdColumns_doc[] =
1369 "C.rowIdColumns(table, catalog=None, schema=None, nullable=True) -->\n\n" 1355 "C.rowIdColumns(table, catalog=None, schema=None, nullable=True) -->\n\n"
1370 "Executes SQLSpecialColumns with SQL_BEST_ROWID which creates a result set of columns that\n" 1356 "Executes SQLSpecialColumns with SQL_BEST_ROWID which creates a result set of columns that\n"
1371 "uniquely identify a row\n\n" 1357 "uniquely identify a row\n\n"
1372 "Each row fetched has the following columns:\n" 1358 "Each row fetched has the following columns:\n"
1373 " 0) scope\n" 1359 " 0) scope\n"
1374 " 1) column_name\n" 1360 " 1) column_name\n"
1375 " 2) data_type\n" 1361 " 2) data_type\n"
1376 " 3) type_name\n" 1362 " 3) type_name\n"
1377 " 4) column_size\n" 1363 " 4) column_size\n"
1378 " 5) buffer_length\n" 1364 " 5) buffer_length\n"
1379 " 6) decimal_digits\n" 1365 " 6) decimal_digits\n"
1380 " 7) pseudo_column"; 1366 " 7) pseudo_column";
1381 1367
1382 static char rowVerColumns_doc[] = 1368 static char rowVerColumns_doc[] =
1383 "C.rowIdColumns(table, catalog=None, schema=None, nullable=True) --> self\n\n" 1369 "C.rowIdColumns(table, catalog=None, schema=None, nullable=True) --> self\n\n"
1384 "Executes SQLSpecialColumns with SQL_ROWVER which creates a result set of columns that\n" 1370 "Executes SQLSpecialColumns with SQL_ROWVER which creates a result set of columns that\n"
1385 "are automatically updated when any value in the row is updated.\n\n" 1371 "are automatically updated when any value in the row is updated.\n\n"
1386 "Each row fetched has the following columns:\n" 1372 "Each row fetched has the following columns:\n"
1387 " 0) scope\n" 1373 " 0) scope\n"
1388 " 1) column_name\n" 1374 " 1) column_name\n"
1389 " 2) data_type\n" 1375 " 2) data_type\n"
1390 " 3) type_name\n" 1376 " 3) type_name\n"
1391 " 4) column_size\n" 1377 " 4) column_size\n"
1392 " 5) buffer_length\n" 1378 " 5) buffer_length\n"
1393 " 6) decimal_digits\n" 1379 " 6) decimal_digits\n"
1394 " 7) pseudo_column"; 1380 " 7) pseudo_column";
1395 1381
1396 char* Cursor_specialColumn_kwnames[] = { "table", "catalog", "schema", "nullable", 0 }; 1382 char* Cursor_specialColumn_kwnames[] = { "table", "catalog", "schema", "nullable", 0 };
1397 1383
1398 static PyObject* 1384 static PyObject* _specialColumns(PyObject* self, PyObject* args, PyObject* kwargs, SQLUSMALLINT nIdType)
1399 _specialColumns(PyObject* self, PyObject* args, PyObject* kwargs, SQLUSMALLINT nIdType)
1400 { 1385 {
1401 const char* szTable; 1386 const char* szTable;
1402 const char* szCatalog = 0; 1387 const char* szCatalog = 0;
1403 const char* szSchema = 0; 1388 const char* szSchema = 0;
1404 PyObject* pNullable = Py_True; 1389 PyObject* pNullable = Py_True;
1405 1390
1406 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ssO", Cursor_specialColumn_kwnames, &szTable, &szCatalog, &szSchema, &pNullable)) 1391 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ssO", Cursor_specialColumn_kwnames, &szTable, &szCatalog, &szSchema, &pNullable))
1407 return 0; 1392 return 0;
1408 1393
1409 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1394 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1410 1395
1411 if (!free_results(cur, FREE_STATEMENT)) 1396 if (!free_results(cur, FREE_STATEMENT))
1412 return 0; 1397 return 0;
1413 1398
1414 SQLRETURN ret = 0; 1399 SQLRETURN ret = 0;
1415 1400
1416 SQLUSMALLINT nNullable = (SQLUSMALLINT)(PyObject_IsTrue(pNullable) ? SQL_NULLABLE : SQL_NO_NULLS); 1401 SQLUSMALLINT nNullable = (SQLUSMALLINT)(PyObject_IsTrue(pNullable) ? SQL_NULLABLE : SQL_NO_NULLS);
1417 1402
1418 Py_BEGIN_ALLOW_THREADS 1403 Py_BEGIN_ALLOW_THREADS
1419 ret = SQLSpecialColumns(cur->hstmt, nIdType, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS, 1404 ret = SQLSpecialColumns(cur->hstmt, nIdType, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS,
1420 SQL_SCOPE_TRANSACTION, nNullable); 1405 SQL_SCOPE_TRANSACTION, nNullable);
1421 Py_END_ALLOW_THREADS 1406 Py_END_ALLOW_THREADS
1422 1407
1423 if (!SQL_SUCCEEDED(ret)) 1408 if (!SQL_SUCCEEDED(ret))
1424 return RaiseErrorFromHandle("SQLSpecialColumns", cur->cnxn->hdbc, cur->hstmt); 1409 return RaiseErrorFromHandle("SQLSpecialColumns", cur->cnxn->hdbc, cur->hstmt);
1425 1410
1426 SQLSMALLINT cCols; 1411 SQLSMALLINT cCols;
1427 Py_BEGIN_ALLOW_THREADS 1412 Py_BEGIN_ALLOW_THREADS
1428 ret = SQLNumResultCols(cur->hstmt, &cCols); 1413 ret = SQLNumResultCols(cur->hstmt, &cCols);
1429 Py_END_ALLOW_THREADS 1414 Py_END_ALLOW_THREADS
1430 if (!SQL_SUCCEEDED(ret)) 1415 if (!SQL_SUCCEEDED(ret))
1431 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1416 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1432 1417
1433 if (!PrepareResults(cur, cCols)) 1418 if (!PrepareResults(cur, cCols))
1434 return 0; 1419 return 0;
1435 1420
1436 if (!create_name_map(cur, cCols, true)) 1421 if (!create_name_map(cur, cCols, true))
1437 return 0; 1422 return 0;
1438 1423
1439 // Return the cursor so the results can be iterated over directly. 1424 // Return the cursor so the results can be iterated over directly.
1440 Py_INCREF(cur); 1425 Py_INCREF(cur);
1441 return (PyObject*)cur; 1426 return (PyObject*)cur;
1442 } 1427 }
1443 1428
1444 static PyObject* 1429
1445 Cursor_rowIdColumns(PyObject* self, PyObject* args, PyObject* kwargs) 1430 static PyObject* Cursor_rowIdColumns(PyObject* self, PyObject* args, PyObject* kwargs)
1446 { 1431 {
1447 return _specialColumns(self, args, kwargs, SQL_BEST_ROWID); 1432 return _specialColumns(self, args, kwargs, SQL_BEST_ROWID);
1448 } 1433 }
1449 1434
1450 static PyObject* 1435
1451 Cursor_rowVerColumns(PyObject* self, PyObject* args, PyObject* kwargs) 1436 static PyObject* Cursor_rowVerColumns(PyObject* self, PyObject* args, PyObject* kwargs)
1452 { 1437 {
1453 return _specialColumns(self, args, kwargs, SQL_ROWVER); 1438 return _specialColumns(self, args, kwargs, SQL_ROWVER);
1454 } 1439 }
1455 1440
1456 1441
1457 static char primaryKeys_doc[] = 1442 static char primaryKeys_doc[] =
1458 "C.primaryKeys(table, catalog=None, schema=None) --> self\n\n" 1443 "C.primaryKeys(table, catalog=None, schema=None) --> self\n\n"
1459 "Creates a results set of column names that make up the primary key for a table\n" 1444 "Creates a results set of column names that make up the primary key for a table\n"
1460 "by executing the SQLPrimaryKeys function.\n" 1445 "by executing the SQLPrimaryKeys function.\n"
1461 "Each row fetched has the following columns:\n" 1446 "Each row fetched has the following columns:\n"
1462 " 0) table_cat\n" 1447 " 0) table_cat\n"
1463 " 1) table_schem\n" 1448 " 1) table_schem\n"
1464 " 2) table_name\n" 1449 " 2) table_name\n"
1465 " 3) column_name\n" 1450 " 3) column_name\n"
1466 " 4) key_seq\n" 1451 " 4) key_seq\n"
1467 " 5) pk_name"; 1452 " 5) pk_name";
1468 1453
1469 char* Cursor_primaryKeys_kwnames[] = { "table", "catalog", "schema", 0 }; 1454 char* Cursor_primaryKeys_kwnames[] = { "table", "catalog", "schema", 0 };
1470 1455
1471 static PyObject* 1456 static PyObject* Cursor_primaryKeys(PyObject* self, PyObject* args, PyObject* kwargs)
1472 Cursor_primaryKeys(PyObject* self, PyObject* args, PyObject* kwargs)
1473 { 1457 {
1474 const char* szTable; 1458 const char* szTable;
1475 const char* szCatalog = 0; 1459 const char* szCatalog = 0;
1476 const char* szSchema = 0; 1460 const char* szSchema = 0;
1477 1461
1478 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ss", Cursor_primaryKeys_kwnames, &szTable, &szCatalog, &szSchema)) 1462 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ss", Cursor_primaryKeys_kwnames, &szTable, &szCatalog, &szSchema))
1479 return 0; 1463 return 0;
1480 1464
1481 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1465 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1482 1466
1483 if (!free_results(cur, FREE_STATEMENT)) 1467 if (!free_results(cur, FREE_STATEMENT))
1484 return 0; 1468 return 0;
1485 1469
1486 SQLRETURN ret = 0; 1470 SQLRETURN ret = 0;
1487 1471
1488 Py_BEGIN_ALLOW_THREADS 1472 Py_BEGIN_ALLOW_THREADS
1489 ret = SQLPrimaryKeys(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS); 1473 ret = SQLPrimaryKeys(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS);
1490 Py_END_ALLOW_THREADS 1474 Py_END_ALLOW_THREADS
1491 1475
1492 if (!SQL_SUCCEEDED(ret)) 1476 if (!SQL_SUCCEEDED(ret))
1493 return RaiseErrorFromHandle("SQLPrimaryKeys", cur->cnxn->hdbc, cur->hstmt); 1477 return RaiseErrorFromHandle("SQLPrimaryKeys", cur->cnxn->hdbc, cur->hstmt);
1494 1478
1495 SQLSMALLINT cCols; 1479 SQLSMALLINT cCols;
1496 Py_BEGIN_ALLOW_THREADS 1480 Py_BEGIN_ALLOW_THREADS
1497 ret = SQLNumResultCols(cur->hstmt, &cCols); 1481 ret = SQLNumResultCols(cur->hstmt, &cCols);
1498 Py_END_ALLOW_THREADS 1482 Py_END_ALLOW_THREADS
1499 if (!SQL_SUCCEEDED(ret)) 1483 if (!SQL_SUCCEEDED(ret))
1500 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1484 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1501 1485
1502 if (!PrepareResults(cur, cCols)) 1486 if (!PrepareResults(cur, cCols))
1503 return 0; 1487 return 0;
1504 1488
1505 if (!create_name_map(cur, cCols, true)) 1489 if (!create_name_map(cur, cCols, true))
1506 return 0; 1490 return 0;
1507 1491
1508 // Return the cursor so the results can be iterated over directly. 1492 // Return the cursor so the results can be iterated over directly.
1509 Py_INCREF(cur); 1493 Py_INCREF(cur);
1510 return (PyObject*)cur; 1494 return (PyObject*)cur;
1511 } 1495 }
1512 1496
1513 1497
1514 static char foreignKeys_doc[] = 1498 static char foreignKeys_doc[] =
1515 "C.foreignKeys(table=None, catalog=None, schema=None,\n" 1499 "C.foreignKeys(table=None, catalog=None, schema=None,\n"
1516 " foreignTable=None, foreignCatalog=None, foreignSchema=None) --> self\n\n" 1500 " foreignTable=None, foreignCatalog=None, foreignSchema=None) --> self\n\n"
1517 "Executes the SQLForeignKeys function and creates a results set of column names\n" 1501 "Executes the SQLForeignKeys function and creates a results set of column names\n"
1518 "that are foreign keys in the specified table (columns in the specified table\n" 1502 "that are foreign keys in the specified table (columns in the specified table\n"
1519 "that refer to primary keys in other tables) or foreign keys in other tables\n" 1503 "that refer to primary keys in other tables) or foreign keys in other tables\n"
1520 "that refer to the primary key in the specified table.\n\n" 1504 "that refer to the primary key in the specified table.\n\n"
1521 "Each row fetched has the following columns:\n" 1505 "Each row fetched has the following columns:\n"
1522 " 0) pktable_cat\n" 1506 " 0) pktable_cat\n"
1523 " 1) pktable_schem\n" 1507 " 1) pktable_schem\n"
1524 " 2) pktable_name\n" 1508 " 2) pktable_name\n"
1525 " 3) pkcolumn_name\n" 1509 " 3) pkcolumn_name\n"
1526 " 4) fktable_cat\n" 1510 " 4) fktable_cat\n"
1527 " 5) fktable_schem\n" 1511 " 5) fktable_schem\n"
1528 " 6) fktable_name\n" 1512 " 6) fktable_name\n"
1529 " 7) fkcolumn_name\n" 1513 " 7) fkcolumn_name\n"
1530 " 8) key_seq\n" 1514 " 8) key_seq\n"
1531 " 9) update_rule\n" 1515 " 9) update_rule\n"
1532 " 10) delete_rule\n" 1516 " 10) delete_rule\n"
1533 " 11) fk_name\n" 1517 " 11) fk_name\n"
1534 " 12) pk_name\n" 1518 " 12) pk_name\n"
1535 " 13) deferrability"; 1519 " 13) deferrability";
1536 1520
1537 char* Cursor_foreignKeys_kwnames[] = { "table", "catalog", "schema", "foreignTable", "foreignCatalog", "foreignSchema", 0 }; 1521 char* Cursor_foreignKeys_kwnames[] = { "table", "catalog", "schema", "foreignTable", "foreignCatalog", "foreignSchema", 0 };
1538 1522
1539 static PyObject* 1523 static PyObject* Cursor_foreignKeys(PyObject* self, PyObject* args, PyObject* kwargs)
1540 Cursor_foreignKeys(PyObject* self, PyObject* args, PyObject* kwargs)
1541 { 1524 {
1542 const char* szTable = 0; 1525 const char* szTable = 0;
1543 const char* szCatalog = 0; 1526 const char* szCatalog = 0;
1544 const char* szSchema = 0; 1527 const char* szSchema = 0;
1545 const char* szForeignTable = 0; 1528 const char* szForeignTable = 0;
1546 const char* szForeignCatalog = 0; 1529 const char* szForeignCatalog = 0;
1547 const char* szForeignSchema = 0; 1530 const char* szForeignSchema = 0;
1548 1531
1549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssss", Cursor_foreignKeys_kwnames, &szTable, &szCatalog, &szSchema, 1532 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssss", Cursor_foreignKeys_kwnames, &szTable, &szCatalog, &szSchema,
1550 &szForeignTable, &szForeignCatalog, &szForeignSchema)) 1533 &szForeignTable, &szForeignCatalog, &szForeignSchema))
1551 return 0; 1534 return 0;
1552 1535
1553 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1536 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1554 1537
1555 if (!free_results(cur, FREE_STATEMENT)) 1538 if (!free_results(cur, FREE_STATEMENT))
1556 return 0; 1539 return 0;
1557 1540
1558 SQLRETURN ret = 0; 1541 SQLRETURN ret = 0;
1559 1542
1560 Py_BEGIN_ALLOW_THREADS 1543 Py_BEGIN_ALLOW_THREADS
1561 ret = SQLForeignKeys(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS, 1544 ret = SQLForeignKeys(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szTable, SQL_NTS,
1562 (SQLCHAR*)szForeignCatalog, SQL_NTS, (SQLCHAR*)szForeignSchema, SQL_NTS, (SQLCHAR*)szForeignTable, SQL_NTS); 1545 (SQLCHAR*)szForeignCatalog, SQL_NTS, (SQLCHAR*)szForeignSchema, SQL_NTS, (SQLCHAR*)szForeignTable, SQL_NTS);
1563 Py_END_ALLOW_THREADS 1546 Py_END_ALLOW_THREADS
1564 1547
1565 if (!SQL_SUCCEEDED(ret)) 1548 if (!SQL_SUCCEEDED(ret))
1566 return RaiseErrorFromHandle("SQLForeignKeys", cur->cnxn->hdbc, cur->hstmt); 1549 return RaiseErrorFromHandle("SQLForeignKeys", cur->cnxn->hdbc, cur->hstmt);
1567 1550
1568 SQLSMALLINT cCols; 1551 SQLSMALLINT cCols;
1569 Py_BEGIN_ALLOW_THREADS 1552 Py_BEGIN_ALLOW_THREADS
1570 ret = SQLNumResultCols(cur->hstmt, &cCols); 1553 ret = SQLNumResultCols(cur->hstmt, &cCols);
1571 Py_END_ALLOW_THREADS 1554 Py_END_ALLOW_THREADS
1572 if (!SQL_SUCCEEDED(ret)) 1555 if (!SQL_SUCCEEDED(ret))
1573 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1556 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1574 1557
1575 if (!PrepareResults(cur, cCols)) 1558 if (!PrepareResults(cur, cCols))
1576 return 0; 1559 return 0;
1577 1560
1578 if (!create_name_map(cur, cCols, true)) 1561 if (!create_name_map(cur, cCols, true))
1579 return 0; 1562 return 0;
1580 1563
1581 // Return the cursor so the results can be iterated over directly. 1564 // Return the cursor so the results can be iterated over directly.
1582 Py_INCREF(cur); 1565 Py_INCREF(cur);
1583 return (PyObject*)cur; 1566 return (PyObject*)cur;
1584 } 1567 }
1585 1568
1586 static char getTypeInfo_doc[] = 1569 static char getTypeInfo_doc[] =
1587 "C.getTypeInfo(sqlType=None) --> self\n\n" 1570 "C.getTypeInfo(sqlType=None) --> self\n\n"
1588 "Executes SQLGetTypeInfo a creates a result set with information about the\n" 1571 "Executes SQLGetTypeInfo a creates a result set with information about the\n"
1589 "specified data type or all data types supported by the ODBC driver if not\n" 1572 "specified data type or all data types supported by the ODBC driver if not\n"
1590 "specified.\n\n" 1573 "specified.\n\n"
1591 "Each row fetched has the following columns:\n" 1574 "Each row fetched has the following columns:\n"
1592 " 0) type_name\n" 1575 " 0) type_name\n"
1593 " 1) data_type\n" 1576 " 1) data_type\n"
1594 " 2) column_size\n" 1577 " 2) column_size\n"
1595 " 3) literal_prefix\n" 1578 " 3) literal_prefix\n"
1596 " 4) literal_suffix\n" 1579 " 4) literal_suffix\n"
1597 " 5) create_params\n" 1580 " 5) create_params\n"
1598 " 6) nullable\n" 1581 " 6) nullable\n"
1599 " 7) case_sensitive\n" 1582 " 7) case_sensitive\n"
1600 " 8) searchable\n" 1583 " 8) searchable\n"
1601 " 9) unsigned_attribute\n" 1584 " 9) unsigned_attribute\n"
1602 "10) fixed_prec_scale\n" 1585 "10) fixed_prec_scale\n"
1603 "11) auto_unique_value\n" 1586 "11) auto_unique_value\n"
1604 "12) local_type_name\n" 1587 "12) local_type_name\n"
1605 "13) minimum_scale\n" 1588 "13) minimum_scale\n"
1606 "14) maximum_scale\n" 1589 "14) maximum_scale\n"
1607 "15) sql_data_type\n" 1590 "15) sql_data_type\n"
1608 "16) sql_datetime_sub\n" 1591 "16) sql_datetime_sub\n"
1609 "17) num_prec_radix\n" 1592 "17) num_prec_radix\n"
1610 "18) interval_precision"; 1593 "18) interval_precision";
1611 1594
1612 static PyObject* 1595 static PyObject* Cursor_getTypeInfo(PyObject* self, PyObject* args, PyObject* kwargs)
1613 Cursor_getTypeInfo(PyObject* self, PyObject* args, PyObject* kwargs)
1614 { 1596 {
1615 UNUSED(kwargs); 1597 UNUSED(kwargs);
1616 1598
1617 SQLSMALLINT nDataType = SQL_ALL_TYPES; 1599 SQLSMALLINT nDataType = SQL_ALL_TYPES;
1618 1600
1619 if (!PyArg_ParseTuple(args, "|i", &nDataType)) 1601 if (!PyArg_ParseTuple(args, "|i", &nDataType))
1620 return 0; 1602 return 0;
1621 1603
1622 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1604 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1623 1605
1624 if (!free_results(cur, FREE_STATEMENT)) 1606 if (!free_results(cur, FREE_STATEMENT))
1625 return 0; 1607 return 0;
1626 1608
1627 SQLRETURN ret = 0; 1609 SQLRETURN ret = 0;
1628 1610
1629 Py_BEGIN_ALLOW_THREADS 1611 Py_BEGIN_ALLOW_THREADS
1630 ret = SQLGetTypeInfo(cur->hstmt, nDataType); 1612 ret = SQLGetTypeInfo(cur->hstmt, nDataType);
1631 Py_END_ALLOW_THREADS 1613 Py_END_ALLOW_THREADS
1632 1614
1633 if (!SQL_SUCCEEDED(ret)) 1615 if (!SQL_SUCCEEDED(ret))
1634 return RaiseErrorFromHandle("SQLGetTypeInfo", cur->cnxn->hdbc, cur->hstmt); 1616 return RaiseErrorFromHandle("SQLGetTypeInfo", cur->cnxn->hdbc, cur->hstmt);
1635 1617
1636 SQLSMALLINT cCols; 1618 SQLSMALLINT cCols;
1637 Py_BEGIN_ALLOW_THREADS 1619 Py_BEGIN_ALLOW_THREADS
1638 ret = SQLNumResultCols(cur->hstmt, &cCols); 1620 ret = SQLNumResultCols(cur->hstmt, &cCols);
1639 Py_END_ALLOW_THREADS 1621 Py_END_ALLOW_THREADS
1640 if (!SQL_SUCCEEDED(ret)) 1622 if (!SQL_SUCCEEDED(ret))
1641 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1623 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1642 1624
1643 if (!PrepareResults(cur, cCols)) 1625 if (!PrepareResults(cur, cCols))
1644 return 0; 1626 return 0;
1645 1627
1646 if (!create_name_map(cur, cCols, true)) 1628 if (!create_name_map(cur, cCols, true))
1647 return 0; 1629 return 0;
1648 1630
1649 // Return the cursor so the results can be iterated over directly. 1631 // Return the cursor so the results can be iterated over directly.
1650 Py_INCREF(cur); 1632 Py_INCREF(cur);
1651 return (PyObject*)cur; 1633 return (PyObject*)cur;
1652 } 1634 }
1653 1635
1654 static PyObject* 1636
1655 Cursor_nextset(PyObject* self, PyObject* args) 1637 static PyObject* Cursor_nextset(PyObject* self, PyObject* args)
1656 { 1638 {
1657 UNUSED(args); 1639 UNUSED(args);
1658 1640
1659 Cursor* cur = Cursor_Validate(self, 0); 1641 Cursor* cur = Cursor_Validate(self, 0);
1660 1642
1661 if (!cur) 1643 if (!cur)
1662 return 0; 1644 return 0;
1663 1645
1664 SQLRETURN ret = 0; 1646 SQLRETURN ret = 0;
1665 1647
1666 Py_BEGIN_ALLOW_THREADS 1648 Py_BEGIN_ALLOW_THREADS
1667 ret = SQLMoreResults(cur->hstmt); 1649 ret = SQLMoreResults(cur->hstmt);
1668 Py_END_ALLOW_THREADS 1650 Py_END_ALLOW_THREADS
1669 1651
1670 if (ret == SQL_NO_DATA) 1652 if (ret == SQL_NO_DATA)
1671 { 1653 {
1672 free_results(cur, FREE_STATEMENT); 1654 free_results(cur, FREE_STATEMENT);
1673 Py_RETURN_FALSE; 1655 Py_RETURN_FALSE;
1674 } 1656 }
1675 1657
1676 SQLSMALLINT cCols; 1658 SQLSMALLINT cCols;
1677 Py_BEGIN_ALLOW_THREADS 1659 Py_BEGIN_ALLOW_THREADS
1678 ret = SQLNumResultCols(cur->hstmt, &cCols); 1660 ret = SQLNumResultCols(cur->hstmt, &cCols);
1679 Py_END_ALLOW_THREADS 1661 Py_END_ALLOW_THREADS
1680 if (!SQL_SUCCEEDED(ret)) 1662 if (!SQL_SUCCEEDED(ret))
1681 { 1663 {
1682 // Note: The SQL Server driver sometimes returns HY007 here if multiple statements (separated by ;) were 1664 // Note: The SQL Server driver sometimes returns HY007 here if multiple statements (separated by ;) were
1683 // submitted. This is not documented, but I've seen it with multiple successful inserts. 1665 // submitted. This is not documented, but I've seen it with multiple successful inserts.
1684 1666
1685 free_results(cur, FREE_STATEMENT); 1667 free_results(cur, FREE_STATEMENT);
1686 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1668 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1687 } 1669 }
1688 free_results(cur, KEEP_STATEMENT); 1670 free_results(cur, KEEP_STATEMENT);
1689 1671
1690 if (cCols != 0) 1672 if (cCols != 0)
1691 { 1673 {
1692 // A result set was created. 1674 // A result set was created.
1693 1675
1694 if (!PrepareResults(cur, cCols)) 1676 if (!PrepareResults(cur, cCols))
1695 return 0; 1677 return 0;
1696 1678
1697 if (!create_name_map(cur, cCols, lowercase())) 1679 if (!create_name_map(cur, cCols, lowercase()))
1698 return 0; 1680 return 0;
1699 } 1681 }
1700 1682
1701 SQLLEN cRows; 1683 SQLLEN cRows;
1702 Py_BEGIN_ALLOW_THREADS 1684 Py_BEGIN_ALLOW_THREADS
1703 ret = SQLRowCount(cur->hstmt, &cRows); 1685 ret = SQLRowCount(cur->hstmt, &cRows);
1704 Py_END_ALLOW_THREADS 1686 Py_END_ALLOW_THREADS
1705 cur->rowcount = (int)cRows; 1687 cur->rowcount = (int)cRows;
1706 1688
1707 if (!SQL_SUCCEEDED(ret)) 1689 if (!SQL_SUCCEEDED(ret))
1708 return RaiseErrorFromHandle("SQLRowCount", cur->cnxn->hdbc, cur->hstmt); 1690 return RaiseErrorFromHandle("SQLRowCount", cur->cnxn->hdbc, cur->hstmt);
1709 1691
1710 Py_RETURN_TRUE; 1692 Py_RETURN_TRUE;
1711 } 1693 }
1712 1694
1713 1695
1714 static char procedureColumns_doc[] = 1696 static char procedureColumns_doc[] =
1715 "C.procedureColumns(procedure=None, catalog=None, schema=None) --> self\n\n" 1697 "C.procedureColumns(procedure=None, catalog=None, schema=None) --> self\n\n"
1716 "Executes SQLProcedureColumns and creates a result set of information\n" 1698 "Executes SQLProcedureColumns and creates a result set of information\n"
1717 "about stored procedure columns and results.\n" 1699 "about stored procedure columns and results.\n"
1718 " 0) procedure_cat\n" 1700 " 0) procedure_cat\n"
1719 " 1) procedure_schem\n" 1701 " 1) procedure_schem\n"
1720 " 2) procedure_name\n" 1702 " 2) procedure_name\n"
1721 " 3) column_name\n" 1703 " 3) column_name\n"
1722 " 4) column_type\n" 1704 " 4) column_type\n"
1723 " 5) data_type\n" 1705 " 5) data_type\n"
1724 " 6) type_name\n" 1706 " 6) type_name\n"
1725 " 7) column_size\n" 1707 " 7) column_size\n"
1726 " 8) buffer_length\n" 1708 " 8) buffer_length\n"
1727 " 9) decimal_digits\n" 1709 " 9) decimal_digits\n"
1728 " 10) num_prec_radix\n" 1710 " 10) num_prec_radix\n"
1729 " 11) nullable\n" 1711 " 11) nullable\n"
1730 " 12) remarks\n" 1712 " 12) remarks\n"
1731 " 13) column_def\n" 1713 " 13) column_def\n"
1732 " 14) sql_data_type\n" 1714 " 14) sql_data_type\n"
1733 " 15) sql_datetime_sub\n" 1715 " 15) sql_datetime_sub\n"
1734 " 16) char_octet_length\n" 1716 " 16) char_octet_length\n"
1735 " 17) ordinal_position\n" 1717 " 17) ordinal_position\n"
1736 " 18) is_nullable"; 1718 " 18) is_nullable";
1737 1719
1738 char* Cursor_procedureColumns_kwnames[] = { "procedure", "catalog", "schema", 0 }; 1720 char* Cursor_procedureColumns_kwnames[] = { "procedure", "catalog", "schema", 0 };
1739 1721
1740 static PyObject* 1722 static PyObject* Cursor_procedureColumns(PyObject* self, PyObject* args, PyObject* kwargs)
1741 Cursor_procedureColumns(PyObject* self, PyObject* args, PyObject* kwargs)
1742 { 1723 {
1743 const char* szProcedure = 0; 1724 const char* szProcedure = 0;
1744 const char* szCatalog = 0; 1725 const char* szCatalog = 0;
1745 const char* szSchema = 0; 1726 const char* szSchema = 0;
1746 1727
1747 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sss", Cursor_procedureColumns_kwnames, &szProcedure, &szCatalog, &szSchema)) 1728 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sss", Cursor_procedureColumns_kwnames, &szProcedure, &szCatalog, &szSchema))
1748 return 0; 1729 return 0;
1749 1730
1750 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1731 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1751 1732
1752 if (!free_results(cur, FREE_STATEMENT)) 1733 if (!free_results(cur, FREE_STATEMENT))
1753 return 0; 1734 return 0;
1754 1735
1755 SQLRETURN ret = 0; 1736 SQLRETURN ret = 0;
1756 1737
1757 Py_BEGIN_ALLOW_THREADS 1738 Py_BEGIN_ALLOW_THREADS
1758 ret = SQLProcedureColumns(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, 1739 ret = SQLProcedureColumns(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS,
1759 (SQLCHAR*)szProcedure, SQL_NTS, 0, 0); 1740 (SQLCHAR*)szProcedure, SQL_NTS, 0, 0);
1760 Py_END_ALLOW_THREADS 1741 Py_END_ALLOW_THREADS
1761 1742
1762 if (!SQL_SUCCEEDED(ret)) 1743 if (!SQL_SUCCEEDED(ret))
1763 return RaiseErrorFromHandle("SQLProcedureColumns", cur->cnxn->hdbc, cur->hstmt); 1744 return RaiseErrorFromHandle("SQLProcedureColumns", cur->cnxn->hdbc, cur->hstmt);
1764 1745
1765 SQLSMALLINT cCols; 1746 SQLSMALLINT cCols;
1766 Py_BEGIN_ALLOW_THREADS 1747 Py_BEGIN_ALLOW_THREADS
1767 ret = SQLNumResultCols(cur->hstmt, &cCols); 1748 ret = SQLNumResultCols(cur->hstmt, &cCols);
1768 Py_END_ALLOW_THREADS 1749 Py_END_ALLOW_THREADS
1769 if (!SQL_SUCCEEDED(ret)) 1750 if (!SQL_SUCCEEDED(ret))
1770 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1751 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1771 1752
1772 if (!PrepareResults(cur, cCols)) 1753 if (!PrepareResults(cur, cCols))
1773 return 0; 1754 return 0;
1774 1755
1775 if (!create_name_map(cur, cCols, true)) 1756 if (!create_name_map(cur, cCols, true))
1776 return 0; 1757 return 0;
1777 1758
1778 // Return the cursor so the results can be iterated over directly. 1759 // Return the cursor so the results can be iterated over directly.
1779 Py_INCREF(cur); 1760 Py_INCREF(cur);
1780 return (PyObject*)cur; 1761 return (PyObject*)cur;
1781 } 1762 }
1782 1763
1783 1764
1784 static char procedures_doc[] = 1765 static char procedures_doc[] =
1785 "C.procedures(procedure=None, catalog=None, schema=None) --> self\n\n" 1766 "C.procedures(procedure=None, catalog=None, schema=None) --> self\n\n"
1786 "Executes SQLProcedures and creates a result set of information about the\n" 1767 "Executes SQLProcedures and creates a result set of information about the\n"
1787 "procedures in the data source.\n" 1768 "procedures in the data source.\n"
1788 "Each row fetched has the following columns:\n" 1769 "Each row fetched has the following columns:\n"
1789 " 0) procedure_cat\n" 1770 " 0) procedure_cat\n"
1790 " 1) procedure_schem\n" 1771 " 1) procedure_schem\n"
1791 " 2) procedure_name\n" 1772 " 2) procedure_name\n"
1792 " 3) num_input_params\n" 1773 " 3) num_input_params\n"
1793 " 4) num_output_params\n" 1774 " 4) num_output_params\n"
1794 " 5) num_result_sets\n" 1775 " 5) num_result_sets\n"
1795 " 6) remarks\n" 1776 " 6) remarks\n"
1796 " 7) procedure_type"; 1777 " 7) procedure_type";
1797 1778
1798 char* Cursor_procedures_kwnames[] = { "procedure", "catalog", "schema", 0 }; 1779 char* Cursor_procedures_kwnames[] = { "procedure", "catalog", "schema", 0 };
1799 1780
1800 static PyObject* 1781 static PyObject* Cursor_procedures(PyObject* self, PyObject* args, PyObject* kwargs)
1801 Cursor_procedures(PyObject* self, PyObject* args, PyObject* kwargs)
1802 { 1782 {
1803 const char* szProcedure = 0; 1783 const char* szProcedure = 0;
1804 const char* szCatalog = 0; 1784 const char* szCatalog = 0;
1805 const char* szSchema = 0; 1785 const char* szSchema = 0;
1806 1786
1807 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sss", Cursor_procedures_kwnames, &szProcedure, &szCatalog, &szSchema)) 1787 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sss", Cursor_procedures_kwnames, &szProcedure, &szCatalog, &szSchema))
1808 return 0; 1788 return 0;
1809 1789
1810 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN); 1790 Cursor* cur = Cursor_Validate(self, CURSOR_REQUIRE_OPEN);
1811 1791
1812 if (!free_results(cur, FREE_STATEMENT)) 1792 if (!free_results(cur, FREE_STATEMENT))
1813 return 0; 1793 return 0;
1814 1794
1815 SQLRETURN ret = 0; 1795 SQLRETURN ret = 0;
1816 1796
1817 Py_BEGIN_ALLOW_THREADS 1797 Py_BEGIN_ALLOW_THREADS
1818 ret = SQLProcedures(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szProcedure, SQL_NTS); 1798 ret = SQLProcedures(cur->hstmt, (SQLCHAR*)szCatalog, SQL_NTS, (SQLCHAR*)szSchema, SQL_NTS, (SQLCHAR*)szProcedure, SQL_NTS);
1819 Py_END_ALLOW_THREADS 1799 Py_END_ALLOW_THREADS
1820 1800
1821 if (!SQL_SUCCEEDED(ret)) 1801 if (!SQL_SUCCEEDED(ret))
1822 return RaiseErrorFromHandle("SQLProcedures", cur->cnxn->hdbc, cur->hstmt); 1802 return RaiseErrorFromHandle("SQLProcedures", cur->cnxn->hdbc, cur->hstmt);
1823 1803
1824 SQLSMALLINT cCols; 1804 SQLSMALLINT cCols;
1825 Py_BEGIN_ALLOW_THREADS 1805 Py_BEGIN_ALLOW_THREADS
1826 ret = SQLNumResultCols(cur->hstmt, &cCols); 1806 ret = SQLNumResultCols(cur->hstmt, &cCols);
1827 Py_END_ALLOW_THREADS 1807 Py_END_ALLOW_THREADS
1828 if (!SQL_SUCCEEDED(ret)) 1808 if (!SQL_SUCCEEDED(ret))
1829 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt); 1809 return RaiseErrorFromHandle("SQLNumResultCols", cur->cnxn->hdbc, cur->hstmt);
1830 1810
1831 if (!PrepareResults(cur, cCols)) 1811 if (!PrepareResults(cur, cCols))
1832 return 0; 1812 return 0;
1833 1813
1834 if (!create_name_map(cur, cCols, true)) 1814 if (!create_name_map(cur, cCols, true))
1835 return 0; 1815 return 0;
1836 1816
1837 // Return the cursor so the results can be iterated over directly. 1817 // Return the cursor so the results can be iterated over directly.
1838 Py_INCREF(cur); 1818 Py_INCREF(cur);
1839 return (PyObject*)cur; 1819 return (PyObject*)cur;
1840 } 1820 }
1841 1821
1842 static char skip_doc[] = 1822 static char skip_doc[] =
1843 "skip(count) --> None\n" \ 1823 "skip(count) --> None\n" \
1844 "\n" \ 1824 "\n" \
1845 "Skips the next `count` records by calling SQLFetchScroll with SQL_FETCH_NEXT.\n" 1825 "Skips the next `count` records by calling SQLFetchScroll with SQL_FETCH_NEXT.\n"
1846 "For convenience, skip(0) is accepted and will do nothing."; 1826 "For convenience, skip(0) is accepted and will do nothing.";
1847 1827
1848 static PyObject* Cursor_skip(PyObject* self, PyObject* args) 1828 static PyObject* Cursor_skip(PyObject* self, PyObject* args)
1849 { 1829 {
1850 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR); 1830 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_RESULTS | CURSOR_RAISE_ERROR);
1851 if (!cursor) 1831 if (!cursor)
1852 return 0; 1832 return 0;
1853 1833
1854 int count; 1834 int count;
1855 if (!PyArg_ParseTuple(args, "i", &count)) 1835 if (!PyArg_ParseTuple(args, "i", &count))
1856 return 0; 1836 return 0;
1857 if (count == 0) 1837 if (count == 0)
1858 Py_RETURN_NONE; 1838 Py_RETURN_NONE;
1859 1839
1860 // Note: I'm not sure about the performance implications of looping here -- I certainly would rather use 1840 // Note: I'm not sure about the performance implications of looping here -- I certainly would rather use
1861 // SQLFetchScroll(SQL_FETCH_RELATIVE, count), but it requires scrollable cursors which are often slower. I would 1841 // SQLFetchScroll(SQL_FETCH_RELATIVE, count), but it requires scrollable cursors which are often slower. I would
1862 // not expect skip to be used in performance intensive code since different SQL would probably be the "right" 1842 // not expect skip to be used in performance intensive code since different SQL would probably be the "right"
1863 // answer instead of skip anyway. 1843 // answer instead of skip anyway.
1864 1844
1865 SQLRETURN ret = SQL_SUCCESS; 1845 SQLRETURN ret = SQL_SUCCESS;
1866 Py_BEGIN_ALLOW_THREADS 1846 Py_BEGIN_ALLOW_THREADS
1867 for (int i = 0; i < count && SQL_SUCCEEDED(ret); i++) 1847 for (int i = 0; i < count && SQL_SUCCEEDED(ret); i++)
1868 ret = SQLFetchScroll(cursor->hstmt, SQL_FETCH_NEXT, 0); 1848 ret = SQLFetchScroll(cursor->hstmt, SQL_FETCH_NEXT, 0);
1869 Py_END_ALLOW_THREADS 1849 Py_END_ALLOW_THREADS
1870 1850
1871 if (!SQL_SUCCEEDED(ret) && ret != SQL_NO_DATA) 1851 if (!SQL_SUCCEEDED(ret) && ret != SQL_NO_DATA)
1872 return RaiseErrorFromHandle("SQLFetchScroll", cursor->cnxn->hdbc, cursor->hstmt); 1852 return RaiseErrorFromHandle("SQLFetchScroll", cursor->cnxn->hdbc, cursor->hstmt);
1873 1853
1874 Py_RETURN_NONE; 1854 Py_RETURN_NONE;
1875 } 1855 }
1876 1856
1877 static PyObject* 1857
1878 Cursor_ignored(PyObject* self, PyObject* args) 1858 static PyObject* Cursor_ignored(PyObject* self, PyObject* args)
1879 { 1859 {
1880 UNUSED(self, args); 1860 UNUSED(self, args);
1881 Py_RETURN_NONE; 1861 Py_RETURN_NONE;
1882 } 1862 }
1863
1883 1864
1884 static char rowcount_doc[] = 1865 static char rowcount_doc[] =
1885 "This read-only attribute specifies the number of rows the last DML statement\n" 1866 "This read-only attribute specifies the number of rows the last DML statement\n"
1886 " (INSERT, UPDATE, DELETE) affected. This is set to -1 for SELECT statements."; 1867 " (INSERT, UPDATE, DELETE) affected. This is set to -1 for SELECT statements.";
1887 1868
1888 static char description_doc[] = 1869 static char description_doc[] =
1889 "This read-only attribute is a sequence of 7-item sequences. Each of these\n" \ 1870 "This read-only attribute is a sequence of 7-item sequences. Each of these\n" \
1890 "sequences contains information describing one result column: (name, type_code,\n" \ 1871 "sequences contains information describing one result column: (name, type_code,\n" \
1891 "display_size, internal_size, precision, scale, null_ok). All values except\n" \ 1872 "display_size, internal_size, precision, scale, null_ok). All values except\n" \
1892 "name, type_code, and internal_size are None. The type_code entry will be the\n" \ 1873 "name, type_code, and internal_size are None. The type_code entry will be the\n" \
1893 "type object used to create values for that column (e.g. `str` or\n" \ 1874 "type object used to create values for that column (e.g. `str` or\n" \
1894 "`datetime.datetime`).\n" \ 1875 "`datetime.datetime`).\n" \
1895 "\n" \ 1876 "\n" \
1896 "This attribute will be None for operations that do not return rows or if the\n" \ 1877 "This attribute will be None for operations that do not return rows or if the\n" \
1897 "cursor has not had an operation invoked via the execute() method yet.\n" \ 1878 "cursor has not had an operation invoked via the execute() method yet.\n" \
1898 "\n" \ 1879 "\n" \
1899 "The type_code can be interpreted by comparing it to the Type Objects defined in\n" \ 1880 "The type_code can be interpreted by comparing it to the Type Objects defined in\n" \
1900 "the DB API and defined the pyodbc module: Date, Time, Timestamp, Binary,\n" \ 1881 "the DB API and defined the pyodbc module: Date, Time, Timestamp, Binary,\n" \
1901 "STRING, BINARY, NUMBER, and DATETIME."; 1882 "STRING, BINARY, NUMBER, and DATETIME.";
1902 1883
1903 static char arraysize_doc[] = 1884 static char arraysize_doc[] =
1904 "This read/write attribute specifies the number of rows to fetch at a time with\n" \ 1885 "This read/write attribute specifies the number of rows to fetch at a time with\n" \
1905 "fetchmany(). It defaults to 1 meaning to fetch a single row at a time."; 1886 "fetchmany(). It defaults to 1 meaning to fetch a single row at a time.";
1906 1887
1907 static char connection_doc[] = 1888 static char connection_doc[] =
1908 "This read-only attribute return a reference to the Connection object on which\n" \ 1889 "This read-only attribute return a reference to the Connection object on which\n" \
1909 "the cursor was created.\n" \ 1890 "the cursor was created.\n" \
1910 "\n" \ 1891 "\n" \
1911 "The attribute simplifies writing polymorph code in multi-connection\n" \ 1892 "The attribute simplifies writing polymorph code in multi-connection\n" \
1912 "environments."; 1893 "environments.";
1913 1894
1914 static PyMemberDef Cursor_members[] = 1895 static PyMemberDef Cursor_members[] =
1915 { 1896 {
1916 {"rowcount", T_INT, offsetof(Cursor, rowcount), READONLY, rowcount_doc }, 1897 {"rowcount", T_INT, offsetof(Cursor, rowcount), READONLY, rowcount_doc },
1917 {"description", T_OBJECT_EX, offsetof(Cursor, description), READONLY, description_doc }, 1898 {"description", T_OBJECT_EX, offsetof(Cursor, description), READONLY, description_doc },
1918 {"arraysize", T_INT, offsetof(Cursor, arraysize), 0, arraysize_doc }, 1899 {"arraysize", T_INT, offsetof(Cursor, arraysize), 0, arraysize_doc },
1919 {"connection", T_OBJECT_EX, offsetof(Cursor, cnxn), READONLY, connection_doc }, 1900 {"connection", T_OBJECT_EX, offsetof(Cursor, cnxn), READONLY, connection_doc },
1920 { 0 } 1901 { 0 }
1921 }; 1902 };
1922 1903
1923 static PyObject* Cursor_getnoscan(PyObject* self, void *closure) 1904 static PyObject* Cursor_getnoscan(PyObject* self, void *closure)
1924 { 1905 {
1925 UNUSED(closure); 1906 UNUSED(closure);
1926 1907
1927 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR); 1908 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR);
1928 if (!cursor) 1909 if (!cursor)
1929 return 0; 1910 return 0;
1930 1911
1931 SQLUINTEGER noscan = SQL_NOSCAN_OFF; 1912 SQLUINTEGER noscan = SQL_NOSCAN_OFF;
1932 SQLRETURN ret; 1913 SQLRETURN ret;
1933 Py_BEGIN_ALLOW_THREADS 1914 Py_BEGIN_ALLOW_THREADS
1934 ret = SQLGetStmtAttr(cursor->hstmt, SQL_ATTR_NOSCAN, (SQLPOINTER)&noscan, sizeof(SQLUINTEGER), 0); 1915 ret = SQLGetStmtAttr(cursor->hstmt, SQL_ATTR_NOSCAN, (SQLPOINTER)&noscan, sizeof(SQLUINTEGER), 0);
1935 Py_END_ALLOW_THREADS 1916 Py_END_ALLOW_THREADS
1936 1917
1937 if (!SQL_SUCCEEDED(ret)) 1918 if (!SQL_SUCCEEDED(ret))
1938 { 1919 {
1939 // Not supported? We're going to assume 'no'. 1920 // Not supported? We're going to assume 'no'.
1940 Py_RETURN_FALSE; 1921 Py_RETURN_FALSE;
1941 } 1922 }
1942 1923
1943 if (noscan == SQL_NOSCAN_OFF) 1924 if (noscan == SQL_NOSCAN_OFF)
1944 Py_RETURN_FALSE; 1925 Py_RETURN_FALSE;
1945 1926
1946 Py_RETURN_TRUE; 1927 Py_RETURN_TRUE;
1947 } 1928 }
1948 1929
1949 static PyObject* Cursor_setnoscan(PyObject* self, PyObject* value, void *closure) 1930 static int Cursor_setnoscan(PyObject* self, PyObject* value, void *closure)
1950 { 1931 {
1951 UNUSED(closure); 1932 UNUSED(closure);
1952 1933
1953 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR); 1934 Cursor* cursor = Cursor_Validate(self, CURSOR_REQUIRE_OPEN | CURSOR_RAISE_ERROR);
1954 if (!cursor) 1935 if (!cursor)
1955 return 0; 1936 return -1;
1956 1937
1957 if (value == 0) 1938 if (value == 0)
1958 { 1939 {
1959 PyErr_SetString(PyExc_TypeError, "Cannot delete the noscan attribute"); 1940 PyErr_SetString(PyExc_TypeError, "Cannot delete the noscan attribute");
1960 return 0; 1941 return -1;
1961 } 1942 }
1962 1943
1963 uintptr_t noscan = PyObject_IsTrue(value) ? SQL_NOSCAN_ON : SQL_NOSCAN_OFF; 1944 uintptr_t noscan = PyObject_IsTrue(value) ? SQL_NOSCAN_ON : SQL_NOSCAN_OFF;
1964 SQLRETURN ret; 1945 SQLRETURN ret;
1965 Py_BEGIN_ALLOW_THREADS 1946 Py_BEGIN_ALLOW_THREADS
1966 ret = SQLSetStmtAttr(cursor->hstmt, SQL_ATTR_NOSCAN, (SQLPOINTER)noscan, 0); 1947 ret = SQLSetStmtAttr(cursor->hstmt, SQL_ATTR_NOSCAN, (SQLPOINTER)noscan, 0);
1967 Py_END_ALLOW_THREADS 1948 Py_END_ALLOW_THREADS
1968 if (!SQL_SUCCEEDED(ret)) 1949 if (!SQL_SUCCEEDED(ret))
1969 { 1950 {
1970 return RaiseErrorFromHandle("SQLSetStmtAttr(SQL_ATTR_NOSCAN)", cursor->cnxn->hdbc, cursor->hstmt); 1951 RaiseErrorFromHandle("SQLSetStmtAttr(SQL_ATTR_NOSCAN)", cursor->cnxn->hdbc, cursor->hstmt);
1952 return -1;
1971 } 1953 }
1972 1954
1973 return 0; 1955 return 0;
1974 } 1956 }
1975 1957
1976 static PyGetSetDef Cursor_getsetters[] = 1958 static PyGetSetDef Cursor_getsetters[] =
1977 { 1959 {
1978 {"noscan", (getter)Cursor_getnoscan, (setter)Cursor_setnoscan, "NOSCAN statement attr", 0}, 1960 {"noscan", Cursor_getnoscan, Cursor_setnoscan, "NOSCAN statement attr", 0},
1979 { 0 } 1961 { 0 }
1980 }; 1962 };
1981 1963
1982 static char executemany_doc[] = 1964 static char executemany_doc[] =
1983 "executemany(sql, seq_of_params) --> Cursor | count | None\n" \ 1965 "executemany(sql, seq_of_params) --> Cursor | count | None\n" \
1984 "\n" \ 1966 "\n" \
1985 "Prepare a database query or command and then execute it against all parameter\n" \ 1967 "Prepare a database query or command and then execute it against all parameter\n" \
1986 "sequences found in the sequence seq_of_params.\n" \ 1968 "sequences found in the sequence seq_of_params.\n" \
1987 "\n" \ 1969 "\n" \
1988 "Only the result of the final execution is returned. See `execute` for a\n" \ 1970 "Only the result of the final execution is returned. See `execute` for a\n" \
1989 "description of parameter passing the return value."; 1971 "description of parameter passing the return value.";
1990 1972
1991 static char nextset_doc[] = "nextset() --> True | None\n" \ 1973 static char nextset_doc[] = "nextset() --> True | None\n" \
1992 "\n" \ 1974 "\n" \
1993 "Jumps to the next resultset if the last sql has multiple resultset." \ 1975 "Jumps to the next resultset if the last sql has multiple resultset." \
1994 "Returns True if there is a next resultset otherwise None."; 1976 "Returns True if there is a next resultset otherwise None.";
1995 1977
1996 static char ignored_doc[] = "Ignored."; 1978 static char ignored_doc[] = "Ignored.";
1997 1979
1998 static char fetchone_doc[] = 1980 static char fetchone_doc[] =
1999 "fetchone() --> Row | None\n" \ 1981 "fetchone() --> Row | None\n" \
2000 "\n" \ 1982 "\n" \
2001 "Fetch the next row of a query result set, returning a single Row instance, or\n" \ 1983 "Fetch the next row of a query result set, returning a single Row instance, or\n" \
2002 "None when no more data is available.\n" \ 1984 "None when no more data is available.\n" \
2003 "\n" \ 1985 "\n" \
2004 "A ProgrammingError exception is raised if the previous call to execute() did\n" \ 1986 "A ProgrammingError exception is raised if the previous call to execute() did\n" \
2005 "not produce any result set or no call was issued yet."; 1987 "not produce any result set or no call was issued yet.";
2006 1988
2007 static char fetchall_doc[] = 1989 static char fetchall_doc[] =
2008 "fetchmany(size=cursor.arraysize) --> list of Rows\n" \ 1990 "fetchmany(size=cursor.arraysize) --> list of Rows\n" \
2009 "\n" \ 1991 "\n" \
2010 "Fetch the next set of rows of a query result, returning a list of Row\n" \ 1992 "Fetch the next set of rows of a query result, returning a list of Row\n" \
2011 "instances. An empty list is returned when no more rows are available.\n" \ 1993 "instances. An empty list is returned when no more rows are available.\n" \
2012 "\n" \ 1994 "\n" \
2013 "The number of rows to fetch per call is specified by the parameter. If it is\n" \ 1995 "The number of rows to fetch per call is specified by the parameter. If it is\n" \
2014 "not given, the cursor's arraysize determines the number of rows to be\n" \ 1996 "not given, the cursor's arraysize determines the number of rows to be\n" \
2015 "fetched. The method should try to fetch as many rows as indicated by the size\n" \ 1997 "fetched. The method should try to fetch as many rows as indicated by the size\n" \
2016 "parameter. If this is not possible due to the specified number of rows not\n" \ 1998 "parameter. If this is not possible due to the specified number of rows not\n" \
2017 "being available, fewer rows may be returned.\n" \ 1999 "being available, fewer rows may be returned.\n" \
2018 "\n" \ 2000 "\n" \
2019 "A ProgrammingError exception is raised if the previous call to execute() did\n" \ 2001 "A ProgrammingError exception is raised if the previous call to execute() did\n" \
2020 "not produce any result set or no call was issued yet."; 2002 "not produce any result set or no call was issued yet.";
2021 2003
2022 static char fetchmany_doc[] = 2004 static char fetchmany_doc[] =
2023 "fetchmany() --> list of Rows\n" \ 2005 "fetchmany() --> list of Rows\n" \
2024 "\n" \ 2006 "\n" \
2025 "Fetch all remaining rows of a query result, returning them as a list of Rows.\n" \ 2007 "Fetch all remaining rows of a query result, returning them as a list of Rows.\n" \
2026 "An empty list is returned if there are no more rows.\n" \ 2008 "An empty list is returned if there are no more rows.\n" \
2027 "\n" \ 2009 "\n" \
2028 "A ProgrammingError exception is raised if the previous call to execute() did\n" \ 2010 "A ProgrammingError exception is raised if the previous call to execute() did\n" \
2029 "not produce any result set or no call was issued yet."; 2011 "not produce any result set or no call was issued yet.";
2030 2012
2031 static PyMethodDef Cursor_methods[] = 2013 static PyMethodDef Cursor_methods[] =
2032 { 2014 {
2033 { "close", (PyCFunction)Cursor_close, METH_NOARGS, close_doc }, 2015 { "close", (PyCFunction)Cursor_close, METH_NOARGS, close_doc },
2034 { "execute", (PyCFunction)Cursor_execute, METH_VARARGS, execute_doc }, 2016 { "execute", (PyCFunction)Cursor_execute, METH_VARARGS, execute_doc },
2035 { "executemany", (PyCFunction)Cursor_executemany, METH_VARARGS, executemany_doc }, 2017 { "executemany", (PyCFunction)Cursor_executemany, METH_VARARGS, executemany_doc },
2036 { "setinputsizes", (PyCFunction)Cursor_ignored, METH_VARARGS, ignored_doc }, 2018 { "setinputsizes", (PyCFunction)Cursor_ignored, METH_VARARGS, ignored_doc },
2037 { "setoutputsize", (PyCFunction)Cursor_ignored, METH_VARARGS, ignored_doc }, 2019 { "setoutputsize", (PyCFunction)Cursor_ignored, METH_VARARGS, ignored_doc },
2038 { "fetchone", (PyCFunction)Cursor_fetchone, METH_NOARGS, fetchone_doc }, 2020 { "fetchone", (PyCFunction)Cursor_fetchone, METH_NOARGS, fetchone_doc },
2039 { "fetchall", (PyCFunction)Cursor_fetchall, METH_NOARGS, fetchall_doc }, 2021 { "fetchall", (PyCFunction)Cursor_fetchall, METH_NOARGS, fetchall_doc },
2040 { "fetchmany", (PyCFunction)Cursor_fetchmany, METH_VARARGS, fetchmany_doc }, 2022 { "fetchmany", (PyCFunction)Cursor_fetchmany, METH_VARARGS, fetchmany_doc },
2041 { "nextset", (PyCFunction)Cursor_nextset, METH_NOARGS, nextset_doc }, 2023 { "nextset", (PyCFunction)Cursor_nextset, METH_NOARGS, nextset_doc },
2042 { "tables", (PyCFunction)Cursor_tables, METH_VARARGS|METH_KEYWORDS, tables_doc }, 2024 { "tables", (PyCFunction)Cursor_tables, METH_VARARGS|METH_KEYWORDS, tables_doc },
2043 { "columns", (PyCFunction)Cursor_columns, METH_VARARGS|METH_KEYWORDS, columns_doc }, 2025 { "columns", (PyCFunction)Cursor_columns, METH_VARARGS|METH_KEYWORDS, columns_doc },
2044 { "statistics", (PyCFunction)Cursor_statistics, METH_VARARGS|METH_KEYWORDS, statistics_doc }, 2026 { "statistics", (PyCFunction)Cursor_statistics, METH_VARARGS|METH_KEYWORDS, statistics_doc },
2045 { "rowIdColumns", (PyCFunction)Cursor_rowIdColumns, METH_VARARGS|METH_KEYWORDS, rowIdColumns_doc }, 2027 { "rowIdColumns", (PyCFunction)Cursor_rowIdColumns, METH_VARARGS|METH_KEYWORDS, rowIdColumns_doc },
2046 { "rowVerColumns", (PyCFunction)Cursor_rowVerColumns, METH_VARARGS|METH_KEYWORDS, rowVerColumns_doc }, 2028 { "rowVerColumns", (PyCFunction)Cursor_rowVerColumns, METH_VARARGS|METH_KEYWORDS, rowVerColumns_doc },
2047 { "primaryKeys", (PyCFunction)Cursor_primaryKeys, METH_VARARGS|METH_KEYWORDS, primaryKeys_doc }, 2029 { "primaryKeys", (PyCFunction)Cursor_primaryKeys, METH_VARARGS|METH_KEYWORDS, primaryKeys_doc },
2048 { "foreignKeys", (PyCFunction)Cursor_foreignKeys, METH_VARARGS|METH_KEYWORDS, foreignKeys_doc }, 2030 { "foreignKeys", (PyCFunction)Cursor_foreignKeys, METH_VARARGS|METH_KEYWORDS, foreignKeys_doc },
2049 { "getTypeInfo", (PyCFunction)Cursor_getTypeInfo, METH_VARARGS|METH_KEYWORDS, getTypeInfo_doc }, 2031 { "getTypeInfo", (PyCFunction)Cursor_getTypeInfo, METH_VARARGS|METH_KEYWORDS, getTypeInfo_doc },
2050 { "procedures", (PyCFunction)Cursor_procedures, METH_VARARGS|METH_KEYWORDS, procedures_doc }, 2032 { "procedures", (PyCFunction)Cursor_procedures, METH_VARARGS|METH_KEYWORDS, procedures_doc },
2051 { "procedureColumns", (PyCFunction)Cursor_procedureColumns, METH_VARARGS|METH_KEYWORDS, procedureColumns_doc }, 2033 { "procedureColumns", (PyCFunction)Cursor_procedureColumns, METH_VARARGS|METH_KEYWORDS, procedureColumns_doc },
2052 { "skip", (PyCFunction)Cursor_skip, METH_VARARGS, skip_doc }, 2034 { "skip", (PyCFunction)Cursor_skip, METH_VARARGS, skip_doc },
2053 { 0, 0, 0, 0 } 2035 { 0, 0, 0, 0 }
2054 }; 2036 };
2055 2037
2056 static char cursor_doc[] = 2038 static char cursor_doc[] =
2057 "Cursor objects represent a database cursor, which is used to manage the context\n" \ 2039 "Cursor objects represent a database cursor, which is used to manage the context\n" \
2058 "of a fetch operation. Cursors created from the same connection are not\n" \ 2040 "of a fetch operation. Cursors created from the same connection are not\n" \
2059 "isolated, i.e., any changes done to the database by a cursor are immediately\n" \ 2041 "isolated, i.e., any changes done to the database by a cursor are immediately\n" \
2060 "visible by the other cursors. Cursors created from different connections are\n" \ 2042 "visible by the other cursors. Cursors created from different connections are\n" \
2061 "isolated.\n" \ 2043 "isolated.\n" \
2062 "\n" \ 2044 "\n" \
2063 "Cursors implement the iterator protocol, so results can be iterated:\n" \ 2045 "Cursors implement the iterator protocol, so results can be iterated:\n" \
2064 "\n" \ 2046 "\n" \
2065 " cursor.execute(sql)\n" \ 2047 " cursor.execute(sql)\n" \
2066 " for row in cursor:\n" \ 2048 " for row in cursor:\n" \
2067 " print row[0]"; 2049 " print row[0]";
2068 2050
2069 PyTypeObject CursorType = 2051 PyTypeObject CursorType =
2070 { 2052 {
2071 PyVarObject_HEAD_INIT(0, 0) 2053 PyVarObject_HEAD_INIT(0, 0)
2072 "pyodbc.Cursor", // tp_name 2054 "pyodbc.Cursor", // tp_name
2073 sizeof(Cursor), // tp_basicsize 2055 sizeof(Cursor), // tp_basicsize
2074 0, // tp_itemsize 2056 0, // tp_itemsize
2075 (destructor)Cursor_dealloc, // destructor tp_dealloc 2057 (destructor)Cursor_dealloc, // destructor tp_dealloc
2076 0, // tp_print 2058 0, // tp_print
2077 0, // tp_getattr 2059 0, // tp_getattr
2078 0, // tp_setattr 2060 0, // tp_setattr
2079 0, // tp_compare 2061 0, // tp_compare
2080 0, // tp_repr 2062 0, // tp_repr
2081 0, // tp_as_number 2063 0, // tp_as_number
2082 0, // tp_as_sequence 2064 0, // tp_as_sequence
2083 0, // tp_as_mapping 2065 0, // tp_as_mapping
2084 0, // tp_hash 2066 0, // tp_hash
2085 0, // tp_call 2067 0, // tp_call
2086 0, // tp_str 2068 0, // tp_str
2087 0, // tp_getattro 2069 0, // tp_getattro
2088 0, // tp_setattro 2070 0, // tp_setattro
2089 0, // tp_as_buffer 2071 0, // tp_as_buffer
2090 #if defined(Py_TPFLAGS_HAVE_ITER) 2072 #if defined(Py_TPFLAGS_HAVE_ITER)
2091 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, 2073 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
2092 #else 2074 #else
2093 Py_TPFLAGS_DEFAULT, 2075 Py_TPFLAGS_DEFAULT,
2094 #endif 2076 #endif
2095 cursor_doc, // tp_doc 2077 cursor_doc, // tp_doc
2096 0, // tp_traverse 2078 0, // tp_traverse
2097 0, // tp_clear 2079 0, // tp_clear
2098 0, // tp_richcompare 2080 0, // tp_richcompare
2099 0, // tp_weaklistoffset 2081 0, // tp_weaklistoffset
2100 (getiterfunc)Cursor_iter, // tp_iter 2082 Cursor_iter, // tp_iter
2101 (iternextfunc)Cursor_iternext, // tp_iternext 2083 Cursor_iternext, // tp_iternext
2102 Cursor_methods, // tp_methods 2084 Cursor_methods, // tp_methods
2103 Cursor_members, // tp_members 2085 Cursor_members, // tp_members
2104 Cursor_getsetters, // tp_getset 2086 Cursor_getsetters, // tp_getset
2105 0, // tp_base 2087 0, // tp_base
2106 0, // tp_dict 2088 0, // tp_dict
2107 0, // tp_descr_get 2089 0, // tp_descr_get
2108 0, // tp_descr_set 2090 0, // tp_descr_set
2109 0, // tp_dictoffset 2091 0, // tp_dictoffset
2110 0, // tp_init 2092 0, // tp_init
2111 0, // tp_alloc 2093 0, // tp_alloc
2112 0, // tp_new 2094 0, // tp_new
2113 0, // tp_free 2095 0, // tp_free
2114 0, // tp_is_gc 2096 0, // tp_is_gc
2115 0, // tp_bases 2097 0, // tp_bases
2116 0, // tp_mro 2098 0, // tp_mro
2117 0, // tp_cache 2099 0, // tp_cache
2118 0, // tp_subclasses 2100 0, // tp_subclasses
2119 0, // tp_weaklist 2101 0, // tp_weaklist
2120 }; 2102 };
2121 2103
2122 Cursor* 2104 Cursor*
2123 Cursor_New(Connection* cnxn) 2105 Cursor_New(Connection* cnxn)
2124 { 2106 {
2125 // Exported to allow the connection class to create cursors. 2107 // Exported to allow the connection class to create cursors.
2126 2108
2127 #ifdef _MSC_VER 2109 #ifdef _MSC_VER
2128 #pragma warning(disable : 4365) 2110 #pragma warning(disable : 4365)
2129 #endif 2111 #endif
2130 Cursor* cur = PyObject_NEW(Cursor, &CursorType); 2112 Cursor* cur = PyObject_NEW(Cursor, &CursorType);
2131 #ifdef _MSC_VER 2113 #ifdef _MSC_VER
2132 #pragma warning(default : 4365) 2114 #pragma warning(default : 4365)
2133 #endif 2115 #endif
2134 2116
2135 if (cur) 2117 if (cur)
2136 { 2118 {
2137 cur->cnxn = cnxn; 2119 cur->cnxn = cnxn;
2138 cur->hstmt = SQL_NULL_HANDLE; 2120 cur->hstmt = SQL_NULL_HANDLE;
2139 cur->description = Py_None; 2121 cur->description = Py_None;
2140 cur->pPreparedSQL = 0; 2122 cur->pPreparedSQL = 0;
2141 cur->paramcount = 0; 2123 cur->paramcount = 0;
2142 cur->paramtypes = 0; 2124 cur->paramtypes = 0;
2143 cur->paramInfos = 0; 2125 cur->paramInfos = 0;
2144 cur->colinfos = 0; 2126 cur->colinfos = 0;
2145 cur->arraysize = 1; 2127 cur->arraysize = 1;
2146 cur->rowcount = -1; 2128 cur->rowcount = -1;
2147 cur->map_name_to_index = 0; 2129 cur->map_name_to_index = 0;
2148 2130
2149 Py_INCREF(cnxn); 2131 Py_INCREF(cnxn);
2150 Py_INCREF(cur->description); 2132 Py_INCREF(cur->description);
2151 2133
2152 SQLRETURN ret; 2134 SQLRETURN ret;
2153 Py_BEGIN_ALLOW_THREADS 2135 Py_BEGIN_ALLOW_THREADS
2154 ret = SQLAllocHandle(SQL_HANDLE_STMT, cnxn->hdbc, &cur->hstmt); 2136 ret = SQLAllocHandle(SQL_HANDLE_STMT, cnxn->hdbc, &cur->hstmt);
2155 Py_END_ALLOW_THREADS 2137 Py_END_ALLOW_THREADS
2156 2138
2157 if (!SQL_SUCCEEDED(ret)) 2139 if (!SQL_SUCCEEDED(ret))
2158 { 2140 {
2159 RaiseErrorFromHandle("SQLAllocHandle", cnxn->hdbc, SQL_NULL_HANDLE); 2141 RaiseErrorFromHandle("SQLAllocHandle", cnxn->hdbc, SQL_NULL_HANDLE);
2160 Py_DECREF(cur); 2142 Py_DECREF(cur);
2161 return 0; 2143 return 0;
2162 } 2144 }
2163 2145
2164 if (cnxn->timeout) 2146 if (cnxn->timeout)
2165 { 2147 {
2166 Py_BEGIN_ALLOW_THREADS 2148 Py_BEGIN_ALLOW_THREADS
2167 ret = SQLSetStmtAttr(cur->hstmt, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER)cnxn->timeout, 0); 2149 ret = SQLSetStmtAttr(cur->hstmt, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER)cnxn->timeout, 0);
2168 Py_END_ALLOW_THREADS 2150 Py_END_ALLOW_THREADS
2169 2151
2170 if (!SQL_SUCCEEDED(ret)) 2152 if (!SQL_SUCCEEDED(ret))
2171 { 2153 {
2172 RaiseErrorFromHandle("SQLSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT)", cnxn->hdbc, cur->hstmt); 2154 RaiseErrorFromHandle("SQLSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT)", cnxn->hdbc, cur->hstmt);
2173 Py_DECREF(cur); 2155 Py_DECREF(cur);
2174 return 0; 2156 return 0;
2175 } 2157 }
2176 } 2158 }
2177 2159
2178 TRACE("cursor.new cnxn=%p hdbc=%d cursor=%p hstmt=%d\n", (Connection*)cur->cnxn, ((Connection*)cur->cnxn)->hdbc, cur, cur->hstmt); 2160 TRACE("cursor.new cnxn=%p hdbc=%d cursor=%p hstmt=%d\n", (Connection*)cur->cnxn, ((Connection*)cur->cnxn)->hdbc, cur, cur->hstmt);
2179 } 2161 }
2180 2162
2181 return cur; 2163 return cur;
2182 } 2164 }
2183 2165
2184 void Cursor_init() 2166 void Cursor_init()
2185 { 2167 {
2186 PyDateTime_IMPORT; 2168 PyDateTime_IMPORT;
2187 } 2169 }
2188 2170
Powered by Google Project Hosting