227 lines
9.3 KiB
Python
Executable File
227 lines
9.3 KiB
Python
Executable File
# MySQL Connector/Python - MySQL driver written in Python.
|
|
# Copyright (c) 2009,2010, Oracle and/or its affiliates. All rights reserved.
|
|
# Use is subject to license terms. (See COPYING)
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation.
|
|
#
|
|
# There are special exceptions to the terms and conditions of the GNU
|
|
# General Public License as it is applied to this software. View the
|
|
# full text of the exception in file EXCEPTIONS-CLIENT in the directory
|
|
# of this software distribution or see the FOSS License Exception at
|
|
# www.mysql.com.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
"""Python exceptions
|
|
"""
|
|
|
|
import logging
|
|
import utils
|
|
|
|
logger = logging.getLogger('myconnpy')
|
|
|
|
# see get_mysql_exceptions method for errno ranges and smaller lists
|
|
__programming_errors = (
|
|
1083,1084,1090,1091,1093,1096,1097,1101,1102,1103,1107,1108,1110,1111,
|
|
1113,1120,1124,1125,1128,1136,1366,1139,1140,1146,1149,)
|
|
__operational_errors = (
|
|
1028,1029,1030,1053,1077,1078,1079,1080,1081,1095,1104,1106,1114,1116,
|
|
1117,1119,1122,1123,1126,1133,1135,1137,1145,1147,)
|
|
|
|
def get_mysql_exception(errno,msg):
|
|
|
|
exception = OperationalError
|
|
|
|
if (errno >= 1046 and errno <= 1052) or \
|
|
(errno >= 1054 and errno <= 1061) or \
|
|
(errno >= 1063 and errno <= 1075) or \
|
|
errno in __programming_errors:
|
|
exception = ProgrammingError
|
|
elif errno in (1097,1109,1118,1121,1138,1292):
|
|
exception = DataError
|
|
elif errno in (1031,1089,1112,1115,1127,1148,1149):
|
|
exception = NotSupportedError
|
|
elif errno in (1062,1082,1099,1100):
|
|
exception = IntegrityError
|
|
elif errno in (1085,1086,1094,1098):
|
|
exception = InternalError
|
|
elif (errno >= 1004 and errno <= 1030) or \
|
|
(errno >= 1132 and errno <= 1045) or \
|
|
(errno >= 1141 and errno <= 1145) or \
|
|
(errno >= 1129 and errno <= 1133) or \
|
|
errno in __operational_errors:
|
|
exception = OperationalError
|
|
|
|
return exception(msg,errno=errno)
|
|
|
|
def raise_error(buf):
|
|
"""Raise an errors.Error when buffer has a MySQL error"""
|
|
errno = errmsg = None
|
|
try:
|
|
buf = buf[5:]
|
|
(buf,errno) = utils.read_int(buf, 2)
|
|
if buf[0] != '\x23':
|
|
# Error without SQLState
|
|
errmsg = buf
|
|
else:
|
|
(buf,sqlstate) = utils.read_bytes(buf[1:],5)
|
|
errmsg = buf
|
|
except Exception, e:
|
|
raise InterfaceError("Failed getting Error information (%r)"\
|
|
% e)
|
|
else:
|
|
raise get_mysql_exception(errno,errmsg)
|
|
|
|
class ClientError(object):
|
|
|
|
client_errors = {
|
|
2000: "Unknown MySQL error",
|
|
2001: "Can't create UNIX socket (%(socketaddr)d)",
|
|
2002: "Can't connect to local MySQL server through socket '%(socketaddr)s' (%(errno)s)",
|
|
2003: "Can't connect to MySQL server on '%(socketaddr)s' (%(errno)s)",
|
|
2004: "Can't create TCP/IP socket (%s)",
|
|
2005: "Unknown MySQL server host '%(socketaddr)s' (%s)",
|
|
2006: "MySQL server has gone away",
|
|
2007: "Protocol mismatch; server version = %(server_version)d, client version = %(client_version)d",
|
|
2008: "MySQL client ran out of memory",
|
|
2009: "Wrong host info",
|
|
2010: "Localhost via UNIX socket",
|
|
2011: "%(misc)s via TCP/IP",
|
|
2012: "Error in server handshake",
|
|
2013: "Lost connection to MySQL server during query",
|
|
2014: "Commands out of sync; you can't run this command now",
|
|
2015: "Named pipe: %(socketaddr)s",
|
|
2016: "Can't wait for named pipe to host: %(host)s pipe: %(socketaddr)s (%(errno)d)",
|
|
2017: "Can't open named pipe to host: %s pipe: %s (%(errno)d)",
|
|
2018: "Can't set state of named pipe to host: %(host)s pipe: %(socketaddr)s (%(errno)d)",
|
|
2019: "Can't initialize character set %(charset)s (path: %(misc)s)",
|
|
2020: "Got packet bigger than 'max_allowed_packet' bytes",
|
|
2021: "Embedded server",
|
|
2022: "Error on SHOW SLAVE STATUS:",
|
|
2023: "Error on SHOW SLAVE HOSTS:",
|
|
2024: "Error connecting to slave:",
|
|
2025: "Error connecting to master:",
|
|
2026: "SSL connection error",
|
|
2027: "Malformed packet",
|
|
2028: "This client library is licensed only for use with MySQL servers having '%s' license",
|
|
2029: "Invalid use of null pointer",
|
|
2030: "Statement not prepared",
|
|
2031: "No data supplied for parameters in prepared statement",
|
|
2032: "Data truncated",
|
|
2033: "No parameters exist in the statement",
|
|
2034: "Invalid parameter number",
|
|
2035: "Can't send long data for non-string/non-binary data types (parameter: %d)",
|
|
2036: "Using unsupported buffer type: %d (parameter: %d)",
|
|
2037: "Shared memory: %s",
|
|
2038: "Can't open shared memory; client could not create request event (%d)",
|
|
2039: "Can't open shared memory; no answer event received from server (%d)",
|
|
2040: "Can't open shared memory; server could not allocate file mapping (%d)",
|
|
2041: "Can't open shared memory; server could not get pointer to file mapping (%d)",
|
|
2042: "Can't open shared memory; client could not allocate file mapping (%d)",
|
|
2043: "Can't open shared memory; client could not get pointer to file mapping (%d)",
|
|
2044: "Can't open shared memory; client could not create %s event (%d)",
|
|
2045: "Can't open shared memory; no answer from server (%d)",
|
|
2046: "Can't open shared memory; cannot send request event to server (%d)",
|
|
2047: "Wrong or unknown protocol",
|
|
2048: "Invalid connection handle",
|
|
2049: "Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)",
|
|
2050: "Row retrieval was canceled by mysql_stmt_close() call",
|
|
2051: "Attempt to read column without prior row fetch",
|
|
2052: "Prepared statement contains no metadata",
|
|
2053: "Attempt to read a row while there is no result set associated with the statement",
|
|
2054: "This feature is not implemented yet",
|
|
2055: "Lost connection to MySQL server at '%(socketaddr)s', system error: %(errno)d",
|
|
2056: "Statement closed indirectly because of a preceeding %s() call",
|
|
2057: "The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
|
|
}
|
|
|
|
def __new__(cls):
|
|
raise TypeError, "Can not instanciate from %s" % cls.__name__
|
|
|
|
@classmethod
|
|
def get_error_msg(cls,errno,values=None):
|
|
res = None
|
|
if cls.client_errors.has_key(errno):
|
|
if values is not None:
|
|
try:
|
|
res = cls.client_errors[errno] % values
|
|
except:
|
|
logger.debug("Missing values for errno %d" % errno)
|
|
res = cls.client_errors[errno], "(missing values!)"
|
|
else:
|
|
res = cls.client_errors[errno]
|
|
if res is None:
|
|
res = "Unknown client error %d" % errno
|
|
logger.debug(res)
|
|
return res
|
|
|
|
class Error(StandardError):
|
|
|
|
def __init__(self, m, errno=None, values=None):
|
|
try:
|
|
# process MySQL error packet
|
|
self._process_packet(m)
|
|
except:
|
|
self.errno = errno or -1
|
|
self.sqlstate = -1
|
|
if m is None and (errno >= 2000 and errno < 3000):
|
|
m = ClientError.get_error_msg(errno,values)
|
|
elif m is None:
|
|
m = 'Unknown error'
|
|
if self.errno != -1:
|
|
self.msg = "%s: %s" % (self.errno,m)
|
|
else:
|
|
self.msg = m
|
|
|
|
def _process_packet(self, packet):
|
|
self.errno = packet.errno
|
|
self.sqlstate = packet.sqlstate
|
|
if self.sqlstate:
|
|
self.msg = '%d (%s): %s' % (self.errno,self.sqlstate,packet.errmsg)
|
|
else:
|
|
self.msg = '%d: %s' % (self.errno, packet.errmsg)
|
|
|
|
def __str__(self):
|
|
return self.msg
|
|
|
|
def __unicode__(self):
|
|
return self.msg
|
|
|
|
class Warning(StandardError):
|
|
pass
|
|
|
|
class InterfaceError(Error):
|
|
def __init__(self, m=None, errno=None, values=None):
|
|
Error.__init__(self, m, errno, values)
|
|
|
|
class DatabaseError(Error):
|
|
def __init__(self, m=None, errno=None, values=None):
|
|
Error.__init__(self, m, errno, values)
|
|
|
|
class InternalError(DatabaseError):
|
|
pass
|
|
|
|
class OperationalError(DatabaseError):
|
|
pass
|
|
|
|
class ProgrammingError(DatabaseError):
|
|
pass
|
|
|
|
class IntegrityError(DatabaseError):
|
|
pass
|
|
|
|
class DataError(DatabaseError):
|
|
pass
|
|
|
|
class NotSupportedError(DatabaseError):
|
|
pass
|