| @@ -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> | ||
| :Revision: $Id$ |
| @@ -0,0 +1,14 @@ | ||
| recursive-include doc *.txt | ||
| recursive-include tests *.py | ||
| include MANIFEST.in | ||
| include HISTORY | ||
| include INSTALL | ||
| include README.md | ||
| include GPL-2.0 | ||
| include pymemcompat.h | ||
| include metadata.cfg | ||
| include site.cfg | ||
| include distribute_setup.py | ||
| include setup_common.py | ||
| include setup_posix.py | ||
| include setup_windows.py |
| @@ -0,0 +1,43 @@ | ||
| Metadata-Version: 1.1 | ||
| Name: MySQL-python | ||
| Version: 1.2.4b4 | ||
| Summary: Python interface to MySQL | ||
| Home-page: http://sourceforge.net/projects/mysql-python | ||
| Author: Andy Dustman | ||
| Author-email: farcepest@gmail.com | ||
| License: GPL | ||
| Download-URL: http://osdn.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.4b4.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.5 and Python-2.4 through 2.7 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 |
| @@ -0,0 +1,41 @@ | ||
| GPL-2.0 | ||
| HISTORY | ||
| INSTALL | ||
| MANIFEST.in | ||
| README.md | ||
| _mysql.c | ||
| _mysql_exceptions.py | ||
| distribute_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/__init__.py | ||
| MySQLdb/connections.py | ||
| MySQLdb/converters.py | ||
| MySQLdb/cursors.py | ||
| MySQLdb/release.py | ||
| MySQLdb/times.py | ||
| 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/FAQ.txt | ||
| doc/MySQLdb.txt | ||
| tests/capabilities.py | ||
| tests/configdb.py | ||
| tests/dbapi20.py | ||
| tests/test_MySQLdb_capabilities.py | ||
| tests/test_MySQLdb_dbapi20.py | ||
| tests/test_MySQLdb_nonstandard.py |
| @@ -0,0 +1 @@ | ||
|
|
| @@ -0,0 +1,3 @@ | ||
| _mysql | ||
| MySQLdb | ||
| _mysql_exceptions |
| @@ -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$"""[11:-2] | ||
| from MySQLdb.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 MySQLdb.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'] | ||
|
|
||
|
|
||
|
|
||
|
|
| @@ -0,0 +1,337 @@ | ||
| """ | ||
| 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 _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 MySQLdb.constants import CLIENT, FIELD_TYPE | ||
| from MySQLdb.converters import conversions | ||
| from weakref import proxy, WeakValueDictionary | ||
|
|
||
| import types | ||
|
|
||
| kwargs2 = kwargs.copy() | ||
|
|
||
| if 'conv' in kwargs: | ||
| 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 | ||
|
|
||
| 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.cursorclass = cursorclass | ||
| 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 charset == "utf8mb4": | ||
| py_charset = "utf8" | ||
| else: | ||
| py_charset = charset | ||
| 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 = py_charset | ||
| self.unicode_literal.charset = py_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 |
| @@ -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 | ||
|
|
||
|
|
| @@ -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 |
| @@ -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 |
| @@ -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 |
| @@ -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 |
| @@ -0,0 +1 @@ | ||
| __all__ = ['CR', 'FIELD_TYPE','CLIENT','REFRESH','ER','FLAG'] |
| @@ -0,0 +1,181 @@ | ||
| """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 MySQLdb.constants import FIELD_TYPE, FLAG | ||
| from MySQLdb.times import * | ||
|
|
||
| try: | ||
| from types import IntType, LongType, FloatType, NoneType, TupleType, ListType, DictType, InstanceType, \ | ||
| StringType, UnicodeType, ObjectType, BooleanType, ClassType, TypeType | ||
| except ImportError: | ||
| # Python 3 | ||
| long = int | ||
| IntType, LongType, FloatType, NoneType = int, long, float, type(None) | ||
| TupleType, ListType, DictType, InstanceType = tuple, list, dict, None | ||
| StringType, UnicodeType, ObjectType, BooleanType = bytes, str, object, bool | ||
|
|
||
| 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 o.__class__ in d: | ||
| return d[o.__class__](o, d) | ||
| cl = filter(lambda x,o=o: | ||
| type(x) is ClassType | ||
| and isinstance(o, x), d.keys()) | ||
| if not cl and hasattr(types, 'ObjectType'): | ||
| cl = filter(lambda x,o=o: | ||
| type(x) is 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 = { | ||
| IntType: Thing2Str, | ||
| LongType: Long2Int, | ||
| FloatType: Float2Str, | ||
| NoneType: None2NULL, | ||
| TupleType: escape_sequence, | ||
| ListType: escape_sequence, | ||
| DictType: escape_dict, | ||
| InstanceType: Instance2Str, | ||
| array.ArrayType: array2Str, | ||
| StringType: Thing2Literal, # default | ||
| UnicodeType: Unicode2Str, | ||
| ObjectType: Instance2Str, | ||
| 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 | ||
|
|
||
|
|
||
|
|
| @@ -0,0 +1,4 @@ | ||
|
|
||
| __author__ = "Andy Dustman <farcepest@gmail.com>" | ||
| version_info = (1,2,4,'beta',4) | ||
| __version__ = "1.2.4b4" |
| @@ -0,0 +1,111 @@ | ||
| """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.isoformat(" ") | ||
|
|
||
|
|
||
| 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 (SystemExit, KeyboardInterrupt): | ||
| raise | ||
| 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 (SystemExit, KeyboardInterrupt): | ||
| raise | ||
| 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 (SystemExit, KeyboardInterrupt): | ||
| raise | ||
| except: | ||
| return None |
| @@ -0,0 +1,43 @@ | ||
| Metadata-Version: 1.0 | ||
| Name: MySQL-python | ||
| Version: 1.2.4b4 | ||
| Summary: Python interface to MySQL | ||
| Home-page: http://sourceforge.net/projects/mysql-python | ||
| Author: Andy Dustman | ||
| Author-email: farcepest@gmail.com | ||
| License: GPL | ||
| Download-URL: http://osdn.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.4b4.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.5 and Python-2.4 through 2.7 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 |
| @@ -0,0 +1,41 @@ | ||
| MySQLdb1 | ||
| ======== | ||
|
|
||
| This is the legacy (1.x) version of MySQLdb. While it is still being | ||
| maintained, there will not be a lot of new feature development. | ||
|
|
||
| [](http://travis-ci.org/farcepest/MySQLdb1) | ||
|
|
||
| TODO | ||
| ---- | ||
|
|
||
| * A bugfix 1.2.4 release | ||
| * A 1.3.0 release that will support Python 2.7-3.3 | ||
| * The 2.0 version is being renamed [moist][] and is heavily refactored. | ||
|
|
||
| Projects | ||
| -------- | ||
|
|
||
| * [MySQLdb-svn][] | ||
|
|
||
| This is the old Subversion repository located on SourceForge. | ||
| It has all the early historical development of MySQLdb through 1.2.3, | ||
| and also is the working repository for ZMySQLDA. The trunk on this | ||
| repository was forked to create the [MySQLdb2][] repository. | ||
|
|
||
| * [MySQLdb1][] | ||
|
|
||
| This is the new (active) git repository. | ||
| Only updates to the 1.x series will happen here. | ||
|
|
||
| * [MySQLdb2][] | ||
|
|
||
| This is the now obsolete Mercurial repository for MySQLdb-2.0 | ||
| located on SourceForge. This repository has been migrated to the | ||
| [moist][] repository. | ||
|
|
||
|
|
||
| [MySQLdb1]: https://github.com/farcepest/MySQLdb1 | ||
| [moist]: https://github.com/farcepest/moist | ||
| [MySQLdb-svn]: https://sourceforge.net/p/mysql-python/svn/ | ||
| [MySQLdb2]: https://sourceforge.net/p/mysql-python/mysqldb-2/ |
| @@ -0,0 +1,87 @@ | ||
| """_mysql_exceptions: Exception classes for _mysql and MySQLdb. | ||
| These classes are dictated by the DB API v2.0: | ||
| http://www.python.org/topics/database/DatabaseAPI-2.0.html | ||
| """ | ||
|
|
||
| try: | ||
| from exceptions import Exception, StandardError, Warning | ||
| except ImportError: | ||
| # Python 3 | ||
| StandardError = Exception | ||
|
|
||
|
|
||
| class MySQLError(StandardError): | ||
|
|
||
| """Exception related to operation with MySQL.""" | ||
|
|
||
|
|
||
| class Warning(Warning, MySQLError): | ||
|
|
||
| """Exception raised for important warnings like data truncations | ||
| while inserting, etc.""" | ||
|
|
||
| class Error(MySQLError): | ||
|
|
||
| """Exception that is the base class of all other error exceptions | ||
| (not Warning).""" | ||
|
|
||
|
|
||
| class InterfaceError(Error): | ||
|
|
||
| """Exception raised for errors that are related to the database | ||
| interface rather than the database itself.""" | ||
|
|
||
|
|
||
| class DatabaseError(Error): | ||
|
|
||
| """Exception raised for errors that are related to the | ||
| database.""" | ||
|
|
||
|
|
||
| class DataError(DatabaseError): | ||
|
|
||
| """Exception raised for errors that are due to problems with the | ||
| processed data like division by zero, numeric value out of range, | ||
| etc.""" | ||
|
|
||
|
|
||
| class OperationalError(DatabaseError): | ||
|
|
||
| """Exception raised for errors that are related to the database's | ||
| operation and not necessarily under the control of the programmer, | ||
| e.g. an unexpected disconnect occurs, the data source name is not | ||
| found, a transaction could not be processed, a memory allocation | ||
| error occurred during processing, etc.""" | ||
|
|
||
|
|
||
| class IntegrityError(DatabaseError): | ||
|
|
||
| """Exception raised when the relational integrity of the database | ||
| is affected, e.g. a foreign key check fails, duplicate key, | ||
| etc.""" | ||
|
|
||
|
|
||
| class InternalError(DatabaseError): | ||
|
|
||
| """Exception raised when the database encounters an internal | ||
| error, e.g. the cursor is not valid anymore, the transaction is | ||
| out of sync, etc.""" | ||
|
|
||
|
|
||
| class ProgrammingError(DatabaseError): | ||
|
|
||
| """Exception raised for programming errors, e.g. table not found | ||
| or already exists, syntax error in the SQL statement, wrong number | ||
| of parameters specified, etc.""" | ||
|
|
||
|
|
||
| class NotSupportedError(DatabaseError): | ||
|
|
||
| """Exception raised in case a method or database API was used | ||
| which is not supported by the database, e.g. requesting a | ||
| .rollback() on a connection that does not support transaction or | ||
| has transactions turned off.""" | ||
|
|
||
|
|
| @@ -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$"""[11:-2] | ||
| from MySQLdb.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 MySQLdb.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'] | ||
|
|
||
|
|
||
|
|
||
|
|
| @@ -0,0 +1,337 @@ | ||
| """ | ||
| 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 _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 MySQLdb.constants import CLIENT, FIELD_TYPE | ||
| from MySQLdb.converters import conversions | ||
| from weakref import proxy, WeakValueDictionary | ||
|
|
||
| import types | ||
|
|
||
| kwargs2 = kwargs.copy() | ||
|
|
||
| if 'conv' in kwargs: | ||
| 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 | ||
|
|
||
| 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.cursorclass = cursorclass | ||
| 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 charset == "utf8mb4": | ||
| py_charset = "utf8" | ||
| else: | ||
| py_charset = charset | ||
| 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 = py_charset | ||
| self.unicode_literal.charset = py_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 |
| @@ -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 | ||
|
|
||
|
|
| @@ -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 |
| @@ -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 |
| @@ -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 |
| @@ -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 |
| @@ -0,0 +1 @@ | ||
| __all__ = ['CR', 'FIELD_TYPE','CLIENT','REFRESH','ER','FLAG'] |
| @@ -0,0 +1,181 @@ | ||
| """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 MySQLdb.constants import FIELD_TYPE, FLAG | ||
| from MySQLdb.times import * | ||
|
|
||
| try: | ||
| from types import IntType, LongType, FloatType, NoneType, TupleType, ListType, DictType, InstanceType, \ | ||
| StringType, UnicodeType, ObjectType, BooleanType, ClassType, TypeType | ||
| except ImportError: | ||
| # Python 3 | ||
| long = int | ||
| IntType, LongType, FloatType, NoneType = int, long, float, type(None) | ||
| TupleType, ListType, DictType, InstanceType = tuple, list, dict, None | ||
| StringType, UnicodeType, ObjectType, BooleanType = bytes, str, object, bool | ||
|
|
||
| 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 o.__class__ in d: | ||
| return d[o.__class__](o, d) | ||
| cl = filter(lambda x,o=o: | ||
| type(x) is ClassType | ||
| and isinstance(o, x), d.keys()) | ||
| if not cl and hasattr(types, 'ObjectType'): | ||
| cl = filter(lambda x,o=o: | ||
| type(x) is 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 = { | ||
| IntType: Thing2Str, | ||
| LongType: Long2Int, | ||
| FloatType: Float2Str, | ||
| NoneType: None2NULL, | ||
| TupleType: escape_sequence, | ||
| ListType: escape_sequence, | ||
| DictType: escape_dict, | ||
| InstanceType: Instance2Str, | ||
| array.ArrayType: array2Str, | ||
| StringType: Thing2Literal, # default | ||
| UnicodeType: Unicode2Str, | ||
| ObjectType: Instance2Str, | ||
| 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 | ||
|
|
||
|
|
||
|
|
| @@ -0,0 +1,4 @@ | ||
|
|
||
| __author__ = "Andy Dustman <farcepest@gmail.com>" | ||
| version_info = (1,2,4,'beta',4) | ||
| __version__ = "1.2.4b4" |
| @@ -0,0 +1,111 @@ | ||
| """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.isoformat(" ") | ||
|
|
||
|
|
||
| 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 (SystemExit, KeyboardInterrupt): | ||
| raise | ||
| 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 (SystemExit, KeyboardInterrupt): | ||
| raise | ||
| 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 (SystemExit, KeyboardInterrupt): | ||
| raise | ||
| except: | ||
| return None |
| @@ -0,0 +1,87 @@ | ||
| """_mysql_exceptions: Exception classes for _mysql and MySQLdb. | ||
| These classes are dictated by the DB API v2.0: | ||
| http://www.python.org/topics/database/DatabaseAPI-2.0.html | ||
| """ | ||
|
|
||
| try: | ||
| from exceptions import Exception, StandardError, Warning | ||
| except ImportError: | ||
| # Python 3 | ||
| StandardError = Exception | ||
|
|
||
|
|
||
| class MySQLError(StandardError): | ||
|
|
||
| """Exception related to operation with MySQL.""" | ||
|
|
||
|
|
||
| class Warning(Warning, MySQLError): | ||
|
|
||
| """Exception raised for important warnings like data truncations | ||
| while inserting, etc.""" | ||
|
|
||
| class Error(MySQLError): | ||
|
|
||
| """Exception that is the base class of all other error exceptions | ||
| (not Warning).""" | ||
|
|
||
|
|
||
| class InterfaceError(Error): | ||
|
|
||
| """Exception raised for errors that are related to the database | ||
| interface rather than the database itself.""" | ||
|
|
||
|
|
||
| class DatabaseError(Error): | ||
|
|
||
| """Exception raised for errors that are related to the | ||
| database.""" | ||
|
|
||
|
|
||
| class DataError(DatabaseError): | ||
|
|
||
| """Exception raised for errors that are due to problems with the | ||
| processed data like division by zero, numeric value out of range, | ||
| etc.""" | ||
|
|
||
|
|
||
| class OperationalError(DatabaseError): | ||
|
|
||
| """Exception raised for errors that are related to the database's | ||
| operation and not necessarily under the control of the programmer, | ||
| e.g. an unexpected disconnect occurs, the data source name is not | ||
| found, a transaction could not be processed, a memory allocation | ||
| error occurred during processing, etc.""" | ||
|
|
||
|
|
||
| class IntegrityError(DatabaseError): | ||
|
|
||
| """Exception raised when the relational integrity of the database | ||
| is affected, e.g. a foreign key check fails, duplicate key, | ||
| etc.""" | ||
|
|
||
|
|
||
| class InternalError(DatabaseError): | ||
|
|
||
| """Exception raised when the database encounters an internal | ||
| error, e.g. the cursor is not valid anymore, the transaction is | ||
| out of sync, etc.""" | ||
|
|
||
|
|
||
| class ProgrammingError(DatabaseError): | ||
|
|
||
| """Exception raised for programming errors, e.g. table not found | ||
| or already exists, syntax error in the SQL statement, wrong number | ||
| of parameters specified, etc.""" | ||
|
|
||
|
|
||
| class NotSupportedError(DatabaseError): | ||
|
|
||
| """Exception raised in case a method or database API was used | ||
| which is not supported by the database, e.g. requesting a | ||
| .rollback() on a connection that does not support transaction or | ||
| has transactions turned off.""" | ||
|
|
||
|
|
| @@ -0,0 +1,143 @@ | ||
| ==================================== | ||
| MySQLdb Frequently Asked Questions | ||
| ==================================== | ||
|
|
||
| .. contents:: | ||
| .. | ||
|
|
||
|
|
||
| Build Errors | ||
| ------------ | ||
|
|
||
| ld: fatal: library -lmysqlclient_r: not found | ||
|
|
||
| mysqlclient_r is the thread-safe library. It's not available on | ||
| all platforms, or all installations, apparently. You'll need to | ||
| reconfigure site.cfg (in MySQLdb-1.2.1 and newer) to have | ||
| threadsafe = False. | ||
|
|
||
| mysql.h: No such file or directory | ||
|
|
||
| This almost always mean you don't have development packages | ||
| installed. On some systems, C headers for various things (like MySQL) | ||
| are distributed as a seperate package. You'll need to figure out | ||
| what that is and install it, but often the name ends with -devel. | ||
|
|
||
| Another possibility: Some older versions of mysql_config behave oddly | ||
| and may throw quotes around some of the path names, which confused | ||
| MySQLdb-1.2.0. 1.2.1 works around these problems. If you see things | ||
| like -I'/usr/local/include/mysql' in your compile command, that's | ||
| probably the issue, but it shouldn't happen any more. | ||
|
|
||
|
|
||
| ImportError | ||
| ----------- | ||
|
|
||
| ImportError: No module named _mysql | ||
|
|
||
| If you see this, it's likely you did some wrong when installing | ||
| MySQLdb; re-read (or read) README. _mysql is the low-level C module | ||
| that interfaces with the MySQL client library. | ||
|
|
||
| Various versions of MySQLdb in the past have had build issues on | ||
| "weird" platforms; "weird" in this case means "not Linux", though | ||
| generally there aren't problems on Unix/POSIX platforms, including | ||
| BSDs and Mac OS X. Windows has been more problematic, in part because | ||
| there is no `mysql_config` available in the Windows installation of | ||
| MySQL. 1.2.1 solves most, if not all, of these problems, but you will | ||
| still have to edit a configuration file so that the setup knows where | ||
| to find MySQL and what libraries to include. | ||
|
|
||
|
|
||
| ImportError: libmysqlclient_r.so.14: cannot open shared object file: No such file or directory | ||
|
|
||
| The number after .so may vary, but this means you have a version of | ||
| MySQLdb compiled against one version of MySQL, and are now trying to | ||
| run it against a different version. The shared library version tends | ||
| to change between major releases. | ||
|
|
||
| Solution: Rebuilt MySQLdb, or get the matching version of MySQL. | ||
|
|
||
| Another thing that can cause this: The MySQL libraries may not be on | ||
| your system path. | ||
|
|
||
| Solutions: | ||
|
|
||
| * set the LD_LIBRARY_PATH environment variable so that it includes | ||
| the path to the MySQL libraries. | ||
|
|
||
| * set static=True in site.cfg for static linking | ||
|
|
||
| * reconfigure your system so that the MySQL libraries are on the | ||
| default loader path. In Linux, you edit /etc/ld.so.conf and run | ||
| ldconfig. For Solaris, see `Linker and Libraries Guide | ||
| <http://docs.sun.com/app/docs/doc/817-3677/6mj8mbtbe?a=view>`_. | ||
|
|
||
|
|
||
| ImportError: ld.so.1: python: fatal: libmtmalloc.so.1: DF_1_NOOPEN tagged object may not be dlopen()'ed | ||
|
|
||
| This is a weird one from Solaris. What does it mean? I have no idea. | ||
| However, things like this can happen if there is some sort of a compiler | ||
| or environment mismatch between Python and MySQL. For example, on some | ||
| commercial systems, you might have some code compiled with their own | ||
| compiler, and other things compiled with GCC. They don't always mesh | ||
| together. One way to encounter this is by getting binary packages from | ||
| different vendors. | ||
|
|
||
| Solution: Rebuild Python or MySQL (or maybe both) from source. | ||
|
|
||
| ImportError: dlopen(./_mysql.so, 2): Symbol not found: _sprintf$LDBLStub | ||
| Referenced from: ./_mysql.so | ||
| Expected in: dynamic lookup | ||
|
|
||
| This is one from Mac OS X. It seems to have been a compiler mismatch, | ||
| but this time between two different versions of GCC. It seems nearly | ||
| every major release of GCC changes the ABI in some why, so linking | ||
| code compiled with GCC-3.3 and GCC-4.0, for example, can be | ||
| problematic. | ||
|
|
||
|
|
||
| My data disappeared! (or won't go away!) | ||
| ---------------------------------------- | ||
|
|
||
| Starting with 1.2.0, MySQLdb disables autocommit by default, as | ||
| required by the DB-API standard (`PEP-249`_). If you are using InnoDB | ||
| tables or some other type of transactional table type, you'll need | ||
| to do connection.commit() before closing the connection, or else | ||
| none of your changes will be written to the database. | ||
|
|
||
| Conversely, you can also use connection.rollback() to throw away | ||
| any changes you've made since the last commit. | ||
|
|
||
| Important note: Some SQL statements -- specifically DDL statements | ||
| like CREATE TABLE -- are non-transactional, so they can't be | ||
| rolled back, and they cause pending transactions to commit. | ||
|
|
||
|
|
||
| Other Errors | ||
| ------------ | ||
|
|
||
| OperationalError: (1251, 'Client does not support authentication protocol requested by server; consider upgrading MySQL client') | ||
|
|
||
| This means your server and client libraries are not the same version. | ||
| More specifically, it probably means you have a 4.1 or newer server | ||
| and 4.0 or older client. You can either upgrade the client side, or | ||
| try some of the workarounds in `Password Hashing as of MySQL 4.1 | ||
| <http://dev.mysql.com/doc/refman/5.0/en/password-hashing.html>`_. | ||
|
|
||
|
|
||
| Other Resources | ||
| --------------- | ||
|
|
||
| * Help forum. Please search before posting. | ||
|
|
||
| * `Google <http://www.google.com/>`_ | ||
|
|
||
| * READ README! | ||
|
|
||
| * Read the User's Guide | ||
|
|
||
| * Read `PEP-249`_ | ||
|
|
||
| .. _`PEP-249`: http://www.python.org/peps/pep-0249.html | ||
|
|
| @@ -0,0 +1,58 @@ | ||
| [metadata] | ||
| version: 1.2.4b4 | ||
| version_info: (1,2,4,'beta',4) | ||
| description: Python interface to MySQL | ||
| long_description: | ||
| ========================= | ||
| Python interface to MySQL | ||
| ========================= | ||
| \n | ||
| MySQLdb is an interface to the popular MySQL_ database server for | ||
| Python. The design goals are: | ||
| \n | ||
| - Compliance with Python database API version 2.0 [PEP-0249]_ | ||
| - Thread-safety | ||
| - Thread-friendliness (threads will not block each other) | ||
| \n | ||
| MySQL-3.23 through 5.5 and Python-2.4 through 2.7 are currently | ||
| supported. Python-3.0 will be supported in a future release. | ||
| \n | ||
| MySQLdb is `Free Software`_. | ||
| \n | ||
| .. _MySQL: http://www.mysql.com/ | ||
| .. _`Free Software`: http://www.gnu.org/ | ||
| .. [PEP-0249] http://www.python.org/peps/pep-0249.html | ||
| author: Andy Dustman | ||
| author_email: farcepest@gmail.com | ||
| license: GPL | ||
| platforms: ALL | ||
| url: http://sourceforge.net/projects/mysql-python | ||
| download_url: http://osdn.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-%(version)s.tar.gz | ||
| classifiers: | ||
| Development Status :: 5 - Production/Stable | ||
| Environment :: Other Environment | ||
| License :: OSI Approved :: GNU General Public License (GPL) | ||
| Operating System :: MacOS :: MacOS X | ||
| Operating System :: Microsoft :: Windows :: Windows NT/2000 | ||
| Operating System :: OS Independent | ||
| Operating System :: POSIX | ||
| Operating System :: POSIX :: Linux | ||
| Operating System :: Unix | ||
| Programming Language :: C | ||
| Programming Language :: Python | ||
| Topic :: Database | ||
| Topic :: Database :: Database Engines/Servers | ||
| py_modules: | ||
| _mysql_exceptions | ||
| MySQLdb.converters | ||
| MySQLdb.connections | ||
| MySQLdb.cursors | ||
| MySQLdb.release | ||
| MySQLdb.times | ||
| MySQLdb.constants.CR | ||
| MySQLdb.constants.FIELD_TYPE | ||
| MySQLdb.constants.ER | ||
| MySQLdb.constants.FLAG | ||
| MySQLdb.constants.REFRESH | ||
| MySQLdb.constants.CLIENT | ||
|
|
| @@ -0,0 +1,87 @@ | ||
|
|
||
| /* The idea of this file is that you bundle it with your extension, | ||
| #include it, program to Python 2.3's memory API and have your | ||
| extension build with any version of Python from 1.5.2 through to | ||
| 2.3 (and hopefully beyond). */ | ||
|
|
||
| #ifndef Py_PYMEMCOMPAT_H | ||
| #define Py_PYMEMCOMPAT_H | ||
|
|
||
| #include "Python.h" | ||
|
|
||
| /* There are three "families" of memory API: the "raw memory", "object | ||
| memory" and "object" families. (This is ignoring the matter of the | ||
| cycle collector, about which more is said below). | ||
| Raw Memory: | ||
| PyMem_Malloc, PyMem_Realloc, PyMem_Free | ||
| Object Memory: | ||
| PyObject_Malloc, PyObject_Realloc, PyObject_Free | ||
| Object: | ||
| PyObject_New, PyObject_NewVar, PyObject_Del | ||
| The raw memory and object memory allocators both mimic the | ||
| malloc/realloc/free interface from ANSI C, but the object memory | ||
| allocator can (and, since 2.3, does by default) use a different | ||
| allocation strategy biased towards lots of lots of "small" | ||
| allocations. | ||
| The object family is used for allocating Python objects, and the | ||
| initializers take care of some basic initialization (setting the | ||
| refcount to 1 and filling out the ob_type field) as well as having | ||
| a somewhat different interface. | ||
| Do not mix the families! E.g. do not allocate memory with | ||
| PyMem_Malloc and free it with PyObject_Free. You may get away with | ||
| it quite a lot of the time, but there *are* scenarios where this | ||
| will break. You Have Been Warned. | ||
| Also, in many versions of Python there are an insane amount of | ||
| memory interfaces to choose from. Use the ones described above. */ | ||
|
|
||
| #if PY_VERSION_HEX < 0x01060000 | ||
| /* raw memory interface already present */ | ||
|
|
||
| /* there is no object memory interface in 1.5.2 */ | ||
| #define PyObject_Malloc PyMem_Malloc | ||
| #define PyObject_Realloc PyMem_Realloc | ||
| #define PyObject_Free PyMem_Free | ||
|
|
||
| /* the object interface is there, but the names have changed */ | ||
| #define PyObject_New PyObject_NEW | ||
| #define PyObject_NewVar PyObject_NEW_VAR | ||
| #define PyObject_Del PyMem_Free | ||
| #endif | ||
|
|
||
| /* If your object is a container you probably want to support the | ||
| cycle collector, which was new in Python 2.0. | ||
| Unfortunately, the interface to the collector that was present in | ||
| Python 2.0 and 2.1 proved to be tricky to use, and so changed in | ||
| 2.2 -- in a way that can't easily be papered over with macros. | ||
| This file contains macros that let you program to the 2.2 GC API. | ||
| Your module will compile against any Python since version 1.5.2, | ||
| but the type will only participate in the GC in versions 2.2 and | ||
| up. Some work is still necessary on your part to only fill out the | ||
| tp_traverse and tp_clear fields when they exist and set tp_flags | ||
| appropriately. | ||
| It is possible to support both the 2.0 and 2.2 GC APIs, but it's | ||
| not pretty and this comment block is too narrow to contain a | ||
| desciption of what's required... */ | ||
|
|
||
| #if PY_VERSION_HEX < 0x020200B1 | ||
| #define PyObject_GC_New PyObject_New | ||
| #define PyObject_GC_NewVar PyObject_NewVar | ||
| #define PyObject_GC_Del PyObject_Del | ||
| #define PyObject_GC_Track(op) | ||
| #define PyObject_GC_UnTrack(op) | ||
| #endif | ||
|
|
||
| #endif /* !Py_PYMEMCOMPAT_H */ |
| @@ -0,0 +1,19 @@ | ||
| [test] | ||
| test_suite = nose.collector | ||
|
|
||
| [bdist_rpm] | ||
| vendor = MySQL-python SourceForge Project | ||
| install-requires = distribute | ||
| doc_files = README MANIFEST doc/*.txt | ||
| distribution-name = Red Stains Linux | ||
| packager = Andy Dustman <adustman@users.sourceforge.net> | ||
| requires = python | ||
| build-requires = python-devel mysql-devel zlib-devel openssl-devel | ||
|
|
||
| [egg_info] | ||
| tag_build = | ||
| tag_date = 0 | ||
| tag_svn_revision = 0 | ||
|
|
||
| [build_ext] | ||
|
|
| @@ -0,0 +1,21 @@ | ||
| #!/usr/bin/env python | ||
|
|
||
| import os | ||
| import sys | ||
|
|
||
| from distribute_setup import use_setuptools | ||
| use_setuptools() | ||
| from setuptools import setup, Extension | ||
|
|
||
| if not hasattr(sys, "hexversion") or sys.hexversion < 0x02040000: | ||
| raise Error("Python 2.4 or newer is required") | ||
|
|
||
| if os.name == "posix": | ||
| from setup_posix import get_config | ||
| else: # assume windows | ||
| from setup_windows import get_config | ||
|
|
||
| metadata, options = get_config() | ||
| metadata['ext_modules'] = [Extension(sources=['_mysql.c'], **options)] | ||
| metadata['long_description'] = metadata['long_description'].replace(r'\n', '') | ||
| setup(**metadata) |
| @@ -0,0 +1,37 @@ | ||
| try: | ||
| # Python 2.x | ||
| from ConfigParser import SafeConfigParser | ||
| except ImportError: | ||
| # Python 3.x | ||
| from configparser import ConfigParser as SafeConfigParser | ||
|
|
||
| def get_metadata_and_options(): | ||
| config = SafeConfigParser() | ||
| config.read(['metadata.cfg', 'site.cfg']) | ||
|
|
||
| metadata = dict(config.items('metadata')) | ||
| options = dict(config.items('options')) | ||
|
|
||
| metadata['py_modules'] = list(filter(None, metadata['py_modules'].split('\n'))) | ||
| metadata['classifiers'] = list(filter(None, metadata['classifiers'].split('\n'))) | ||
|
|
||
| return metadata, options | ||
|
|
||
| def enabled(options, option): | ||
| value = options[option] | ||
| s = value.lower() | ||
| if s in ('yes','true','1','y'): | ||
| return True | ||
| elif s in ('no', 'false', '0', 'n'): | ||
| return False | ||
| else: | ||
| raise ValueError("Unknown value %s for option %s" % (value, option)) | ||
|
|
||
| def create_release_file(metadata): | ||
| rel = open("MySQLdb/release.py",'w') | ||
| rel.write(""" | ||
| __author__ = "%(author)s <%(author_email)s>" | ||
| version_info = %(version_info)s | ||
| __version__ = "%(version)s" | ||
| """ % metadata) | ||
| rel.close() |
| @@ -0,0 +1,102 @@ | ||
| import os, sys | ||
| from ConfigParser import SafeConfigParser | ||
|
|
||
| # This dequote() business is required for some older versions | ||
| # of mysql_config | ||
|
|
||
| def dequote(s): | ||
| if s[0] in "\"'" and s[0] == s[-1]: | ||
| s = s[1:-1] | ||
| return s | ||
|
|
||
| def compiler_flag(f): | ||
| return "-%s" % f | ||
|
|
||
| def mysql_config(what): | ||
| from os import popen | ||
|
|
||
| f = popen("%s --%s" % (mysql_config.path, what)) | ||
| data = f.read().strip().split() | ||
| ret = f.close() | ||
| if ret: | ||
| if ret/256: | ||
| data = [] | ||
| if ret/256 > 1: | ||
| raise EnvironmentError("%s not found" % (mysql_config.path,)) | ||
| return data | ||
| mysql_config.path = "mysql_config" | ||
|
|
||
| def get_config(): | ||
| from setup_common import get_metadata_and_options, enabled, create_release_file | ||
|
|
||
| metadata, options = get_metadata_and_options() | ||
|
|
||
| if 'mysql_config' in options: | ||
| mysql_config.path = options['mysql_config'] | ||
|
|
||
| extra_objects = [] | ||
| static = enabled(options, 'static') | ||
| if enabled(options, 'embedded'): | ||
| libs = mysql_config("libmysqld-libs") | ||
| client = "mysqld" | ||
| elif enabled(options, 'threadsafe'): | ||
| libs = mysql_config("libs_r") | ||
| client = "mysqlclient_r" | ||
| if not libs: | ||
| libs = mysql_config("libs") | ||
| client = "mysqlclient" | ||
| else: | ||
| libs = mysql_config("libs") | ||
| client = "mysqlclient" | ||
|
|
||
| library_dirs = [ dequote(i[2:]) for i in libs if i.startswith(compiler_flag("L")) ] | ||
| libraries = [ dequote(i[2:]) for i in libs if i.startswith(compiler_flag("l")) ] | ||
|
|
||
| removable_compile_args = [ compiler_flag(f) for f in "ILl" ] | ||
| extra_compile_args = [ i.replace("%", "%%") for i in mysql_config("cflags") | ||
| if i[:2] not in removable_compile_args ] | ||
|
|
||
| # Copy the arch flags for linking as well | ||
| extra_link_args = list() | ||
| for i in range(len(extra_compile_args)): | ||
| if extra_compile_args[i] == '-arch': | ||
| extra_link_args += ['-arch', extra_compile_args[i + 1]] | ||
|
|
||
| include_dirs = [ dequote(i[2:]) | ||
| for i in mysql_config('include') | ||
| if i.startswith(compiler_flag('I')) ] | ||
| if not include_dirs: # fix for MySQL-3.23 | ||
| include_dirs = [ dequote(i[2:]) | ||
| for i in mysql_config('cflags') | ||
| if i.startswith(compiler_flag('I')) ] | ||
|
|
||
| if static: | ||
| extra_objects.append(os.path.join( | ||
| library_dirs[0],'lib%s.a' % client)) | ||
|
|
||
| name = "MySQL-python" | ||
| if enabled(options, 'embedded'): | ||
| name = name + "-embedded" | ||
| metadata['name'] = name | ||
|
|
||
| define_macros = [ | ||
| ('version_info', metadata['version_info']), | ||
| ('__version__', metadata['version']), | ||
| ] | ||
| create_release_file(metadata) | ||
| del metadata['version_info'] | ||
| ext_options = dict( | ||
| name = "_mysql", | ||
| library_dirs = library_dirs, | ||
| libraries = libraries, | ||
| extra_compile_args = extra_compile_args, | ||
| extra_link_args = extra_link_args, | ||
| include_dirs = include_dirs, | ||
| extra_objects = extra_objects, | ||
| define_macros = define_macros, | ||
| ) | ||
| return metadata, ext_options | ||
|
|
||
| if __name__ == "__main__": | ||
| sys.stderr.write("""You shouldn't be running this directly; it is used by setup.py.""") | ||
|
|
| @@ -0,0 +1,46 @@ | ||
| import os, sys | ||
|
|
||
| def get_config(): | ||
| from setup_common import get_metadata_and_options, enabled, create_release_file | ||
|
|
||
| metadata, options = get_metadata_and_options() | ||
|
|
||
| connector = options["connector"] | ||
|
|
||
| extra_objects = [] | ||
|
|
||
| if enabled(options, 'embedded'): | ||
| client = "mysqld" | ||
| else: | ||
| client = "mysqlclient" | ||
|
|
||
| library_dirs = [ os.path.join(connector, r'lib\opt') ] | ||
| libraries = [ 'kernel32', 'advapi32', 'wsock32', client ] | ||
| include_dirs = [ os.path.join(connector, r'include') ] | ||
| extra_compile_args = [ '/Zl' ] | ||
|
|
||
| name = "MySQL-python" | ||
| if enabled(options, 'embedded'): | ||
| name = name + "-embedded" | ||
| metadata['name'] = name | ||
|
|
||
| define_macros = [ | ||
| ('version_info', metadata['version_info']), | ||
| ('__version__', metadata['version']), | ||
| ] | ||
| create_release_file(metadata) | ||
| del metadata['version_info'] | ||
| ext_options = dict( | ||
| name = "_mysql", | ||
| library_dirs = library_dirs, | ||
| libraries = libraries, | ||
| extra_compile_args = extra_compile_args, | ||
| include_dirs = include_dirs, | ||
| extra_objects = extra_objects, | ||
| define_macros = define_macros, | ||
| ) | ||
| return metadata, ext_options | ||
|
|
||
| if __name__ == "__main__": | ||
| sys.stderr.write("""You shouldn't be running this directly; it is used by setup.py.""") | ||
|
|
| @@ -0,0 +1,17 @@ | ||
| [options] | ||
| # embedded: link against the embedded server library | ||
| # threadsafe: use the threadsafe client | ||
| # static: link against a static library (probably required for embedded) | ||
|
|
||
| embedded = False | ||
| threadsafe = True | ||
| static = False | ||
|
|
||
| # The path to mysql_config. | ||
| # Only use this if mysql_config is not on your PATH, or you have some weird | ||
| # setup that requires it. | ||
| #mysql_config = /usr/local/bin/mysql_config | ||
|
|
||
| # http://stackoverflow.com/questions/1972259/mysql-python-install-problem-using-virtualenv-windows-pip | ||
| # Windows connector libs for MySQL. You need a 32-bit connector for your 32-bit Python build. | ||
| connector = C:\Program Files (x86)\MySQL\MySQL Connector C 6.0.2 |