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