Skip to content
Browse files

Initial Commit 1.2.3

  • Loading branch information...
0 parents commit bb905b788ad6244252c16e91acc91810f8ca887c @eliast committed Jun 12, 2011
6 .cvsignore
@@ -0,0 +1,6 @@
+dist
+build
+regress.py
+test.py
+PKG-INFO
+*.pyc
116 HISTORY
@@ -0,0 +1,116 @@
+=====================
+ What's new in 1.2.3
+=====================
+
+ez_setup.py has been update to include various fixes that affect the build.
+
+Better Python version and dependency detection as well as eliminate exception
+warnings under Python 2.6.
+
+Eliminated memory leaks related to Unicode and failed connections.
+
+Corrected connection .escape() functionality.
+
+Miscellaneous cleanups and and expanded testing suite to ensure ongoing release
+quality.
+
+=====================
+ What's new in 1.2.2
+=====================
+
+The build system has been completely redone and should now build
+on Windows without any patching; uses setuptools.
+
+Added compatibility for Python 2.5, including support for with statement.
+
+connection.ping() now takes an optional boolean argument which can
+enable (or disable) automatic reconnection.
+
+Support returning SET columns as Python sets was removed due to an
+API bug in MySQL; corresponding test removed.
+
+Added a test for single-character CHAR columns.
+
+BLOB columns are now returned as Python strings instead of byte arrays.
+
+BINARY character columns are always returned as Python strings, and not
+unicode.
+
+Fixed a bug introduced in 1.2.1 where the new SHOW WARNINGS support broke
+SSCursor.
+
+Only encode the query (convert to a string) when it is a unicode instance;
+re-encoding encoded strings would break things.
+
+Make a deep copy of conv when connecting, since it can be modified.
+
+Added support for new VARCHAR and BIT column types.
+
+DBAPISet objects were broken, but nobody noticed.
+
+
+========================
+ What's new in 1.2.1_p2
+========================
+
+There are some minor build fixes which probably only affect MySQL
+older than 4.0.
+
+If you had MySQL older than 4.1, the new charset and sql_mode
+parameters didn't work right. In fact, it was impossible to create
+a connection due to the charset problem.
+
+If you are using MySQL-4.1 or newer, there is no practical difference
+between 1.2.1 and 1.2.1_p2, and you don't need to upgrade.
+
+
+=====================
+ What's new in 1.2.1
+=====================
+
+Switched to Subversion. Was going to do this for 1.3, but a
+SourceForge CVS outage has forced the issue.
+
+Mapped a lot of new 4.1 and 5.0 error codes to Python exceptions
+
+Added an API call for mysql_set_character_set(charset) (MySQL > 5.0.7)
+
+Added an API call for mysql_get_character_set_info() (MySQL > 5.0.10)
+
+Revamped the build system. Edit site.cfg if necessary (probably not
+in most cases)
+
+Python-2.3 is now the minimum version.
+
+Dropped support for mx.Datetime and stringtimes; always uses Python
+datetime module now.
+
+Improved unit tests
+
+New connect() options:
+* charset: sets character set, implies use_unicode
+* sql_mode: sets SQL mode (i.e. ANSI, etc.; see MySQL docs)
+
+When using MySQL-4.1 or newer, enables MULTI_STATEMENTS
+
+When using MySQL-5.0 or newer, enables MULTI_RESULTS
+
+When using MySQL-4.1 or newer, more detailed warning messages
+are produced
+
+SET columns returned as Python Set types; you can pass a Set as
+a parameter to cursor.execute().
+
+Support for the new MySQL-5.0 DECIMAL implementation
+
+Support for Python Decimal type
+
+Some use of weak references internally. Cursors no longer leak
+if you don't close them. Connections still do, unfortunately.
+
+ursor.fetchXXXDict() methods raise DeprecationWarning
+
+cursor.begin() is making a brief reappearence.
+
+cursor.callproc() now works, with some limitations.
+
13 MANIFEST.in
@@ -0,0 +1,13 @@
+recursive-include doc *.txt
+recursive-include tests *.py
+include MANIFEST.in
+include MANIFEST
+include ChangeLog
+include HISTORY
+include GPL
+include pymemcompat.h
+include metadata.cfg
+include site.cfg
+include setup_common.py
+include setup_posix.py
+include setup_windows.py
45 MySQL_python.egg-info/PKG-INFO
@@ -0,0 +1,45 @@
+Metadata-Version: 1.0
+Name: MySQL-python
+Version: 1.2.3
+Summary: Python interface to MySQL
+Home-page: http://sourceforge.net/projects/mysql-python
+Author: Andy Dustman
+Author-email: adustman@users.sourceforge.net
+License: GPL
+Download-URL: http://osdn.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.3.tar.gz
+Description:
+ =========================
+ Python interface to MySQL
+ =========================
+
+ MySQLdb is an interface to the popular MySQL_ database server for
+ Python. The design goals are:
+
+ - Compliance with Python database API version 2.0 [PEP-0249]_
+
+ - Thread-safety
+
+ - Thread-friendliness (threads will not block each other)
+
+ MySQL-3.23 through 5.0 and Python-2.3 through 2.6 are currently
+ supported. Python-3.0 will be supported in a future release.
+
+ MySQLdb is `Free Software`_.
+
+ .. _MySQL: http://www.mysql.com/
+ .. _`Free Software`: http://www.gnu.org/
+ .. [PEP-0249] http://www.python.org/peps/pep-0249.html
+Platform: ALL
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Other Environment
+Classifier: License :: OSI Approved :: GNU General Public License (GPL)
+Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
+Classifier: Operating System :: OS Independent
+Classifier: Operating System :: POSIX
+Classifier: Operating System :: POSIX :: Linux
+Classifier: Operating System :: Unix
+Classifier: Programming Language :: C
+Classifier: Programming Language :: Python
+Classifier: Topic :: Database
+Classifier: Topic :: Database :: Database Engines/Servers
42 MySQL_python.egg-info/SOURCES.txt
@@ -0,0 +1,42 @@
+.cvsignore
+HISTORY
+MANIFEST.in
+README
+_mysql.c
+_mysql_exceptions.py
+ez_setup.py
+metadata.cfg
+pymemcompat.h
+setup.cfg
+setup.py
+setup_common.py
+setup_posix.py
+setup_windows.py
+site.cfg
+MySQL_python.egg-info/PKG-INFO
+MySQL_python.egg-info/SOURCES.txt
+MySQL_python.egg-info/dependency_links.txt
+MySQL_python.egg-info/top_level.txt
+MySQLdb/.cvsignore
+MySQLdb/__init__.py
+MySQLdb/connections.py
+MySQLdb/converters.py
+MySQLdb/cursors.py
+MySQLdb/release.py
+MySQLdb/times.py
+MySQLdb/constants/.cvsignore
+MySQLdb/constants/CLIENT.py
+MySQLdb/constants/CR.py
+MySQLdb/constants/ER.py
+MySQLdb/constants/FIELD_TYPE.py
+MySQLdb/constants/FLAG.py
+MySQLdb/constants/REFRESH.py
+MySQLdb/constants/__init__.py
+doc/.cvsignore
+doc/FAQ.txt
+doc/MySQLdb.txt
+tests/capabilities.py
+tests/dbapi20.py
+tests/test_MySQLdb_capabilities.py
+tests/test_MySQLdb_dbapi20.py
+tests/test_MySQLdb_nonstandard.py
1 MySQL_python.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
3 MySQL_python.egg-info/top_level.txt
@@ -0,0 +1,3 @@
+_mysql
+MySQLdb
+_mysql_exceptions
1 MySQLdb/.cvsignore
@@ -0,0 +1 @@
+*.pyc
98 MySQLdb/__init__.py
@@ -0,0 +1,98 @@
+"""MySQLdb - A DB API v2.0 compatible interface to MySQL.
+
+This package is a wrapper around _mysql, which mostly implements the
+MySQL C API.
+
+connect() -- connects to server
+
+See the C API specification and the MySQL documentation for more info
+on other items.
+
+For information on how MySQLdb handles type conversion, see the
+MySQLdb.converters module.
+
+"""
+
+__revision__ = """$Revision: 603 $"""[11:-2]
+from release import __version__, version_info, __author__
+
+import _mysql
+
+if version_info != _mysql.version_info:
+ raise ImportError("this is MySQLdb version %s, but _mysql is version %r" %
+ (version_info, _mysql.version_info))
+
+threadsafety = 1
+apilevel = "2.0"
+paramstyle = "format"
+
+from _mysql import *
+from MySQLdb.constants import FIELD_TYPE
+from MySQLdb.times import Date, Time, Timestamp, \
+ DateFromTicks, TimeFromTicks, TimestampFromTicks
+
+try:
+ frozenset
+except NameError:
+ from sets import ImmutableSet as frozenset
+
+class DBAPISet(frozenset):
+
+ """A special type of set for which A == x is true if A is a
+ DBAPISet and x is a member of that set."""
+
+ def __eq__(self, other):
+ if isinstance(other, DBAPISet):
+ return not self.difference(other)
+ return other in self
+
+
+STRING = DBAPISet([FIELD_TYPE.ENUM, FIELD_TYPE.STRING,
+ FIELD_TYPE.VAR_STRING])
+BINARY = DBAPISet([FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB,
+ FIELD_TYPE.MEDIUM_BLOB, FIELD_TYPE.TINY_BLOB])
+NUMBER = DBAPISet([FIELD_TYPE.DECIMAL, FIELD_TYPE.DOUBLE, FIELD_TYPE.FLOAT,
+ FIELD_TYPE.INT24, FIELD_TYPE.LONG, FIELD_TYPE.LONGLONG,
+ FIELD_TYPE.TINY, FIELD_TYPE.YEAR])
+DATE = DBAPISet([FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE])
+TIME = DBAPISet([FIELD_TYPE.TIME])
+TIMESTAMP = DBAPISet([FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME])
+DATETIME = TIMESTAMP
+ROWID = DBAPISet()
+
+def test_DBAPISet_set_equality():
+ assert STRING == STRING
+
+def test_DBAPISet_set_inequality():
+ assert STRING != NUMBER
+
+def test_DBAPISet_set_equality_membership():
+ assert FIELD_TYPE.VAR_STRING == STRING
+
+def test_DBAPISet_set_inequality_membership():
+ assert FIELD_TYPE.DATE != STRING
+
+def Binary(x):
+ return str(x)
+
+def Connect(*args, **kwargs):
+ """Factory function for connections.Connection."""
+ from connections import Connection
+ return Connection(*args, **kwargs)
+
+connect = Connection = Connect
+
+__all__ = [ 'BINARY', 'Binary', 'Connect', 'Connection', 'DATE',
+ 'Date', 'Time', 'Timestamp', 'DateFromTicks', 'TimeFromTicks',
+ 'TimestampFromTicks', 'DataError', 'DatabaseError', 'Error',
+ 'FIELD_TYPE', 'IntegrityError', 'InterfaceError', 'InternalError',
+ 'MySQLError', 'NULL', 'NUMBER', 'NotSupportedError', 'DBAPISet',
+ 'OperationalError', 'ProgrammingError', 'ROWID', 'STRING', 'TIME',
+ 'TIMESTAMP', 'Warning', 'apilevel', 'connect', 'connections',
+ 'constants', 'converters', 'cursors', 'debug', 'escape', 'escape_dict',
+ 'escape_sequence', 'escape_string', 'get_client_info',
+ 'paramstyle', 'string_literal', 'threadsafety', 'version_info']
+
+
+
+
333 MySQLdb/connections.py
@@ -0,0 +1,333 @@
+"""
+
+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.
+
+"""
+import cursors
+from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
+ DatabaseError, OperationalError, IntegrityError, InternalError, \
+ NotSupportedError, ProgrammingError
+import types, _mysql
+import re
+
+
+def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
+ """
+
+ If cursor is not None, (errorclass, errorvalue) is appended to
+ cursor.messages; otherwise it is appended to
+ connection.messages. Then errorclass is raised with errorvalue as
+ the value.
+
+ You can override this with your own error handler by assigning it
+ to the instance.
+
+ """
+ error = errorclass, errorvalue
+ if cursor:
+ cursor.messages.append(error)
+ else:
+ connection.messages.append(error)
+ del cursor
+ del connection
+ raise errorclass, errorvalue
+
+re_numeric_part = re.compile(r"^(\d+)")
+
+def numeric_part(s):
+ """Returns the leading numeric part of a string.
+
+ >>> numeric_part("20-alpha")
+ 20
+ >>> numeric_part("foo")
+ >>> numeric_part("16b")
+ 16
+ """
+
+ m = re_numeric_part.match(s)
+ if m:
+ return int(m.group(1))
+ return None
+
+
+class Connection(_mysql.connection):
+
+ """MySQL Database Connection Object"""
+
+ default_cursor = cursors.Cursor
+
+ def __init__(self, *args, **kwargs):
+ """
+
+ Create a connection to the database. It is strongly recommended
+ that you only use keyword parameters. Consult the MySQL C API
+ documentation for more information.
+
+ host
+ string, host to connect
+
+ user
+ string, user to connect as
+
+ passwd
+ string, password to use
+
+ db
+ string, database to use
+
+ port
+ integer, TCP/IP port to connect to
+
+ unix_socket
+ string, location of unix_socket to use
+
+ conv
+ conversion dictionary, see MySQLdb.converters
+
+ connect_timeout
+ number of seconds to wait before the connection attempt
+ fails.
+
+ compress
+ if set, compression is enabled
+
+ named_pipe
+ if set, a named pipe is used to connect (Windows only)
+
+ init_command
+ command which is run once the connection is created
+
+ read_default_file
+ file from which default client values are read
+
+ read_default_group
+ configuration group to use from the default file
+
+ cursorclass
+ class object, used to create cursors (keyword only)
+
+ use_unicode
+ If True, text-like columns are returned as unicode objects
+ using the connection's character set. Otherwise, text-like
+ columns are returned as strings. columns are returned as
+ normal strings. Unicode objects will always be encoded to
+ the connection's character set regardless of this setting.
+
+ charset
+ If supplied, the connection character set will be changed
+ to this character set (MySQL-4.1 and newer). This implies
+ use_unicode=True.
+
+ sql_mode
+ If supplied, the session SQL mode will be changed to this
+ setting (MySQL-4.1 and newer). For more details and legal
+ values, see the MySQL documentation.
+
+ client_flag
+ integer, flags to use or 0
+ (see MySQL docs or constants/CLIENTS.py)
+
+ ssl
+ dictionary or mapping, contains SSL connection parameters;
+ see the MySQL documentation for more details
+ (mysql_ssl_set()). If this is set, and the client does not
+ support SSL, NotSupportedError will be raised.
+
+ local_infile
+ integer, non-zero enables LOAD LOCAL INFILE; zero disables
+
+ There are a number of undocumented, non-standard methods. See the
+ documentation for the MySQL C API for some hints on what they do.
+
+ """
+ from constants import CLIENT, FIELD_TYPE
+ from converters import conversions
+ from weakref import proxy, WeakValueDictionary
+
+ import types
+
+ kwargs2 = kwargs.copy()
+
+ if kwargs.has_key('conv'):
+ conv = kwargs['conv']
+ else:
+ conv = conversions
+
+ conv2 = {}
+ for k, v in conv.items():
+ if isinstance(k, int) and isinstance(v, list):
+ conv2[k] = v[:]
+ else:
+ conv2[k] = v
+ kwargs2['conv'] = conv2
+
+ self.cursorclass = kwargs2.pop('cursorclass', self.default_cursor)
+ charset = kwargs2.pop('charset', '')
+
+ if charset:
+ use_unicode = True
+ else:
+ use_unicode = False
+
+ use_unicode = kwargs2.pop('use_unicode', use_unicode)
+ sql_mode = kwargs2.pop('sql_mode', '')
+
+ client_flag = kwargs.get('client_flag', 0)
+ client_version = tuple([ numeric_part(n) for n in _mysql.get_client_info().split('.')[:2] ])
+ if client_version >= (4, 1):
+ client_flag |= CLIENT.MULTI_STATEMENTS
+ if client_version >= (5, 0):
+ client_flag |= CLIENT.MULTI_RESULTS
+
+ kwargs2['client_flag'] = client_flag
+
+ super(Connection, self).__init__(*args, **kwargs2)
+
+ self.encoders = dict([ (k, v) for k, v in conv.items()
+ if type(k) is not int ])
+
+ self._server_version = tuple([ numeric_part(n) for n in self.get_server_info().split('.')[:2] ])
+
+ db = proxy(self)
+ def _get_string_literal():
+ def string_literal(obj, dummy=None):
+ return db.string_literal(obj)
+ return string_literal
+
+ def _get_unicode_literal():
+ def unicode_literal(u, dummy=None):
+ return db.literal(u.encode(unicode_literal.charset))
+ return unicode_literal
+
+ def _get_string_decoder():
+ def string_decoder(s):
+ return s.decode(string_decoder.charset)
+ return string_decoder
+
+ string_literal = _get_string_literal()
+ self.unicode_literal = unicode_literal = _get_unicode_literal()
+ self.string_decoder = string_decoder = _get_string_decoder()
+ if not charset:
+ charset = self.character_set_name()
+ self.set_character_set(charset)
+
+ if sql_mode:
+ self.set_sql_mode(sql_mode)
+
+ if use_unicode:
+ self.converter[FIELD_TYPE.STRING].append((None, string_decoder))
+ self.converter[FIELD_TYPE.VAR_STRING].append((None, string_decoder))
+ self.converter[FIELD_TYPE.VARCHAR].append((None, string_decoder))
+ self.converter[FIELD_TYPE.BLOB].append((None, string_decoder))
+
+ self.encoders[types.StringType] = string_literal
+ self.encoders[types.UnicodeType] = unicode_literal
+ self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
+ if self._transactional:
+ # PEP-249 requires autocommit to be initially off
+ self.autocommit(False)
+ self.messages = []
+
+ def cursor(self, cursorclass=None):
+ """
+
+ Create a cursor on which queries may be performed. The
+ optional cursorclass parameter is used to create the
+ Cursor. By default, self.cursorclass=cursors.Cursor is
+ used.
+
+ """
+ return (cursorclass or self.cursorclass)(self)
+
+ def __enter__(self): return self.cursor()
+
+ def __exit__(self, exc, value, tb):
+ if exc:
+ self.rollback()
+ else:
+ self.commit()
+
+ def literal(self, o):
+ """
+
+ 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.
+
+ """
+ return self.escape(o, self.encoders)
+
+ def begin(self):
+ """Explicitly begin a connection. Non-standard.
+ DEPRECATED: Will be removed in 1.3.
+ Use an SQL BEGIN statement instead."""
+ from warnings import warn
+ warn("begin() is non-standard and will be removed in 1.3",
+ DeprecationWarning, 2)
+ self.query("BEGIN")
+
+ if not hasattr(_mysql.connection, 'warning_count'):
+
+ def warning_count(self):
+ """Return the number of warnings generated from the
+ last query. This is derived from the info() method."""
+ from string import atoi
+ info = self.info()
+ if info:
+ return atoi(info.split()[-1])
+ else:
+ return 0
+
+ def set_character_set(self, charset):
+ """Set the connection character set to charset. The character
+ set can only be changed in MySQL-4.1 and newer. If you try
+ to change the character set from the current value in an
+ older version, NotSupportedError will be raised."""
+ if self.character_set_name() != charset:
+ try:
+ super(Connection, self).set_character_set(charset)
+ except AttributeError:
+ if self._server_version < (4, 1):
+ raise NotSupportedError("server is too old to set charset")
+ self.query('SET NAMES %s' % charset)
+ self.store_result()
+ self.string_decoder.charset = charset
+ self.unicode_literal.charset = charset
+
+ def set_sql_mode(self, sql_mode):
+ """Set the connection sql_mode. See MySQL documentation for
+ legal values."""
+ if self._server_version < (4, 1):
+ raise NotSupportedError("server is too old to set sql_mode")
+ self.query("SET SESSION sql_mode='%s'" % sql_mode)
+ self.store_result()
+
+ def show_warnings(self):
+ """Return detailed information about warnings as a
+ sequence of tuples of (Level, Code, Message). This
+ is only supported in MySQL-4.1 and up. If your server
+ is an earlier version, an empty sequence is returned."""
+ if self._server_version < (4,1): return ()
+ self.query("SHOW WARNINGS")
+ r = self.store_result()
+ warnings = r.fetch_row(0)
+ return warnings
+
+ Warning = Warning
+ Error = Error
+ InterfaceError = InterfaceError
+ DatabaseError = DatabaseError
+ DataError = DataError
+ OperationalError = OperationalError
+ IntegrityError = IntegrityError
+ InternalError = InternalError
+ ProgrammingError = ProgrammingError
+ NotSupportedError = NotSupportedError
+
+ errorhandler = defaulterrorhandler
1 MySQLdb/constants/.cvsignore
@@ -0,0 +1 @@
+*.pyc
29 MySQLdb/constants/CLIENT.py
@@ -0,0 +1,29 @@
+"""MySQL CLIENT constants
+
+These constants are used when creating the connection. Use bitwise-OR
+(|) to combine options together, and pass them as the client_flags
+parameter to MySQLdb.Connection. For more information on these flags,
+see the MySQL C API documentation for mysql_real_connect().
+
+"""
+
+LONG_PASSWORD = 1
+FOUND_ROWS = 2
+LONG_FLAG = 4
+CONNECT_WITH_DB = 8
+NO_SCHEMA = 16
+COMPRESS = 32
+ODBC = 64
+LOCAL_FILES = 128
+IGNORE_SPACE = 256
+CHANGE_USER = 512
+INTERACTIVE = 1024
+SSL = 2048
+IGNORE_SIGPIPE = 4096
+TRANSACTIONS = 8192 # mysql_com.h was WRONG prior to 3.23.35
+RESERVED = 16384
+SECURE_CONNECTION = 32768
+MULTI_STATEMENTS = 65536
+MULTI_RESULTS = 131072
+
+
30 MySQLdb/constants/CR.py
@@ -0,0 +1,30 @@
+"""MySQL Connection Errors
+
+Nearly all of these raise OperationalError. COMMANDS_OUT_OF_SYNC
+raises ProgrammingError.
+
+"""
+
+MIN_ERROR = 2000
+MAX_ERROR = 2999
+UNKNOWN_ERROR = 2000
+SOCKET_CREATE_ERROR = 2001
+CONNECTION_ERROR = 2002
+CONN_HOST_ERROR = 2003
+IPSOCK_ERROR = 2004
+UNKNOWN_HOST = 2005
+SERVER_GONE_ERROR = 2006
+VERSION_ERROR = 2007
+OUT_OF_MEMORY = 2008
+WRONG_HOST_INFO = 2009
+LOCALHOST_CONNECTION = 2010
+TCP_CONNECTION = 2011
+SERVER_HANDSHAKE_ERR = 2012
+SERVER_LOST = 2013
+COMMANDS_OUT_OF_SYNC = 2014
+NAMEDPIPE_CONNECTION = 2015
+NAMEDPIPEWAIT_ERROR = 2016
+NAMEDPIPEOPEN_ERROR = 2017
+NAMEDPIPESETSTATE_ERROR = 2018
+CANT_READ_CHARSET = 2019
+NET_PACKET_TOO_LARGE = 2020
467 MySQLdb/constants/ER.py
@@ -0,0 +1,467 @@
+"""MySQL ER Constants
+
+These constants are error codes for the bulk of the error conditions
+that may occur.
+
+"""
+
+HASHCHK = 1000
+NISAMCHK = 1001
+NO = 1002
+YES = 1003
+CANT_CREATE_FILE = 1004
+CANT_CREATE_TABLE = 1005
+CANT_CREATE_DB = 1006
+DB_CREATE_EXISTS = 1007
+DB_DROP_EXISTS = 1008
+DB_DROP_DELETE = 1009
+DB_DROP_RMDIR = 1010
+CANT_DELETE_FILE = 1011
+CANT_FIND_SYSTEM_REC = 1012
+CANT_GET_STAT = 1013
+CANT_GET_WD = 1014
+CANT_LOCK = 1015
+CANT_OPEN_FILE = 1016
+FILE_NOT_FOUND = 1017
+CANT_READ_DIR = 1018
+CANT_SET_WD = 1019
+CHECKREAD = 1020
+DISK_FULL = 1021
+DUP_KEY = 1022
+ERROR_ON_CLOSE = 1023
+ERROR_ON_READ = 1024
+ERROR_ON_RENAME = 1025
+ERROR_ON_WRITE = 1026
+FILE_USED = 1027
+FILSORT_ABORT = 1028
+FORM_NOT_FOUND = 1029
+GET_ERRNO = 1030
+ILLEGAL_HA = 1031
+KEY_NOT_FOUND = 1032
+NOT_FORM_FILE = 1033
+NOT_KEYFILE = 1034
+OLD_KEYFILE = 1035
+OPEN_AS_READONLY = 1036
+OUTOFMEMORY = 1037
+OUT_OF_SORTMEMORY = 1038
+UNEXPECTED_EOF = 1039
+CON_COUNT_ERROR = 1040
+OUT_OF_RESOURCES = 1041
+BAD_HOST_ERROR = 1042
+HANDSHAKE_ERROR = 1043
+DBACCESS_DENIED_ERROR = 1044
+ACCESS_DENIED_ERROR = 1045
+NO_DB_ERROR = 1046
+UNKNOWN_COM_ERROR = 1047
+BAD_NULL_ERROR = 1048
+BAD_DB_ERROR = 1049
+TABLE_EXISTS_ERROR = 1050
+BAD_TABLE_ERROR = 1051
+NON_UNIQ_ERROR = 1052
+SERVER_SHUTDOWN = 1053
+BAD_FIELD_ERROR = 1054
+WRONG_FIELD_WITH_GROUP = 1055
+WRONG_GROUP_FIELD = 1056
+WRONG_SUM_SELECT = 1057
+WRONG_VALUE_COUNT = 1058
+TOO_LONG_IDENT = 1059
+DUP_FIELDNAME = 1060
+DUP_KEYNAME = 1061
+DUP_ENTRY = 1062
+WRONG_FIELD_SPEC = 1063
+PARSE_ERROR = 1064
+EMPTY_QUERY = 1065
+NONUNIQ_TABLE = 1066
+INVALID_DEFAULT = 1067
+MULTIPLE_PRI_KEY = 1068
+TOO_MANY_KEYS = 1069
+TOO_MANY_KEY_PARTS = 1070
+TOO_LONG_KEY = 1071
+KEY_COLUMN_DOES_NOT_EXITS = 1072
+BLOB_USED_AS_KEY = 1073
+TOO_BIG_FIELDLENGTH = 1074
+WRONG_AUTO_KEY = 1075
+READY = 1076
+NORMAL_SHUTDOWN = 1077
+GOT_SIGNAL = 1078
+SHUTDOWN_COMPLETE = 1079
+FORCING_CLOSE = 1080
+IPSOCK_ERROR = 1081
+NO_SUCH_INDEX = 1082
+WRONG_FIELD_TERMINATORS = 1083
+BLOBS_AND_NO_TERMINATED = 1084
+TEXTFILE_NOT_READABLE = 1085
+FILE_EXISTS_ERROR = 1086
+LOAD_INFO = 1087
+ALTER_INFO = 1088
+WRONG_SUB_KEY = 1089
+CANT_REMOVE_ALL_FIELDS = 1090
+CANT_DROP_FIELD_OR_KEY = 1091
+INSERT_INFO = 1092
+INSERT_TABLE_USED = 1093
+NO_SUCH_THREAD = 1094
+KILL_DENIED_ERROR = 1095
+NO_TABLES_USED = 1096
+TOO_BIG_SET = 1097
+NO_UNIQUE_LOGFILE = 1098
+TABLE_NOT_LOCKED_FOR_WRITE = 1099
+TABLE_NOT_LOCKED = 1100
+BLOB_CANT_HAVE_DEFAULT = 1101
+WRONG_DB_NAME = 1102
+WRONG_TABLE_NAME = 1103
+TOO_BIG_SELECT = 1104
+UNKNOWN_ERROR = 1105
+UNKNOWN_PROCEDURE = 1106
+WRONG_PARAMCOUNT_TO_PROCEDURE = 1107
+WRONG_PARAMETERS_TO_PROCEDURE = 1108
+UNKNOWN_TABLE = 1109
+FIELD_SPECIFIED_TWICE = 1110
+INVALID_GROUP_FUNC_USE = 1111
+UNSUPPORTED_EXTENSION = 1112
+TABLE_MUST_HAVE_COLUMNS = 1113
+RECORD_FILE_FULL = 1114
+UNKNOWN_CHARACTER_SET = 1115
+TOO_MANY_TABLES = 1116
+TOO_MANY_FIELDS = 1117
+TOO_BIG_ROWSIZE = 1118
+STACK_OVERRUN = 1119
+WRONG_OUTER_JOIN = 1120
+NULL_COLUMN_IN_INDEX = 1121
+CANT_FIND_UDF = 1122
+CANT_INITIALIZE_UDF = 1123
+UDF_NO_PATHS = 1124
+UDF_EXISTS = 1125
+CANT_OPEN_LIBRARY = 1126
+CANT_FIND_DL_ENTRY = 1127
+FUNCTION_NOT_DEFINED = 1128
+HOST_IS_BLOCKED = 1129
+HOST_NOT_PRIVILEGED = 1130
+PASSWORD_ANONYMOUS_USER = 1131
+PASSWORD_NOT_ALLOWED = 1132
+PASSWORD_NO_MATCH = 1133
+UPDATE_INFO = 1134
+CANT_CREATE_THREAD = 1135
+WRONG_VALUE_COUNT_ON_ROW = 1136
+CANT_REOPEN_TABLE = 1137
+INVALID_USE_OF_NULL = 1138
+REGEXP_ERROR = 1139
+MIX_OF_GROUP_FUNC_AND_FIELDS = 1140
+NONEXISTING_GRANT = 1141
+TABLEACCESS_DENIED_ERROR = 1142
+COLUMNACCESS_DENIED_ERROR = 1143
+ILLEGAL_GRANT_FOR_TABLE = 1144
+GRANT_WRONG_HOST_OR_USER = 1145
+NO_SUCH_TABLE = 1146
+NONEXISTING_TABLE_GRANT = 1147
+NOT_ALLOWED_COMMAND = 1148
+SYNTAX_ERROR = 1149
+DELAYED_CANT_CHANGE_LOCK = 1150
+TOO_MANY_DELAYED_THREADS = 1151
+ABORTING_CONNECTION = 1152
+NET_PACKET_TOO_LARGE = 1153
+NET_READ_ERROR_FROM_PIPE = 1154
+NET_FCNTL_ERROR = 1155
+NET_PACKETS_OUT_OF_ORDER = 1156
+NET_UNCOMPRESS_ERROR = 1157
+NET_READ_ERROR = 1158
+NET_READ_INTERRUPTED = 1159
+NET_ERROR_ON_WRITE = 1160
+NET_WRITE_INTERRUPTED = 1161
+TOO_LONG_STRING = 1162
+TABLE_CANT_HANDLE_BLOB = 1163
+TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164
+DELAYED_INSERT_TABLE_LOCKED = 1165
+WRONG_COLUMN_NAME = 1166
+WRONG_KEY_COLUMN = 1167
+WRONG_MRG_TABLE = 1168
+DUP_UNIQUE = 1169
+BLOB_KEY_WITHOUT_LENGTH = 1170
+PRIMARY_CANT_HAVE_NULL = 1171
+TOO_MANY_ROWS = 1172
+REQUIRES_PRIMARY_KEY = 1173
+NO_RAID_COMPILED = 1174
+UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175
+KEY_DOES_NOT_EXITS = 1176
+CHECK_NO_SUCH_TABLE = 1177
+CHECK_NOT_IMPLEMENTED = 1178
+CANT_DO_THIS_DURING_AN_TRANSACTION = 1179
+ERROR_DURING_COMMIT = 1180
+ERROR_DURING_ROLLBACK = 1181
+ERROR_DURING_FLUSH_LOGS = 1182
+ERROR_DURING_CHECKPOINT = 1183
+NEW_ABORTING_CONNECTION = 1184
+DUMP_NOT_IMPLEMENTED = 1185
+FLUSH_MASTER_BINLOG_CLOSED = 1186
+INDEX_REBUILD = 1187
+MASTER = 1188
+MASTER_NET_READ = 1189
+MASTER_NET_WRITE = 1190
+FT_MATCHING_KEY_NOT_FOUND = 1191
+LOCK_OR_ACTIVE_TRANSACTION = 1192
+UNKNOWN_SYSTEM_VARIABLE = 1193
+CRASHED_ON_USAGE = 1194
+CRASHED_ON_REPAIR = 1195
+WARNING_NOT_COMPLETE_ROLLBACK = 1196
+TRANS_CACHE_FULL = 1197
+SLAVE_MUST_STOP = 1198
+SLAVE_NOT_RUNNING = 1199
+BAD_SLAVE = 1200
+MASTER_INFO = 1201
+SLAVE_THREAD = 1202
+TOO_MANY_USER_CONNECTIONS = 1203
+SET_CONSTANTS_ONLY = 1204
+LOCK_WAIT_TIMEOUT = 1205
+LOCK_TABLE_FULL = 1206
+READ_ONLY_TRANSACTION = 1207
+DROP_DB_WITH_READ_LOCK = 1208
+CREATE_DB_WITH_READ_LOCK = 1209
+WRONG_ARGUMENTS = 1210
+NO_PERMISSION_TO_CREATE_USER = 1211
+UNION_TABLES_IN_DIFFERENT_DIR = 1212
+LOCK_DEADLOCK = 1213
+TABLE_CANT_HANDLE_FT = 1214
+CANNOT_ADD_FOREIGN = 1215
+NO_REFERENCED_ROW = 1216
+ROW_IS_REFERENCED = 1217
+CONNECT_TO_MASTER = 1218
+QUERY_ON_MASTER = 1219
+ERROR_WHEN_EXECUTING_COMMAND = 1220
+WRONG_USAGE = 1221
+WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222
+CANT_UPDATE_WITH_READLOCK = 1223
+MIXING_NOT_ALLOWED = 1224
+DUP_ARGUMENT = 1225
+USER_LIMIT_REACHED = 1226
+SPECIFIC_ACCESS_DENIED_ERROR = 1227
+LOCAL_VARIABLE = 1228
+GLOBAL_VARIABLE = 1229
+NO_DEFAULT = 1230
+WRONG_VALUE_FOR_VAR = 1231
+WRONG_TYPE_FOR_VAR = 1232
+VAR_CANT_BE_READ = 1233
+CANT_USE_OPTION_HERE = 1234
+NOT_SUPPORTED_YET = 1235
+MASTER_FATAL_ERROR_READING_BINLOG = 1236
+SLAVE_IGNORED_TABLE = 1237
+INCORRECT_GLOBAL_LOCAL_VAR = 1238
+WRONG_FK_DEF = 1239
+KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240
+OPERAND_COLUMNS = 1241
+SUBQUERY_NO_1_ROW = 1242
+UNKNOWN_STMT_HANDLER = 1243
+CORRUPT_HELP_DB = 1244
+CYCLIC_REFERENCE = 1245
+AUTO_CONVERT = 1246
+ILLEGAL_REFERENCE = 1247
+DERIVED_MUST_HAVE_ALIAS = 1248
+SELECT_REDUCED = 1249
+TABLENAME_NOT_ALLOWED_HERE = 1250
+NOT_SUPPORTED_AUTH_MODE = 1251
+SPATIAL_CANT_HAVE_NULL = 1252
+COLLATION_CHARSET_MISMATCH = 1253
+SLAVE_WAS_RUNNING = 1254
+SLAVE_WAS_NOT_RUNNING = 1255
+TOO_BIG_FOR_UNCOMPRESS = 1256
+ZLIB_Z_MEM_ERROR = 1257
+ZLIB_Z_BUF_ERROR = 1258
+ZLIB_Z_DATA_ERROR = 1259
+CUT_VALUE_GROUP_CONCAT = 1260
+WARN_TOO_FEW_RECORDS = 1261
+WARN_TOO_MANY_RECORDS = 1262
+WARN_NULL_TO_NOTNULL = 1263
+WARN_DATA_OUT_OF_RANGE = 1264
+WARN_DATA_TRUNCATED = 1265
+WARN_USING_OTHER_HANDLER = 1266
+CANT_AGGREGATE_2COLLATIONS = 1267
+DROP_USER = 1268
+REVOKE_GRANTS = 1269
+CANT_AGGREGATE_3COLLATIONS = 1270
+CANT_AGGREGATE_NCOLLATIONS = 1271
+VARIABLE_IS_NOT_STRUCT = 1272
+UNKNOWN_COLLATION = 1273
+SLAVE_IGNORED_SSL_PARAMS = 1274
+SERVER_IS_IN_SECURE_AUTH_MODE = 1275
+WARN_FIELD_RESOLVED = 1276
+BAD_SLAVE_UNTIL_COND = 1277
+MISSING_SKIP_SLAVE = 1278
+UNTIL_COND_IGNORED = 1279
+WRONG_NAME_FOR_INDEX = 1280
+WRONG_NAME_FOR_CATALOG = 1281
+WARN_QC_RESIZE = 1282
+BAD_FT_COLUMN = 1283
+UNKNOWN_KEY_CACHE = 1284
+WARN_HOSTNAME_WONT_WORK = 1285
+UNKNOWN_STORAGE_ENGINE = 1286
+WARN_DEPRECATED_SYNTAX = 1287
+NON_UPDATABLE_TABLE = 1288
+FEATURE_DISABLED = 1289
+OPTION_PREVENTS_STATEMENT = 1290
+DUPLICATED_VALUE_IN_TYPE = 1291
+TRUNCATED_WRONG_VALUE = 1292
+TOO_MUCH_AUTO_TIMESTAMP_COLS = 1293
+INVALID_ON_UPDATE = 1294
+UNSUPPORTED_PS = 1295
+GET_ERRMSG = 1296
+GET_TEMPORARY_ERRMSG = 1297
+UNKNOWN_TIME_ZONE = 1298
+WARN_INVALID_TIMESTAMP = 1299
+INVALID_CHARACTER_STRING = 1300
+WARN_ALLOWED_PACKET_OVERFLOWED = 1301
+CONFLICTING_DECLARATIONS = 1302
+SP_NO_RECURSIVE_CREATE = 1303
+SP_ALREADY_EXISTS = 1304
+SP_DOES_NOT_EXIST = 1305
+SP_DROP_FAILED = 1306
+SP_STORE_FAILED = 1307
+SP_LILABEL_MISMATCH = 1308
+SP_LABEL_REDEFINE = 1309
+SP_LABEL_MISMATCH = 1310
+SP_UNINIT_VAR = 1311
+SP_BADSELECT = 1312
+SP_BADRETURN = 1313
+SP_BADSTATEMENT = 1314
+UPDATE_LOG_DEPRECATED_IGNORED = 1315
+UPDATE_LOG_DEPRECATED_TRANSLATED = 1316
+QUERY_INTERRUPTED = 1317
+SP_WRONG_NO_OF_ARGS = 1318
+SP_COND_MISMATCH = 1319
+SP_NORETURN = 1320
+SP_NORETURNEND = 1321
+SP_BAD_CURSOR_QUERY = 1322
+SP_BAD_CURSOR_SELECT = 1323
+SP_CURSOR_MISMATCH = 1324
+SP_CURSOR_ALREADY_OPEN = 1325
+SP_CURSOR_NOT_OPEN = 1326
+SP_UNDECLARED_VAR = 1327
+SP_WRONG_NO_OF_FETCH_ARGS = 1328
+SP_FETCH_NO_DATA = 1329
+SP_DUP_PARAM = 1330
+SP_DUP_VAR = 1331
+SP_DUP_COND = 1332
+SP_DUP_CURS = 1333
+SP_CANT_ALTER = 1334
+SP_SUBSELECT_NYI = 1335
+STMT_NOT_ALLOWED_IN_SF_OR_TRG = 1336
+SP_VARCOND_AFTER_CURSHNDLR = 1337
+SP_CURSOR_AFTER_HANDLER = 1338
+SP_CASE_NOT_FOUND = 1339
+FPARSER_TOO_BIG_FILE = 1340
+FPARSER_BAD_HEADER = 1341
+FPARSER_EOF_IN_COMMENT = 1342
+FPARSER_ERROR_IN_PARAMETER = 1343
+FPARSER_EOF_IN_UNKNOWN_PARAMETER = 1344
+VIEW_NO_EXPLAIN = 1345
+FRM_UNKNOWN_TYPE = 1346
+WRONG_OBJECT = 1347
+NONUPDATEABLE_COLUMN = 1348
+VIEW_SELECT_DERIVED = 1349
+VIEW_SELECT_CLAUSE = 1350
+VIEW_SELECT_VARIABLE = 1351
+VIEW_SELECT_TMPTABLE = 1352
+VIEW_WRONG_LIST = 1353
+WARN_VIEW_MERGE = 1354
+WARN_VIEW_WITHOUT_KEY = 1355
+VIEW_INVALID = 1356
+SP_NO_DROP_SP = 1357
+SP_GOTO_IN_HNDLR = 1358
+TRG_ALREADY_EXISTS = 1359
+TRG_DOES_NOT_EXIST = 1360
+TRG_ON_VIEW_OR_TEMP_TABLE = 1361
+TRG_CANT_CHANGE_ROW = 1362
+TRG_NO_SUCH_ROW_IN_TRG = 1363
+NO_DEFAULT_FOR_FIELD = 1364
+DIVISION_BY_ZERO = 1365
+TRUNCATED_WRONG_VALUE_FOR_FIELD = 1366
+ILLEGAL_VALUE_FOR_TYPE = 1367
+VIEW_NONUPD_CHECK = 1368
+VIEW_CHECK_FAILED = 1369
+PROCACCESS_DENIED_ERROR = 1370
+RELAY_LOG_FAIL = 1371
+PASSWD_LENGTH = 1372
+UNKNOWN_TARGET_BINLOG = 1373
+IO_ERR_LOG_INDEX_READ = 1374
+BINLOG_PURGE_PROHIBITED = 1375
+FSEEK_FAIL = 1376
+BINLOG_PURGE_FATAL_ERR = 1377
+LOG_IN_USE = 1378
+LOG_PURGE_UNKNOWN_ERR = 1379
+RELAY_LOG_INIT = 1380
+NO_BINARY_LOGGING = 1381
+RESERVED_SYNTAX = 1382
+WSAS_FAILED = 1383
+DIFF_GROUPS_PROC = 1384
+NO_GROUP_FOR_PROC = 1385
+ORDER_WITH_PROC = 1386
+LOGGING_PROHIBIT_CHANGING_OF = 1387
+NO_FILE_MAPPING = 1388
+WRONG_MAGIC = 1389
+PS_MANY_PARAM = 1390
+KEY_PART_0 = 1391
+VIEW_CHECKSUM = 1392
+VIEW_MULTIUPDATE = 1393
+VIEW_NO_INSERT_FIELD_LIST = 1394
+VIEW_DELETE_MERGE_VIEW = 1395
+CANNOT_USER = 1396
+XAER_NOTA = 1397
+XAER_INVAL = 1398
+XAER_RMFAIL = 1399
+XAER_OUTSIDE = 1400
+XAER_RMERR = 1401
+XA_RBROLLBACK = 1402
+NONEXISTING_PROC_GRANT = 1403
+PROC_AUTO_GRANT_FAIL = 1404
+PROC_AUTO_REVOKE_FAIL = 1405
+DATA_TOO_LONG = 1406
+SP_BAD_SQLSTATE = 1407
+STARTUP = 1408
+LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR = 1409
+CANT_CREATE_USER_WITH_GRANT = 1410
+WRONG_VALUE_FOR_TYPE = 1411
+TABLE_DEF_CHANGED = 1412
+SP_DUP_HANDLER = 1413
+SP_NOT_VAR_ARG = 1414
+SP_NO_RETSET = 1415
+CANT_CREATE_GEOMETRY_OBJECT = 1416
+FAILED_ROUTINE_BREAK_BINLOG = 1417
+BINLOG_UNSAFE_ROUTINE = 1418
+BINLOG_CREATE_ROUTINE_NEED_SUPER = 1419
+EXEC_STMT_WITH_OPEN_CURSOR = 1420
+STMT_HAS_NO_OPEN_CURSOR = 1421
+COMMIT_NOT_ALLOWED_IN_SF_OR_TRG = 1422
+NO_DEFAULT_FOR_VIEW_FIELD = 1423
+SP_NO_RECURSION = 1424
+TOO_BIG_SCALE = 1425
+TOO_BIG_PRECISION = 1426
+M_BIGGER_THAN_D = 1427
+WRONG_LOCK_OF_SYSTEM_TABLE = 1428
+CONNECT_TO_FOREIGN_DATA_SOURCE = 1429
+QUERY_ON_FOREIGN_DATA_SOURCE = 1430
+FOREIGN_DATA_SOURCE_DOESNT_EXIST = 1431
+FOREIGN_DATA_STRING_INVALID_CANT_CREATE = 1432
+FOREIGN_DATA_STRING_INVALID = 1433
+CANT_CREATE_FEDERATED_TABLE = 1434
+TRG_IN_WRONG_SCHEMA = 1435
+STACK_OVERRUN_NEED_MORE = 1436
+TOO_LONG_BODY = 1437
+WARN_CANT_DROP_DEFAULT_KEYCACHE = 1438
+TOO_BIG_DISPLAYWIDTH = 1439
+XAER_DUPID = 1440
+DATETIME_FUNCTION_OVERFLOW = 1441
+CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG = 1442
+VIEW_PREVENT_UPDATE = 1443
+PS_NO_RECURSION = 1444
+SP_CANT_SET_AUTOCOMMIT = 1445
+MALFORMED_DEFINER = 1446
+VIEW_FRM_NO_USER = 1447
+VIEW_OTHER_USER = 1448
+NO_SUCH_USER = 1449
+FORBID_SCHEMA_CHANGE = 1450
+ROW_IS_REFERENCED_2 = 1451
+NO_REFERENCED_ROW_2 = 1452
+SP_BAD_VAR_SHADOW = 1453
+TRG_NO_DEFINER = 1454
+OLD_FILE_FORMAT = 1455
+SP_RECURSION_LIMIT = 1456
+SP_PROC_TABLE_CORRUPT = 1457
+ERROR_LAST = 1457
+
37 MySQLdb/constants/FIELD_TYPE.py
@@ -0,0 +1,37 @@
+"""MySQL FIELD_TYPE Constants
+
+These constants represent the various column (field) types that are
+supported by MySQL.
+
+"""
+
+DECIMAL = 0
+TINY = 1
+SHORT = 2
+LONG = 3
+FLOAT = 4
+DOUBLE = 5
+NULL = 6
+TIMESTAMP = 7
+LONGLONG = 8
+INT24 = 9
+DATE = 10
+TIME = 11
+DATETIME = 12
+YEAR = 13
+NEWDATE = 14
+VARCHAR = 15
+BIT = 16
+NEWDECIMAL = 246
+ENUM = 247
+SET = 248
+TINY_BLOB = 249
+MEDIUM_BLOB = 250
+LONG_BLOB = 251
+BLOB = 252
+VAR_STRING = 253
+STRING = 254
+GEOMETRY = 255
+
+CHAR = TINY
+INTERVAL = ENUM
23 MySQLdb/constants/FLAG.py
@@ -0,0 +1,23 @@
+"""MySQL FLAG Constants
+
+These flags are used along with the FIELD_TYPE to indicate various
+properties of columns in a result set.
+
+"""
+
+NOT_NULL = 1
+PRI_KEY = 2
+UNIQUE_KEY = 4
+MULTIPLE_KEY = 8
+BLOB = 16
+UNSIGNED = 32
+ZEROFILL = 64
+BINARY = 128
+ENUM = 256
+AUTO_INCREMENT = 512
+TIMESTAMP = 1024
+SET = 2048
+NUM = 32768
+PART_KEY = 16384
+GROUP = 32768
+UNIQUE = 65536
17 MySQLdb/constants/REFRESH.py
@@ -0,0 +1,17 @@
+"""MySQL REFRESH Constants
+
+These constants seem to mostly deal with things internal to the
+MySQL server. Forget you saw this.
+
+"""
+
+GRANT = 1
+LOG = 2
+TABLES = 4
+HOSTS = 8
+STATUS = 16
+THREADS = 32
+SLAVE = 64
+MASTER = 128
+READ_LOCK = 16384
+FAST = 32768
1 MySQLdb/constants/__init__.py
@@ -0,0 +1 @@
+__all__ = ['CR', 'FIELD_TYPE','CLIENT','REFRESH','ER','FLAG']
171 MySQLdb/converters.py
@@ -0,0 +1,171 @@
+"""MySQLdb type conversion module
+
+This module handles all the type conversions for MySQL. If the default
+type conversions aren't what you need, you can make your own. The
+dictionary conversions maps some kind of type to a conversion function
+which returns the corresponding value:
+
+Key: FIELD_TYPE.* (from MySQLdb.constants)
+
+Conversion function:
+
+ Arguments: string
+
+ Returns: Python object
+
+Key: Python type object (from types) or class
+
+Conversion function:
+
+ Arguments: Python object of indicated type or class AND
+ conversion dictionary
+
+ Returns: SQL literal value
+
+ Notes: Most conversion functions can ignore the dictionary, but
+ it is a required parameter. It is necessary for converting
+ things like sequences and instances.
+
+Don't modify conversions if you can avoid it. Instead, make copies
+(with the copy() method), modify the copies, and then pass them to
+MySQL.connect().
+
+"""
+
+from _mysql import string_literal, escape_sequence, escape_dict, escape, NULL
+from constants import FIELD_TYPE, FLAG
+from times import *
+import types
+import array
+
+try:
+ set
+except NameError:
+ from sets import Set as set
+
+def Bool2Str(s, d): return str(int(s))
+
+def Str2Set(s):
+ return set([ i for i in s.split(',') if i ])
+
+def Set2Str(s, d):
+ return string_literal(','.join(s), d)
+
+def Thing2Str(s, d):
+ """Convert something into a string via str()."""
+ return str(s)
+
+def Unicode2Str(s, d):
+ """Convert a unicode object to a string using the default encoding.
+ This is only used as a placeholder for the real function, which
+ is connection-dependent."""
+ return s.encode()
+
+Long2Int = Thing2Str
+
+def Float2Str(o, d):
+ return '%.15g' % o
+
+def None2NULL(o, d):
+ """Convert None to NULL."""
+ return NULL # duh
+
+def Thing2Literal(o, d):
+
+ """Convert something into a SQL string literal. If using
+ MySQL-3.23 or newer, string_literal() is a method of the
+ _mysql.MYSQL object, and this function will be overridden with
+ that method when the connection is created."""
+
+ return string_literal(o, d)
+
+
+def Instance2Str(o, d):
+
+ """
+
+ Convert an Instance to a string representation. If the __str__()
+ method produces acceptable output, then you don't need to add the
+ class to conversions; it will be handled by the default
+ converter. If the exact class is not found in d, it will use the
+ first class it can find for which o is an instance.
+
+ """
+
+ if d.has_key(o.__class__):
+ return d[o.__class__](o, d)
+ cl = filter(lambda x,o=o:
+ type(x) is types.ClassType
+ and isinstance(o, x), d.keys())
+ if not cl and hasattr(types, 'ObjectType'):
+ cl = filter(lambda x,o=o:
+ type(x) is types.TypeType
+ and isinstance(o, x)
+ and d[x] is not Instance2Str,
+ d.keys())
+ if not cl:
+ return d[types.StringType](o,d)
+ d[o.__class__] = d[cl[0]]
+ return d[cl[0]](o, d)
+
+def char_array(s):
+ return array.array('c', s)
+
+def array2Str(o, d):
+ return Thing2Literal(o.tostring(), d)
+
+conversions = {
+ types.IntType: Thing2Str,
+ types.LongType: Long2Int,
+ types.FloatType: Float2Str,
+ types.NoneType: None2NULL,
+ types.TupleType: escape_sequence,
+ types.ListType: escape_sequence,
+ types.DictType: escape_dict,
+ types.InstanceType: Instance2Str,
+ array.ArrayType: array2Str,
+ types.StringType: Thing2Literal, # default
+ types.UnicodeType: Unicode2Str,
+ types.ObjectType: Instance2Str,
+ types.BooleanType: Bool2Str,
+ DateTimeType: DateTime2literal,
+ DateTimeDeltaType: DateTimeDelta2literal,
+ set: Set2Str,
+ FIELD_TYPE.TINY: int,
+ FIELD_TYPE.SHORT: int,
+ FIELD_TYPE.LONG: long,
+ FIELD_TYPE.FLOAT: float,
+ FIELD_TYPE.DOUBLE: float,
+ FIELD_TYPE.DECIMAL: float,
+ FIELD_TYPE.NEWDECIMAL: float,
+ FIELD_TYPE.LONGLONG: long,
+ FIELD_TYPE.INT24: int,
+ FIELD_TYPE.YEAR: int,
+ FIELD_TYPE.SET: Str2Set,
+ FIELD_TYPE.TIMESTAMP: mysql_timestamp_converter,
+ FIELD_TYPE.DATETIME: DateTime_or_None,
+ FIELD_TYPE.TIME: TimeDelta_or_None,
+ FIELD_TYPE.DATE: Date_or_None,
+ FIELD_TYPE.BLOB: [
+ (FLAG.BINARY, str),
+ ],
+ FIELD_TYPE.STRING: [
+ (FLAG.BINARY, str),
+ ],
+ FIELD_TYPE.VAR_STRING: [
+ (FLAG.BINARY, str),
+ ],
+ FIELD_TYPE.VARCHAR: [
+ (FLAG.BINARY, str),
+ ],
+ }
+
+try:
+ from decimal import Decimal
+ conversions[FIELD_TYPE.DECIMAL] = Decimal
+ conversions[FIELD_TYPE.NEWDECIMAL] = Decimal
+except ImportError:
+ pass
+
+
+
503 MySQLdb/cursors.py
@@ -0,0 +1,503 @@
+"""MySQLdb Cursors
+
+This module implements Cursors of various types for MySQLdb. By
+default, MySQLdb uses the Cursor class.
+
+"""
+
+import re
+import sys
+from types import ListType, TupleType, UnicodeType
+
+
+restr = (r"\svalues\s*"
+ r"(\(((?<!\\)'[^\)]*?\)[^\)]*(?<!\\)?'"
+ r"|[^\(\)]|"
+ r"(?:\([^\)]*\))"
+ r")+\))")
+
+insert_values= re.compile(restr)
+from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
+ DatabaseError, OperationalError, IntegrityError, InternalError, \
+ NotSupportedError, ProgrammingError
+
+
+class BaseCursor(object):
+
+ """A base for Cursor classes. Useful attributes:
+
+ description
+ A tuple of DB API 7-tuples describing the columns in
+ the last executed query; see PEP-249 for details.
+
+ description_flags
+ Tuple of column flags for last query, one entry per column
+ in the result set. Values correspond to those in
+ MySQLdb.constants.FLAG. See MySQL documentation (C API)
+ for more information. Non-standard extension.
+
+ arraysize
+ default number of rows fetchmany() will fetch
+
+ """
+
+ from _mysql_exceptions import MySQLError, Warning, Error, InterfaceError, \
+ DatabaseError, DataError, OperationalError, IntegrityError, \
+ InternalError, ProgrammingError, NotSupportedError
+
+ _defer_warnings = False
+
+ def __init__(self, connection):
+ from weakref import proxy
+
+ self.connection = proxy(connection)
+ self.description = None
+ self.description_flags = None
+ self.rowcount = -1
+ self.arraysize = 1
+ self._executed = None
+ self.lastrowid = None
+ self.messages = []
+ self.errorhandler = connection.errorhandler
+ self._result = None
+ self._warnings = 0
+ self._info = None
+ self.rownumber = None
+
+ def __del__(self):
+ self.close()
+ self.errorhandler = None
+ self._result = None
+
+ def close(self):
+ """Close the cursor. No further queries will be possible."""
+ if not self.connection: return
+ while self.nextset(): pass
+ self.connection = None
+
+ def _check_executed(self):
+ if not self._executed:
+ self.errorhandler(self, ProgrammingError, "execute() first")
+
+ def _warning_check(self):
+ from warnings import warn
+ if self._warnings:
+ warnings = self._get_db().show_warnings()
+ if warnings:
+ # This is done in two loops in case
+ # Warnings are set to raise exceptions.
+ for w in warnings:
+ self.messages.append((self.Warning, w))
+ for w in warnings:
+ warn(w[-1], self.Warning, 3)
+ elif self._info:
+ self.messages.append((self.Warning, self._info))
+ warn(self._info, self.Warning, 3)
+
+ def nextset(self):
+ """Advance to the next result set.
+
+ Returns None if there are no more result sets.
+ """
+ if self._executed:
+ self.fetchall()
+ del self.messages[:]
+
+ db = self._get_db()
+ nr = db.next_result()
+ if nr == -1:
+ return None
+ self._do_get_result()
+ self._post_get_result()
+ self._warning_check()
+ return 1
+
+ def _post_get_result(self): pass
+
+ def _do_get_result(self):
+ db = self._get_db()
+ self._result = self._get_result()
+ self.rowcount = db.affected_rows()
+ self.rownumber = 0
+ self.description = self._result and self._result.describe() or None
+ self.description_flags = self._result and self._result.field_flags() or None
+ self.lastrowid = db.insert_id()
+ self._warnings = db.warning_count()
+ self._info = db.info()
+
+ def setinputsizes(self, *args):
+ """Does nothing, required by DB API."""
+
+ def setoutputsizes(self, *args):
+ """Does nothing, required by DB API."""
+
+ def _get_db(self):
+ if not self.connection:
+ self.errorhandler(self, ProgrammingError, "cursor closed")
+ return self.connection
+
+ def execute(self, query, args=None):
+
+ """Execute a query.
+
+ query -- string, query to execute on server
+ args -- optional sequence or mapping, parameters to use with query.
+
+ Note: If args is a sequence, then %s must be used as the
+ 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
+
+ """
+ del self.messages[:]
+ db = self._get_db()
+ charset = db.character_set_name()
+ if isinstance(query, unicode):
+ query = query.encode(charset)
+ if args is not None:
+ query = query % db.literal(args)
+ try:
+ r = self._query(query)
+ except TypeError, m:
+ if m.args[0] in ("not enough arguments for format string",
+ "not all arguments converted"):
+ self.messages.append((ProgrammingError, m.args[0]))
+ self.errorhandler(self, ProgrammingError, m.args[0])
+ else:
+ self.messages.append((TypeError, m))
+ self.errorhandler(self, TypeError, m)
+ except:
+ exc, value, tb = sys.exc_info()
+ del tb
+ self.messages.append((exc, value))
+ self.errorhandler(self, exc, value)
+ self._executed = query
+ if not self._defer_warnings: self._warning_check()
+ return r
+
+ def executemany(self, query, args):
+
+ """Execute a multi-row query.
+
+ query -- string, query to execute on server
+
+ args
+
+ Sequence of sequences or mappings, parameters to use with
+ query.
+
+ Returns long integer rows affected, if any.
+
+ This method improves performance on multiple-row INSERT and
+ REPLACE. Otherwise it is equivalent to looping over args with
+ execute().
+
+ """
+ del self.messages[:]
+ db = self._get_db()
+ if not args: return
+ charset = db.character_set_name()
+ if isinstance(query, unicode): query = query.encode(charset)
+ m = insert_values.search(query)
+ if not m:
+ r = 0
+ for a in args:
+ r = r + self.execute(query, a)
+ return r
+ p = m.start(1)
+ e = m.end(1)
+ qv = m.group(1)
+ try:
+ q = [ qv % db.literal(a) for a in args ]
+ except TypeError, msg:
+ if msg.args[0] in ("not enough arguments for format string",
+ "not all arguments converted"):
+ self.errorhandler(self, ProgrammingError, msg.args[0])
+ else:
+ self.errorhandler(self, TypeError, msg)
+ except:
+ exc, value, tb = sys.exc_info()
+ del tb
+ self.errorhandler(self, exc, value)
+ r = self._query('\n'.join([query[:p], ',\n'.join(q), query[e:]]))
+ if not self._defer_warnings: self._warning_check()
+ return r
+
+ def callproc(self, procname, args=()):
+
+ """Execute stored procedure procname with args
+
+ procname -- string, name of procedure to execute on server
+
+ args -- Sequence of parameters to use with procedure
+
+ Returns the original args.
+
+ Compatibility warning: PEP-249 specifies that any modified
+ parameters must be returned. This is currently impossible
+ as they are only available by storing them in a server
+ variable and then retrieved by a query. Since stored
+ procedures return zero or more result sets, there is no
+ reliable way to get at OUT or INOUT parameters via callproc.
+ The server variables are named @_procname_n, where procname
+ is the parameter above and n is the position of the parameter
+ (from zero). Once all result sets generated by the procedure
+ have been fetched, you can issue a SELECT @_procname_0, ...
+ query using .execute() to get any OUT or INOUT values.
+
+ Compatibility warning: The act of calling a stored procedure
+ itself creates an empty result set. This appears after any
+ result sets generated by the procedure. This is non-standard
+ behavior with respect to the DB-API. Be sure to use nextset()
+ to advance through all result sets; otherwise you may get
+ disconnected.
+ """
+
+ db = self._get_db()
+ charset = db.character_set_name()
+ for index, arg in enumerate(args):
+ q = "SET @_%s_%d=%s" % (procname, index,
+ db.literal(arg))
+ if isinstance(q, unicode):
+ q = q.encode(charset)
+ self._query(q)
+ self.nextset()
+
+ q = "CALL %s(%s)" % (procname,
+ ','.join(['@_%s_%d' % (procname, i)
+ for i in range(len(args))]))
+ if type(q) is UnicodeType:
+ q = q.encode(charset)
+ self._query(q)
+ self._executed = q
+ if not self._defer_warnings: self._warning_check()
+ return args
+
+ def _do_query(self, q):
+ db = self._get_db()
+ self._last_executed = q
+ db.query(q)
+ self._do_get_result()
+ return self.rowcount
+
+ def _query(self, q): return self._do_query(q)
+
+ def _fetch_row(self, size=1):
+ if not self._result:
+ return ()
+ return self._result.fetch_row(size, self._fetch_type)
+
+ def __iter__(self):
+ return iter(self.fetchone, None)
+
+ Warning = Warning
+ Error = Error
+ InterfaceError = InterfaceError
+ DatabaseError = DatabaseError
+ DataError = DataError
+ OperationalError = OperationalError
+ IntegrityError = IntegrityError
+ InternalError = InternalError
+ ProgrammingError = ProgrammingError
+ NotSupportedError = NotSupportedError
+
+
+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 _query(self, q):
+ rowcount = self._do_query(q)
+ self._post_get_result()
+ return rowcount
+
+ def _post_get_result(self):
+ self._rows = self._fetch_row(0)
+ self._result = None
+
+ 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
+ result = self._rows[self.rownumber]
+ self.rownumber = self.rownumber+1
+ return result
+
+ def fetchmany(self, size=None):
+ """Fetch up to size rows from the cursor. Result set may be smaller
+ than size. If size is not defined, cursor.arraysize is used."""
+ self._check_executed()
+ end = self.rownumber + (size or self.arraysize)
+ result = self._rows[self.rownumber:end]
+ self.rownumber = min(end, len(self._rows))
+ return result
+
+ def fetchall(self):
+ """Fetchs all available rows from the cursor."""
+ self._check_executed()
+ if self.rownumber:
+ result = self._rows[self.rownumber:]
+ else:
+ result = self._rows
+ self.rownumber = len(self._rows)
+ return result
+
+ def scroll(self, value, mode='relative'):
+ """Scroll the cursor in the result set to a new position according
+ to mode.
+
+ If mode is 'relative' (default), value is taken as offset to
+ the current position in the result set, if set to 'absolute',
+ value states an absolute target position."""
+ self._check_executed()
+ if mode == 'relative':
+ r = self.rownumber + value
+ elif mode == 'absolute':
+ r = value
+ else:
+ self.errorhandler(self, ProgrammingError,
+ "unknown scroll mode %s" % `mode`)
+ if r < 0 or r >= len(self._rows):
+ self.errorhandler(self, IndexError, "out of range")
+ self.rownumber = r
+
+ def __iter__(self):
+ self._check_executed()
+ result = self.rownumber and self._rows[self.rownumber:] or self._rows
+ return iter(result)
+
+
+class CursorUseResultMixIn(object):
+
+ """This is a MixIn class which causes the result set to be stored
+ in the server and sent row-by-row to client side, i.e. it uses
+ mysql_use_result(). You MUST retrieve the entire result set and
+ close() the cursor before additional queries can be peformed on
+ the connection."""
+
+ _defer_warnings = True
+
+ def _get_result(self): return self._get_db().use_result()
+
+ def fetchone(self):
+ """Fetches a single row from the cursor."""
+ self._check_executed()
+ r = self._fetch_row(1)
+ if not r:
+ self._warning_check()
+ return None
+ self.rownumber = self.rownumber + 1
+ return r[0]
+
+ def fetchmany(self, size=None):
+ """Fetch up to size rows from the cursor. Result set may be smaller
+ than size. If size is not defined, cursor.arraysize is used."""
+ self._check_executed()
+ r = self._fetch_row(size or self.arraysize)
+ self.rownumber = self.rownumber + len(r)
+ if not r:
+ self._warning_check()
+ return r
+
+ def fetchall(self):
+ """Fetchs all available rows from the cursor."""
+ self._check_executed()
+ r = self._fetch_row(0)
+ self.rownumber = self.rownumber + len(r)
+ self._warning_check()
+ return r
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ row = self.fetchone()
+ if row is None:
+ raise StopIteration
+ return row
+
+
+class CursorTupleRowsMixIn(object):
+
+ """This is a MixIn class that causes all rows to be returned as tuples,
+ which is the standard form required by DB API."""
+
+ _fetch_type = 0
+
+
+class CursorDictRowsMixIn(object):
+
+ """This is a MixIn class that causes all rows to be returned as
+ dictionaries. This is a non-standard feature."""
+
+ _fetch_type = 1
+
+ def fetchoneDict(self):
+ """Fetch a single row as a dictionary. Deprecated:
+ Use fetchone() instead. Will be removed in 1.3."""
+ from warnings import warn
+ warn("fetchoneDict() is non-standard and will be removed in 1.3",
+ DeprecationWarning, 2)
+ return self.fetchone()
+
+ def fetchmanyDict(self, size=None):
+ """Fetch several rows as a list of dictionaries. Deprecated:
+ Use fetchmany() instead. Will be removed in 1.3."""
+ from warnings import warn
+ warn("fetchmanyDict() is non-standard and will be removed in 1.3",
+ DeprecationWarning, 2)
+ return self.fetchmany(size)
+
+ def fetchallDict(self):
+ """Fetch all available rows as a list of dictionaries. Deprecated:
+ Use fetchall() instead. Will be removed in 1.3."""
+ from warnings import warn
+ warn("fetchallDict() is non-standard and will be removed in 1.3",
+ DeprecationWarning, 2)
+ return self.fetchall()
+
+
+class CursorOldDictRowsMixIn(CursorDictRowsMixIn):
+
+ """This is a MixIn class that returns rows as dictionaries with
+ the same key convention as the old Mysqldb (MySQLmodule). Don't
+ use this."""
+
+ _fetch_type = 2
+
+
+class Cursor(CursorStoreResultMixIn, CursorTupleRowsMixIn,
+ BaseCursor):
+
+ """This is the standard Cursor class that returns rows as tuples
+ and stores the result set in the client."""
+
+
+class DictCursor(CursorStoreResultMixIn, CursorDictRowsMixIn,
+ BaseCursor):
+
+ """This is a Cursor class that returns rows as dictionaries and
+ stores the result set in the client."""
+
+
+class SSCursor(CursorUseResultMixIn, CursorTupleRowsMixIn,
+ BaseCursor):
+
+ """This is a Cursor class that returns rows as tuples and stores
+ the result set in the server."""
+
+
+class SSDictCursor(CursorUseResultMixIn, CursorDictRowsMixIn,
+ BaseCursor):
+
+ """This is a Cursor class that returns rows as dictionaries and
+ stores the result set in the server."""
+
+
4 MySQLdb/release.py
@@ -0,0 +1,4 @@
+
+__author__ = "Andy Dustman <adustman@users.sourceforge.net>"
+version_info = (1,2,3,'final',0)
+__version__ = "1.2.3"
101 MySQLdb/times.py
@@ -0,0 +1,101 @@
+"""times module
+
+This module provides some Date and Time classes for dealing with MySQL data.
+
+Use Python datetime module to handle date and time columns."""
+
+import math
+from time import localtime
+from datetime import date, datetime, time, timedelta
+from _mysql import string_literal
+
+Date = date
+Time = time
+TimeDelta = timedelta
+Timestamp = datetime
+
+DateTimeDeltaType = timedelta
+DateTimeType = datetime
+
+def DateFromTicks(ticks):
+ """Convert UNIX ticks into a date instance."""
+ return date(*localtime(ticks)[:3])
+
+def TimeFromTicks(ticks):
+ """Convert UNIX ticks into a time instance."""
+ return time(*localtime(ticks)[3:6])
+
+def TimestampFromTicks(ticks):
+ """Convert UNIX ticks into a datetime instance."""
+ return datetime(*localtime(ticks)[:6])
+
+format_TIME = format_DATE = str
+
+def format_TIMEDELTA(v):
+ seconds = int(v.seconds) % 60
+ minutes = int(v.seconds / 60) % 60
+ hours = int(v.seconds / 3600) % 24
+ return '%d %d:%d:%d' % (v.days, hours, minutes, seconds)
+
+def format_TIMESTAMP(d):
+ return d.strftime("%Y-%m-%d %H:%M:%S")
+
+
+def DateTime_or_None(s):
+ if ' ' in s:
+ sep = ' '
+ elif 'T' in s:
+ sep = 'T'
+ else:
+ return Date_or_None(s)
+
+ try:
+ d, t = s.split(sep, 1)
+ return datetime(*[ int(x) for x in d.split('-')+t.split(':') ])
+ except:
+ return Date_or_None(s)
+
+def TimeDelta_or_None(s):
+ try:
+ h, m, s = s.split(':')
+ h, m, s = int(h), int(m), float(s)
+ td = timedelta(hours=abs(h), minutes=m, seconds=int(s),
+ microseconds=int(math.modf(s)[0] * 1000000))
+ if h < 0:
+ return -td
+ else:
+ return td
+ except ValueError:
+ # unpacking or int/float conversion failed
+ return None
+
+def Time_or_None(s):
+ try:
+ h, m, s = s.split(':')
+ h, m, s = int(h), int(m), float(s)
+ return time(hour=h, minute=m, second=int(s),
+ microsecond=int(math.modf(s)[0] * 1000000))
+ except ValueError:
+ return None
+
+def Date_or_None(s):
+ try: return date(*[ int(x) for x in s.split('-',2)])
+ except: return None
+
+def DateTime2literal(d, c):
+ """Format a DateTime object as an ISO timestamp."""
+ return string_literal(format_TIMESTAMP(d),c)
+
+def DateTimeDelta2literal(d, c):
+ """Format a DateTimeDelta object as a time."""
+ return string_literal(format_TIMEDELTA(d),c)
+
+def mysql_timestamp_converter(s):
+ """Convert a MySQL TIMESTAMP to a Timestamp object."""
+ # MySQL>4.1 returns TIMESTAMP in the same format as DATETIME
+ if s[4] == '-': return DateTime_or_None(s)
+ s = s + "0"*(14-len(s)) # padding
+ parts = map(int, filter(None, (s[:4],s[4:6],s[6:8],
+ s[8:10],s[10:12],s[12:14])))
+ try: return Timestamp(*parts)
+ except: return None
45 PKG-INFO
@@ -0,0 +1,45 @@
+Metadata-Version: 1.0
+Name: MySQL-python
+Version: 1.2.3
+Summary: Python interface to MySQL
+Home-page: http://sourceforge.net/projects/mysql-python
+Author: Andy Dustman
+Author-email: adustman@users.sourceforge.net
+License: GPL
+Download-URL: http://osdn.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.3.tar.gz
+Description:
+ =========================
+ Python interface to MySQL
+ =========================
+
+ MySQLdb is an interface to the popular MySQL_ database server for
+ Python. The design goals are:
+
+ - Compliance with Python database API version 2.0 [PEP-0249]_
+
+ - Thread-safety
+
+ - Thread-friendliness (threads will not block each other)
+
+ MySQL-3.23 through 5.0 and Python-2.3 through 2.6 are currently
+ supported. Python-3.0 will be supported in a future release.
+
+ MySQLdb is `Free Software`_.
+
+ .. _MySQL: http://www.mysql.com/
+ .. _`Free Software`: http://www.gnu.org/
+ .. [PEP-0249] http://www.python.org/peps/pep-0249.html
+Platform: ALL
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Other Environment
+Classifier: License :: OSI Approved :: GNU General Public License (GPL)
+Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
+Classifier: Operating System :: OS Independent
+Classifier: Operating System :: POSIX
+Classifier: Operating System :: POSIX :: Linux
+Classifier: Operating System :: Unix
+Classifier: Programming Language :: C
+Classifier: Programming Language :: Python
+Classifier: Topic :: Database
+Classifier: Topic :: Database :: Database Engines/Servers
253 README
@@ -0,0 +1,253 @@
+====================
+MySQLdb Installation
+====================
+
+.. contents::
+..
+
+Prerequisites
+-------------
+
++ Python 2.3.4 or higher
+
+ * http://www.python.org/
+
+ * Versions lower than 2.3 WON'T WORK.
+
+ * 2.4 is the primary test environment.
+
+ * Red Hat Linux:
+
+ - Make sure you have the Python development headers and libraries
+ (python-devel).
+
++ setuptools
+
+ * http://pypi.python.org/pypi/setuptools
+
++ MySQL 3.23.32 or higher
+
+ * http://www.mysql.com/downloads/
+
+ * Versions lower than 3.22 definitely WON'T WORK.
+
+ * Versions lower than 3.22.19 might not work.
+
+ * MySQL-3.22 might work but isn't supported anymore. It's very old.
+
+ * MySQL-3.23 ought to work, but it's pretty elderly.
+
+ * MySQL-4.0 is supported, but not tested and slightly discouraged.
+
+ * MySQL-4.1 is supported. The prepared statements API is not
+ supported, and won't be until MySQLdb-1.3 or 2.0, if ever.
+
+ * MySQL-5.0 is supported and tested, including stored procedures.
+
+ * MySQL-5.1 is supported (currently a release candidate) but untested.
+ It should work.
+
+ * MySQL-6.0 is sorta-kinda-supported (currently alpha) but untested.
+ It should work.
+
+ * Drizzle <https://launchpad.net/drizzle> is a fork of MySQL. So far
+ the C API looks really similar except everything is renamed.
+ Drizzle support probably won't happen in 1.2. There may be have to
+ be an entirely different module, but still using DB-API.
+
+ * MaxDB, formerly known as SAP DB (and maybe Adabas D?), is a
+ completely different animal. Use the sapdb.sql module that comes
+ with MaxDB.
+
+ * Red Hat Linux packages:
+
+ - mysql-devel to compile
+
+ - mysql and/or mysql-devel to run
+
+ * MySQL.com RPM packages:
+
+ - MySQL-devel to compile
+
+ - MySQL-shared if you want to use their shared
+ library. Otherwise you'll get a statically-linked module,
+ which may or may not be what you want.
+
+ - MySQL-shared to run if you compiled with MySQL-shared installed
+
+ * Transactions (particularly InnoDB tables) are supported for
+ MySQL-3.23 and up. You may need a special package from your vendor
+ with this support turned on.
+
++ zlib
+
+ * Required for MySQL-3.23 and newer.
+
+ * Red Hat Linux
+
+ - zlib-devel to compile
+
+ - zlib to run
+
++ openssl
+
+ * May be needed for MySQL-4.0 or newer, depending on compilation
+ options. If you need it, you probably already have it.
+
+ - you may need openssl-devel on some platforms
+
++ C compiler
+
+ * Most free software-based systems already have this, usually gcc.
+
+ * Most commercial UNIX platforms also come with a C compiler, or
+ you can also use gcc.
+
+ * If you have some Windows flavor, you usually have to pay extra
+ for this, or you can use Cygwin_.
+
+.. _Cygwin: http://www.cygwin.com/
+
+
+Building and installing
+-----------------------
+
+The setup.py script uses mysql_config to find all compiler and linker
+options, and should work as is on any POSIX-like platform, so long as
+mysql_config is in your path.
+
+Depending on which version of MySQL you have, you may have the option
+of using three different client libraries. To select the client library,
+edit the [options] section of site.cfg:
+
+ embedded
+ use embedded server library (libmysqld) if True; otherwise use
+ one of the client libraries (default).
+
+ threadsafe
+ thread-safe client library (libmysqlclient_r) if True (default);
+ otherwise use non-thread-safe (libmysqlclient). You should
+ always use the thread-safe library if you have the option;
+ otherwise you *may* have problems.
+
+ static
+ if True, try to link against a static library; otherwise link
+ against dynamic libraries (default). You may need static linking
+ to use the embedded server.
+
+
+Finally, putting it together::
+
+ $ tar xfz MySQL-python-1.2.1.tar.gz
+ $ cd MySQL-python-1.2.1
+ $ # edit site.cfg if necessary
+ $ python setup.py build
+ $ sudo python setup.py install # or su first
+
+
+Windows
+.......
+
+I don't do Windows. However if someone provides me with a package for
+Windows, I'll make it available. Don't ask me for help with Windows
+because I can't help you.
+
+Generally, though, running setup.py is similar to above::
+
+ C:\...> python setup.py install
+ C:\...> python setup.py bdist_wininst
+
+The latter example should build a Windows installer package, if you
+have the correct tools. In any event, you *must* have a C compiler.
+Additionally, you have to set an environment variable (mysqlroot)
+which is the path to your MySQL installation. In theory, it would be
+possible to get this information out of the registry, but like I said,
+I don't do Windows, but I'll accept a patch that does this.
+
+On Windows, you will definitely have to edit site.cfg since there is
+no mysql_config in the MySQL package.
+
+
+Zope
+....
+
+If you are using a binary package of Zope, you need run setup.py with
+the python executable that came with Zope. Otherwise, you'll install
+into the wrong Python tree and Zope (ZMySQLDA) will not be able to
+find _mysql.
+
+
+Binary Packages
+---------------
+
+I don't plan to make binary packages any more. However, if someone
+contributes one, I will make it available. Several OS vendors have
+their own packages available.
+
+
+RPMs
+....
+
+If you prefer to install RPMs, you can use the bdist_rpm command with
+setup.py. This only builds the RPM; it does not install it. You may
+want to use the --python=XXX option, where XXX is the name of the
+Python executable, i.e. python, python2, python2.4; the default is
+python. Using this will incorporate the Python executable name into
+the package name for the RPM so you have install the package multiple
+times if you need to support more than one version of Python. You can
+also set this in setup.cfg.
+
+
+Red Hat Linux
+.............
+
+MySQL-python is pre-packaged in Red Hat Linux 7.x and newer. This
+includes Fedora Core and Red Hat Enterprise Linux. You can also
+build your own RPM packages as described above.
+
+
+Debian GNU/Linux
+................
+
+Packaged as `python-mysqldb`_::
+
+ # apt-get install python-mysqldb
+
+Or use Synaptic.
+
+.. _`python-mysqldb`: http://packages.debian.org/python-mysqldb
+
+
+Ubuntu
+......
+
+Same as with Debian.
+
+
+Gentoo Linux
+............
+
+Packaged as `mysql-python`_. ::
+
+ # emerge sync
+ # emerge mysql-python
+ # emerge zmysqlda # if you use Zope
+
+.. _`mysql-python`: http://packages.gentoo.org/search/?sstring=mysql-python
+
+
+BSD
+...
+
+MySQL-python is a ported package in FreeBSD, NetBSD, and OpenBSD,
+although the name may vary to match OS conventions.
+
+
+License
+-------
+
+GPL or the original license based on Python 1.5.2's license.
+
+
+:Author: Andy Dustman <andy@dustman.net>