diff --git a/MySQLdb/ChangeLog b/MySQLdb/ChangeLog deleted file mode 100644 index c7f9ece..0000000 --- a/MySQLdb/ChangeLog +++ /dev/null @@ -1,691 +0,0 @@ -2004-09-19 adustman - - * _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py: - * Removed some old-style Python stuff from setup.py - - * Added a bit of documentation on ssl parameter to Connection - - * Version 1.1.5 - - * MANIFEST.in: Include new ChangeLog - - * setup.py: Restore missing common on include_dirs - -2004-09-11 adustman - - * ChangeLog: *** empty log message *** - - * _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py: - Version 1.1.4 - - * setup.py: changed include and library path order - - * MySQLdb/connections.py: fix super class reference in autocommit() - - * Tested against MySQL-4.1.4a with InnoDB tables - - * _mysql.c: Re-fix typo - - * _mysql.c: - Fix _mysql_Execption() typo. Code is only compiled when MySQL-4.1 - is in use, and I haven't done any actual testing against 4.1 yet. - Please report any bugs to the SourceForge tracker. - -2004-09-11 adustman - - * _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py: - Version 1.1.4 - - * setup.py: changed include and library path order - - * MySQLdb/connections.py: fix super class reference in autocommit() - - * Tested against MySQL-4.1.4a with InnoDB tables - - * _mysql.c: Re-fix typo - - * _mysql.c: - Fix _mysql_Execption() typo. Code is only compiled when MySQL-4.1 - is in use, and I haven't done any actual testing against 4.1 yet. - Please report any bugs to the SourceForge tracker. - -2004-09-08 adustman - - * _mysql.c, setup.py, MySQLdb/__init__.py: Version 1.1.3 - - * _mysql.c: restored missing mysql_errno() call (bug #1023466) - - * _mysql.c: Only try to use SSL support if HAVE_OPENSSL is defined. - Raise NotSupportedError if ssl is requested but not available. - -2004-09-06 adustman - - * ChangeLog, _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, MySQLdb/cursors.py, MySQLdb/times.py: - General cleanups. - - * Turn autocommit off initially - - * Add support for mysql_autocommit, _commit, and _rollback API functions - (new in MySQL-4.1) - - * Remove Connection.begin(); use SQL BEGIN or START TRANSACTION instead - - * pytimes (standard datetime module) is now the default implementation - - * Detect and handle MySQL-4.1 and newer TIMESTAMP (looks like DATETIME) - - * UnicodeType and ObjectType now always handled (required features) - - * Ditch support for L at the end of long integer - - * Remove z and crypt libs if building for Windows - - * Version 1.1.2 - - * setup.py: Don't include z and crypt libs on Windows. - - * _mysql.c: Conditionally define uint on all platforms. - - * MySQLdb/cursors.py: Fix indentation error (again) - - * _mysql.c: Fix bug #992756: - - * Embedded server: List of groups was not NULL-terminated correctly. - - * MySQLdb/cursors.py: Fix bug #989262: - - * Changed errant tab to spaces in cursors.py - - * _mysql.c, setup.py, MySQLdb/__init__.py: Fixes for bug #999588: - - * Use os.environ.get() instead of os.getenv() in setup.py - - * Use PySequence_Length() instead of PySequence_Check() in _mysql.c - - Bump version to 1.0.1b1 - -2004-09-06 adustman - - * ChangeLog, _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, MySQLdb/cursors.py, MySQLdb/times.py: - General cleanups. - - * Turn autocommit off initially - - * Add support for mysql_autocommit, _commit, and _rollback API functions - (new in MySQL-4.1) - - * Remove Connection.begin(); use SQL BEGIN or START TRANSACTION instead - - * pytimes (standard datetime module) is now the default implementation - - * Detect and handle MySQL-4.1 and newer TIMESTAMP (looks like DATETIME) - - * UnicodeType and ObjectType now always handled (required features) - - * Ditch support for L at the end of long integer - - * Remove z and crypt libs if building for Windows - - * Version 1.1.2 - - * setup.py: Don't include z and crypt libs on Windows. - - * _mysql.c: Conditionally define uint on all platforms. - - * MySQLdb/cursors.py: Fix indentation error (again) - - * _mysql.c: Fix bug #992756: - - * Embedded server: List of groups was not NULL-terminated correctly. - - * MySQLdb/cursors.py: Fix bug #989262: - - * Changed errant tab to spaces in cursors.py - - * _mysql.c, setup.py, MySQLdb/__init__.py: Fixes for bug #999588: - - * Use os.environ.get() instead of os.getenv() in setup.py - - * Use PySequence_Length() instead of PySequence_Check() in _mysql.c - - Bump version to 1.0.1b1 - -2004-06-07 adustman - - * MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/cursors.py, README, _mysql.c, setup.py: - Bump version. Update README. Convert all classes to new-style. - -2004-06-06 adustman - - * README, _mysql.c, setup.py, MySQLdb/__init__.py: 1.0.0 (D-Day) - -2004-05-19 adustman - - * MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, MySQLdb/cursors.py, MySQLdb/mxdatetimes.py, MySQLdb/pytimes.py, MySQLdb/sets.py, MySQLdb/times.py, _mysql.c, _mysql_exceptions.py, setup.cfg, setup.py: - Initial conversion to modern Python. - - * _mysql.c, setup.py, MySQLdb/__init__.py: Version bump (1.0.0c2) - -2004-05-18 adustman - - * MySQLdb/pytimes.py: Fix bug #933911 - - * _mysql.c: Fix bug #955031 - - * setup.cfg: Fix bug #955032 - -2004-05-16 adustman - - * MySQLdb/__init__.py, _mysql.c, setup.py: Version Bump - -2004-02-29 adustman - - * setup.py: Fix bug #897344 - - * MySQLdb/__init__.py: Fix bug #902024 - -2003-12-30 adustman - - * _mysql.c, setup.py, MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py: - * Check for module initialization failure (extremely rare) - - * The MySQL FIELD_TYPE converter can now be a sequence of 2-tuples. - Item 0 is a bit mask (using FLAG.*) which must be matched. This should - be an integer. Item 1 is the conversion function. If item 0 is not an - integer, then this function is considered the default converter for - this FIELD_TYPE. Note that these tuples are considered when the query - has been executed and the result is available, so it doesn't add a - per-row overhead. - - * As a result of the above, BINARY BLOB fields are now returned as - character arrays using the array.array class. Non-BINARY BLOB fields - (i.e. TEXT) are returned as strings. If unicode is enabled, they are - returned as unicode strings. - - * Bump version to 0.9.3b3. - -2003-12-13 adustman - - * MySQLdb/converters.py: - https://sourceforge.net/tracker/?func=detail&aid=850174&group_id=22307&atid=374932 - - Use more precision for floats; str() doesn't return full precision. - -2003-11-27 adustman - - * _mysql.c: Preliminary SSL support. Adds a ssl parameter to connect(). - ssl should be a mapping. These are the recognized keys: - - ca*, cert*, capath, key*, cipher - - Items marked with * are required. All values must be strings. - They are described here: - - http://www.mysql.com/doc/en/SSL_options.html - - You're probably better off putting these variables into an - option file and using read_option_file instead. - - SSL is supported in MySQL-4.0 and newer. Even if you don't - specify all the required parameters, the connection will probably - succeed, although without SSL. - - This is not yet tested in any significant way. - -2003-11-23 adustman - - * _mysql.c, setup.py, MySQLdb/__init__.py: Version bump - - * MySQLdb/converters.py, MySQLdb/mxdatetimes.py, MySQLdb/pytimes.py, MySQLdb/stringtimes.py, MySQLdb/times.py: - Time-handling updates. New load order is: - - mxdatetime (wrapper around mx.DateTime) - pytimes (wrapper around Python-2.3+ datetime) - stringtimes (minimal string implementation) - - The logic is, if you're running Python-2.3 and are have mx.Datetime, - you probably want to use that instead of datetime. - -2003-11-22 adustman - - * MySQLdb/pytimes.py: Bug #816721 - - * _mysql.c: Bug #811636 fix (?) - -2003-09-07 adustman - - * MySQLdb/cursors.py: info() might return None or empty string - - * MySQLdb/connections.py: - Don't treat FIELD_TYPE.CHAR as a character type, it's really - a TINYINT (FIELD_TYPE.TINY). - - * MySQLdb/connections.py, _mysql.c: Bug#778822 - - * setup.py: Fix version number correctly - - * setup.py, MySQLdb/__init__.py, _mysql.c: Version bump - -2003-07-11 adustman - - * setup.py: Include new time handling modules - - * MySQLdb/mxdatetimes.py, MySQLdb/stringtimes.py: - Split out old Date/Time handling classes into separate modules - - * MySQLdb/pytimes.py: Finish up TimeDelta_or_None - -2003-07-10 adustman - - * CHANGELOG, MySQLdb/times.py: - Add support for Python 2.3 datetime classes. - -2003-07-08 adustman - - * CHANGELOG, MySQLdb/__init__.py, setup.py: Bump version numbers. - - * _mysql.c: Bump version and remove some unneccesary casts that seem to - break things when using Python 2.3. - -2003-07-07 adustman - - * MySQLdb/converters.py: Fix bug 605849 (I hope). - - * _mysql.c: Fix member access problems - -2003-04-21 adustman - - * _mysql.c: Eliminate use of deprecated PyArg_NoArgs() - - * _mysql.c: Dumb typo - -2003-04-19 adustman - - * README, setup.py: Build and documentation updates - -2002-08-22 adustman - - * MySQLdb/__init__.py, CHANGELOG, _mysql.c, setup.py: - Embedded server support - - * _mysql.c: Clean up compiler warnings about - assignment discards qualifiers from pointer target type - -2002-08-02 adustman - - * _mysql.c: Windows (blech) compatibility changes. (Gerhard Häring) - -2002-08-01 adustman - - * CHANGELOG: CHANGELOG - - * _mysql.c: Not supporting GC for python < 2.2 - - * MANIFEST.in, pymemcompat.h: Memory API updates - - * MySQLdb/connections.py: Ignore exception from close() in __del__ - - * _mysql.c: GC for Python 2.2+ - -2002-07-21 adustman - - * MySQLdb/__init__.py, CHANGELOG, _mysql.c, setup.py: 0.9.2 (finally) - -2002-07-16 adustman - - * MySQLdb/cursors.py: - Revert execute behavior: Do not use % operator when there are no args - -2002-07-10 adustman - - * README: Rewrite - - * setup.cfg: Packaging cleanups - - * MySQLdb/__init__.py, MySQLdb/cursors.py, CHANGELOG, _mysql.c, setup.py: - Version 0.9.2c3, see CHANGELOG - -2002-07-03 adustman - - * MySQLdb/converters.py: - Revert returning BLOBs as arrays, since MySQL doesn't distinquish - between TEXT and BLOB types. (Skip Montanaro) - - * MySQLdb/connections.py: - Passing both conv and unicode to connect was broken (Skip Montanaro) - -2002-07-02 adustman - - * setup.py: FreeBSD/OpenBSD update - -2002-07-01 adustman - - * MySQLdb/cursors.py: Fix dumb (but working) iterator implementation - - * doc/MySQLdb.sgml: Doc updates - -2002-06-26 adustman - - * _mysql.c: - Add _mysql.thread_safe() (boolean, true if linked with thread-safe lib) - -2002-06-24 adustman - - * MySQLdb/__init__.py, _mysql.c, setup.py: Smack my version up - -2002-06-23 adustman - - * MySQLdb/connections.py, MySQLdb/cursors.py, CHANGELOG: - Some errorhandler cleanups - -2002-06-20 adustman - - * CHANGELOG: *** empty log message *** - - * MySQLdb/connections.py: Make the new unicode option actually work - - * MySQLdb/cursors.py: Add nextset() dummy stub - - * MySQLdb/converters.py: BLOBs as array support - - * MySQLdb/connections.py: - More Python 2.2 and doc updates. Return blobs as array. - The unicode option to connect() causes (VAR)CHAR columns - to be returned as unicode stings. - - * _mysql.c: Lots of Python 2.2 updates, especially documentation - -2002-06-18 adustman - - * MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, _mysql.c, MANIFEST.in: - Mostly documentation updates, and some code cleanups - -2002-06-15 adustman - - * MySQLdb/cursors.py: - Make executemany iterate over queries that don't use multiple VALUES - -2002-04-28 adustman - - * CHANGELOG, _mysql.c, setup.py: - packaging changes, pre-emptive version bump - - * setup.py: Bump version - - * MySQLdb/cursors.py: - Errorhandler was broken in cursor - CVSr ---------------------------------------------------------------------- - - * CHANGELOG: changelog - - * MySQLdb/__init__.py: Version bump - - * _mysql.c: Macro cleanups - -2002-04-27 adustman - - * _mysql.c: Fix memory leak in _mysql_escape_dict. (Danny Yoo) - - SSCursor.fetchall() (_mysql_ResultObject_fetch_row) didn't properly - increase the size of the result tuple if the result set was more than - 1000 rows. (Danny Yoo) - -2002-03-19 adustman - - * _mysql.c: More (de)allocation cleanups, based on suggestions from - python-dev and Skip Montanaro - - * _mysql.c: Use modern allocation with modern Python - -2002-03-14 adustman - - * MySQLdb/connections.py: Elminate debugging statement. - - * MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/cursors.py, _mysql.c, setup.py: - Bump version. Minor Alpha Linux update. Clear errorhandler on close. - -2002-03-01 adustman - - * _mysql.c: Fix a memory leak if the connect fails - -2002-01-29 adustman - - * MySQLdb/cursors.py: Stricter regex for finding INSERT values - ([ #505295 ] Wrong regexp in executemany() function.) - -2002-01-25 adustman - - * CHANGELOG: changes - - * MySQLdb/__init__.py: Verision bump. - - * _mysql.c: - Use modern memory deallocation on modern versions of Python. - - * setup.py: - Rework platform config a bit, default to thread-safe client. - -2001-12-29 adustman - - * MySQLdb/cursors.py: Fix fetchmany(). - -2001-12-24 adustman - - * setup.py: Fix version. - - * MySQLdb/connections.py, MySQLdb/cursors.py, doc/.cvsignore, .cvsignore, CHANGELOG, setup.py: - Version 0.9.2a1. Unicode + DB-API extensions. - -2001-12-23 adustman - - * _mysql.c, MySQLdb/__init__.py: 0.9.2 alpha 1 - - * MySQLdb/converters.py: Unicode support. - -2001-12-22 adustman - - * _mysql.c: str() can fail in some cases, particularly unicode. - Watch for it to prevent core dumps. - -2001-12-03 adustman - - * MySQLdb/cursors.py: - Fix cursor.rownumber for CursorStoreResultMixIn.fetchmany() - and implement cursor.rownumber for CursorUseResultMixIn.fetchXXX(). - -2001-11-28 adustman - - * setup.py: Catch more *bsd platforms. (Suggested by Ragnar Beer) - -2001-11-07 adustman - - * setup.py: Simplify the various configurations. - - Solaris might be fixed for gcc and broken for standard compiler. - -2001-10-31 adustman - - * README: Some additional Zope notes. - - * CHANGELOG: Mac OS X updates - - * setup.py: Link with -flat_namespace on Mac OS X/darwin. (Dan Grassi) - -2001-10-25 adustman - - * MySQLdb/cursors.py: - Do some renaming suggested by recent DB-SIG discussions. - - This should not break anything unless you are using private members. - -2001-10-23 adustman - - * CHANGELOG, setup.py: netbsd config - -2001-10-17 adustman - - * CHANGELOG, MySQLdb/__init__.py, README, _mysql.c, setup.py: - 0.9.0 updates - -2001-10-13 adustman - - * MySQLdb/__init__.py: import Set - -2001-09-29 adustman - - * setup.py: Catch more Linux platforms in the config. - -2001-09-21 adustman - - * setup.py: Solaris config (Bent NAgstrup Terp) - -2001-09-20 adustman - - * README: Good to update this at least once a year. - - * CHANGELOG, MySQLdb/__init__.py, _mysql.c, setup.py: - Update to 0.9.1c2. - -2001-09-13 adustman - - * _mysql.c: Fix exception handling in connect() (broken by 0.9.1.c1) - -2001-09-12 adustman - - * MANIFEST.in: Added CHANGELOG. (John Bowe) - -2001-09-07 adustman - - * setup.py: - OSX config (Paul DuBois); tab/space cleanups; more package info - - * PKG-INFO: Generated by distutils. - - * CHANGELOG: More stuff I forgot about. - - * _mysql.c: Use two arg _PyTuple_Resize() for Python 2.2 and newer. - - * setup.py: Version 0.9.1c1 - - * MySQLdb/converters.py: Return DECIMAL/NUMERIC as floating point. - -2001-09-06 adustman - - * CHANGELOG: Added a CHANGELOG, for people who like that sort of thing. - - * _mysql.c: - Kill bastardly refcount bug that occurs starting with Python 2.0.1. - PyArgs_ParseTupleAndKeywords() returns borrowed references for O format - starting in 2.0.1, prior to that it returns new references, so it's - necessary to test the Python version to determine whether or not we - should Py_INCREF() it. If we always Py_INCREF() it, this produces a - memory leak in versions prior to 2.0.1. - - * MySQLdb/__init__.py, _mysql.c, setup.py: - Change version number, back out memory changes. - - * _mysql.c: - Memory allocation cleanups. Add missing newline in docstring. - -2001-07-29 adustman - - * _mysql.c: ER_PARSE_ERROR -> ProgrammingError; - #ifdef around some recent error types - -2001-07-12 adustman - - * _mysql.c: Fix leak on converter dictionary. (Ted Wright) - -2001-07-11 adustman - - * MANIFEST.in, MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/cursors.py, PKG-INFO, _mysql.c, doc/MySQLdb.sgml, setup.py: - Minor fixes for 1.0.0. - -2001-06-20 adustman - - * doc/MySQLdb.sgml: Clarify use of host parameter to connect(). - - * doc/MySQLdb-FAQ.sgml, doc/MySQLdb.sgml: - Some corrections courtesy of Paul DuBois. - -2001-06-04 adustman - - * MySQLdb/__init__.py, _mysql.c, setup.py: Update version number. - -2001-05-28 adustman - - * .cvsignore, MySQLdb/.cvsignore, MySQLdb/constants/.cvsignore, doc/.cvsignore: - Ignore stuff. - -2001-05-25 adustman - - * MySQLdb/connections.py, _mysql.c, doc/MySQLdb.sgml, setup.py: - Rip out _mysql.field_*() methods, as MySQL recommends using SQL - instead. See C API docs. - -2001-05-24 adustman - - * PKG-INFO: Update version. - - * MySQLdb/__init__.py, _mysql.c: - Clean up some import statements, bump versions to 0.9.0c2. - -2001-05-23 adustman - - * MySQLdb/times.py: Fix the case where there is no mx.DateTime. - - * MySQLdb/connections.py: Remove a debug string. - - * MANIFEST.in, MySQLdb/__init__.py, MySQLdb/connections.py, _mysql.c, _mysql_version.h, doc/MySQLdb.sgml, setup.cfg, setup.py: - 0.9.0c1 minor edit. - -2001-05-14 adustman - - * _mysql.c: PyObject_Length() == -1 on error. Thanks, Jon Ribbens. - -2001-05-12 adustman - - * MySQLdb/__init__.py, MySQLdb/converters.py, MySQLdb/data.py, MySQLdb/sets.py, MySQLdb/times.py, _mysql_version.h, setup.py: - Smash data into two separate modules: sets and times. I never liked - that name anyway. - - Set has been extended somewhat. The comparision operators really only - work properly with Python 2.1, due to the limitations of __cmp__. - Set also uses the binary operators (&, |, ^), since these make somewhat - more sense than the arithmetic ones, though there is no good analog for - - (if only there were a nand operator...) - - Bump the version to 0.9.0b3. This is not the actual 0.9.0b3 release yet, - however. I want to do some more insanity checking. But almost ready for - some candidate releases. - -2001-05-11 adustman - - * MySQLdb/__init__.py, MySQLdb/connections.py, MySQLdb/converters.py, MySQLdb/cursors.py, MySQLdb/data.py, doc/MySQLdb.sgml, _mysql_version.h, setup.py: - More major code heaving. - - All the threading stuff is ripped out and burned. - Too much code for not enough benefit. Still thread-safe, - just don't share connections. - - Made a nice Set class for SET columns. - - Updated the docs. - -2001-05-10 adustman - - * doc/MySQLdb-FAQ.sgml, doc/MySQLdb.sgml: Revamped docs. - -2001-05-09 adustman - - * MySQLdb/__init__.py, MySQLdb/connections.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, MySQLdb/converters.py, MySQLdb/cursors.py, PKG-INFO, _mysql_exceptions.py, _mysql_version.h: - Initial import of 0.9.0 series (pre-1.0.0). - - * MySQLdb/__init__.py, MySQLdb/connections.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, MySQLdb/converters.py, MySQLdb/cursors.py, PKG-INFO, _mysql_exceptions.py, _mysql_version.h: - New file. - - * CompatMysqldb.py, MANIFEST.in, README, _mysql.c, setup.py: - Initial import of 0.9.0 series (pre-1.0.0). - - * CompatMysqldb.py, MANIFEST.in, README, _mysql.c, setup.py: New file. - diff --git a/MySQLdb/CompatMysqldb.py b/MySQLdb/CompatMysqldb.py deleted file mode 100755 index a20c832..0000000 --- a/MySQLdb/CompatMysqldb.py +++ /dev/null @@ -1,318 +0,0 @@ -""" -Original author: James Henstridge -Adapted by: Andy Dustman - -This is the original Mysqldb.py module which came with MySQLmodule-1.4, -only it has been adapted to use _mysql instead MySQL. It is intended -for backwards compatibility purposes only. But as a bonus, transactions -will work if your database server and table types support them. It is -called CompatMysqldb instead of Mysqldb so as not to interfere with an -existing Mysqldb, or MySQLdb on case-insensitive brain-dead operating -systems. - -Under no circumstances should you bug James Henstridge about this!!! - ------ - -This is a class that implements an interface to mySQL databases, conforming -to the API published by the Python db-sig at -http://www.python.org/sigs/db-sig/DatabaseAPI.html - -It is really just a wrapper for an older python interface to mySQL databases -called mySQL, which I modified to facilitate use of a cursor. That module was -Joseph Skinner's port of the mSQL module by David Gibson, which was a modified -version of Anthony Baxter's msql module. - -As an example, to add some extra (unprivelledged) users to your database system, -and delete them again: - ->>> import Mysqldb ->>> conn = Mysqldb.mysqldb('mysql@localhost root rootpasswd') ->>> curs = conn.cursor() ->>> curs.execute("insert into user (host, user) values ('%s', '%s')", -... [('localhost', 'linus'), ('somewhere.com.au', 'james')]) -2 ->>> curs.execute("select * from user") ->>> curs.fetchall() - -- record listing -- ->>> curs.execute("delete from user where host = 'somewhere.com.au' or user = 'linus'") -2 ->>> curs.close() ->>> conn.close() - -The argument to mysqldb.mysqldb is of the form 'db@host user pass', -'db@host user', 'db@host', 'db', 'db user pass' or 'db user'. - -As always, the source is a good manual :-) - -James Henstridge -""" - -import _mysql -MySQL = _mysql -from string import upper, split, join - -error = 'mysqldb.error' - -from MySQLdb.constants import FIELD_TYPE -_type_conv = { FIELD_TYPE.TINY: int, - FIELD_TYPE.SHORT: int, - FIELD_TYPE.LONG: long, - FIELD_TYPE.FLOAT: float, - FIELD_TYPE.DOUBLE: float, - FIELD_TYPE.LONGLONG: long, - FIELD_TYPE.INT24: int, - FIELD_TYPE.YEAR: int } - -def isDDL(q): - return upper(split(q)[0]) in ('CREATE', 'ALTER', 'GRANT', 'REVOKE', - 'DROP', 'SET') -def isDML(q): - return upper(split(q)[0]) in ('DELETE', 'INSERT', 'UPDATE', 'LOAD') -def isDQL(q): - return upper(split(q)[0]) in ('SELECT', 'SHOW', 'DESC', 'DESCRIBE') - -class DBAPITypeObject: - - def __init__(self,*values): - self.values = values - - def __cmp__(self,other): - if other in self.values: - return 0 - if other < self.values: - return 1 - else: - return -1 - -_Set = DBAPITypeObject - -STRING = _Set(FIELD_TYPE.CHAR, FIELD_TYPE.ENUM, FIELD_TYPE.INTERVAL, - FIELD_TYPE.SET, FIELD_TYPE.STRING, FIELD_TYPE.VAR_STRING) -BINARY = _Set(FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB, FIELD_TYPE.MEDIUM_BLOB, - FIELD_TYPE.TINY_BLOB) -NUMBER = _Set(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 = _Set(FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE) -TIME = _Set(FIELD_TYPE.TIME) -TIMESTAMP = _Set(FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME) -ROWID = _Set() - -class Connection: - """This is the connection object for the mySQL database interface.""" - def __init__(self, host, user, passwd, db): - from MySQLdb.constants import CLIENT - kwargs = {} - kwargs['conv'] = _type_conv - if host: kwargs['host'] = host - if user: kwargs['user'] = user - if passwd: kwargs['passwd'] = passwd - if db: kwargs['db'] = db - try: - self.__conn = apply(MySQL.connect, (), kwargs) - except MySQL.Error, msg: - raise error, msg - self.__curs = Cursor(self.__conn) - self.__transactional = self.__conn.server_capabilities & CLIENT.TRANSACTIONS - - def __del__(self): - self.close() - - def __getattr__(self, key): - return getattr(self.__curs, key) - - def __setattr__(self, key, val): - if key in ('arraysize', 'description', 'insert_id'): - setattr(self.__curs, key, val) - else: - self.__dict__[key] = val - - def close(self): - self.__conn = None - - def cursor(self): - if self.__conn == None: raise error, "Connection is closed." - return Cursor(self.__conn) - - def commit(self): - """Commit the current transaction.""" - if self.__transactional: - self.__conn.query("COMMIT") - - def rollback(self): - """Rollback the current transaction.""" - if self.__transactional: - self.__conn.query("ROLLBACK") - else: raise error, "Not supported by server" - - def callproc(self, params=None): pass - - # These functions are just here so that every action that is - # covered by mySQL is covered by mysqldb. They are not standard - # DB API. The list* methods are not included, since they can be - # done with the SQL SHOW command. - def create(self, dbname): - """This is not a standard part of Python DB API.""" - self.__conn.query("CREATE DATABASE %s" % dbname) - self.__conn.store_result() - return None - def drop(self, dbname): - """This is not a standard part of Python DB API.""" - self.__conn.query("DROP DATABASE %s" % dbname) - self.__conn.store_result() - return None - def reload(self): - """This is not a standard part of Python DB API.""" - self.__conn.query("RELOAD TABLES") - self.__conn.store_result() - return None - def shutdown(self): - """This is not a standard part of Python DB API.""" - return self.__conn.shutdown() - - -class Cursor: - """A cursor object for use with connecting to mySQL databases.""" - def __init__(self, conn): - self.__conn = conn - self.__res = None - self.arraysize = 1 - self.__dict__['description'] = None - self.__open = 1 - self.insert_id = 0 - - def __del__(self): - self.close() - - def __setattr__(self, key, val): - if key == 'description': - raise error, "description is a read-only attribute." - else: - self.__dict__[key] = val - - def __delattr__(self, key): - if key in ('description', 'arraysize', 'insert_id'): - raise error, "%s can't be deleted." % (key,) - else: - del self.__dict__[key] - - def close(self): - self.__conn = None - self.__res = None - self.__open = 0 - - def execute(self, op, params=None): - if not self.__open: raise error, "Cursor has been closed." - if params: - if type(params[0]) not in (type(()), type([])): - params = [params] - if isDDL(op): - self.__dict__['description'] = None - try: - for x in params: - self.__res = \ - self.__conn.query(op % x) - self.insert_id = self.__res.insert_id() - except MySQL.Error, msg: - raise error, msg - return 1 - if isDML(op): - self.__dict__['description'] = None - af = 0 - try: - for x in params: - self.__res = \ - self.__conn.query(op % x) - af =af+self.__res.affectedrows() - self.insert_id = self.__res.insert_id() - except MySQL.Error, msg: - raise error, msg - return af - if isDQL(op): - try: - self.__res = self.__conn.query( - op % params[-1]) - self.insert_id = self.__res.insert_id() - except MySQL.Error, msg: - raise error, msg - self.__dict__['description'] = self.__res.describe() - return None - else: - try: - self.__conn.query(op) - self.__res = self.__conn.store_result() - self.insert_id = self.__conn.insert_id() - except MySQL.Error, msg: - raise error, msg - self.__dict__['description'] = None - if isDDL(op): - return 1 - elif self.__conn.affected_rows() != -1: - return self.__conn.affected_rows() - else: - self.__dict__['description'] = self.__res.describe() - return None - def fetchone(self): - if not self.__res: raise error, "no query made yet." - try: - return self.__res.fetch_row(1)[0] - except MySQL.Error, msg: - raise error, msg - - def fetchmany(self, size=None): - if not self.__res: raise error, "no query made yet." - try: - return self.__res.fetch_row(size or self.arraysize) - except MySQL.Error, msg: - raise error, msg - - def fetchall(self): - if not self.__res: raise error, "no query made yet." - try: - return self.__res.fetch_row(0) - except MySQL.Error, msg: - raise error, msg - - def fetchoneDict(self): - """This is not a standard part of Python DB API.""" - if not self.__res: raise error, "no query made yet." - try: - return self.__res.fetch_row(1, 2)[0] - except MySQL.Error, msg: - raise error, msg - - def fetchmanyDict(self, size=None): - """This is not a standard part of Python DB API.""" - if not self.__res: raise error, "no query made yet." - try: - return self.__res.fetch_row(size or self.arraysize, 2) - except MySQL.Error, msg: - raise error, msg - - def fetchallDict(self): - """This is not a standard part of Python DB API.""" - if not self.__res: raise error, "no query made yet." - try: - return self.__res.fetch_row(0,2) - except MySQL.Error, msg: - raise error, msg - - def setinputsizes(self, sizes): pass - def setoutputsize(self, size, col=None): pass - - -def mysqldb(connect_string): - """Makes a connection to the MySQL server. The Argument should be of - the form 'db@host user pass' or 'db@host user' or 'db@host' or 'db' - or 'db user pass' or 'db user', where db is the database name, host - is the server's host name, user is your user name, and pass is your - password.""" - val = split(connect_string) - if len(val) == 0: raise error, "no database specified" - while len(val) < 3: val.append('') - dh = split(val[0], '@') - if len(dh) == 0: raise error, "no database specified" - while len(dh) < 2: dh.append('') - return Connection(dh[1], val[1], val[2], dh[0]) - diff --git a/MySQLdb/MySQLdb/__init__.py b/MySQLdb/MySQLdb/__init__.py index a79578d..c6ee9c4 100644 --- a/MySQLdb/MySQLdb/__init__.py +++ b/MySQLdb/MySQLdb/__init__.py @@ -18,7 +18,7 @@ __revision__ = """$Revision$"""[11:-2] version_info = ( 1, 1, - 6, + 7, "final", 1) if version_info[3] == "final": __version__ = "%d.%d.%d" % version_info[:3] diff --git a/MySQLdb/_mysql.c b/MySQLdb/_mysql.c index 6c01a17..7818212 100644 --- a/MySQLdb/_mysql.c +++ b/MySQLdb/_mysql.c @@ -1,5 +1,5 @@ -#define version_info "(1,1,6,'final',1)" -#define __version__ "1.1.6" +#define version_info "(1,1,7,'final',1)" +#define __version__ "1.1.7" /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/MySQLdb/doc/MySQLdb.txt b/MySQLdb/doc/MySQLdb.txt new file mode 100644 index 0000000..69d6bdd --- /dev/null +++ b/MySQLdb/doc/MySQLdb.txt @@ -0,0 +1,622 @@ +==================== +MySQLdb User's Guide +==================== +Introduction +------------ + +MySQLdb is an thread-compatible interface to the popular MySQL +database server that provides the Python database API. + +Installation +------------ + +The ``README`` file has complete installation instructions. + + +_mysql +------ + +If you want to write applications which are portable across databases, +use MySQLdb_, and avoid using this module directly. ``_mysql`` +provides an interface which mostly implements the MySQL C API. For +more information, see the `MySQL documentation`_. The documentation +for this module is intentionally weak because you probably should use +the higher-level MySQLdb module. If you really need it, use the +standard MySQL docs and transliterate as necessary. + +.. _`MySQL documentation`: http://dev.mysql.com/doc/mysql/en/index.html + + +MySQL C API translation +....................... + +The MySQL C API has been wrapped in an object-oriented way. The only +MySQL data structures which are implemented are the ``MYSQL`` +(database connection handle) and ``MYSQL_RES`` (result handle) +types. In general, any function which takes ``MYSQL *mysql`` as an +argument is now a method of the connection object, and any function +which takes ``MYSQL_RES *result`` as an argument is a method of the +result object. Functions requiring none of the MySQL data structures +are implemented as functions in the module. Functions requiring one of +the other MySQL data structures are generally not implemented. +Deprecated functions are not implemented. In all cases, the ``mysql_`` +prefix is dropped from the name. Most of the ``conn`` methods listed +are also available as MySQLdb Connection object methods. Their use is +non-portable. + +MySQL C API function mapping +............................ + +================================= ================================== + C API ``_mysql`` +================================= ================================== + ``mysql_affected_rows()`` ``conn.affected_rows()`` + ``mysql_close()`` ``conn.close()`` + ``mysql_connect()`` ``_mysql.connect()`` + ``mysql_data_seek()`` ``result.data_seek()`` + ``mysql_debug()`` ``_mysql.debug()`` + ``mysql_dump_debug_info`` ``conn.dump_debug_info()`` + ``mysql_escape_string()`` ``_mysql.escape_string()`` + ``mysql_fetch_row()`` ``result.fetch_row()`` + ``mysql_get_client_info()`` ``_mysql.get_client_info()`` + ``mysql_get_host_info()`` ``conn.get_host_info()`` + ``mysql_get_proto_info()`` ``conn.get_proto_info()`` + ``mysql_get_server_info()`` ``conn.get_server_info()`` + ``mysql_info()`` ``conn.info()`` + ``mysql_insert_id()`` ``conn.insert_id()`` + ``mysql_num_fields()`` ``result.num_fields()`` + ``mysql_num_rows()`` ``result.num_rows()`` + ``mysql_options()`` ``_mysql.connect()`` + ``mysql_ping()`` ``conn.ping()`` + ``mysql_query()`` ``conn.query()`` + ``mysql_real_connect()`` ``_mysql.connect()`` + ``mysql_real_query()`` ``conn.query()`` + ``mysql_real_escape_string()`` ``conn.escape_string()`` + ``mysql_row_seek()`` ``result.row_seek()`` + ``mysql_row_tell()`` ``result.row_tell()`` + ``mysql_select_db()`` ``conn.select_db()`` + ``mysql_stat()`` ``conn.stat()`` + ``mysql_store_result()`` ``conn.store_result()`` + ``mysql_thread_id()`` ``conn.thread_id()`` + ``mysql_thread_safe_client()`` ``conn.thread_safe_client()`` + ``mysql_use_result()`` ``conn.use_result()`` + ``CLIENT_*`` ``MySQLdb.constants.CLIENT.*`` + ``CR_*`` ``MySQLdb.constants.CR.*`` + ``ER_*`` ``MySQLdb.constants.ER.*`` + ``FIELD_TYPE_*`` ``MySQLdb.constants.FIELD_TYPE.*`` + ``FLAG_*`` ``MySQLdb.constants.FLAG.*`` +================================= ================================== + + +Some _mysql examples +.................... + +Okay, so you want to use ``_mysql`` anyway. Here are some examples. + +The simplest possible database connection is:: + + import _mysql + db=_mysql.connect() + +This creates a connection to the MySQL server running on the local +machine using the standard UNIX socket (or named pipe on Windows), +your login name (from the USER environment variable), no password, and +does not ``USE`` a database. Chances are you need to supply more +information.:: + + db=_mysql.connect("localhost","joebob","moonpie","thangs") + +This creates a connection to the MySQL server running on the local +machine via a UNIX socket (or named pipe), the user name "joebob", the +password "moonpie", and selects the initial database "thangs". + +We haven't even begun to touch upon all the parameters ``connect()`` +can take. For this reason, I prefer to use keyword parameters:: + + db=_mysql.connect(host="localhost",user="joebob", + passwd="moonpie",db="thangs") + +This does exactly what the last example did, but is arguably easier to +read. But since the default host is "localhost", and if your login +name really was "joebob", you could shorten it to this:: + + db=_mysql.connect(passwd="moonpie",db="thangs") + +UNIX sockets and named pipes don't work over a network, so if you +specify a host other than localhost, TCP will be used, and you can +specify an odd port if you need to (the default port is 3306):: + + db=_mysql.connect(host="outhouse",port=3307,passwd="moonpie",db="thangs") + +If you really had to, you could connect to the local host with TCP by +specifying the full host name, or 127.0.0.1. + +Generally speaking, putting passwords in your code is not such a good +idea:: + + db=_mysql.connect(host="outhouse",db="thangs",read_default_file="~/.my.cnf") + +This does what the previous example does, but gets the username and +password and other parameters from ~/.my.cnf (UNIX-like systems). Read +about `option files`_ for more details. + +.. _`option files`: http://dev.mysql.com/doc/mysql/en/Option_files.html + +So now you have an open connection as ``db`` and want to do a +query. Well, there are no cursors in MySQL, and no parameter +substitution, so you have to pass a complete query string to +``db.query()``:: + + db.query("""SELECT spam, eggs, sausage FROM breakfast + WHERE price < 5""") + +There's no return value from this, but exceptions can be raised. The +exceptions are defined in a separate module, ``_mysql_exceptions``, +but ``_mysql`` exports them. Read DB API specification PEP-249_ to +find out what they are, or you can use the catch-all ``MySQLError``. + +.. _PEP-249: http://www.python.org/peps/pep-0249.html + +At this point your query has been executed and you need to get the +results. You have two options:: + + r=db.store_result() + # ...or... + r=db.use_result() + +Both methods return a result object. What's the difference? +``store_result()`` returns the entire result set to the client +immediately. If your result set is really large, this could be a +problem. One way around this is to add a ``LIMIT`` clause to your +query, to limit the number of rows returned. The other is to use +``use_result()``, which keeps the result set in the server and sends +it row-by-row when you fetch. This does, however, tie up server +resources, and it ties up the connection: You cannot do any more +queries until you have fetched **all** the rows. Generally I +recommend using ``store_result()`` unless your result set is really +huge and you can't use ``LIMIT`` for some reason. + +Now, for actually getting real results:: + + >>> r.fetch_row() + (('3','2','0'),) + +This might look a little odd. The first thing you should know is, +``fetch_row()`` takes some additional parameters. The first one is, +how many rows (``maxrows``) should be returned. By default, it returns +one row. It may return fewer rows than you asked for, but never +more. If you set ``maxrows=0``, it returns all rows of the result +set. If you ever get an empty tuple back, you ran out of rows. + +The second parameter (``how``) tells it how the row should be +represented. By default, it is zero which means, return as a tuple. +``how=1`` means, return it as a dictionary, where the keys are the +column names, or ``table.column`` if there are two columns with the +same name (say, from a join). ``how=2`` means the same as ``how=1`` +except that the keys are *always* ``table.column``; this is for +compatibility with the old ``Mysqldb`` module. + +OK, so why did we get a 1-tuple with a tuple inside? Because we +implicitly asked for one row, since we didn't specify ``maxrows``. + +The other oddity is: Assuming these are numeric columns, why are they +returned as strings? Because MySQL returns all data as strings and +expects you to convert it yourself. This would be a real pain in the +ass, but in fact, ``_mysql`` can do this for you. (And ``MySQLdb`` +does do this for you.) To have automatic type conversion done, you +need to create a type converter dictionary, and pass this to +``connect()`` as the ``conv`` keyword parameter. + +The keys of ``conv`` should be MySQL column types, which in the +C API are ``FIELD_TYPE_*``. You can get these values like this:: + + from MySQLdb.constants import FIELD_TYPE + +By default, any column type that can't be found in ``conv`` is +returned as a string, which works for a lot of stuff. For our +purposes, we probably want this:: + + my_conv = { FIELD_TYPE.LONG: int } + +This means, if it's a ``FIELD_TYPE_LONG``, call the builtin ``int()`` +function on it. Note that ``FIELD_TYPE_LONG`` is an ``INTEGER`` +column, which corresponds to a C ``long``, which is also the type used +for a normal Python integer. But beware: If it's really an ``UNSIGNED +INTEGER`` column, this could cause overflows. For this reason, +``MySQLdb`` actually uses ``long()`` to do the conversion. But we'll +ignore this potential problem for now. + +Then if you use ``db=_mysql.connect(conv=my_conv...)``, the +results will come back ``((3, 2, 0),)``, which is what you would +expect. + +MySQLdb +------- + +MySQLdb is a thin Python wrapper around ``_mysql`` which makes it +compatible with the Python DB API interface (version 2). In reality, +a fair amount of the code which implements the API is in ``_mysql`` +for the sake of efficiency. + +The DB API specification PEP-249_ should be your primary guide for +using this module. Only deviations from the spec and other +database-dependent things will be documented here. + +Functions and attributes +........................ + +Only a few top-level functions and attributes are defined within +MySQLdb. + +connect(parameters...) + Constructor for creating a connection to the + database. Returns a Connection Object. Parameters are the + same as for the MySQL C API. In addition, there are a few + additional keywords that correspond to what you would pass + ``mysql_options()`` before connecting. Note that some + parameters must be specified as keyword arguments! The + default value for each parameter is NULL or zero, as + appropriate. Consult the MySQL documentation for more + details. The important parameters are: + + host + name of host to connect to. Default: use the local host + via a UNIX socket (where applicable) + + user + user to authenticate as. Default: current effective user. + + passwd + password to authenticate with. Default: no password. + + db + database to use. Default: no default database. + + port + TCP port of MySQL server. Default: standard port (3306). + + unix_socket + location of UNIX socket. Default: use default location or + TCP for remote hosts. + + conv + type conversion dictionary. Default: a copy of + ``MySQLdb.converters.conversions`` + + compress + Enable protocol compression. Default: no compression. + + connect_timeout + Abort if connect is not completed within + given number of seconds. Default: no timeout (?) + + named_pipe + Use a named pipe (Windows). Default: don't. + + init_command + Initial command to issue to server upon + connection. Default: Nothing. + + read_default_file + MySQL configuration file to read; see + the MySQL documentation for ``mysql_options()``. + + read_default_group + Default group to read; see the MySQL + documentation for ``mysql_options()``. + + cursorclass + cursor class that ``cursor()`` uses, unless + overridden. Default: ``MySQLdb.cursors.Cursor``. *This + must be a keyword parameter.* + + unicode + If set, CHAR and VARCHAR columns are returned as Unicode + strings, using the specified character set. None means to + use a default encoding. *This must be a keyword + parameter.* + + unicode_errors + If set, this is used as the errors parameter to the + ``unicode()`` function. Default: "strict". *This must be a + keyword parameter.* + + ssl + This parameter takes a dictionary or mapping, where the + keys are parameter names used by the mysql_ssl_set_ MySQL + C API call. If this is set, it initiates an SSL connection + to the server; if there is no SSL support in the client, + an exception is raised. *This must be a keyword + parameter.* + +.. _mysql_ssl_set: http://dev.mysql.com/doc/mysql/en/mysql_ssl_set.html + + +apilevel + String constant stating the supported DB API level. '2.0' + +threadsafety + Integer constant stating the level of thread safety the + interface supports. This is set to 1, which means: Threads may + share the module. + + The MySQL protocol can not handle multiple threads using the + same connection at once. Some earlier versions of MySQLdb + utilized locking to achieve a threadsafety of 2. While this is + not terribly hard to accomplish using the standard Cursor class + (which uses ``mysql_store_result()``), it is complicated by + SSCursor (which uses ``mysql_use_result()``; with the latter you + must ensure all the rows have been read before another query can + be executed. It is further complicated by the addition of + transactions, since transactions start when a cursor execute a + query, but end when ``COMMIT`` or ``ROLLBACK`` is executed by + the Connection object. Two threads simply cannot share a + connection while a transaction is in progress, in addition to + not being able to share it during query execution. This + excessively complicated the code to the point where it just + isn't worth it. + + The general upshot of this is: Don't share connections between + threads. It's really not worth your effort or mine, and in the + end, will probably hurt performance, since the MySQL server runs + a separate thread for each connection. You can certainly do + things like cache connections in a pool, and give those + connections to one thread at a time. If you let two threads use + a connection simultaneously, the MySQL client library will + probably upchuck and die. You have been warned. + + For threaded applications, try using a connection pool. + This can be done using the `Pool module`_. + + .. _`Pool module`: http://dustman.net/andy/python/Pool + +paramstyle + String constant stating the type of parameter marker formatting + expected by the interface. Set to 'format' = ANSI C printf + format codes, e.g. '...WHERE name=%s'. If a mapping object is + used for conn.execute(), then the interface actually uses + 'pyformat' = Python extended format codes, e.g. '...WHERE + name=%(name)s'. However, the API does not presently allow the + specification of more than one style in paramstyle. + + Note that any literal percent signs in the query string passed + to execute() must be escaped, i.e. %%. + + Parameter placeholders can **only** be used to insert column + values. They can **not** be used for other parts of SQL, such as + table names, statements, etc. + +conv + A dictionary or mapping which controls how types are converted + from MySQL to Python and vice versa. + + If the key is a MySQL type (from ``FIELD_TYPE.*``), then the value + can be either: + + * a callable object which takes a string argument (the MySQL + value),' returning a Python value + + * a sequence of 2-tuples, where the first value is a combination + of flags from ``MySQLdb.constants.FLAG``, and the second value + is a function as above. The sequence is tested until the flags + on the field match those of the first value. If both values + are None, then the default conversion is done. Presently this + is only used to distinquish TEXT and BLOB columns. + + If the key is a Python type or class, then the value is a + callable Python object (usually a function) taking two arguments + (value to convert, and the conversion dictionary) which converts + values of this type to a SQL literal string value. + + This is initialized with reasonable defaults for most + types. When creating a Connection object, you can pass your own + type converter dictionary as a keyword parameter. Otherwise, it + uses a copy of ``MySQLdb.converters.conversions``. Several + non-standard types are returned as strings, which is how MySQL + returns all columns. For more details, see the built-in module + documentation. + + +Connection Objects +.................. + +Connection objects are returned by the ``connect()`` function. + +commit() + If the database and the tables support transactions, this + commits the current transaction; otherwise this method + successfully does nothing. + +rollback() + If the database and tables support transactions, this rolls back + (cancels) the current transaction; otherwise a + ``NotSupportedError`` is raised. + +cursor([cursorclass]) + MySQL does not support cursors; however, cursors are easily + emulated. You can supply an alternative cursor class as an + optional parameter. If this is not present, it defaults to the + value given when creating the connection object, or the standard + ``Cursor`` class. Also see the additional supplied cursor + classes in the usage section. + +There are many more methods defined on the connection object which +are MySQL-specific. For more information on them, consult the internal +documentation using ``pydoc``. + + +Cursor Objects +.............. + +callproc() + Not implemented. + +close() + Closes the cursor. Future operations raise ``ProgrammingError``. + If you are using server-side cursors, it is very important to + close the cursor when you are done with it and before creating a + new one. + +insert_id() + Returns the last ``AUTO_INCREMENT`` field value inserted + into the database. (Non-standard) + +info() + Returns some information about the last query. Normally + you don't need to check this. With the default cursor, any MySQL + warnings cause ``Warning`` to be raised. If you are using a + cursor class without warnings, then you might want to use + this. See the MySQL docs for ``mysql_info()``. (Non-standard) + +setinputsizes() + Does nothing, successfully. + +setoutputsizes() + Does nothing, successfully. + +nextset() + Advances the cursor to the next result set, discarding the remaining + rows in the current result set. If there are no additional result + sets, it returns None; otherwise it returns a true value. + + Note that MySQL doesn't support multiple result sets until 4.1; + there is currently no support for this in MySQLdb. + +Some examples +............. + +The ``connect()`` method works nearly the same as with `_mysql`_:: + + import MySQLdb + db=MySQLdb.connect(passwd="moonpie",db="thangs") + +To perform a query, you first need a cursor, and then you can execute +queries on it:: + + c=db.cursor() + max_price=5 + c.execute("""SELECT spam, eggs, sausage FROM breakfast + WHERE price < %s""", (max_price,)) + +In this example, ``max_price=5`` Why, then, use ``%s`` in the +string? Because MySQLdb will convert it to a SQL literal value, which +is the string '5'. When it's finished, the query will actually say, +"...WHERE price < 5". + +Why the tuple? Because the DB API requires you to pass in any +parameters as a sequence. + +And now, the results:: + + >>> c.fetchone() + (3L, 2L, 0L) + +Quite unlike the ``_mysql`` example, this returns a single tuple, +which is the row, and the values are properly converted by default... +except... What's with the L's? + +As mentioned earlier, while MySQL's INTEGER column translates +perfectly into a Python integer, UNSIGNED INTEGER could overflow, so +these values are converted to Python long integers instead. + +If you wanted more rows, you could use ``c.fetchmany(n)`` or +``c.fetchall()``. These do exactly what you think they do. On +``c.fetchmany(n)``, the ``n`` is optional and defaults to +``c.arraysize``, which is normally 100. Both of these methods return a +sequence of rows, or an empty sequence if there are no more rows. If +you use a weird cursor class, the rows themselves might not be tuples. + +Note that in contrast to the above, ``c.fetchone()`` returns ``None`` +when there are no more rows to fetch. + +The only other method you are very likely to use is when you have to +do a multi-row insert:: + + c.executemany( + """INSERT INTO breakfast (name, spam, eggs, sausage, price) + VALUES (%s, %s, %s, %s, %s)""", + [ + ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ), + ("Not So Much Spam Plate", 3, 2, 0, 3.95 ), + ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 ) + ] ) + +Here we are inserting three rows of five values. Notice that there is +a mix of types (strings, ints, floats) though we still only use +``%s``. And also note that we only included format strings for one +row. MySQLdb picks those out and duplicates them for each row. + +Using and extending +------------------- + +In general, it is probably wise to not directly interact with the DB +API except for small applicatons. Databases, even SQL databases, vary +widely in capabilities and may have non-standard features. The DB API +does a good job of providing a reasonably portable interface but some +methods are non-portable. Specifically, the parameters accepted by +``connect()`` are completely implementation-dependent. + +If you believe your application may need to run on several different +databases, the author recommends the following approach, based on +personal experience: Write a simplified API for your application which +implements the specific queries and operations your application needs +to perform. Implement this API as a base class which should be have +few database dependencies, and then derive a subclass from this which +implements the necessary dependencies. In this way, porting your +application to a new database should be a relatively simple matter of +creating a new subclass, assuming the new database is reasonably +standard. + +Because MySQLdb's Connection and Cursor objects are written in Python, +you can easily derive your own subclasses. There are several Cursor +classes in MySQLdb.cursors: + +BaseCursor + The base class for Cursor objects. This does not raise Warnings. + +CursorStoreResultMixIn + Causes the Cursor to use the ``mysql_store_result()`` function to + get the query result. The entire result set is stored on the + client side. + +CursorUseResultMixIn + Causes the cursor to use the ``mysql_use_result()`` function to + get the query result. The result set is stored on the server side + and is transferred row by row using fetch operations. + +CursorTupleRowsMixIn + Causes the cursor to return rows as a tuple of the column values. + +CursorDictRowsMixIn + + Causes the cursor to return rows as a dictionary, where the keys + are column names and the values are column values. Note that if + the column names are not unique, i.e., you are selecting from two + tables that share column names, some of them will be rewritten as + ``table.column``. This can be avoided by using the SQL ``AS`` + keyword. (This is yet-another reason not to use ``*`` in SQL + queries, particularly where ``JOIN`` is involved.) + +Cursor + The default cursor class. This class is composed of + ``CursorWarningMixIn``, ``CursorStoreResultMixIn``, + ``CursorTupleRowsMixIn,`` and ``BaseCursor``, i.e. it raises + ``Warning``, uses ``mysql_store_result()``, and returns rows as + tuples. + +DictCursor + Like ``Cursor`` except it returns rows as dictionaries. + +SSCursor + A "server-side" cursor. Like ``Cursor`` but uses + ``CursorUseResultMixIn``. Use only if you are dealing with + potentially large result sets. + +SSDictCursor + Like ``SSCursor`` except it returns rows as dictionaries. + + + +:Title: MySQLdb: a Python interface for MySQL +:Author: Andy Dustman +:Version: $Revision$ diff --git a/MySQLdb/setup.py b/MySQLdb/setup.py index bb37f8f..5a12aba 100644 --- a/MySQLdb/setup.py +++ b/MySQLdb/setup.py @@ -2,7 +2,8 @@ """Setup script for the MySQLdb module distribution.""" -import os, sys +import os +import sys from distutils.core import setup from distutils.extension import Extension @@ -18,7 +19,7 @@ embedded_server = (mysqlclient == 'mysqld') name = "MySQL-%s" % os.path.basename(sys.executable) if embedded_server: name = name + "-embedded" -version = "1.1.6" +version = "1.1.7" # include files and library locations should cover most platforms include_dirs = [ @@ -87,7 +88,11 @@ elif os.name == "posix": # UNIX-ish platforms not covered above else: raise "UnknownPlatform", "sys.platform=%s, os.name=%s" % \ (sys.platform, os.name) - + +# avoid frightening noobs with warnings about missing directories +include_dirs = [ d for d in include_dirs if os.path.isdir(d) ] +library_dirs = [ d for d in library_dirs if os.path.isdir(d) ] + long_description = \ """Python interface to MySQL