Mercurial > p > mysql-python > mysqldb-2
annotate MySQLdb/cursors.py @ 70:29b4cfd9af07 MySQLdb
show_warnings was renamed show_warnings (bug 2796727)
author | kylev |
---|---|
date | Fri, 24 Jul 2009 00:35:20 +0000 |
parents | 98d968f5af11 |
children | c0c00294239b |
rev | line source |
---|---|
14 | 1 """ |
2 MySQLdb Cursors | |
3 --------------- | |
0 | 4 |
5 This module implements Cursors of various types for MySQLdb. By | |
6 default, MySQLdb uses the Cursor class. | |
7 | |
8 """ | |
9 | |
14 | 10 __revision__ = "$Revision$"[11:-2] |
11 __author__ = "$Author$"[9:-2] | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
12 |
0 | 13 import re |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
14 import sys |
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
15 import weakref |
0 | 16 |
65
7a60c4574baf
figleaf revealed that the INSERT_VALUES regex never matched. Added a test for this, and fixed the regex (forgot to add group anchors)
adustman
parents:
64
diff
changeset
|
17 INSERT_VALUES = re.compile(r"(?P<start>.+values\s*)" |
7a60c4574baf
figleaf revealed that the INSERT_VALUES regex never matched. Added a test for this, and fixed the regex (forgot to add group anchors)
adustman
parents:
64
diff
changeset
|
18 r"(?P<values>\(((?<!\\)'[^\)]*?\)[^\)]*(?<!\\)?'|[^\(\)]|(?:\([^\)]*\)))+\))" |
7a60c4574baf
figleaf revealed that the INSERT_VALUES regex never matched. Added a test for this, and fixed the regex (forgot to add group anchors)
adustman
parents:
64
diff
changeset
|
19 r"(?P<end>.*)", re.I) |
0 | 20 |
64
2d6a35051f64
Cursor MixIns: DEAD. More of the new type conversion scheme exposed. Two tests failing because encoding hasn't been finished yet.
adustman
parents:
57
diff
changeset
|
21 |
2d6a35051f64
Cursor MixIns: DEAD. More of the new type conversion scheme exposed. Two tests failing because encoding hasn't been finished yet.
adustman
parents:
57
diff
changeset
|
22 class Cursor(object): |
0 | 23 |
24 """A base for Cursor classes. Useful attributes: | |
25 | |
26 description | |
27 A tuple of DB API 7-tuples describing the columns in | |
28 the last executed query; see PEP-249 for details. | |
29 | |
30 description_flags | |
31 Tuple of column flags for last query, one entry per column | |
32 in the result set. Values correspond to those in | |
33 MySQLdb.constants.FLAG. See MySQL documentation (C API) | |
34 for more information. Non-standard extension. | |
35 | |
36 arraysize | |
37 default number of rows fetchmany() will fetch | |
38 | |
39 """ | |
40 | |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
41 from MySQLdb.exceptions import MySQLError, Warning, Error, InterfaceError, \ |
0 | 42 DatabaseError, DataError, OperationalError, IntegrityError, \ |
43 InternalError, ProgrammingError, NotSupportedError | |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
44 |
4 | 45 _defer_warnings = False |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
46 _fetch_type = None |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
47 |
67
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
48 def __init__(self, connection, encoders): |
64
2d6a35051f64
Cursor MixIns: DEAD. More of the new type conversion scheme exposed. Two tests failing because encoding hasn't been finished yet.
adustman
parents:
57
diff
changeset
|
49 from MySQLdb.converters import default_decoders |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
50 self.connection = weakref.proxy(connection) |
0 | 51 self.description = None |
52 self.description_flags = None | |
53 self.rowcount = -1 | |
54 self.arraysize = 1 | |
55 self._executed = None | |
56 self.lastrowid = None | |
57 self.messages = [] | |
58 self.errorhandler = connection.errorhandler | |
59 self._result = None | |
60 self._warnings = 0 | |
61 self._info = None | |
62 self.rownumber = None | |
67
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
63 self._encoders = encoders |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
64 |
0 | 65 def __del__(self): |
66 self.close() | |
67 self.errorhandler = None | |
68 self._result = None | |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
69 |
0 | 70 def close(self): |
71 """Close the cursor. No further queries will be possible.""" | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
72 if not self.connection: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
73 return |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
74 try: |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
75 while self.nextset(): |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
76 pass |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
77 except: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
78 pass |
0 | 79 self.connection = None |
80 | |
81 def _check_executed(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
82 """Ensure that .execute() has been called.""" |
0 | 83 if not self._executed: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
84 self.errorhandler(self, self.ProgrammingError, "execute() first") |
0 | 85 |
86 def _warning_check(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
87 """Check for warnings, and report via the warnings module.""" |
0 | 88 from warnings import warn |
89 if self._warnings: | |
70 | 90 warnings = self._get_db()._show_warnings() |
0 | 91 if warnings: |
92 # This is done in two loops in case | |
93 # Warnings are set to raise exceptions. | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
94 for warning in warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
95 self.messages.append((self.Warning, warning)) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
96 for warning in warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
97 warn(warning[-1], self.Warning, 3) |
0 | 98 elif self._info: |
99 self.messages.append((self.Warning, self._info)) | |
100 warn(self._info, self.Warning, 3) | |
101 | |
102 def nextset(self): | |
103 """Advance to the next result set. | |
104 | |
105 Returns None if there are no more result sets. | |
106 """ | |
107 if self._executed: | |
108 self.fetchall() | |
109 del self.messages[:] | |
70 | 110 |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
111 connection = self._get_db() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
112 num_rows = connection.next_result() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
113 if num_rows == -1: |
0 | 114 return None |
115 self._do_get_result() | |
116 self._post_get_result() | |
117 self._warning_check() | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
118 return True |
0 | 119 |
120 def _do_get_result(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
121 """Get the result from the last query.""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
122 connection = self._get_db() |
0 | 123 self._result = self._get_result() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
124 self.rowcount = connection.affected_rows() |
0 | 125 self.rownumber = 0 |
126 self.description = self._result and self._result.describe() or None | |
127 self.description_flags = self._result and self._result.field_flags() or None | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
128 self.lastrowid = connection.insert_id() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
129 self._warnings = connection.warning_count() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
130 self._info = connection.info() |
0 | 131 |
132 def setinputsizes(self, *args): | |
133 """Does nothing, required by DB API.""" | |
134 | |
135 def setoutputsizes(self, *args): | |
136 """Does nothing, required by DB API.""" | |
137 | |
138 def _get_db(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
139 """Get the database connection. |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
140 |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
141 Raises ProgrammingError if the connection has been closed.""" |
0 | 142 if not self.connection: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
143 self.errorhandler(self, self.ProgrammingError, "cursor closed") |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
144 return self.connection._db |
0 | 145 |
146 def execute(self, query, args=None): | |
147 """Execute a query. | |
148 | |
149 query -- string, query to execute on server | |
150 args -- optional sequence or mapping, parameters to use with query. | |
151 | |
152 Note: If args is a sequence, then %s must be used as the | |
153 parameter placeholder in the query. If a mapping is used, | |
154 %(key)s must be used as the placeholder. | |
155 | |
156 Returns long integer rows affected, if any | |
157 | |
158 """ | |
159 del self.messages[:] | |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
160 db = self._get_db() |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
161 charset = db.character_set_name() |
4 | 162 if isinstance(query, unicode): |
163 query = query.encode(charset) | |
0 | 164 try: |
67
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
165 if args is not None: |
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
166 query = query % tuple(map(self.connection.literal, args)) |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
167 result = self._query(query) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
168 except TypeError, msg: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
169 if msg.args[0] in ("not enough arguments for format string", |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
170 "not all arguments converted"): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
171 self.messages.append((self.ProgrammingError, msg.args[0])) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
172 self.errorhandler(self, self.ProgrammingError, msg.args[0]) |
0 | 173 else: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
174 self.messages.append((TypeError, msg)) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
175 self.errorhandler(self, TypeError, msg) |
0 | 176 except: |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
177 exc, value, traceback = sys.exc_info() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
178 del traceback |
0 | 179 self.messages.append((exc, value)) |
180 self.errorhandler(self, exc, value) | |
57
9ea2b0e9302e
The pure Python SQL-to-Python conversion code. TODO: There should be a way to register plugins in the module and in the connection.
adustman
parents:
54
diff
changeset
|
181 |
0 | 182 self._executed = query |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
183 if not self._defer_warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
184 self._warning_check() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
185 return result |
0 | 186 |
187 def executemany(self, query, args): | |
188 """Execute a multi-row query. | |
189 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
190 query |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
191 |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
192 string, query to execute on server |
0 | 193 |
194 args | |
195 | |
196 Sequence of sequences or mappings, parameters to use with | |
197 query. | |
198 | |
199 Returns long integer rows affected, if any. | |
200 | |
201 This method improves performance on multiple-row INSERT and | |
202 REPLACE. Otherwise it is equivalent to looping over args with | |
203 execute(). | |
204 | |
205 """ | |
206 del self.messages[:] | |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
207 db = self._get_db() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
208 if not args: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
209 return |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
210 charset = self.connection.character_set_name() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
211 if isinstance(query, unicode): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
212 query = query.encode(charset) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
213 matched = INSERT_VALUES.match(query) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
214 if not matched: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
215 self.rowcount = sum([ self.execute(query, arg) for arg in args ]) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
216 return self.rowcount |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
217 |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
218 start = matched.group('start') |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
219 end = matched.group('end') |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
220 values = matched.group('values') |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
221 |
0 | 222 try: |
67
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
223 sql_params = ( values % tuple(map(self.connection.literal, row)) for row in args ) |
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
224 multirow_query = '\n'.join([start, ',\n'.join(sql_params), end]) |
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
225 self._executed = multirow_query |
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
226 self.rowcount = int(self._query(multirow_query)) |
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
227 |
0 | 228 except TypeError, msg: |
229 if msg.args[0] in ("not enough arguments for format string", | |
230 "not all arguments converted"): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
231 self.messages.append((self.ProgrammingError, msg.args[0])) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
232 self.errorhandler(self, self.ProgrammingError, msg.args[0]) |
0 | 233 else: |
234 self.messages.append((TypeError, msg)) | |
235 self.errorhandler(self, TypeError, msg) | |
236 except: | |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
237 exc, value, traceback = sys.exc_info() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
238 del traceback |
0 | 239 self.errorhandler(self, exc, value) |
67
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
240 |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
241 if not self._defer_warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
242 self._warning_check() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
243 return self.rowcount |
0 | 244 |
245 def callproc(self, procname, args=()): | |
246 """Execute stored procedure procname with args | |
247 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
248 procname |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
249 string, name of procedure to execute on server |
0 | 250 |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
251 args |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
252 Sequence of parameters to use with procedure |
0 | 253 |
254 Returns the original args. | |
255 | |
256 Compatibility warning: PEP-249 specifies that any modified | |
257 parameters must be returned. This is currently impossible | |
258 as they are only available by storing them in a server | |
259 variable and then retrieved by a query. Since stored | |
260 procedures return zero or more result sets, there is no | |
261 reliable way to get at OUT or INOUT parameters via callproc. | |
262 The server variables are named @_procname_n, where procname | |
263 is the parameter above and n is the position of the parameter | |
264 (from zero). Once all result sets generated by the procedure | |
265 have been fetched, you can issue a SELECT @_procname_0, ... | |
266 query using .execute() to get any OUT or INOUT values. | |
267 | |
268 Compatibility warning: The act of calling a stored procedure | |
269 itself creates an empty result set. This appears after any | |
270 result sets generated by the procedure. This is non-standard | |
271 behavior with respect to the DB-API. Be sure to use nextset() | |
272 to advance through all result sets; otherwise you may get | |
273 disconnected. | |
274 """ | |
275 | |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
276 db = self._get_db() |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
277 charset = self.connection.character_set_name() |
0 | 278 for index, arg in enumerate(args): |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
279 query = "SET @_%s_%d=%s" % (procname, index, |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
280 self.connection.literal(arg)) |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
281 if isinstance(query, unicode): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
282 query = query.encode(charset) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
283 self._query(query) |
0 | 284 self.nextset() |
285 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
286 query = "CALL %s(%s)" % (procname, |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
287 ','.join(['@_%s_%d' % (procname, i) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
288 for i in range(len(args))])) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
289 if isinstance(query, unicode): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
290 query = query.encode(charset) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
291 self._query(query) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
292 self._executed = query |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
293 if not self._defer_warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
294 self._warning_check() |
0 | 295 return args |
296 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
297 def _do_query(self, query): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
298 """Low-levey query wrapper. Overridden by MixIns.""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
299 connection = self._get_db() |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
300 self._executed = query |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
301 connection.query(query) |
0 | 302 self._do_get_result() |
303 return self.rowcount | |
304 | |
305 def _fetch_row(self, size=1): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
306 """Low-level fetch_row wrapper.""" |
0 | 307 if not self._result: |
308 return () | |
67
98d968f5af11
Reimplement MySQL->Python type conversion in C; much simpler and easier to deal with now. Hey, all my tests pass, so I guess that means I need to write some more tests.
adustman
parents:
66
diff
changeset
|
309 return self._result.fetch_row(size, self._fetch_type) |
0 | 310 |
311 def __iter__(self): | |
312 return iter(self.fetchone, None) | |
313 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
314 def _get_result(self): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
315 """Low-level; uses mysql_store_result()""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
316 return self._get_db().store_result() |
0 | 317 |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
318 def _query(self, query): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
319 """Low-level; executes query, gets result, and returns rowcount.""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
320 rowcount = self._do_query(query) |
0 | 321 self._post_get_result() |
322 return rowcount | |
323 | |
324 def _post_get_result(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
325 """Low-level""" |
0 | 326 self._rows = self._fetch_row(0) |
327 self._result = None | |
328 | |
329 def fetchone(self): | |
330 """Fetches a single row from the cursor. None indicates that | |
331 no more rows are available.""" | |
332 self._check_executed() | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
333 if self.rownumber >= len(self._rows): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
334 return None |
0 | 335 result = self._rows[self.rownumber] |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
336 self.rownumber += 1 |
0 | 337 return result |
338 | |
339 def fetchmany(self, size=None): | |
340 """Fetch up to size rows from the cursor. Result set may be smaller | |
341 than size. If size is not defined, cursor.arraysize is used.""" | |
342 self._check_executed() | |
343 end = self.rownumber + (size or self.arraysize) | |
344 result = self._rows[self.rownumber:end] | |
345 self.rownumber = min(end, len(self._rows)) | |
346 return result | |
347 | |
348 def fetchall(self): | |
349 """Fetchs all available rows from the cursor.""" | |
350 self._check_executed() | |
351 if self.rownumber: | |
352 result = self._rows[self.rownumber:] | |
353 else: | |
354 result = self._rows | |
355 self.rownumber = len(self._rows) | |
356 return result | |
357 | |
358 def scroll(self, value, mode='relative'): | |
359 """Scroll the cursor in the result set to a new position according | |
360 to mode. | |
361 | |
362 If mode is 'relative' (default), value is taken as offset to | |
363 the current position in the result set, if set to 'absolute', | |
364 value states an absolute target position.""" | |
365 self._check_executed() | |
366 if mode == 'relative': | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
367 row = self.rownumber + value |
0 | 368 elif mode == 'absolute': |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
369 row = value |
0 | 370 else: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
371 self.errorhandler(self, self.ProgrammingError, |
0 | 372 "unknown scroll mode %s" % `mode`) |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
373 if row < 0 or row >= len(self._rows): |
0 | 374 self.errorhandler(self, IndexError, "out of range") |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
375 self.rownumber = row |
0 | 376 |
377 def __iter__(self): | |
378 self._check_executed() | |
379 result = self.rownumber and self._rows[self.rownumber:] or self._rows | |
380 return iter(result) | |
381 | |
382 _fetch_type = 0 |