My favorites | Sign in
Project Home Downloads Wiki
READ-ONLY: This project has been archived. For more information see this post.
Search
for
  Advanced search   Search tips   Subscriptions

Issue 47 attachment: pyodbc_timeout.patch (4.0 KB)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
diff --git a/src/connection.cpp b/src/connection.cpp
index 668a03f..5068fc9 100644
--- a/src/connection.cpp
+++ b/src/connection.cpp
@@ -187,6 +187,7 @@ PyObject* Connection_New(PyObject* pConnectString, bool fAutoCommit, bool fAnsi,
cnxn->hdbc = hdbc;
cnxn->nAutoCommit = fAutoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
cnxn->searchescape = 0;
+ cnxn->timeout = 0;
cnxn->unicode_results = fUnicodeResults;

//
@@ -694,7 +695,58 @@ Connection_getsearchescape(Connection* self, void* closure)
Py_INCREF(self->searchescape);
return self->searchescape;
}
-
+
+
+static PyObject*
+Connection_gettimeout(PyObject* self, void* closure)
+{
+ UNUSED(closure);
+
+ Connection* cnxn = Connection_Validate(self);
+ if (!cnxn)
+ return 0;
+
+ return PyInt_FromLong(cnxn->timeout);
+}
+
+static int
+Connection_settimeout(PyObject* self, PyObject* value, void* closure)
+{
+ UNUSED(closure);
+
+ Connection* cnxn = Connection_Validate(self);
+ if (!cnxn)
+ return -1;
+
+ if (value == 0)
+ {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the timeout attribute.");
+ return -1;
+ }
+ int timeout = PyInt_AsLong(value);
+ if (timeout == -1 && PyErr_Occurred())
+ return -1;
+ if (timeout < 0)
+ {
+ PyErr_SetString(PyExc_ValueError, "Cannot set a negative timeout.");
+ return -1;
+ }
+
+ SQLRETURN ret;
+ Py_BEGIN_ALLOW_THREADS
+ ret = SQLSetConnectAttr(cnxn->hdbc, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER)timeout, SQL_IS_UINTEGER);
+ Py_END_ALLOW_THREADS
+ if (!SQL_SUCCEEDED(ret))
+ {
+ RaiseErrorFromHandle("SQLSetConnectAttr", cnxn->hdbc, SQL_NULL_HANDLE);
+ return -1;
+ }
+
+ cnxn->timeout = timeout;
+
+ return 0;
+}
+
static struct PyMethodDef Connection_methods[] =
{
{ "cursor", (PyCFunction)Connection_cursor, METH_NOARGS, cursor_doc },
@@ -712,6 +764,8 @@ static PyGetSetDef Connection_getseters[] = {
"SQLGetInfo(SQL_SEARCH_PATTERN_ESCAPE). These are driver specific.", 0 },
{ "autocommit", Connection_getautocommit, Connection_setautocommit,
"Returns True if the connection is in autocommit mode; False otherwise.", 0 },
+ { "timeout", Connection_gettimeout, Connection_settimeout,
+ "The timeout in seconds, zero means no timeout.", 0 },
{ 0 }
};

diff --git a/src/connection.h b/src/connection.h
index 18b0b1c..4a79a4b 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -42,6 +42,9 @@ struct Connection

// If true, then the strings in the rows are returned as unicode objects.
bool unicode_results;
+
+ // The connection timeout in seconds.
+ int timeout;
};

#define Connection_Check(op) PyObject_TypeCheck(op, &ConnectionType)
diff --git a/src/cursor.cpp b/src/cursor.cpp
index 45b3f20..3d21fb7 100644
--- a/src/cursor.cpp
+++ b/src/cursor.cpp
@@ -2108,6 +2108,19 @@ Cursor_New(Connection* cnxn)
return 0;
}

+ if (cnxn->timeout)
+ {
+ Py_BEGIN_ALLOW_THREADS
+ ret = SQLSetStmtAttr(cur->hstmt, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER)cnxn->timeout, 0);
+ Py_END_ALLOW_THREADS
+ if (!SQL_SUCCEEDED(ret))
+ {
+ RaiseErrorFromHandle("SQLSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT)", cnxn->hdbc, cur->hstmt);
+ Py_DECREF(cur);
+ return 0;
+ }
+ }
+
#ifdef TRACE_ALL
printf("cursor.new cnxn=%p hdbc=%d cursor=%p hstmt=%d\n", (Connection*)cur->cnxn, ((Connection*)cur->cnxn)->hdbc, cur, cur->hstmt);
#endif
diff --git a/src/errors.cpp b/src/errors.cpp
index fd3f6f8..6a780fd 100644
--- a/src/errors.cpp
+++ b/src/errors.cpp
@@ -22,6 +22,8 @@ static const struct SqlStateMapping sql_state_mapping[] =
{ "24", 2, &ProgrammingError },
{ "25", 2, &ProgrammingError },
{ "42", 2, &ProgrammingError },
+ { "HYT00", 5, &OperationalError },
+ { "HYT01", 5, &OperationalError },
};


Powered by Google Project Hosting