Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions MySQLdb/connections.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
"""

This module implements connections for MySQLdb. Presently there is
only one class: Connection. Others are unlikely. However, you might
want to make your own subclasses. In most cases, you will probably
override Connection.default_cursor with a non-standard Cursor class.

"""
from MySQLdb import cursors
from MySQLdb.compat import unicode, PY2
Expand All @@ -15,6 +13,14 @@
import re


if not PY2:
# See http://bugs.python.org/issue24870
_surrogateescape_table = [chr(i) if i < 0x80 else chr(i + 0xdc00) for i in range(256)]

def _fast_surroundescape(s):
return s.decode('latin1').translate(_surrogateescape_table)


def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
"""
If cursor is not None, (errorclass, errorvalue) is appended to
Expand All @@ -34,7 +40,7 @@ def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
del connection
if isinstance(errorvalue, BaseException):
raise errorvalue
if errorclass is not None:
if errorclass is not None:
raise errorclass(errorvalue)
else:
raise Exception(errorvalue)
Expand Down Expand Up @@ -291,24 +297,21 @@ def __exit__(self, exc, value, tb):
self.commit()

def literal(self, o):
"""

If o is a single object, returns an SQL literal as a string.
"""If o is a single object, returns an SQL literal as a string.
If o is a non-string sequence, the items of the sequence are
converted and returned as a sequence.

Non-standard. For internal use; do not use this in your
applications.

"""
s = self.escape(o, self.encoders)
# Python 3 doesn't support % operation for bytes object.
# Python 3(~3.4) doesn't support % operation for bytes object.
# We should decode it before using %.
# Decoding with ascii and surrogateescape allows convert arbitrary
# bytes to unicode and back again.
# See http://python.org/dev/peps/pep-0383/
if not PY2 and isinstance(s, bytes):
return s.decode('ascii', 'surrogateescape')
if not PY2 and isinstance(s, (bytes, bytearray)):
return _fast_surroundescape(s)
return s

def begin(self):
Expand Down
27 changes: 13 additions & 14 deletions MySQLdb/cursors.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def execute(self, query, args=None):
parameter placeholder in the query. If a mapping is used,
%(key)s must be used as the placeholder.

Returns long integer rows affected, if any
Returns integer represents rows affected, if any
"""
while self.nextset():
pass
Expand All @@ -208,27 +208,25 @@ def execute(self, query, args=None):
args = dict((key, db.literal(item)) for key, item in args.items())
else:
args = tuple(map(db.literal, args))
if not PY2 and isinstance(query, bytes):
if not PY2 and isinstance(query, (bytes, bytearray)):
query = query.decode(db.unicode_literal.charset)
query = query % args
try:
query = query % args
except TypeError as m:
self.errorhandler(self, ProgrammingError, str(m))

if isinstance(query, unicode):
query = query.encode(db.unicode_literal.charset, 'surrogateescape')

res = None
try:
res = self._query(query)
except TypeError as m:
if m.args[0] in ("not enough arguments for format string",
"not all arguments converted"):
self.errorhandler(self, ProgrammingError, m.args[0])
else:
self.errorhandler(self, TypeError, m)
except Exception:
exc, value = sys.exc_info()[:2]
self.errorhandler(self, exc, value)
self._executed = query
if not self._defer_warnings: self._warning_check()
if not self._defer_warnings:
self._warning_check()
return res

def executemany(self, query, args):
Expand Down Expand Up @@ -369,13 +367,13 @@ def __iter__(self):


class CursorStoreResultMixIn(object):

"""This is a MixIn class which causes the entire result set to be
stored on the client side, i.e. it uses mysql_store_result(). If the
result set can be very large, consider adding a LIMIT clause to your
query, or using CursorUseResultMixIn instead."""

def _get_result(self): return self._get_db().store_result()
def _get_result(self):
return self._get_db().store_result()

def _query(self, q):
rowcount = self._do_query(q)
Expand All @@ -390,9 +388,10 @@ def fetchone(self):
"""Fetches a single row from the cursor. None indicates that
no more rows are available."""
self._check_executed()
if self.rownumber >= len(self._rows): return None
if self.rownumber >= len(self._rows):
return None
result = self._rows[self.rownumber]
self.rownumber = self.rownumber+1
self.rownumber = self.rownumber + 1
return result

def fetchmany(self, size=None):
Expand Down