Mercurial > p > mysql-python > mysqldb-2
annotate MySQLdb/cursors.py @ 54:6e31278d3433 MySQLdb
There's no good reason to delay imports when the module is (1) useless without
it or (2) you do the same late import more than once.
author | kylev |
---|---|
date | Mon, 23 Feb 2009 23:52:44 +0000 |
parents | 10038670b963 |
children | 9ea2b0e9302e |
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 |
31 | 17 INSERT_VALUES = re.compile(r"\svalues\s*" |
18 r"(\(((?<!\\)'[^\)]*?\)[^\)]*(?<!\\)?'" | |
19 r"|[^\(\)]|" | |
20 r"(?:\([^\)]*\))" | |
21 r")+\))") | |
0 | 22 |
23 class BaseCursor(object): | |
24 | |
25 """A base for Cursor classes. Useful attributes: | |
26 | |
27 description | |
28 A tuple of DB API 7-tuples describing the columns in | |
29 the last executed query; see PEP-249 for details. | |
30 | |
31 description_flags | |
32 Tuple of column flags for last query, one entry per column | |
33 in the result set. Values correspond to those in | |
34 MySQLdb.constants.FLAG. See MySQL documentation (C API) | |
35 for more information. Non-standard extension. | |
36 | |
37 arraysize | |
38 default number of rows fetchmany() will fetch | |
39 | |
40 """ | |
41 | |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
42 from MySQLdb.exceptions import MySQLError, Warning, Error, InterfaceError, \ |
0 | 43 DatabaseError, DataError, OperationalError, IntegrityError, \ |
44 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
|
45 |
4 | 46 _defer_warnings = False |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
47 _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
|
48 |
0 | 49 def __init__(self, connection): |
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 | |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
63 |
0 | 64 def __del__(self): |
65 self.close() | |
66 self.errorhandler = None | |
67 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
|
68 |
0 | 69 def close(self): |
70 """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
|
71 if not self.connection: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
72 return |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
73 try: |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
74 while self.nextset(): |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
75 pass |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
76 except: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
77 pass |
0 | 78 self.connection = None |
79 | |
80 def _check_executed(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
81 """Ensure that .execute() has been called.""" |
0 | 82 if not self._executed: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
83 self.errorhandler(self, self.ProgrammingError, "execute() first") |
0 | 84 |
85 def _warning_check(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
86 """Check for warnings, and report via the warnings module.""" |
0 | 87 from warnings import warn |
88 if self._warnings: | |
89 warnings = self._get_db().show_warnings() | |
90 if warnings: | |
91 # This is done in two loops in case | |
92 # 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
|
93 for warning in warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
94 self.messages.append((self.Warning, warning)) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
95 for warning in warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
96 warn(warning[-1], self.Warning, 3) |
0 | 97 elif self._info: |
98 self.messages.append((self.Warning, self._info)) | |
99 warn(self._info, self.Warning, 3) | |
100 | |
101 def nextset(self): | |
102 """Advance to the next result set. | |
103 | |
104 Returns None if there are no more result sets. | |
105 """ | |
106 if self._executed: | |
107 self.fetchall() | |
108 del self.messages[:] | |
109 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
110 connection = self._get_db() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
111 num_rows = connection.next_result() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
112 if num_rows == -1: |
0 | 113 return None |
114 self._do_get_result() | |
115 self._post_get_result() | |
116 self._warning_check() | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
117 return True |
0 | 118 |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
119 def _post_get_result(self): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
120 """Stub to be overridden by MixIn.""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
121 |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
122 def _get_result(self): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
123 """Stub to be overridden by MixIn.""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
124 return [] |
0 | 125 |
126 def _do_get_result(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
127 """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
|
128 connection = self._get_db() |
0 | 129 self._result = self._get_result() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
130 self.rowcount = connection.affected_rows() |
0 | 131 self.rownumber = 0 |
132 self.description = self._result and self._result.describe() or None | |
133 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
|
134 self.lastrowid = connection.insert_id() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
135 self._warnings = connection.warning_count() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
136 self._info = connection.info() |
0 | 137 |
138 def setinputsizes(self, *args): | |
139 """Does nothing, required by DB API.""" | |
140 | |
141 def setoutputsizes(self, *args): | |
142 """Does nothing, required by DB API.""" | |
143 | |
144 def _get_db(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
145 """Get the database connection. |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
146 |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
147 Raises ProgrammingError if the connection has been closed.""" |
0 | 148 if not self.connection: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
149 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
|
150 return self.connection._db |
0 | 151 |
152 def execute(self, query, args=None): | |
153 """Execute a query. | |
154 | |
155 query -- string, query to execute on server | |
156 args -- optional sequence or mapping, parameters to use with query. | |
157 | |
158 Note: If args is a sequence, then %s must be used as the | |
159 parameter placeholder in the query. If a mapping is used, | |
160 %(key)s must be used as the placeholder. | |
161 | |
162 Returns long integer rows affected, if any | |
163 | |
164 """ | |
165 del self.messages[:] | |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
166 db = self._get_db() |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
167 charset = db.character_set_name() |
4 | 168 if isinstance(query, unicode): |
169 query = query.encode(charset) | |
0 | 170 if args is not None: |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
171 query = query % self.connection.literal(args) |
0 | 172 try: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
173 result = self._query(query) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
174 except TypeError, msg: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
175 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
|
176 "not all arguments converted"): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
177 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
|
178 self.errorhandler(self, self.ProgrammingError, msg.args[0]) |
0 | 179 else: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
180 self.messages.append((TypeError, msg)) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
181 self.errorhandler(self, TypeError, msg) |
0 | 182 except: |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
183 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
|
184 del traceback |
0 | 185 self.messages.append((exc, value)) |
186 self.errorhandler(self, exc, value) | |
187 self._executed = query | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
188 if not self._defer_warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
189 self._warning_check() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
190 return result |
0 | 191 |
192 def executemany(self, query, args): | |
193 """Execute a multi-row query. | |
194 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
195 query |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
196 |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
197 string, query to execute on server |
0 | 198 |
199 args | |
200 | |
201 Sequence of sequences or mappings, parameters to use with | |
202 query. | |
203 | |
204 Returns long integer rows affected, if any. | |
205 | |
206 This method improves performance on multiple-row INSERT and | |
207 REPLACE. Otherwise it is equivalent to looping over args with | |
208 execute(). | |
209 | |
210 """ | |
211 del self.messages[:] | |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
212 db = self._get_db() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
213 if not args: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
214 return |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
215 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
|
216 if isinstance(query, unicode): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
217 query = query.encode(charset) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
218 matched = INSERT_VALUES.match(query) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
219 if not matched: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
220 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
|
221 return self.rowcount |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
222 |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
223 start = matched.group('start') |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
224 end = matched.group('end') |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
225 values = matched.group('values') |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
226 |
0 | 227 try: |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
228 sql_params = [ values % self.connection.literal(arg) for arg in args ] |
0 | 229 except TypeError, msg: |
230 if msg.args[0] in ("not enough arguments for format string", | |
231 "not all arguments converted"): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
232 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
|
233 self.errorhandler(self, self.ProgrammingError, msg.args[0]) |
0 | 234 else: |
235 self.messages.append((TypeError, msg)) | |
236 self.errorhandler(self, TypeError, msg) | |
237 except: | |
54
6e31278d3433
There's no good reason to delay imports when the module is (1) useless without
kylev
parents:
31
diff
changeset
|
238 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
|
239 del traceback |
0 | 240 self.errorhandler(self, exc, value) |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
241 self.rowcount = int(self._query( |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
242 '\n'.join([start, ',\n'.join(sql_params), end, |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
243 ]))) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
244 if not self._defer_warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
245 self._warning_check() |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
246 return self.rowcount |
0 | 247 |
248 def callproc(self, procname, args=()): | |
249 """Execute stored procedure procname with args | |
250 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
251 procname |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
252 string, name of procedure to execute on server |
0 | 253 |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
254 args |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
255 Sequence of parameters to use with procedure |
0 | 256 |
257 Returns the original args. | |
258 | |
259 Compatibility warning: PEP-249 specifies that any modified | |
260 parameters must be returned. This is currently impossible | |
261 as they are only available by storing them in a server | |
262 variable and then retrieved by a query. Since stored | |
263 procedures return zero or more result sets, there is no | |
264 reliable way to get at OUT or INOUT parameters via callproc. | |
265 The server variables are named @_procname_n, where procname | |
266 is the parameter above and n is the position of the parameter | |
267 (from zero). Once all result sets generated by the procedure | |
268 have been fetched, you can issue a SELECT @_procname_0, ... | |
269 query using .execute() to get any OUT or INOUT values. | |
270 | |
271 Compatibility warning: The act of calling a stored procedure | |
272 itself creates an empty result set. This appears after any | |
273 result sets generated by the procedure. This is non-standard | |
274 behavior with respect to the DB-API. Be sure to use nextset() | |
275 to advance through all result sets; otherwise you may get | |
276 disconnected. | |
277 """ | |
278 | |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
279 db = self._get_db() |
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
280 charset = self.connection.character_set_name() |
0 | 281 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
|
282 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
|
283 self.connection.literal(arg)) |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
284 if isinstance(query, unicode): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
285 query = query.encode(charset) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
286 self._query(query) |
0 | 287 self.nextset() |
288 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
289 query = "CALL %s(%s)" % (procname, |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
290 ','.join(['@_%s_%d' % (procname, i) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
291 for i in range(len(args))])) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
292 if isinstance(query, unicode): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
293 query = query.encode(charset) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
294 self._query(query) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
295 self._executed = query |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
296 if not self._defer_warnings: |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
297 self._warning_check() |
0 | 298 return args |
299 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
300 def _do_query(self, query): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
301 """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
|
302 connection = self._get_db() |
18
d55bfb1a4701
Tons of changes from major refactoring/cleanup. This is all really broken
adustman
parents:
14
diff
changeset
|
303 self._executed = query |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
304 connection.query(query) |
0 | 305 self._do_get_result() |
306 return self.rowcount | |
307 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
308 def _query(self, query): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
309 """Hook for _do_query.""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
310 return self._do_query(query) |
0 | 311 |
312 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
|
313 """Low-level fetch_row wrapper.""" |
0 | 314 if not self._result: |
315 return () | |
316 return self._result.fetch_row(size, self._fetch_type) | |
317 | |
318 def __iter__(self): | |
319 return iter(self.fetchone, None) | |
320 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
321 def fetchone(self): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
322 """Stub to be overridden by a MixIn.""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
323 return None |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
324 |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
325 def fetchall(self): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
326 """Stub to be overridden by a MixIn.""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
327 return [] |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
328 |
0 | 329 |
330 class CursorStoreResultMixIn(object): | |
331 | |
332 """This is a MixIn class which causes the entire result set to be | |
333 stored on the client side, i.e. it uses mysql_store_result(). If the | |
334 result set can be very large, consider adding a LIMIT clause to your | |
335 query, or using CursorUseResultMixIn instead.""" | |
336 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
337 def _get_result(self): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
338 """Low-level; uses mysql_store_result()""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
339 return self._get_db().store_result() |
0 | 340 |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
341 def _query(self, query): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
342 """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
|
343 rowcount = self._do_query(query) |
0 | 344 self._post_get_result() |
345 return rowcount | |
346 | |
347 def _post_get_result(self): | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
348 """Low-level""" |
0 | 349 self._rows = self._fetch_row(0) |
350 self._result = None | |
351 | |
352 def fetchone(self): | |
353 """Fetches a single row from the cursor. None indicates that | |
354 no more rows are available.""" | |
355 self._check_executed() | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
356 if self.rownumber >= len(self._rows): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
357 return None |
0 | 358 result = self._rows[self.rownumber] |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
359 self.rownumber += 1 |
0 | 360 return result |
361 | |
362 def fetchmany(self, size=None): | |
363 """Fetch up to size rows from the cursor. Result set may be smaller | |
364 than size. If size is not defined, cursor.arraysize is used.""" | |
365 self._check_executed() | |
366 end = self.rownumber + (size or self.arraysize) | |
367 result = self._rows[self.rownumber:end] | |
368 self.rownumber = min(end, len(self._rows)) | |
369 return result | |
370 | |
371 def fetchall(self): | |
372 """Fetchs all available rows from the cursor.""" | |
373 self._check_executed() | |
374 if self.rownumber: | |
375 result = self._rows[self.rownumber:] | |
376 else: | |
377 result = self._rows | |
378 self.rownumber = len(self._rows) | |
379 return result | |
380 | |
381 def scroll(self, value, mode='relative'): | |
382 """Scroll the cursor in the result set to a new position according | |
383 to mode. | |
384 | |
385 If mode is 'relative' (default), value is taken as offset to | |
386 the current position in the result set, if set to 'absolute', | |
387 value states an absolute target position.""" | |
388 self._check_executed() | |
389 if mode == 'relative': | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
390 row = self.rownumber + value |
0 | 391 elif mode == 'absolute': |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
392 row = value |
0 | 393 else: |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
394 self.errorhandler(self, self.ProgrammingError, |
0 | 395 "unknown scroll mode %s" % `mode`) |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
396 if row < 0 or row >= len(self._rows): |
0 | 397 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
|
398 self.rownumber = row |
0 | 399 |
400 def __iter__(self): | |
401 self._check_executed() | |
402 result = self.rownumber and self._rows[self.rownumber:] or self._rows | |
403 return iter(result) | |
404 | |
405 | |
406 class CursorUseResultMixIn(object): | |
407 | |
408 """This is a MixIn class which causes the result set to be stored | |
409 in the server and sent row-by-row to client side, i.e. it uses | |
410 mysql_use_result(). You MUST retrieve the entire result set and | |
411 close() the cursor before additional queries can be peformed on | |
412 the connection.""" | |
413 | |
4 | 414 _defer_warnings = True |
415 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
416 def _get_result(self): |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
417 """Low-level; calls mysql_use_result()""" |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
418 return self._get_db().use_result() |
0 | 419 |
420 def fetchone(self): | |
421 """Fetches a single row from the cursor.""" | |
422 self._check_executed() | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
423 rows = self._fetch_row(1) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
424 if not rows: |
4 | 425 self._warning_check() |
426 return None | |
0 | 427 self.rownumber = self.rownumber + 1 |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
428 return rows[0] |
0 | 429 |
430 def fetchmany(self, size=None): | |
431 """Fetch up to size rows from the cursor. Result set may be smaller | |
432 than size. If size is not defined, cursor.arraysize is used.""" | |
433 self._check_executed() | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
434 rows = self._fetch_row(size or self.arraysize) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
435 self.rownumber = self.rownumber + len(rows) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
436 if not rows: |
4 | 437 self._warning_check() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
438 return rows |
0 | 439 |
440 def fetchall(self): | |
441 """Fetchs all available rows from the cursor.""" | |
442 self._check_executed() | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
443 rows = self._fetch_row(0) |
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
444 self.rownumber = self.rownumber + len(rows) |
4 | 445 self._warning_check() |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
446 return rows |
0 | 447 |
448 def __iter__(self): | |
449 return self | |
450 | |
451 def next(self): | |
452 row = self.fetchone() | |
453 if row is None: | |
454 raise StopIteration | |
455 return row | |
456 | |
457 | |
458 class CursorTupleRowsMixIn(object): | |
459 | |
460 """This is a MixIn class that causes all rows to be returned as tuples, | |
461 which is the standard form required by DB API.""" | |
462 | |
463 _fetch_type = 0 | |
464 | |
465 | |
466 class CursorDictRowsMixIn(object): | |
467 | |
468 """This is a MixIn class that causes all rows to be returned as | |
469 dictionaries. This is a non-standard feature.""" | |
470 | |
471 _fetch_type = 1 | |
472 | |
473 | |
474 class Cursor(CursorStoreResultMixIn, CursorTupleRowsMixIn, | |
475 BaseCursor): | |
476 | |
477 """This is the standard Cursor class that returns rows as tuples | |
478 and stores the result set in the client.""" | |
479 | |
480 | |
481 class DictCursor(CursorStoreResultMixIn, CursorDictRowsMixIn, | |
482 BaseCursor): | |
483 | |
10
3f4c6af70e52
Me and PyLint had a knife fight, but PyLint had a gun.
adustman
parents:
8
diff
changeset
|
484 """This is a Cursor class that returns rows as dictionaries and |
0 | 485 stores the result set in the client.""" |
486 | |
487 | |
488 class SSCursor(CursorUseResultMixIn, CursorTupleRowsMixIn, | |
489 BaseCursor): | |
490 | |
491 """This is a Cursor class that returns rows as tuples and stores | |
492 the result set in the server.""" | |
493 | |
494 | |
495 class SSDictCursor(CursorUseResultMixIn, CursorDictRowsMixIn, | |
496 BaseCursor): | |
497 | |
498 """This is a Cursor class that returns rows as dictionaries and | |
499 stores the result set in the server.""" | |
500 | |
501 |