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