Kaynağa Gözat

[desktop] Upgrade MySQL-python to 1.2.5

Erick Tryzelaar 11 yıl önce
ebeveyn
işleme
187142c
66 değiştirilmiş dosya ile 7129 ekleme ve 7081 silme
  1. 0 6
      desktop/core/ext-py/MySQL-python-1.2.3c1/.cvsignore
  2. 0 1625
      desktop/core/ext-py/MySQL-python-1.2.3c1/ChangeLog
  3. 0 34
      desktop/core/ext-py/MySQL-python-1.2.3c1/MANIFEST
  4. 0 1
      desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/.cvsignore
  5. 0 1
      desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/.cvsignore
  6. 0 4
      desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/release.py
  7. 0 2
      desktop/core/ext-py/MySQL-python-1.2.3c1/doc/.cvsignore
  8. 0 276
      desktop/core/ext-py/MySQL-python-1.2.3c1/ez_setup.py
  9. 0 18
      desktop/core/ext-py/MySQL-python-1.2.3c1/setup.py
  10. 20 21
      desktop/core/ext-py/MySQL-python-1.2.5/GPL-2.0
  11. 193 100
      desktop/core/ext-py/MySQL-python-1.2.5/HISTORY
  12. 6 6
      desktop/core/ext-py/MySQL-python-1.2.5/INSTALL
  13. 14 13
      desktop/core/ext-py/MySQL-python-1.2.5/MANIFEST.in
  14. 98 98
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/__init__.py
  15. 351 334
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/connections.py
  16. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/CLIENT.py
  17. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/CR.py
  18. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/ER.py
  19. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/FIELD_TYPE.py
  20. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/FLAG.py
  21. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/REFRESH.py
  22. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/__init__.py
  23. 189 171
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/converters.py
  24. 541 504
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/cursors.py
  25. 4 0
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/release.py
  26. 126 101
      desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/times.py
  27. 43 45
      desktop/core/ext-py/MySQL-python-1.2.5/PKG-INFO
  28. 41 0
      desktop/core/ext-py/MySQL-python-1.2.5/README.md
  29. 3168 2894
      desktop/core/ext-py/MySQL-python-1.2.5/_mysql.c
  30. 6 2
      desktop/core/ext-py/MySQL-python-1.2.5/_mysql_exceptions.py
  31. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/FAQ.rst
  32. 59 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/MySQLdb.constants.rst
  33. 50 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/MySQLdb.rst
  34. 143 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/FAQ.txt
  35. 59 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/MySQLdb.constants.txt
  36. 50 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/MySQLdb.txt
  37. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/_mysql.txt
  38. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/_mysql_exceptions.txt
  39. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/distribute_setup.txt
  40. 24 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/index.txt
  41. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/modules.txt
  42. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/setup.txt
  43. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/setup_common.txt
  44. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/setup_posix.txt
  45. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/setup_windows.txt
  46. 1 1
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/user_guide.txt
  47. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_mysql.rst
  48. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/_mysql_exceptions.rst
  49. 242 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/conf.py
  50. 24 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/index.rst
  51. 7 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/modules.rst
  52. 718 0
      desktop/core/ext-py/MySQL-python-1.2.5/doc/user_guide.rst
  53. 58 60
      desktop/core/ext-py/MySQL-python-1.2.5/metadata.cfg
  54. 0 0
      desktop/core/ext-py/MySQL-python-1.2.5/pymemcompat.h
  55. 18 18
      desktop/core/ext-py/MySQL-python-1.2.5/setup.cfg
  56. 21 0
      desktop/core/ext-py/MySQL-python-1.2.5/setup.py
  57. 8 3
      desktop/core/ext-py/MySQL-python-1.2.5/setup_common.py
  58. 103 94
      desktop/core/ext-py/MySQL-python-1.2.5/setup_posix.py
  59. 7 8
      desktop/core/ext-py/MySQL-python-1.2.5/setup_windows.py
  60. 3 4
      desktop/core/ext-py/MySQL-python-1.2.5/site.cfg
  61. 281 289
      desktop/core/ext-py/MySQL-python-1.2.5/tests/capabilities.py
  62. 25 0
      desktop/core/ext-py/MySQL-python-1.2.5/tests/configdb.py
  63. 48 48
      desktop/core/ext-py/MySQL-python-1.2.5/tests/dbapi20.py
  64. 102 93
      desktop/core/ext-py/MySQL-python-1.2.5/tests/test_MySQLdb_capabilities.py
  65. 204 205
      desktop/core/ext-py/MySQL-python-1.2.5/tests/test_MySQLdb_dbapi20.py
  66. 4 2
      desktop/core/ext-py/MySQL-python-1.2.5/tests/test_MySQLdb_nonstandard.py

+ 0 - 6
desktop/core/ext-py/MySQL-python-1.2.3c1/.cvsignore

@@ -1,6 +0,0 @@
-dist
-build
-regress.py
-test.py
-PKG-INFO
-*.pyc

+ 0 - 1625
desktop/core/ext-py/MySQL-python-1.2.3c1/ChangeLog

@@ -1,1625 +0,0 @@
-------------------------------------------------------------------------
-r626 | adustman | 2009-03-30 18:23:39 -0500 (Mon, 30 Mar 2009) | 2 lines
-
-1.2.3 release candidate 1
-
-------------------------------------------------------------------------
-r625 | adustman | 2009-03-30 18:01:58 -0500 (Mon, 30 Mar 2009) | 1 line
-
-
-------------------------------------------------------------------------
-r620 | adustman | 2009-03-13 21:37:11 -0500 (Fri, 13 Mar 2009) | 1 line
-
-MySQLdb-1.2.3b2
-------------------------------------------------------------------------
-r618 | adustman | 2009-03-10 21:34:59 -0500 (Tue, 10 Mar 2009) | 2 lines
-
-Add a test for connection.ping()
-
-------------------------------------------------------------------------
-r617 | adustman | 2009-03-10 21:01:49 -0500 (Tue, 10 Mar 2009) | 3 lines
-
-Fix #2061583: Ignore any non-numeric portion of client and server
-version numbers.
-
-------------------------------------------------------------------------
-r616 | adustman | 2009-03-10 19:48:08 -0500 (Tue, 10 Mar 2009) | 3 lines
-
-Fix for bug #2479317 (patch #2496558) by kylev. Make some time handling 
-stuff more consistent.
-
-------------------------------------------------------------------------
-r614 | adustman | 2009-03-08 12:48:11 -0500 (Sun, 08 Mar 2009) | 2 lines
-
-Backport some new trunk tests
-
-------------------------------------------------------------------------
-r613 | adustman | 2009-03-08 12:45:52 -0500 (Sun, 08 Mar 2009) | 2 lines
-
-Move tests into their own directory to parallel trunk
-
-------------------------------------------------------------------------
-r612 | adustman | 2009-03-08 11:34:49 -0500 (Sun, 08 Mar 2009) | 6 lines
-
-Short-term fix for bug #2671682.
-
-Make tests a little more parallel to trunk version.
-
-Add nose.collector as test_suite
-
-------------------------------------------------------------------------
-r609 | kylev | 2009-03-05 13:55:19 -0600 (Thu, 05 Mar 2009) | 1 line
-
-Two more old-style exception invocations
-------------------------------------------------------------------------
-r603 | kylev | 2009-02-23 20:53:46 -0600 (Mon, 23 Feb 2009) | 2 lines
-
-We missed one more 2.6-warning generating exception
-
-------------------------------------------------------------------------
-r602 | kylev | 2009-02-23 20:48:29 -0600 (Mon, 23 Feb 2009) | 2 lines
-
-Fix bug 1808476 for OSX compilation, ported from trunk.
-
-------------------------------------------------------------------------
-r599 | kylev | 2009-02-23 17:39:00 -0600 (Mon, 23 Feb 2009) | 1 line
-
-don't leak special-case tuples (present in unicode modes)
-------------------------------------------------------------------------
-r566 | adustman | 2009-02-05 18:52:34 -0600 (Thu, 05 Feb 2009) | 2 lines
-
-Updated ez_setup.py to latest version.
-
-------------------------------------------------------------------------
-r560 | adustman | 2008-10-17 19:13:35 -0500 (Fri, 17 Oct 2008) | 2 lines
-
-Found one more old-style raise. Should fix #2122496.
-
-------------------------------------------------------------------------
-r559 | adustman | 2008-10-17 19:12:13 -0500 (Fri, 17 Oct 2008) | 4 lines
-
-Found one more Set reference.
-
-Change raise to use the modern syntax for Python 3.0 compatibility.
-
-------------------------------------------------------------------------
-r558 | adustman | 2008-10-17 19:07:14 -0500 (Fri, 17 Oct 2008) | 2 lines
-
-Remove more deprecated Set usage. Refs #2156977.
-
-------------------------------------------------------------------------
-r557 | adustman | 2008-10-16 20:07:01 -0500 (Thu, 16 Oct 2008) | 2 lines
-
-More documentation updates.
-
-------------------------------------------------------------------------
-r556 | adustman | 2008-10-16 19:59:48 -0500 (Thu, 16 Oct 2008) | 2 lines
-
-Documentation and package data updates
-
-------------------------------------------------------------------------
-r555 | adustman | 2008-10-16 19:52:50 -0500 (Thu, 16 Oct 2008) | 2 lines
-
-Fix #2001855: Don't use ez_setup; just use setuptools direction.
-
-------------------------------------------------------------------------
-r554 | adustman | 2008-10-16 19:44:48 -0500 (Thu, 16 Oct 2008) | 3 lines
-
-Fix #2156977: Use frozenset as the base for DBAPISet. Only tested for 
-Python 2.5.
-
-------------------------------------------------------------------------
-r553 | adustman | 2008-10-16 19:15:26 -0500 (Thu, 16 Oct 2008) | 5 lines
-
-Fix bug #2137599: Better regex for parsing INPUT statements. Passes unit 
-tests but has not been thoroughly tested.
-
-Bump version to 1.2.3b1.
-
-------------------------------------------------------------------------
-r498 | adustman | 2007-03-03 21:06:05 -0600 (Sat, 03 Mar 2007) | 5 lines
-
-Remove versioned python name from package as egg packaging
-also does this.
-
-1.2.2.
-
-------------------------------------------------------------------------
-r492 | adustman | 2007-02-26 18:33:21 -0600 (Mon, 26 Feb 2007) | 2 lines
-
-Added to make the build bot happy.
-
-------------------------------------------------------------------------
-r491 | adustman | 2007-02-26 13:00:32 -0600 (Mon, 26 Feb 2007) | 1 line
-
-Turns out DBAPISet has been broken all this time and nobody noticed, which proves no one uses it.
-------------------------------------------------------------------------
-r483 | adustman | 2007-02-25 18:50:14 -0600 (Sun, 25 Feb 2007) | 2 lines
-
-1.2.2 notes
-
-------------------------------------------------------------------------
-r481 | adustman | 2007-02-24 22:06:01 -0600 (Sat, 24 Feb 2007) | 2 lines
-
-Small build/packaging fixes. 1.2.2c1.
-
-------------------------------------------------------------------------
-r480 | adustman | 2007-02-24 18:16:43 -0600 (Sat, 24 Feb 2007) | 1 line
-
-Use setuptools instead of distutils. Add Python-2.5 support for with statement as described in http://docs.python.org/whatsnew/pep-343.html  *Please test*
-------------------------------------------------------------------------
-r476 | adustman | 2007-02-11 10:21:25 -0600 (Sun, 11 Feb 2007) | 3 lines
-
-Fix for #1602592. Some Solaris compiler args could have percent signs,
-which would break distutils.
-
-------------------------------------------------------------------------
-r475 | adustman | 2007-02-11 09:49:53 -0600 (Sun, 11 Feb 2007) | 2 lines
-
-Suggestion from #1655760.
-
-------------------------------------------------------------------------
-r473 | adustman | 2007-02-11 01:31:16 -0600 (Sun, 11 Feb 2007) | 2 lines
-
-Missing setup_common too
-
-------------------------------------------------------------------------
-r472 | adustman | 2007-02-11 01:27:13 -0600 (Sun, 11 Feb 2007) | 2 lines
-
-Missing setup_posix.py and setup_windows.py.
-
-------------------------------------------------------------------------
-r468 | adustman | 2007-02-10 14:09:26 -0600 (Sat, 10 Feb 2007) | 2 lines
-
-Fix for #1655760
-
-------------------------------------------------------------------------
-r467 | adustman | 2007-02-10 13:03:18 -0600 (Sat, 10 Feb 2007) | 3 lines
-
-Revert previous reconnect patches and just handle it
-with ping([reconnect]).
-
-------------------------------------------------------------------------
-r466 | adustman | 2007-02-09 23:37:00 -0600 (Fri, 09 Feb 2007) | 1 line
-
-Fix bug #1567804: Make sure lists are copies/slices and not just the original
-------------------------------------------------------------------------
-r465 | adustman | 2007-02-09 22:37:15 -0600 (Fri, 09 Feb 2007) | 2 lines
-
-Add connection.autoreconnect() (variant of bug #1574825)
-
-------------------------------------------------------------------------
-r464 | adustman | 2007-02-09 22:16:53 -0600 (Fri, 09 Feb 2007) | 3 lines
-
-reconnect option for connect (bug #1550388).
-Enjoy your toes while they last.
-
-------------------------------------------------------------------------
-r463 | adustman | 2007-02-09 22:06:10 -0600 (Fri, 09 Feb 2007) | 4 lines
-
-Remove test_SET() since it cannot work until
-http://bugs.mysql.com/bug.php?id=17758 is fixed
-(MySQL-5.1 or 5.2).
-
-------------------------------------------------------------------------
-r462 | adustman | 2007-02-09 21:41:19 -0600 (Fri, 09 Feb 2007) | 1 line
-
-Patch #1651584 (florentaide): Fixes Windows build
-------------------------------------------------------------------------
-r461 | adustman | 2007-01-30 21:55:53 -0600 (Tue, 30 Jan 2007) | 2 lines
-
-Windows build. Completely untested.
-
-------------------------------------------------------------------------
-r460 | adustman | 2007-01-29 12:00:35 -0600 (Mon, 29 Jan 2007) | 7 lines
-
-Fix dumb setup typo.
-
-SET columns can not be reliably returned as Python sets
-in MySQL<5.1. Fixes bug #1561190. Also see
-http://bugs.mysql.com/bug.php?id=17758
-
-
-------------------------------------------------------------------------
-r459 | adustman | 2007-01-03 17:13:58 -0600 (Wed, 03 Jan 2007) | 3 lines
-
-Factor out most of the setup into setup_posix.py.
-setup_windows.py is next.
-
-------------------------------------------------------------------------
-r458 | adustman | 2006-10-28 09:53:23 -0500 (Sat, 28 Oct 2006) | 3 lines
-
-Cleaner way to handle the compile-time versioning (via distutils
-define_macro), from #1586161 (Alexandr Zamaraev).
-
-------------------------------------------------------------------------
-r457 | adustman | 2006-10-27 18:33:35 -0500 (Fri, 27 Oct 2006) | 6 lines
-
-Fix for Python 2.5.
-
-Added a unit test for single character columns.
-
-Updated download URL.
-
-------------------------------------------------------------------------
-r454 | adustman | 2006-10-13 17:12:34 -0500 (Fri, 13 Oct 2006) | 2 lines
-
-Metadata updates, 1.2.2b2
-
-------------------------------------------------------------------------
-r453 | adustman | 2006-08-29 23:04:42 -0500 (Tue, 29 Aug 2006) | 2 lines
-
-Use CP/M-style switch prefixes (/D instead of -D) on Windows.
-
-------------------------------------------------------------------------
-r452 | adustman | 2006-08-29 22:01:17 -0500 (Tue, 29 Aug 2006) | 3 lines
-
-Windows MySQL has a different configuration file (config-win.h)
-for inexplicable reasons. (Bug 1548032)
-
-------------------------------------------------------------------------
-r450 | adustman | 2006-08-27 13:02:48 -0500 (Sun, 27 Aug 2006) | 24 lines
-
-Version 1.2.2b1.
-
-Raise IntegrityError for a couple types of relatively new errors.
-(Bug 1327679)
-
-Add BIT column support. (Bug 1468725)
-
-Return BINARY columns as normal strings, not arrays. (Bug 1495765)
-
-Add support for a new VARCHAR type; behaves like other CHAR types.
-
-Defer issuing warnings when using SSCursors. (Bug 1495782)
-
-Do not try to encode query strings unless they are unicode instances.
-(Bug 1521274)
-
-Fix problem with callproc() when it is used before execute() (which is
-legal). (Bug 1541124)
-
-Fix formatting of datetime.timedelta values. (Bug 1527801)
-
-Fix connect_timeout documentation bug. (Bug 1523883)
-
-
-------------------------------------------------------------------------
-r447 | adustman | 2006-04-08 22:37:18 -0500 (Sat, 08 Apr 2006) | 2 lines
-
-Rename CHANGES to HISTORY
-
-------------------------------------------------------------------------
-r446 | adustman | 2006-04-08 22:36:29 -0500 (Sat, 08 Apr 2006) | 2 lines
-
-Fix MANIFEST (well, fixed after the NEXT commit)
-
-------------------------------------------------------------------------
-r445 | adustman | 2006-04-08 22:29:59 -0500 (Sat, 08 Apr 2006) | 2 lines
-
-Update CHANGES file
-
-------------------------------------------------------------------------
-r444 | adustman | 2006-04-08 22:25:04 -0500 (Sat, 08 Apr 2006) | 2 lines
-
-Bump version. Disable leak checking by default.
-
-------------------------------------------------------------------------
-r443 | adustman | 2006-04-08 21:56:39 -0500 (Sat, 08 Apr 2006) | 3 lines
-
-Fallback to non-thread-safe libraries if the thread-safe ones
-are unavailable.
-
-------------------------------------------------------------------------
-r440 | adustman | 2006-04-05 12:56:36 -0500 (Wed, 05 Apr 2006) | 3 lines
-
-Remove conditionals for registering server_start and server_end.
-Not needed since the code itself is conditional on client version.
-
-------------------------------------------------------------------------
-r439 | adustman | 2006-04-04 10:04:20 -0500 (Tue, 04 Apr 2006) | 7 lines
-
-raise NotSupportedError instead of non-existent UnsupportedError
-
-connection.set_character_set() now avoids raising an exception
-if the current character set is already correct, regardless of
-MySQL version.
-
-
-------------------------------------------------------------------------
-r433 | adustman | 2006-04-02 12:45:58 -0500 (Sun, 02 Apr 2006) | 2 lines
-
-1.2.1
-
-------------------------------------------------------------------------
-r432 | adustman | 2006-04-02 12:15:48 -0500 (Sun, 02 Apr 2006) | 2 lines
-
-Rename branch
-
-------------------------------------------------------------------------
-r423 | adustman | 2006-03-28 06:59:24 -0600 (Tue, 28 Mar 2006) | 2 lines
-
-Fix leak test for subclassing
-
-------------------------------------------------------------------------
-r422 | adustman | 2006-03-27 23:03:35 -0600 (Mon, 27 Mar 2006) | 6 lines
-
-Fix some inconsistent spacing.
-
-Try to fix some memory leaks. I think cursors don't leak any more
-but I've had no luck with connections. If you close your connections
-you should be fine, even if you don't close your cursors.
-
-------------------------------------------------------------------------
-r421 | adustman | 2006-03-05 23:33:01 -0600 (Sun, 05 Mar 2006) | 2 lines
-
-Added documentation for sql_mode support.
-
-------------------------------------------------------------------------
-r420 | adustman | 2006-03-05 23:28:05 -0600 (Sun, 05 Mar 2006) | 11 lines
-
-Added a bunch of new error codes to MySQLdb.constants.ER (complete for
-MySQL-5.0).
-
-Mapped some new error codes to DataError, which has always existed,
-but never had anything mapped to it.
-
-Cleaned set_character_set() a bit.
-
-Added new connection option sql_mode and correspond set_sql_mode()
-method.
-
-------------------------------------------------------------------------
-r418 | adustman | 2006-03-04 22:59:14 -0600 (Sat, 04 Mar 2006) | 13 lines
-
-Bump metadata version.
-
-Clean up setup.cfg so it doesn't break RPM builds on files which
-are no longer included.
-
-Add a test case for warnings for column truncation.
-
-Clean up warnings; was working around the introduced bug that
-returned (var)char columns with binary collations as array.
-
-Exposed the column flags (values from constants.FLAG) as
-description_flags on the cursor.
-
-------------------------------------------------------------------------
-r417 | adustman | 2006-03-04 17:27:24 -0600 (Sat, 04 Mar 2006) | 12 lines
-
-Reverted patch #1387290. It caused char/varchar columns with a binary
-collation to return array('c', ...), which should only be returned for
-actual BLOB columns.
-
-Figured out how to fix loading SET columns. Bug #1214916.
-
-Cleaned up the SET test.
-
-Removed *.html and *.css files from MANIFEST; their presence (or lack
-thereof since they are no longer being packaged) caused RPM builds to
-fail, and possibly others.
-
-------------------------------------------------------------------------
-r415 | adustman | 2006-03-02 22:09:21 -0600 (Thu, 02 Mar 2006) | 10 lines
-
-* Added set_character_set(charset) method to database connections
-
-* Added get_character_set_info() method to database connections
-
-* Added charset option to database connections
-
-* Updated docs, added FAQ
-
-* 1.2.1c6
-
-------------------------------------------------------------------------
-r413 | adustman | 2006-03-01 22:19:32 -0600 (Wed, 01 Mar 2006) | 9 lines
-
-* Add metadata.cfg and site.cfg to MANIFEST.in so they get packaged
-
-* Remove version_info from metadata before calling setup() to avoid
-  complaints
-
-* Fix cursor.callproc() as good as can be fixed.
-
-* Improve/fix various tests for stored procedures.
-
-------------------------------------------------------------------------
-r412 | adustman | 2006-02-28 11:50:22 -0600 (Tue, 28 Feb 2006) | 2 lines
-
-Fix classifiers and package file handling
-
-------------------------------------------------------------------------
-r411 | adustman | 2006-02-28 11:36:32 -0600 (Tue, 28 Feb 2006) | 2 lines
-
-Fix distribution naming
-
-------------------------------------------------------------------------
-r410 | adustman | 2006-02-28 11:16:50 -0600 (Tue, 28 Feb 2006) | 2 lines
-
-Derive all version information from metadata.cfg
-
-------------------------------------------------------------------------
-r409 | adustman | 2006-02-28 10:34:16 -0600 (Tue, 28 Feb 2006) | 2 lines
-
-Fix embedded build
-
-------------------------------------------------------------------------
-r408 | adustman | 2006-02-27 22:19:27 -0600 (Mon, 27 Feb 2006) | 6 lines
-
-* Update README
-
-* Completely rewrite setup.py
-
-* Make pytimes the only time implementation, moved into times
-
-------------------------------------------------------------------------
-r407 | adustman | 2006-02-27 17:10:38 -0600 (Mon, 27 Feb 2006) | 4 lines
-
-Python Sets (from sets module) as parameters work, but *only* Set
-and not ImmutableSet. Still trying to get it to work on BaseSet
-so any subclasses will work.
-
-------------------------------------------------------------------------
-r406 | adustman | 2006-02-27 12:48:57 -0600 (Mon, 27 Feb 2006) | 3 lines
-
-Fix client_flag fubar and add support for more detailed warning
-information available from MySQL-4.1 and newer server.
-
-------------------------------------------------------------------------
-r405 | adustman | 2006-02-27 12:39:53 -0600 (Mon, 27 Feb 2006) | 2 lines
-
-Add sets module support and make boolean support non-optional
-
-------------------------------------------------------------------------
-r404 | adustman | 2006-02-27 11:19:40 -0600 (Mon, 27 Feb 2006) | 3 lines
-
-Remove sets module in favor of standard sets module (Python-2.3 and
-newer)
-
-------------------------------------------------------------------------
-r403 | adustman | 2006-02-27 09:45:37 -0600 (Mon, 27 Feb 2006) | 3 lines
-
-Remove FIELD_TYPE.CHAR (deprecated) from STRING set since it conflicts
-with FIELD_TYPE.TINY (NUMBER).
-
-------------------------------------------------------------------------
-r402 | adustman | 2006-02-26 23:49:26 -0600 (Sun, 26 Feb 2006) | 2 lines
-
-Fix fubared TimeDelta_or_None and Time_or_None
-
-------------------------------------------------------------------------
-r401 | adustman | 2006-02-26 23:37:22 -0600 (Sun, 26 Feb 2006) | 2 lines
-
-Remove erroneous insert_id() on cursor reference.
-
-------------------------------------------------------------------------
-r400 | adustman | 2006-02-26 23:31:14 -0600 (Sun, 26 Feb 2006) | 2 lines
-
-Translate some additional error codes
-
-------------------------------------------------------------------------
-r399 | adustman | 2006-02-26 22:48:02 -0600 (Sun, 26 Feb 2006) | 2 lines
-
-Documentation is good. Correct documentation is better.
-
-------------------------------------------------------------------------
-r398 | adustman | 2006-02-26 22:20:48 -0600 (Sun, 26 Feb 2006) | 4 lines
-
-Enable MULTI_STATEMENTS if the client library is 4.1 or newer.
-
-Enable MULTI_RESULTS if the client library is 5.0 or newer.
-
-------------------------------------------------------------------------
-r397 | adustman | 2006-02-26 08:50:47 -0600 (Sun, 26 Feb 2006) | 3 lines
-
-Encode queries to connection character set before inserting
-parameters. Bug 1438913
-
-------------------------------------------------------------------------
-r396 | adustman | 2006-02-24 21:44:32 -0600 (Fri, 24 Feb 2006) | 2 lines
-
-Generic DB-API unit test module
-
-------------------------------------------------------------------------
-r395 | adustman | 2006-02-24 21:43:47 -0600 (Fri, 24 Feb 2006) | 2 lines
-
-Add the DB API unit tester for MySQLdb
-
-------------------------------------------------------------------------
-r394 | adustman | 2006-02-24 21:31:52 -0600 (Fri, 24 Feb 2006) | 6 lines
-
-* Fix callproc
-
-* Subtle bug: fetchall() could return the entire result set
-  over and over again if you called it multiple times (not
-  likely)
-
-------------------------------------------------------------------------
-r393 | adustman | 2006-02-24 18:56:15 -0600 (Fri, 24 Feb 2006) | 2 lines
-
-Add callproc() support.
-
-------------------------------------------------------------------------
-r392 | adustman | 2006-02-24 18:43:09 -0600 (Fri, 24 Feb 2006) | 3 lines
-
-Don't convert binary varchar columns to unicode.
-Patch 1387290
-
-------------------------------------------------------------------------
-r391 | adustman | 2006-02-24 18:33:17 -0600 (Fri, 24 Feb 2006) | 2 lines
-
-Include my_config.h so that SSL support can be properly detected.
-
-------------------------------------------------------------------------
-r387 | adustman | 2006-02-22 20:00:58 -0600 (Wed, 22 Feb 2006) | 2 lines
-
-Apply Gentoo patch for NEWDECIMAL support (MySQL-5.0)
-
-------------------------------------------------------------------------
-r386 | adustman | 2005-05-11 21:08:50 -0500 (Wed, 11 May 2005) | 12 lines
-
-Version 1.2.1c3:
-
-* _mysql.c: raise ProgrammingError for certain methods if they
-  are used on Result object created with conn.use_result(),
-  since they don't make sense.
-
-* setup.py: Reimplement quote stripping around directory names.
-  This seems to be a bug in older versions of mysql_config
-
-* cursors.py: If a unicode query string is passed, encode it in
-  the connection's character set.
-
-------------------------------------------------------------------------
-r385 | adustman | 2005-05-01 13:41:32 -0500 (Sun, 01 May 2005) | 2 lines
-
-Fix Debian information
-
-------------------------------------------------------------------------
-r384 | adustman | 2005-04-30 19:09:25 -0500 (Sat, 30 Apr 2005) | 11 lines
-
-* removed directory filtering in setup.py; should no longer be necessary,
-  and it seems to cause problems on some platforms or versions of MySQL
-  (most likely 3.23's mysql_config)
-
-* removed use of weak references; I don't think they were needed any more,
-  and they caused problems in some of the threaded tests.
-
-* applied patch #1188359: If converters are passed in, use a copy().
-
-* Version 1.2.1c2.
-
-------------------------------------------------------------------------
-r382 | adustman | 2005-04-10 15:56:55 -0500 (Sun, 10 Apr 2005) | 2 lines
-
-Version 1.2.1c1
-
-------------------------------------------------------------------------
-r381 | adustman | 2005-04-10 15:50:29 -0500 (Sun, 10 Apr 2005) | 4 lines
-
-This should fix the problem with Fedora Core noted on bug
-#1145226: On library/include paths, remove quotation marks,
-if present.
-
-------------------------------------------------------------------------
-r380 | adustman | 2005-04-10 15:41:29 -0500 (Sun, 10 Apr 2005) | 3 lines
-
-Apply patch #1179364 for bug #1037468:
-DeprecationWarnings for deprecated methods.
-
-------------------------------------------------------------------------
-r379 | adustman | 2005-04-02 23:17:34 -0600 (Sat, 02 Apr 2005) | 2 lines
-
-Restore the begin() method, but issue a DeprecationWarning.
-
-------------------------------------------------------------------------
-r378 | adustman | 2005-04-02 23:15:51 -0600 (Sat, 02 Apr 2005) | 4 lines
-
-Add iterator protocol to SSCurors.
-
-Issue deprecation warnings for special DictCursor methods.
-
-------------------------------------------------------------------------
-r377 | adustman | 2005-04-02 22:23:18 -0600 (Sat, 02 Apr 2005) | 2 lines
-
-Merge in changes from the trunk
-
-------------------------------------------------------------------------
-r372 | (no author) | 2005-02-04 11:03:46 -0600 (Fri, 04 Feb 2005) | 1 line
-
-This commit was manufactured by cvs2svn to create branch 'branch-1-2'.
-------------------------------------------------------------------------
-r371 | adustman | 2005-02-04 11:03:46 -0600 (Fri, 04 Feb 2005) | 2 lines
-
-Fix connection leak
-
-------------------------------------------------------------------------
-r369 | adustman | 2005-01-31 22:01:40 -0600 (Mon, 31 Jan 2005) | 4 lines
-
-* Version 1.1.10
-
-* Minor doc updates and setup tweaks.
-
-------------------------------------------------------------------------
-r368 | adustman | 2005-01-26 21:05:32 -0600 (Wed, 26 Jan 2005) | 2 lines
-
-Add additional documentation for RPM build.
-
-------------------------------------------------------------------------
-r367 | adustman | 2005-01-26 20:41:24 -0600 (Wed, 26 Jan 2005) | 2 lines
-
-Fix RPM build
-
-------------------------------------------------------------------------
-r366 | adustman | 2005-01-24 22:45:30 -0600 (Mon, 24 Jan 2005) | 2 lines
-
-Windows fixes
-
-------------------------------------------------------------------------
-r365 | adustman | 2005-01-23 00:56:55 -0600 (Sun, 23 Jan 2005) | 4 lines
-
-Made setup.py usable for Windows again. You must set
-the mysqlroot environment variable or patch to make
-it actually work.
-
-------------------------------------------------------------------------
-r364 | adustman | 2005-01-22 23:47:40 -0600 (Sat, 22 Jan 2005) | 2 lines
-
-Bug #770825
-
-------------------------------------------------------------------------
-r363 | adustman | 2005-01-22 22:49:04 -0600 (Sat, 22 Jan 2005) | 2 lines
-
-add load_infile option and more doc cleanups
-
-------------------------------------------------------------------------
-r361 | adustman | 2005-01-20 21:25:30 -0600 (Thu, 20 Jan 2005) | 2 lines
-
-Documentation updates.
-
-------------------------------------------------------------------------
-r360 | adustman | 2005-01-19 22:20:19 -0600 (Wed, 19 Jan 2005) | 10 lines
-
- * Bump version to 1.1.9
-
- * Reworked Unicode support; please test
-
- * Make Binary() create an array('c')
-
- * Clean up Cursors a bit.
-
- * Add a TimeDelta factory function, even though not in the API spec.
-
-------------------------------------------------------------------------
-r359 | adustman | 2005-01-16 19:51:00 -0600 (Sun, 16 Jan 2005) | 4 lines
-
- * make sure charset has a default (None)
-
- * eliminate lambda usage
-
-------------------------------------------------------------------------
-r358 | adustman | 2005-01-14 20:16:26 -0600 (Fri, 14 Jan 2005) | 7 lines
-
-Should now auto-detect all build settings for any platform.
-win32 now requires win32pipe to build. Build has only been
-tested on Linux, but AFAIK, os.popen() works properly on
-all other platforms, and certainly must work on anything
-remotely POSIX/UNIX-like. I am assuming that it will work
-on Mac OS X as well.
-
-------------------------------------------------------------------------
-r357 | adustman | 2005-01-12 23:00:29 -0600 (Wed, 12 Jan 2005) | 7 lines
-
-
-* Overhaul setup.py
-
-* Clean up warnings in _mysql.c when SSL is not available
-
-* Tidy up MANIFEST.in
-
-------------------------------------------------------------------------
-r356 | adustman | 2005-01-04 21:44:02 -0600 (Tue, 04 Jan 2005) | 2 lines
-
-Add GEOMETRY (new in MySQL-4.1)
-
-------------------------------------------------------------------------
-r352 | adustman | 2004-12-31 18:10:20 -0600 (Fri, 31 Dec 2004) | 2 lines
-
-Fix some formatting problems
-
-------------------------------------------------------------------------
-r351 | adustman | 2004-12-31 17:38:21 -0600 (Fri, 31 Dec 2004) | 3 lines
-
-Clean up handling of warnings and make cursor.messages
-actually useful for something.
-
-------------------------------------------------------------------------
-r350 | adustman | 2004-12-31 16:41:11 -0600 (Fri, 31 Dec 2004) | 2 lines
-
-Version 1.1.8
-
-------------------------------------------------------------------------
-r349 | adustman | 2004-12-31 16:36:50 -0600 (Fri, 31 Dec 2004) | 3 lines
-
-Remove old CHANGELOG. Include some test programs, which are
-not in CVS.
-
-------------------------------------------------------------------------
-r348 | adustman | 2004-12-31 16:34:11 -0600 (Fri, 31 Dec 2004) | 2 lines
-
-Very minor DB-API compliance fixes.
-
-------------------------------------------------------------------------
-r347 | adustman | 2004-12-30 19:30:17 -0600 (Thu, 30 Dec 2004) | 3 lines
-
-Add support for warning_count() and constants needed for
-issuing multiple statements.
-
-------------------------------------------------------------------------
-r346 | adustman | 2004-12-30 16:17:36 -0600 (Thu, 30 Dec 2004) | 2 lines
-
-* add set_server_option() and sqlstate() connection object methods
-
-------------------------------------------------------------------------
-r345 | adustman | 2004-12-30 14:59:58 -0600 (Thu, 30 Dec 2004) | 2 lines
-
-*** empty log message ***
-
-------------------------------------------------------------------------
-r344 | adustman | 2004-12-30 14:58:48 -0600 (Thu, 30 Dec 2004) | 4 lines
-
-* Add connection.next_result()
-
-* Another fix for bug #1093028
-
-------------------------------------------------------------------------
-r343 | adustman | 2004-12-30 13:13:22 -0600 (Thu, 30 Dec 2004) | 4 lines
-
-Convert the new autocommit, commit, and rollback connection methods
-into pure C. When using MySQL<4.1, these issue queries. This simplifies
-the Python layer a bit.
-
-------------------------------------------------------------------------
-r342 | adustman | 2004-12-30 11:50:48 -0600 (Thu, 30 Dec 2004) | 2 lines
-
-Fix bug 1093028
-
-------------------------------------------------------------------------
-r341 | adustman | 2004-10-30 22:53:15 -0500 (Sat, 30 Oct 2004) | 2 lines
-
-*** empty log message ***
-
-------------------------------------------------------------------------
-r339 | adustman | 2004-10-30 22:49:19 -0500 (Sat, 30 Oct 2004) | 2 lines
-
-Convert to restructured text.
-
-------------------------------------------------------------------------
-r338 | adustman | 2004-10-30 21:11:20 -0500 (Sat, 30 Oct 2004) | 2 lines
-
-Version 1.1.7
-
-------------------------------------------------------------------------
-r337 | adustman | 2004-10-30 20:55:51 -0500 (Sat, 30 Oct 2004) | 2 lines
-
-Fix bug #1050841
-
-------------------------------------------------------------------------
-r336 | adustman | 2004-10-28 20:52:52 -0500 (Thu, 28 Oct 2004) | 2 lines
-
-Add unicode_errors parameter to connect()
-
-------------------------------------------------------------------------
-r335 | adustman | 2004-10-28 20:50:34 -0500 (Thu, 28 Oct 2004) | 2 lines
-
-Fix bug #1045512
-
-------------------------------------------------------------------------
-r333 | adustman | 2004-09-26 17:22:59 -0500 (Sun, 26 Sep 2004) | 10 lines
-
- * Fix pytimes.TimeDelta_or_None()
-
- * Include days with mxdatetime.format_TIME()
-
- * Return MySQL TIME columns as a time delta
-
- * Remove old CompatMysqldb module
-
- * Version 1.1.6
-
-------------------------------------------------------------------------
-r327 | adustman | 2004-09-19 16:38:59 -0500 (Sun, 19 Sep 2004) | 2 lines
-
-*** empty log message ***
-
-------------------------------------------------------------------------
-r326 | adustman | 2004-09-19 16:38:08 -0500 (Sun, 19 Sep 2004) | 6 lines
-
- * Removed some old-style Python stuff from setup.py
-
- * Added a bit of documentation on ssl parameter to Connection
-
- * Version 1.1.5
-
-------------------------------------------------------------------------
-r325 | adustman | 2004-09-19 15:14:31 -0500 (Sun, 19 Sep 2004) | 2 lines
-
-Include new ChangeLog
-
-------------------------------------------------------------------------
-r324 | adustman | 2004-09-19 14:56:20 -0500 (Sun, 19 Sep 2004) | 2 lines
-
-Restore missing common on include_dirs
-
-------------------------------------------------------------------------
-r322 | adustman | 2004-09-11 02:26:27 -0500 (Sat, 11 Sep 2004) | 2 lines
-
-*** empty log message ***
-
-------------------------------------------------------------------------
-r321 | adustman | 2004-09-11 02:25:34 -0500 (Sat, 11 Sep 2004) | 8 lines
-
-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
-
-------------------------------------------------------------------------
-r320 | adustman | 2004-09-11 00:57:19 -0500 (Sat, 11 Sep 2004) | 2 lines
-
-Re-fix typo
-
-------------------------------------------------------------------------
-r319 | adustman | 2004-09-11 00:29:00 -0500 (Sat, 11 Sep 2004) | 4 lines
-
-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.
-
-------------------------------------------------------------------------
-r318 | adustman | 2004-09-07 20:40:33 -0500 (Tue, 07 Sep 2004) | 2 lines
-
-*** empty log message ***
-
-------------------------------------------------------------------------
-r317 | adustman | 2004-09-07 20:39:46 -0500 (Tue, 07 Sep 2004) | 7 lines
-
-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.
-
-------------------------------------------------------------------------
-r315 | adustman | 2004-09-06 16:53:40 -0500 (Mon, 06 Sep 2004) | 21 lines
-
-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
-
-------------------------------------------------------------------------
-r307 | adustman | 2004-06-06 22:44:39 -0500 (Sun, 06 Jun 2004) | 2 lines
-
-Bump version. Update README. Convert all classes to new-style.
-
-------------------------------------------------------------------------
-r303 | adustman | 2004-05-18 22:54:01 -0500 (Tue, 18 May 2004) | 2 lines
-
-Initial conversion to modern Python.
-
-------------------------------------------------------------------------
-r295 | adustman | 2004-02-28 20:28:20 -0600 (Sat, 28 Feb 2004) | 2 lines
-
-Fix bug #897344
-
-------------------------------------------------------------------------
-r294 | adustman | 2004-02-28 20:22:59 -0600 (Sat, 28 Feb 2004) | 2 lines
-
-Fix bug #902024
-
-------------------------------------------------------------------------
-r292 | adustman | 2003-12-29 19:30:36 -0600 (Mon, 29 Dec 2003) | 17 lines
-
- * 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.
-
-------------------------------------------------------------------------
-r291 | adustman | 2003-12-12 22:58:25 -0600 (Fri, 12 Dec 2003) | 4 lines
-
-https://sourceforge.net/tracker/?func=detail&aid=850174&group_id=22307&atid=374932
-
-Use more precision for floats; str(<float>) doesn't return full precision.
-
-------------------------------------------------------------------------
-r290 | adustman | 2003-11-27 14:56:40 -0600 (Thu, 27 Nov 2003) | 19 lines
-
-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.
-
-------------------------------------------------------------------------
-r288 | adustman | 2003-11-23 16:04:04 -0600 (Sun, 23 Nov 2003) | 2 lines
-
-Version bump
-
-------------------------------------------------------------------------
-r287 | adustman | 2003-11-23 16:02:13 -0600 (Sun, 23 Nov 2003) | 9 lines
-
-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.
-
-------------------------------------------------------------------------
-r286 | adustman | 2003-11-22 13:30:40 -0600 (Sat, 22 Nov 2003) | 2 lines
-
-Bug #816721
-
-------------------------------------------------------------------------
-r285 | adustman | 2003-11-22 12:55:13 -0600 (Sat, 22 Nov 2003) | 2 lines
-
-Bug #811636 fix (?)
-
-------------------------------------------------------------------------
-r284 | adustman | 2003-09-06 21:51:15 -0500 (Sat, 06 Sep 2003) | 2 lines
-
-info() might return None or empty string
-
-------------------------------------------------------------------------
-r283 | adustman | 2003-09-06 21:45:58 -0500 (Sat, 06 Sep 2003) | 3 lines
-
-Don't treat FIELD_TYPE.CHAR as a character type, it's really
-a TINYINT (FIELD_TYPE.TINY).
-
-------------------------------------------------------------------------
-r282 | adustman | 2003-09-06 21:25:05 -0500 (Sat, 06 Sep 2003) | 2 lines
-
-Bug#778822
-
-------------------------------------------------------------------------
-r281 | adustman | 2003-09-06 21:07:16 -0500 (Sat, 06 Sep 2003) | 2 lines
-
-Fix version number correctly
-
-------------------------------------------------------------------------
-r280 | adustman | 2003-09-06 21:00:34 -0500 (Sat, 06 Sep 2003) | 2 lines
-
-Version bump
-
-------------------------------------------------------------------------
-r279 | adustman | 2003-07-10 19:34:40 -0500 (Thu, 10 Jul 2003) | 2 lines
-
-Include new time handling modules
-
-------------------------------------------------------------------------
-r278 | adustman | 2003-07-10 19:13:44 -0500 (Thu, 10 Jul 2003) | 2 lines
-
-Split out old Date/Time handling classes into separate modules
-
-------------------------------------------------------------------------
-r277 | adustman | 2003-07-10 19:07:06 -0500 (Thu, 10 Jul 2003) | 2 lines
-
-Finish up TimeDelta_or_None
-
-------------------------------------------------------------------------
-r276 | adustman | 2003-07-10 10:58:56 -0500 (Thu, 10 Jul 2003) | 2 lines
-
-Add support for Python 2.3 datetime classes.
-
-------------------------------------------------------------------------
-r275 | adustman | 2003-07-08 01:34:27 -0500 (Tue, 08 Jul 2003) | 2 lines
-
-Bump version numbers.
-
-------------------------------------------------------------------------
-r274 | adustman | 2003-07-08 01:29:56 -0500 (Tue, 08 Jul 2003) | 3 lines
-
-Bump version and remove some unneccesary casts that seem to
-break things when using Python 2.3.
-
-------------------------------------------------------------------------
-r273 | adustman | 2003-07-07 16:44:40 -0500 (Mon, 07 Jul 2003) | 2 lines
-
-Fix bug 605849 (I hope).
-
-------------------------------------------------------------------------
-r272 | adustman | 2003-07-07 12:49:01 -0500 (Mon, 07 Jul 2003) | 2 lines
-
-Fix member access problems
-
-------------------------------------------------------------------------
-r271 | adustman | 2003-04-20 21:50:57 -0500 (Sun, 20 Apr 2003) | 2 lines
-
-Eliminate use of deprecated PyArg_NoArgs()
-
-------------------------------------------------------------------------
-r270 | adustman | 2003-04-20 21:23:06 -0500 (Sun, 20 Apr 2003) | 2 lines
-
-Dumb typo
-
-------------------------------------------------------------------------
-r269 | adustman | 2003-04-18 23:26:57 -0500 (Fri, 18 Apr 2003) | 2 lines
-
-Build and documentation updates
-
-------------------------------------------------------------------------
-r268 | adustman | 2002-08-22 16:12:02 -0500 (Thu, 22 Aug 2002) | 2 lines
-
-Embedded server support
-
-------------------------------------------------------------------------
-r267 | adustman | 2002-08-22 10:20:25 -0500 (Thu, 22 Aug 2002) | 3 lines
-
-Clean up compiler warnings about
-assignment discards qualifiers from pointer target type
-
-------------------------------------------------------------------------
-r266 | adustman | 2002-08-01 23:09:13 -0500 (Thu, 01 Aug 2002) | 2 lines
-
-Windows (blech) compatibility changes. (Gerhard H�ring)
-
-------------------------------------------------------------------------
-r264 | adustman | 2002-08-01 00:18:08 -0500 (Thu, 01 Aug 2002) | 2 lines
-
-CHANGELOG
-
-------------------------------------------------------------------------
-r263 | adustman | 2002-08-01 00:09:51 -0500 (Thu, 01 Aug 2002) | 2 lines
-
-Not supporting GC for python < 2.2
-
-------------------------------------------------------------------------
-r262 | adustman | 2002-07-31 23:49:14 -0500 (Wed, 31 Jul 2002) | 2 lines
-
-Memory API updates
-
-------------------------------------------------------------------------
-r261 | adustman | 2002-07-31 23:48:48 -0500 (Wed, 31 Jul 2002) | 2 lines
-
-Ignore exception from close() in __del__
-
-------------------------------------------------------------------------
-r260 | adustman | 2002-07-31 23:29:54 -0500 (Wed, 31 Jul 2002) | 2 lines
-
-GC for Python 2.2+
-
-------------------------------------------------------------------------
-r259 | adustman | 2002-07-20 23:05:17 -0500 (Sat, 20 Jul 2002) | 2 lines
-
-0.9.2 (finally)
-
-------------------------------------------------------------------------
-r258 | adustman | 2002-07-16 11:26:40 -0500 (Tue, 16 Jul 2002) | 2 lines
-
-Revert execute behavior: Do not use % operator when there are no args
-
-------------------------------------------------------------------------
-r257 | adustman | 2002-07-10 15:28:03 -0500 (Wed, 10 Jul 2002) | 2 lines
-
-Rewrite
-
-------------------------------------------------------------------------
-r256 | adustman | 2002-07-10 14:00:59 -0500 (Wed, 10 Jul 2002) | 2 lines
-
-Packaging cleanups
-
-------------------------------------------------------------------------
-r254 | adustman | 2002-07-10 10:18:13 -0500 (Wed, 10 Jul 2002) | 2 lines
-
-Version 0.9.2c3, see CHANGELOG
-
-------------------------------------------------------------------------
-r253 | adustman | 2002-07-03 10:49:12 -0500 (Wed, 03 Jul 2002) | 3 lines
-
-Revert returning BLOBs as arrays, since MySQL doesn't distinquish
-between TEXT and BLOB types. (Skip Montanaro)
-
-------------------------------------------------------------------------
-r252 | adustman | 2002-07-03 09:40:12 -0500 (Wed, 03 Jul 2002) | 2 lines
-
-Passing both conv and unicode to connect was broken (Skip Montanaro)
-
-------------------------------------------------------------------------
-r251 | adustman | 2002-07-01 22:55:58 -0500 (Mon, 01 Jul 2002) | 2 lines
-
-FreeBSD/OpenBSD update
-
-------------------------------------------------------------------------
-r250 | adustman | 2002-07-01 09:50:24 -0500 (Mon, 01 Jul 2002) | 2 lines
-
-Fix dumb (but working) iterator implementation
-
-------------------------------------------------------------------------
-r249 | adustman | 2002-06-30 22:36:17 -0500 (Sun, 30 Jun 2002) | 2 lines
-
-Doc updates
-
-------------------------------------------------------------------------
-r248 | adustman | 2002-06-26 00:50:11 -0500 (Wed, 26 Jun 2002) | 2 lines
-
-Add _mysql.thread_safe() (boolean, true if linked with thread-safe lib)
-
-------------------------------------------------------------------------
-r246 | adustman | 2002-06-24 13:27:39 -0500 (Mon, 24 Jun 2002) | 2 lines
-
-Smack my version up
-
-------------------------------------------------------------------------
-r245 | adustman | 2002-06-23 15:25:55 -0500 (Sun, 23 Jun 2002) | 2 lines
-
-Some errorhandler cleanups
-
-------------------------------------------------------------------------
-r243 | adustman | 2002-06-20 18:27:18 -0500 (Thu, 20 Jun 2002) | 2 lines
-
-*** empty log message ***
-
-------------------------------------------------------------------------
-r242 | adustman | 2002-06-20 18:17:48 -0500 (Thu, 20 Jun 2002) | 2 lines
-
-Make the new unicode option actually work
-
-------------------------------------------------------------------------
-r241 | adustman | 2002-06-20 16:31:27 -0500 (Thu, 20 Jun 2002) | 2 lines
-
-Add nextset() dummy stub
-
-------------------------------------------------------------------------
-r240 | adustman | 2002-06-20 16:30:49 -0500 (Thu, 20 Jun 2002) | 2 lines
-
-BLOBs as array support
-
-------------------------------------------------------------------------
-r239 | adustman | 2002-06-20 16:27:51 -0500 (Thu, 20 Jun 2002) | 4 lines
-
-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.
-
-------------------------------------------------------------------------
-r238 | adustman | 2002-06-20 16:12:56 -0500 (Thu, 20 Jun 2002) | 2 lines
-
-Lots of Python 2.2 updates, especially documentation
-
-------------------------------------------------------------------------
-r237 | adustman | 2002-06-17 20:01:47 -0500 (Mon, 17 Jun 2002) | 2 lines
-
-Mostly documentation updates, and some code cleanups
-
-------------------------------------------------------------------------
-r236 | adustman | 2002-06-15 18:38:54 -0500 (Sat, 15 Jun 2002) | 2 lines
-
-Make executemany iterate over queries that don't use multiple VALUES
-
-------------------------------------------------------------------------
-r235 | adustman | 2002-04-28 14:55:08 -0500 (Sun, 28 Apr 2002) | 2 lines
-
-packaging changes, pre-emptive version bump
-
-------------------------------------------------------------------------
-r233 | adustman | 2002-04-28 14:26:19 -0500 (Sun, 28 Apr 2002) | 2 lines
-
-Bump version
-
-------------------------------------------------------------------------
-r232 | adustman | 2002-04-28 14:23:50 -0500 (Sun, 28 Apr 2002) | 4 lines
-
-
-Errorhandler was broken in cursor
-CVSr ----------------------------------------------------------------------
-
-------------------------------------------------------------------------
-r231 | adustman | 2002-04-28 14:07:55 -0500 (Sun, 28 Apr 2002) | 2 lines
-
-changelog
-
-------------------------------------------------------------------------
-r230 | adustman | 2002-04-28 13:32:06 -0500 (Sun, 28 Apr 2002) | 2 lines
-
-Version bump
-
-------------------------------------------------------------------------
-r229 | adustman | 2002-04-28 13:31:46 -0500 (Sun, 28 Apr 2002) | 2 lines
-
-Macro cleanups
-
-------------------------------------------------------------------------
-r228 | adustman | 2002-04-26 19:12:57 -0500 (Fri, 26 Apr 2002) | 6 lines
-
-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)
-
-------------------------------------------------------------------------
-r227 | adustman | 2002-03-19 10:31:23 -0600 (Tue, 19 Mar 2002) | 3 lines
-
-More (de)allocation cleanups, based on suggestions from
-python-dev and Skip Montanaro
-
-------------------------------------------------------------------------
-r226 | adustman | 2002-03-19 00:16:21 -0600 (Tue, 19 Mar 2002) | 2 lines
-
-Use modern allocation with modern Python
-
-------------------------------------------------------------------------
-r224 | adustman | 2002-03-14 14:44:42 -0600 (Thu, 14 Mar 2002) | 2 lines
-
-Elminate debugging statement.
-
-------------------------------------------------------------------------
-r223 | adustman | 2002-03-14 14:43:51 -0600 (Thu, 14 Mar 2002) | 2 lines
-
-Bump version. Minor Alpha Linux update. Clear errorhandler on close.
-
-------------------------------------------------------------------------
-r220 | adustman | 2002-03-01 16:27:12 -0600 (Fri, 01 Mar 2002) | 2 lines
-
-Fix a memory leak if the connect fails
-
-------------------------------------------------------------------------
-r212 | adustman | 2002-01-28 19:21:21 -0600 (Mon, 28 Jan 2002) | 3 lines
-
-Stricter regex for finding INSERT values
-([ #505295 ] Wrong regexp in executemany() function.)
-
-------------------------------------------------------------------------
-r210 | adustman | 2002-01-25 14:20:42 -0600 (Fri, 25 Jan 2002) | 2 lines
-
-changes
-
-------------------------------------------------------------------------
-r209 | adustman | 2002-01-25 14:18:18 -0600 (Fri, 25 Jan 2002) | 2 lines
-
-Verision bump.
-
-------------------------------------------------------------------------
-r208 | adustman | 2002-01-25 14:17:03 -0600 (Fri, 25 Jan 2002) | 2 lines
-
-Use modern memory deallocation on modern versions of Python.
-
-------------------------------------------------------------------------
-r207 | adustman | 2002-01-25 13:50:35 -0600 (Fri, 25 Jan 2002) | 2 lines
-
-Rework platform config a bit, default to thread-safe client.
-
-------------------------------------------------------------------------
-r205 | adustman | 2001-12-28 20:28:18 -0600 (Fri, 28 Dec 2001) | 2 lines
-
-Fix fetchmany().
-
-------------------------------------------------------------------------
-r203 | adustman | 2001-12-23 19:26:50 -0600 (Sun, 23 Dec 2001) | 2 lines
-
-Fix version.
-
-------------------------------------------------------------------------
-r202 | adustman | 2001-12-23 19:23:55 -0600 (Sun, 23 Dec 2001) | 2 lines
-
-Version 0.9.2a1. Unicode + DB-API extensions.
-
-------------------------------------------------------------------------
-r201 | adustman | 2001-12-23 15:39:31 -0600 (Sun, 23 Dec 2001) | 2 lines
-
-0.9.2 alpha 1
-
-------------------------------------------------------------------------
-r200 | adustman | 2001-12-23 15:37:33 -0600 (Sun, 23 Dec 2001) | 2 lines
-
-Unicode support.
-
-------------------------------------------------------------------------
-r199 | adustman | 2001-12-22 13:25:28 -0600 (Sat, 22 Dec 2001) | 3 lines
-
-str() can fail in some cases, particularly unicode.
-Watch for it to prevent core dumps.
-
-------------------------------------------------------------------------
-r198 | adustman | 2001-12-03 09:05:39 -0600 (Mon, 03 Dec 2001) | 3 lines
-
-Fix cursor.rownumber for CursorStoreResultMixIn.fetchmany()
-and implement cursor.rownumber for CursorUseResultMixIn.fetchXXX().
-
-------------------------------------------------------------------------
-r197 | adustman | 2001-11-28 10:42:45 -0600 (Wed, 28 Nov 2001) | 2 lines
-
-Catch more *bsd platforms. (Suggested by Ragnar Beer)
-
-------------------------------------------------------------------------
-r196 | adustman | 2001-11-06 21:32:20 -0600 (Tue, 06 Nov 2001) | 4 lines
-
-Simplify the various configurations.
-
-Solaris might be fixed for gcc and broken for standard compiler.
-
-------------------------------------------------------------------------
-r195 | adustman | 2001-10-30 22:41:34 -0600 (Tue, 30 Oct 2001) | 2 lines
-
-Some additional Zope notes.
-
-------------------------------------------------------------------------
-r194 | adustman | 2001-10-30 22:29:21 -0600 (Tue, 30 Oct 2001) | 2 lines
-
-Mac OS X updates
-
-------------------------------------------------------------------------
-r193 | adustman | 2001-10-30 22:25:02 -0600 (Tue, 30 Oct 2001) | 2 lines
-
-Link with -flat_namespace on Mac OS X/darwin. (Dan Grassi)
-
-------------------------------------------------------------------------
-r192 | adustman | 2001-10-25 10:06:35 -0500 (Thu, 25 Oct 2001) | 4 lines
-
-Do some renaming suggested by recent DB-SIG discussions.
-
-This should not break anything unless you are using private members.
-
-------------------------------------------------------------------------
-r191 | adustman | 2001-10-22 23:54:00 -0500 (Mon, 22 Oct 2001) | 2 lines
-
-netbsd config
-
-------------------------------------------------------------------------
-r188 | adustman | 2001-10-16 22:21:22 -0500 (Tue, 16 Oct 2001) | 2 lines
-
-0.9.0 updates
-
-------------------------------------------------------------------------
-r187 | adustman | 2001-10-13 09:06:27 -0500 (Sat, 13 Oct 2001) | 2 lines
-
-import Set
-
-------------------------------------------------------------------------
-r186 | adustman | 2001-09-29 10:40:27 -0500 (Sat, 29 Sep 2001) | 2 lines
-
-Catch more Linux platforms in the config.
-
-------------------------------------------------------------------------
-r185 | adustman | 2001-09-21 08:33:32 -0500 (Fri, 21 Sep 2001) | 2 lines
-
-Solaris config (Bent NAgstrup Terp)
-
-------------------------------------------------------------------------
-r183 | adustman | 2001-09-20 12:26:22 -0500 (Thu, 20 Sep 2001) | 2 lines
-
-Good to update this at least once a year.
-
-------------------------------------------------------------------------
-r182 | adustman | 2001-09-20 12:15:02 -0500 (Thu, 20 Sep 2001) | 2 lines
-
-Update to 0.9.1c2.
-
-------------------------------------------------------------------------
-r181 | adustman | 2001-09-13 07:53:07 -0500 (Thu, 13 Sep 2001) | 2 lines
-
-Fix exception handling in connect() (broken by 0.9.1.c1)
-
-------------------------------------------------------------------------
-r180 | adustman | 2001-09-12 12:29:27 -0500 (Wed, 12 Sep 2001) | 2 lines
-
-Added CHANGELOG. (John Bowe)
-
-------------------------------------------------------------------------
-r173 | adustman | 2001-09-06 20:24:04 -0500 (Thu, 06 Sep 2001) | 2 lines
-
-OSX config (Paul DuBois); tab/space cleanups; more package info
-
-------------------------------------------------------------------------
-r172 | adustman | 2001-09-06 20:12:06 -0500 (Thu, 06 Sep 2001) | 2 lines
-
-Generated by distutils.
-
-------------------------------------------------------------------------
-r170 | adustman | 2001-09-06 20:08:17 -0500 (Thu, 06 Sep 2001) | 2 lines
-
-More stuff I forgot about.
-
-------------------------------------------------------------------------
-r169 | adustman | 2001-09-06 20:07:01 -0500 (Thu, 06 Sep 2001) | 2 lines
-
-Use two arg _PyTuple_Resize() for Python 2.2 and newer.
-
-------------------------------------------------------------------------
-r168 | adustman | 2001-09-06 20:06:08 -0500 (Thu, 06 Sep 2001) | 2 lines
-
-Version 0.9.1c1
-
-------------------------------------------------------------------------
-r167 | adustman | 2001-09-06 20:05:50 -0500 (Thu, 06 Sep 2001) | 2 lines
-
-Return DECIMAL/NUMERIC as floating point.
-
-------------------------------------------------------------------------
-r166 | adustman | 2001-09-06 18:08:14 -0500 (Thu, 06 Sep 2001) | 2 lines
-
-Added a CHANGELOG, for people who like that sort of thing.
-
-------------------------------------------------------------------------
-r165 | adustman | 2001-09-06 01:29:21 -0500 (Thu, 06 Sep 2001) | 7 lines
-
-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.
-
-------------------------------------------------------------------------
-r164 | adustman | 2001-09-05 22:04:26 -0500 (Wed, 05 Sep 2001) | 2 lines
-
-Change version number, back out memory changes.
-
-------------------------------------------------------------------------
-r163 | adustman | 2001-09-05 21:02:57 -0500 (Wed, 05 Sep 2001) | 2 lines
-
-Memory allocation cleanups. Add missing newline in docstring.
-
-------------------------------------------------------------------------
-r160 | adustman | 2001-07-28 22:08:11 -0500 (Sat, 28 Jul 2001) | 3 lines
-
-ER_PARSE_ERROR -> ProgrammingError;
-#ifdef around some recent error types
-
-------------------------------------------------------------------------
-r159 | adustman | 2001-07-12 12:10:59 -0500 (Thu, 12 Jul 2001) | 2 lines
-
-Fix leak on converter dictionary. (Ted Wright)
-
-------------------------------------------------------------------------
-r158 | adustman | 2001-07-11 13:13:09 -0500 (Wed, 11 Jul 2001) | 2 lines
-
-Minor fixes for 1.0.0.
-
-------------------------------------------------------------------------
-r155 | adustman | 2001-06-20 17:48:54 -0500 (Wed, 20 Jun 2001) | 2 lines
-
-Clarify use of host parameter to connect().
-
-------------------------------------------------------------------------
-r154 | adustman | 2001-06-20 16:58:59 -0500 (Wed, 20 Jun 2001) | 2 lines
-
-Some corrections courtesy of Paul DuBois.
-
-------------------------------------------------------------------------
-r152 | adustman | 2001-06-04 11:55:04 -0500 (Mon, 04 Jun 2001) | 2 lines
-
-Update version number.
-
-------------------------------------------------------------------------
-r151 | adustman | 2001-05-28 14:07:07 -0500 (Mon, 28 May 2001) | 2 lines
-
-Ignore stuff.
-
-------------------------------------------------------------------------
-r149 | adustman | 2001-05-25 15:40:24 -0500 (Fri, 25 May 2001) | 3 lines
-
-Rip out _mysql.field_*() methods, as MySQL recommends using SQL
-instead. See C API docs.
-
-------------------------------------------------------------------------
-r148 | adustman | 2001-05-24 13:18:09 -0500 (Thu, 24 May 2001) | 2 lines
-
-Update version.
-
-------------------------------------------------------------------------
-r146 | adustman | 2001-05-24 10:27:17 -0500 (Thu, 24 May 2001) | 2 lines
-
-Clean up some import statements, bump versions to 0.9.0c2.
-
-------------------------------------------------------------------------
-r144 | adustman | 2001-05-22 22:16:34 -0500 (Tue, 22 May 2001) | 2 lines
-
-Fix the case where there is no mx.DateTime.
-
-------------------------------------------------------------------------
-r143 | adustman | 2001-05-22 22:16:12 -0500 (Tue, 22 May 2001) | 2 lines
-
-Remove a debug string.
-
-------------------------------------------------------------------------
-r142 | adustman | 2001-05-22 21:12:10 -0500 (Tue, 22 May 2001) | 2 lines
-
-0.9.0c1 minor edit.
-
-------------------------------------------------------------------------
-r141 | adustman | 2001-05-14 13:49:27 -0500 (Mon, 14 May 2001) | 2 lines
-
-PyObject_Length() == -1 on error. Thanks, Jon Ribbens.
-
-------------------------------------------------------------------------
-r140 | adustman | 2001-05-11 23:30:34 -0500 (Fri, 11 May 2001) | 13 lines
-
-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.
-
-------------------------------------------------------------------------
-r139 | adustman | 2001-05-11 00:07:33 -0500 (Fri, 11 May 2001) | 10 lines
-
-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.
-
-------------------------------------------------------------------------
-r138 | adustman | 2001-05-10 00:31:50 -0500 (Thu, 10 May 2001) | 2 lines
-
-Revamped docs.
-
-------------------------------------------------------------------------
-r131 | adustman | 2001-05-08 21:23:14 -0500 (Tue, 08 May 2001) | 2 lines
-
-Initial revision
-
-------------------------------------------------------------------------

+ 0 - 34
desktop/core/ext-py/MySQL-python-1.2.3c1/MANIFEST

@@ -1,34 +0,0 @@
-ChangeLog
-HISTORY
-MANIFEST
-MANIFEST.in
-README
-_mysql.c
-_mysql_exceptions.py
-dbapi20.py
-metadata.cfg
-pymemcompat.h
-setup.cfg
-setup.py
-setup_common.py
-setup_posix.py
-setup_windows.py
-site.cfg
-test_MySQLdb_capabilities.py
-test_MySQLdb_dbapi20.py
-test_capabilities.py
-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

+ 0 - 1
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/.cvsignore

@@ -1 +0,0 @@
-*.pyc

+ 0 - 1
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/.cvsignore

@@ -1 +0,0 @@
-*.pyc

+ 0 - 4
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/release.py

@@ -1,4 +0,0 @@
-
-__author__ = "Andy Dustman <adustman@users.sourceforge.net>"
-version_info = (1,2,3,'gamma',1)
-__version__ = "1.2.3c1"

+ 0 - 2
desktop/core/ext-py/MySQL-python-1.2.3c1/doc/.cvsignore

@@ -1,2 +0,0 @@
-*.tex
-*.html

+ 0 - 276
desktop/core/ext-py/MySQL-python-1.2.3c1/ez_setup.py

@@ -1,276 +0,0 @@
-#!python
-"""Bootstrap setuptools installation
-
-If you want to use setuptools in your package's setup.py, just include this
-file in the same directory with it, and add this to the top of your setup.py::
-
-    from ez_setup import use_setuptools
-    use_setuptools()
-
-If you want to require a specific version of setuptools, set a download
-mirror, or use an alternate download directory, you can do so by supplying
-the appropriate options to ``use_setuptools()``.
-
-This file can also be run as a script to install or upgrade setuptools.
-"""
-import sys
-DEFAULT_VERSION = "0.6c9"
-DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
-
-md5_data = {
-    'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
-    'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
-    'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
-    'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
-    'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
-    'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
-    'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
-    'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
-    'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
-    'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
-    'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
-    'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
-    'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
-    'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
-    'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
-    'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
-    'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
-    'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
-    'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
-    'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
-    'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
-    'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
-    'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
-    'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
-    'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
-    'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
-    'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
-    'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
-    'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
-    'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
-    'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
-    'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
-    'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
-    'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
-}
-
-import sys, os
-try: from hashlib import md5
-except ImportError: from md5 import md5
-
-def _validate_md5(egg_name, data):
-    if egg_name in md5_data:
-        digest = md5(data).hexdigest()
-        if digest != md5_data[egg_name]:
-            print >>sys.stderr, (
-                "md5 validation of %s failed!  (Possible download problem?)"
-                % egg_name
-            )
-            sys.exit(2)
-    return data
-
-def use_setuptools(
-    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
-    download_delay=15
-):
-    """Automatically find/download setuptools and make it available on sys.path
-
-    `version` should be a valid setuptools version number that is available
-    as an egg for download under the `download_base` URL (which should end with
-    a '/').  `to_dir` is the directory where setuptools will be downloaded, if
-    it is not already available.  If `download_delay` is specified, it should
-    be the number of seconds that will be paused before initiating a download,
-    should one be required.  If an older version of setuptools is installed,
-    this routine will print a message to ``sys.stderr`` and raise SystemExit in
-    an attempt to abort the calling script.
-    """
-    was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
-    def do_download():
-        egg = download_setuptools(version, download_base, to_dir, download_delay)
-        sys.path.insert(0, egg)
-        import setuptools; setuptools.bootstrap_install_from = egg
-    try:
-        import pkg_resources
-    except ImportError:
-        return do_download()       
-    try:
-        pkg_resources.require("setuptools>="+version); return
-    except pkg_resources.VersionConflict, e:
-        if was_imported:
-            print >>sys.stderr, (
-            "The required version of setuptools (>=%s) is not available, and\n"
-            "can't be installed while this script is running. Please install\n"
-            " a more recent version first, using 'easy_install -U setuptools'."
-            "\n\n(Currently using %r)"
-            ) % (version, e.args[0])
-            sys.exit(2)
-        else:
-            del pkg_resources, sys.modules['pkg_resources']    # reload ok
-            return do_download()
-    except pkg_resources.DistributionNotFound:
-        return do_download()
-
-def download_setuptools(
-    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
-    delay = 15
-):
-    """Download setuptools from a specified location and return its filename
-
-    `version` should be a valid setuptools version number that is available
-    as an egg for download under the `download_base` URL (which should end
-    with a '/'). `to_dir` is the directory where the egg will be downloaded.
-    `delay` is the number of seconds to pause before an actual download attempt.
-    """
-    import urllib2, shutil
-    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
-    url = download_base + egg_name
-    saveto = os.path.join(to_dir, egg_name)
-    src = dst = None
-    if not os.path.exists(saveto):  # Avoid repeated downloads
-        try:
-            from distutils import log
-            if delay:
-                log.warn("""
----------------------------------------------------------------------------
-This script requires setuptools version %s to run (even to display
-help).  I will attempt to download it for you (from
-%s), but
-you may need to enable firewall access for this script first.
-I will start the download in %d seconds.
-
-(Note: if this machine does not have network access, please obtain the file
-
-   %s
-
-and place it in this directory before rerunning this script.)
----------------------------------------------------------------------------""",
-                    version, download_base, delay, url
-                ); from time import sleep; sleep(delay)
-            log.warn("Downloading %s", url)
-            src = urllib2.urlopen(url)
-            # Read/write all in one block, so we don't create a corrupt file
-            # if the download is interrupted.
-            data = _validate_md5(egg_name, src.read())
-            dst = open(saveto,"wb"); dst.write(data)
-        finally:
-            if src: src.close()
-            if dst: dst.close()
-    return os.path.realpath(saveto)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-def main(argv, version=DEFAULT_VERSION):
-    """Install or upgrade setuptools and EasyInstall"""
-    try:
-        import setuptools
-    except ImportError:
-        egg = None
-        try:
-            egg = download_setuptools(version, delay=0)
-            sys.path.insert(0,egg)
-            from setuptools.command.easy_install import main
-            return main(list(argv)+[egg])   # we're done here
-        finally:
-            if egg and os.path.exists(egg):
-                os.unlink(egg)
-    else:
-        if setuptools.__version__ == '0.0.1':
-            print >>sys.stderr, (
-            "You have an obsolete version of setuptools installed.  Please\n"
-            "remove it from your system entirely before rerunning this script."
-            )
-            sys.exit(2)
-
-    req = "setuptools>="+version
-    import pkg_resources
-    try:
-        pkg_resources.require(req)
-    except pkg_resources.VersionConflict:
-        try:
-            from setuptools.command.easy_install import main
-        except ImportError:
-            from easy_install import main
-        main(list(argv)+[download_setuptools(delay=0)])
-        sys.exit(0) # try to force an exit
-    else:
-        if argv:
-            from setuptools.command.easy_install import main
-            main(argv)
-        else:
-            print "Setuptools version",version,"or greater has been installed."
-            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
-
-def update_md5(filenames):
-    """Update our built-in md5 registry"""
-
-    import re
-
-    for name in filenames:
-        base = os.path.basename(name)
-        f = open(name,'rb')
-        md5_data[base] = md5(f.read()).hexdigest()
-        f.close()
-
-    data = ["    %r: %r,\n" % it for it in md5_data.items()]
-    data.sort()
-    repl = "".join(data)
-
-    import inspect
-    srcfile = inspect.getsourcefile(sys.modules[__name__])
-    f = open(srcfile, 'rb'); src = f.read(); f.close()
-
-    match = re.search("\nmd5_data = {\n([^}]+)}", src)
-    if not match:
-        print >>sys.stderr, "Internal error!"
-        sys.exit(2)
-
-    src = src[:match.start(1)] + repl + src[match.end(1):]
-    f = open(srcfile,'w')
-    f.write(src)
-    f.close()
-
-
-if __name__=='__main__':
-    if len(sys.argv)>2 and sys.argv[1]=='--md5update':
-        update_md5(sys.argv[2:])
-    else:
-        main(sys.argv[1:])
-
-
-
-
-
-

+ 0 - 18
desktop/core/ext-py/MySQL-python-1.2.3c1/setup.py

@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import sys
-from setuptools import setup, Extension
-
-if sys.version_info < (2, 3):
-    raise Error("Python-2.3 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)

+ 20 - 21
desktop/core/ext-py/MySQL-python-1.2.3c1/GPL → desktop/core/ext-py/MySQL-python-1.2.5/GPL-2.0

@@ -1,12 +1,12 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
 
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-	51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
-			    Preamble
+                            Preamble
 
   The licenses for most software are designed to take away your
 freedom to share and change it.  By contrast, the GNU General Public
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users.  This
 General Public License applies to most of the Free Software
 Foundation's software and to any other program whose authors commit to
 using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
+the GNU Lesser General Public License instead.)  You can apply it to
 your programs, too.
 
   When we speak of free software, we are referring to freedom, not
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
 
   The precise terms and conditions for copying, distribution and
 modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
+
+                    GNU GENERAL PUBLIC LICENSE
    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
   0. This License applies to any program or other work which contains
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
     License.  (Exception: if the Program itself is interactive but
     does not normally print such an announcement, your work based on
     the Program is not required to print an announcement.)
-
+
 These requirements apply to the modified work as a whole.  If
 identifiable sections of that work are not derived from the Program,
 and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
 access to copy the source code from the same place counts as
 distribution of the source code, even though third parties are not
 compelled to copy the source along with the object code.
-
+
   4. You may not copy, modify, sublicense, or distribute the Program
 except as expressly provided under this License.  Any attempt
 otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
 
 This section is intended to make thoroughly clear what is believed to
 be a consequence of the rest of this License.
-
+
   8. If the distribution and/or use of the Program is restricted in
 certain countries either by patents or by copyrighted interfaces, the
 original copyright holder who places the Program under this License
@@ -255,7 +255,7 @@ make exceptions for this.  Our decision will be guided by the two goals
 of preserving the free status of all derivatives of our free software and
 of promoting the sharing and reuse of software generally.
 
-			    NO WARRANTY
+                            NO WARRANTY
 
   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGES.
 
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
 
   If you develop a new program, and you want it to be of the greatest
 possible use to the public, the best way to achieve this is to make it
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
-
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 Also add information on how to contact you by electronic and paper mail.
 
 If the program is interactive, make it output a short notice like this
 when it starts in an interactive mode:
 
-    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision version 69, Copyright (C) year name of author
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.
@@ -336,5 +335,5 @@ necessary.  Here is a sample; alter the names:
 This General Public License does not permit incorporating your program into
 proprietary programs.  If your program is a subroutine library, you may
 consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
+library.  If this is what you want to do, use the GNU Lesser General
 Public License instead of this License.

+ 193 - 100
desktop/core/ext-py/MySQL-python-1.2.3c1/HISTORY → desktop/core/ext-py/MySQL-python-1.2.5/HISTORY

@@ -1,100 +1,193 @@
-=====================
- What's new in 1.2.2
-=====================
-
-The build system has been completely redone and should now build
-on Windows without any patching; uses setuptools.
-
-Added compatibility for Python 2.5, including support for with statement.
-
-connection.ping() now takes an optional boolean argument which can
-enable (or disable) automatic reconnection.
-
-Support returning SET columns as Python sets was removed due to an
-API bug in MySQL; corresponding test removed.
-
-Added a test for single-character CHAR columns.
-
-BLOB columns are now returned as Python strings instead of byte arrays.
-
-BINARY character columns are always returned as Python strings, and not
-unicode.
-
-Fixed a bug introduced in 1.2.1 where the new SHOW WARNINGS support broke
-SSCursor.
-
-Only encode the query (convert to a string) when it is a unicode instance;
-re-encoding encoded strings would break things.
-
-Make a deep copy of conv when connecting, since it can be modified.
-
-Added support for new VARCHAR and BIT column types.
-
-DBAPISet objects were broken, but nobody noticed.
-
-
-========================
- What's new in 1.2.1_p2
-========================
-
-There are some minor build fixes which probably only affect MySQL
-older than 4.0.
-
-If you had MySQL older than 4.1, the new charset and sql_mode
-parameters didn't work right. In fact, it was impossible to create
-a connection due to the charset problem.
-
-If you are using MySQL-4.1 or newer, there is no practical difference
-between 1.2.1 and 1.2.1_p2, and you don't need to upgrade.
-
-
-=====================
- What's new in 1.2.1
-=====================
-
-Switched to Subversion. Was going to do this for 1.3, but a
-SourceForge CVS outage has forced the issue.
-
-Mapped a lot of new 4.1 and 5.0 error codes to Python exceptions
-
-Added an API call for mysql_set_character_set(charset) (MySQL > 5.0.7)
-
-Added an API call for mysql_get_character_set_info() (MySQL > 5.0.10)
-
-Revamped the build system. Edit site.cfg if necessary (probably not
-in most cases)
-
-Python-2.3 is now the minimum version.
-
-Dropped support for mx.Datetime and stringtimes; always uses Python
-datetime module now.
-
-Improved unit tests
-
-New connect() options:
-* charset: sets character set, implies use_unicode
-* sql_mode: sets SQL mode (i.e. ANSI, etc.; see MySQL docs)
-
-When using MySQL-4.1 or newer, enables MULTI_STATEMENTS
-
-When using MySQL-5.0 or newer, enables MULTI_RESULTS
-
-When using MySQL-4.1 or newer, more detailed warning messages
-are produced
-
-SET columns returned as Python Set types; you can pass a Set as
-a parameter to cursor.execute().
-
-Support for the new MySQL-5.0 DECIMAL implementation
-
-Support for Python Decimal type
-
-Some use of weak references internally. Cursors no longer leak
-if you don't close them. Connections still do, unfortunately.
-
-ursor.fetchXXXDict() methods raise DeprecationWarning
-
-cursor.begin() is making a brief reappearence.
-
-cursor.callproc() now works, with some limitations.
-
+=====================
+ What's new in 1.2.4
+=====================
+
+final
+=====
+
+No changes.
+
+
+rc 1
+====
+
+Fixed a dangling reference to the old types module.
+
+
+beta 5
+======
+
+Another internal fix for handling remapped character sets.
+
+_mysql.c was broken for the case where read_timeout was *not* available. (Issue #6)
+
+Documentation was converted to sphinx but there is a lot of cleanup left to do.
+
+
+beta 4
+======
+
+Added support for the MySQL read_timeout option. Contributed by
+Jean Schurger (jean@schurger.org).
+
+Added a workaround so that the MySQL character set utf8mb4 works with Python; utf8 is substituted
+on the Python side.
+
+
+beta 3
+======
+
+Unified test database configuration, and set up CI testing with Travis.
+
+Applied several patches from André Malo (ndparker@users.sf.net) which fix some issues
+with exception handling and reference counting and TEXT/BLOB conversion.
+
+
+beta 2
+======
+
+Reverted an accidental change in the exception format. (issue #1)
+
+Reverted some raise statements so that they will continue to work with Python < 2.6
+
+
+beta 1
+======
+
+A lot of work has been done towards Python 3 compatibility, and avoiding warnings with Python 2.7.
+This includes import changes, converting dict.has_kay(k) to k in dict, updating some test suite methods, etc.
+
+Due to the difficulties of supporting Python 3 and Python < 2.7, 1.2.4 will support Python 2.4 though 2.7.
+1.3.0 will support Python 3 and Python 2.7 and 2.6.
+
+MySQLdb-2.0 is instead going to become moist-1.0. See https://github.com/farcepest/moist
+
+The Windows build has been simplified, and I plan to correct pre-built i386 packages built
+against the python.org Python-2.7 package and MySQL Connector/C-6.0. Contact me if you
+need ia64 packages.
+
+The connection's cursorclass (if not default) was being lost on reconnect.
+
+Newer versions of MySQL don't use OpenSSL and therefore don't have HAVE_SSL defined, but they do have
+a different SSL library. Fixed this so SSL support would be enabled in this case.
+
+The regex that looked for SQL INSERT statement and VALUES in cursor.executemany() was made case-insensitive
+again.
+
+
+=====================
+ What's new in 1.2.3
+=====================
+
+ez_setup.py has been update to include various fixes that affect the build.
+
+Better Python version and dependency detection as well as eliminate exception
+warnings under Python 2.6.
+
+Eliminated memory leaks related to Unicode and failed connections.
+
+Corrected connection .escape() functionality.
+
+Miscellaneous cleanups and and expanded testing suite to ensure ongoing release
+quality.
+
+=====================
+ What's new in 1.2.2
+=====================
+
+The build system has been completely redone and should now build
+on Windows without any patching; uses setuptools.
+
+Added compatibility for Python 2.5, including support for with statement.
+
+connection.ping() now takes an optional boolean argument which can
+enable (or disable) automatic reconnection.
+
+Support returning SET columns as Python sets was removed due to an
+API bug in MySQL; corresponding test removed.
+
+Added a test for single-character CHAR columns.
+
+BLOB columns are now returned as Python strings instead of byte arrays.
+
+BINARY character columns are always returned as Python strings, and not
+unicode.
+
+Fixed a bug introduced in 1.2.1 where the new SHOW WARNINGS support broke
+SSCursor.
+
+Only encode the query (convert to a string) when it is a unicode instance;
+re-encoding encoded strings would break things.
+
+Make a deep copy of conv when connecting, since it can be modified.
+
+Added support for new VARCHAR and BIT column types.
+
+DBAPISet objects were broken, but nobody noticed.
+
+
+========================
+ What's new in 1.2.1_p2
+========================
+
+There are some minor build fixes which probably only affect MySQL
+older than 4.0.
+
+If you had MySQL older than 4.1, the new charset and sql_mode
+parameters didn't work right. In fact, it was impossible to create
+a connection due to the charset problem.
+
+If you are using MySQL-4.1 or newer, there is no practical difference
+between 1.2.1 and 1.2.1_p2, and you don't need to upgrade.
+
+
+=====================
+ What's new in 1.2.1
+=====================
+
+Switched to Subversion. Was going to do this for 1.3, but a
+SourceForge CVS outage has forced the issue.
+
+Mapped a lot of new 4.1 and 5.0 error codes to Python exceptions
+
+Added an API call for mysql_set_character_set(charset) (MySQL > 5.0.7)
+
+Added an API call for mysql_get_character_set_info() (MySQL > 5.0.10)
+
+Revamped the build system. Edit site.cfg if necessary (probably not
+in most cases)
+
+Python-2.3 is now the minimum version.
+
+Dropped support for mx.Datetime and stringtimes; always uses Python
+datetime module now.
+
+Improved unit tests
+
+New connect() options:
+* charset: sets character set, implies use_unicode
+* sql_mode: sets SQL mode (i.e. ANSI, etc.; see MySQL docs)
+
+When using MySQL-4.1 or newer, enables MULTI_STATEMENTS
+
+When using MySQL-5.0 or newer, enables MULTI_RESULTS
+
+When using MySQL-4.1 or newer, more detailed warning messages
+are produced
+
+SET columns returned as Python Set types; you can pass a Set as
+a parameter to cursor.execute().
+
+Support for the new MySQL-5.0 DECIMAL implementation
+
+Support for Python Decimal type
+
+Some use of weak references internally. Cursors no longer leak
+if you don't close them. Connections still do, unfortunately.
+
+ursor.fetchXXXDict() methods raise DeprecationWarning
+
+cursor.begin() is making a brief reappearence.
+
+cursor.callproc() now works, with some limitations.
+

+ 6 - 6
desktop/core/ext-py/MySQL-python-1.2.3c1/README → desktop/core/ext-py/MySQL-python-1.2.5/INSTALL

@@ -15,7 +15,7 @@ Prerequisites
   * 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
@@ -43,7 +43,7 @@ Prerequisites
     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.
 
@@ -93,7 +93,7 @@ Prerequisites
 
   * 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
@@ -134,7 +134,7 @@ edit the [options] section of site.cfg:
         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::
 
@@ -187,7 +187,7 @@ 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
@@ -250,4 +250,4 @@ GPL or the original license based on Python 1.5.2's license.
 
 
 :Author: Andy Dustman <andy@dustman.net>
-:Revision: $Id: README 557 2008-10-17 01:07:01Z adustman $
+:Revision: $Id$

+ 14 - 13
desktop/core/ext-py/MySQL-python-1.2.3c1/MANIFEST.in → desktop/core/ext-py/MySQL-python-1.2.5/MANIFEST.in

@@ -1,13 +1,14 @@
-recursive-include doc *.txt
-recursive-include tests *.py
-include MANIFEST.in
-include MANIFEST
-include ChangeLog
-include HISTORY
-include GPL
-include pymemcompat.h
-include metadata.cfg
-include site.cfg
-include setup_common.py
-include setup_posix.py
-include setup_windows.py
+recursive-include doc *.rst
+recursive-include tests *.py
+include doc/conf.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 setup_common.py
+include setup_posix.py
+include setup_windows.py

+ 98 - 98
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/__init__.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/__init__.py

@@ -1,98 +1,98 @@
-"""MySQLdb - A DB API v2.0 compatible interface to MySQL.
-
-This package is a wrapper around _mysql, which mostly implements the
-MySQL C API.
-
-connect() -- connects to server
-
-See the C API specification and the MySQL documentation for more info
-on other items.
-
-For information on how MySQLdb handles type conversion, see the
-MySQLdb.converters module.
-
-"""
-
-__revision__ = """$Revision: 603 $"""[11:-2]
-from release import __version__, version_info, __author__
-
-import _mysql
-
-if version_info != _mysql.version_info:
-    raise ImportError("this is MySQLdb version %s, but _mysql is version %r" %
-                      (version_info, _mysql.version_info))
-
-threadsafety = 1
-apilevel = "2.0"
-paramstyle = "format"
-
-from _mysql import *
-from MySQLdb.constants import FIELD_TYPE
-from MySQLdb.times import Date, Time, Timestamp, \
-    DateFromTicks, TimeFromTicks, TimestampFromTicks
-
-try:
-    frozenset
-except NameError:
-    from sets import ImmutableSet as frozenset
-
-class DBAPISet(frozenset):
-
-    """A special type of set for which A == x is true if A is a
-    DBAPISet and x is a member of that set."""
-
-    def __eq__(self, other):
-        if isinstance(other, DBAPISet):
-            return not self.difference(other)
-        return other in self
-
-
-STRING    = DBAPISet([FIELD_TYPE.ENUM, FIELD_TYPE.STRING,
-                     FIELD_TYPE.VAR_STRING])
-BINARY    = DBAPISet([FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB,
-                     FIELD_TYPE.MEDIUM_BLOB, FIELD_TYPE.TINY_BLOB])
-NUMBER    = DBAPISet([FIELD_TYPE.DECIMAL, FIELD_TYPE.DOUBLE, FIELD_TYPE.FLOAT,
-                     FIELD_TYPE.INT24, FIELD_TYPE.LONG, FIELD_TYPE.LONGLONG,
-                     FIELD_TYPE.TINY, FIELD_TYPE.YEAR])
-DATE      = DBAPISet([FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE])
-TIME      = DBAPISet([FIELD_TYPE.TIME])
-TIMESTAMP = DBAPISet([FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME])
-DATETIME  = TIMESTAMP
-ROWID     = DBAPISet()
-
-def test_DBAPISet_set_equality():
-    assert STRING == STRING
-
-def test_DBAPISet_set_inequality():
-    assert STRING != NUMBER
-
-def test_DBAPISet_set_equality_membership():
-    assert FIELD_TYPE.VAR_STRING == STRING
-
-def test_DBAPISet_set_inequality_membership():
-    assert FIELD_TYPE.DATE != STRING
-
-def Binary(x):
-    return str(x)
-
-def Connect(*args, **kwargs):
-    """Factory function for connections.Connection."""
-    from connections import Connection
-    return Connection(*args, **kwargs)
-
-connect = Connection = Connect
-
-__all__ = [ 'BINARY', 'Binary', 'Connect', 'Connection', 'DATE',
-    'Date', 'Time', 'Timestamp', 'DateFromTicks', 'TimeFromTicks',
-    'TimestampFromTicks', 'DataError', 'DatabaseError', 'Error',
-    'FIELD_TYPE', 'IntegrityError', 'InterfaceError', 'InternalError',
-    'MySQLError', 'NULL', 'NUMBER', 'NotSupportedError', 'DBAPISet',
-    'OperationalError', 'ProgrammingError', 'ROWID', 'STRING', 'TIME',
-    'TIMESTAMP', 'Warning', 'apilevel', 'connect', 'connections',
-    'constants', 'converters', 'cursors', 'debug', 'escape', 'escape_dict',
-    'escape_sequence', 'escape_string', 'get_client_info',
-    'paramstyle', 'string_literal', 'threadsafety', 'version_info']
-
-
-
-
+"""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']
+
+
+
+

+ 351 - 334
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/connections.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/connections.py

@@ -1,334 +1,351 @@
-"""
-
-This module implements connections for MySQLdb. Presently there is
-only one class: Connection. Others are unlikely. However, you might
-want to make your own subclasses. In most cases, you will probably
-override Connection.default_cursor with a non-standard Cursor class.
-
-"""
-import cursors
-from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
-     DatabaseError, OperationalError, IntegrityError, InternalError, \
-     NotSupportedError, ProgrammingError
-import types, _mysql
-import re
-
-
-def defaulterrorhandler(connection, cursor, errorclass, errorvalue):
-    """
-
-    If cursor is not None, (errorclass, errorvalue) is appended to
-    cursor.messages; otherwise it is appended to
-    connection.messages. Then errorclass is raised with errorvalue as
-    the value.
-
-    You can override this with your own error handler by assigning it
-    to the instance.
-
-    """
-    error = errorclass, errorvalue
-    if cursor:
-        cursor.messages.append(error)
-    else:
-        connection.messages.append(error)
-    del cursor
-    del connection
-    raise errorclass, errorvalue
-
-re_numeric_part = re.compile(r"^(\d+)")
-
-def numeric_part(s):
-    """Returns the leading numeric part of a string.
-    
-    >>> numeric_part("20-alpha")
-    20
-    >>> numeric_part("foo")
-    >>> numeric_part("16b")
-    16
-    """
-    
-    m = re_numeric_part.match(s)
-    if m:
-        return int(m.group(1))
-    return None
-
-
-class Connection(_mysql.connection):
-
-    """MySQL Database Connection Object"""
-
-    default_cursor = cursors.Cursor
-    
-    def __init__(self, *args, **kwargs):
-        """
-
-        Create a connection to the database. It is strongly recommended
-        that you only use keyword parameters. Consult the MySQL C API
-        documentation for more information.
-
-        host
-          string, host to connect
-          
-        user
-          string, user to connect as
-
-        passwd
-          string, password to use
-
-        db
-          string, database to use
-
-        port
-          integer, TCP/IP port to connect to
-
-        unix_socket
-          string, location of unix_socket to use
-
-        conv
-          conversion dictionary, see MySQLdb.converters
-
-        connect_timeout
-          number of seconds to wait before the connection attempt
-          fails.
-
-        compress
-          if set, compression is enabled
-
-        named_pipe
-          if set, a named pipe is used to connect (Windows only)
-
-        init_command
-          command which is run once the connection is created
-
-        read_default_file
-          file from which default client values are read
-
-        read_default_group
-          configuration group to use from the default file
-
-        cursorclass
-          class object, used to create cursors (keyword only)
-
-        use_unicode
-          If True, text-like columns are returned as unicode objects
-          using the connection's character set.  Otherwise, text-like
-          columns are returned as strings.  columns are returned as
-          normal strings. Unicode objects will always be encoded to
-          the connection's character set regardless of this setting.
-
-        charset
-          If supplied, the connection character set will be changed
-          to this character set (MySQL-4.1 and newer). This implies
-          use_unicode=True.
-
-        sql_mode
-          If supplied, the session SQL mode will be changed to this
-          setting (MySQL-4.1 and newer). For more details and legal
-          values, see the MySQL documentation.
-          
-        client_flag
-          integer, flags to use or 0
-          (see MySQL docs or constants/CLIENTS.py)
-
-        ssl
-          dictionary or mapping, contains SSL connection parameters;
-          see the MySQL documentation for more details
-          (mysql_ssl_set()).  If this is set, and the client does not
-          support SSL, NotSupportedError will be raised.
-
-        local_infile
-          integer, non-zero enables LOAD LOCAL INFILE; zero disables
-    
-        There are a number of undocumented, non-standard methods. See the
-        documentation for the MySQL C API for some hints on what they do.
-
-        """
-        from constants import CLIENT, FIELD_TYPE
-        from converters import conversions
-        from weakref import proxy, WeakValueDictionary
-        
-        import types
-
-        kwargs2 = kwargs.copy()
-        
-        if kwargs.has_key('conv'):
-            conv = kwargs['conv']
-        else:
-            conv = conversions
-
-        conv2 = {}
-        for k, v in conv.items():
-            if isinstance(k, int):
-                if isinstance(v, list):
-                    conv2[k] = v[:]
-                else:
-                    conv2[k] = v
-        kwargs2['conv'] = conv2
-
-        self.cursorclass = kwargs2.pop('cursorclass', self.default_cursor)
-        charset = kwargs2.pop('charset', '')
-
-        if charset:
-            use_unicode = True
-        else:
-            use_unicode = False
-            
-        use_unicode = kwargs2.pop('use_unicode', use_unicode)
-        sql_mode = kwargs2.pop('sql_mode', '')
-
-        client_flag = kwargs.get('client_flag', 0)
-        client_version = tuple([ numeric_part(n) for n in _mysql.get_client_info().split('.')[:2] ])
-        if client_version >= (4, 1):
-            client_flag |= CLIENT.MULTI_STATEMENTS
-        if client_version >= (5, 0):
-            client_flag |= CLIENT.MULTI_RESULTS
-            
-        kwargs2['client_flag'] = client_flag
-
-        super(Connection, self).__init__(*args, **kwargs2)
-
-        self.encoders = dict([ (k, v) for k, v in conv.items()
-                               if type(k) is not int ])
-        
-        self._server_version = tuple([ numeric_part(n) for n in self.get_server_info().split('.')[:2] ])
-
-        db = proxy(self)
-        def _get_string_literal():
-            def string_literal(obj, dummy=None):
-                return db.string_literal(obj)
-            return string_literal
-
-        def _get_unicode_literal():
-            def unicode_literal(u, dummy=None):
-                return db.literal(u.encode(unicode_literal.charset))
-            return unicode_literal
-
-        def _get_string_decoder():
-            def string_decoder(s):
-                return s.decode(string_decoder.charset)
-            return string_decoder
-        
-        string_literal = _get_string_literal()
-        self.unicode_literal = unicode_literal = _get_unicode_literal()
-        self.string_decoder = string_decoder = _get_string_decoder()
-        if not charset:
-            charset = self.character_set_name()
-        self.set_character_set(charset)
-
-        if sql_mode:
-            self.set_sql_mode(sql_mode)
-
-        if use_unicode:
-            self.converter[FIELD_TYPE.STRING].append((None, string_decoder))
-            self.converter[FIELD_TYPE.VAR_STRING].append((None, string_decoder))
-            self.converter[FIELD_TYPE.VARCHAR].append((None, string_decoder))
-            self.converter[FIELD_TYPE.BLOB].append((None, string_decoder))
-
-        self.encoders[types.StringType] = string_literal
-        self.encoders[types.UnicodeType] = unicode_literal
-        self._transactional = self.server_capabilities & CLIENT.TRANSACTIONS
-        if self._transactional:
-            # PEP-249 requires autocommit to be initially off
-            self.autocommit(False)
-        self.messages = []
-        
-    def cursor(self, cursorclass=None):
-        """
-
-        Create a cursor on which queries may be performed. The
-        optional cursorclass parameter is used to create the
-        Cursor. By default, self.cursorclass=cursors.Cursor is
-        used.
-
-        """
-        return (cursorclass or self.cursorclass)(self)
-
-    def __enter__(self): return self.cursor()
-    
-    def __exit__(self, exc, value, tb):
-        if exc:
-            self.rollback()
-        else:
-            self.commit()
-            
-    def literal(self, o):
-        """
-
-        If o is a single object, returns an SQL literal as a string.
-        If o is a non-string sequence, the items of the sequence are
-        converted and returned as a sequence.
-
-        Non-standard. For internal use; do not use this in your
-        applications.
-
-        """
-        return self.escape(o, self.encoders)
-
-    def begin(self):
-        """Explicitly begin a connection. Non-standard.
-        DEPRECATED: Will be removed in 1.3.
-        Use an SQL BEGIN statement instead."""
-        from warnings import warn
-        warn("begin() is non-standard and will be removed in 1.3",
-             DeprecationWarning, 2)
-        self.query("BEGIN")
-        
-    if not hasattr(_mysql.connection, 'warning_count'):
-
-        def warning_count(self):
-            """Return the number of warnings generated from the
-            last query. This is derived from the info() method."""
-            from string import atoi
-            info = self.info()
-            if info:
-                return atoi(info.split()[-1])
-            else:
-                return 0
-
-    def set_character_set(self, charset):
-        """Set the connection character set to charset. The character
-        set can only be changed in MySQL-4.1 and newer. If you try
-        to change the character set from the current value in an
-        older version, NotSupportedError will be raised."""
-        if self.character_set_name() != charset:
-            try:
-                super(Connection, self).set_character_set(charset)
-            except AttributeError:
-                if self._server_version < (4, 1):
-                    raise NotSupportedError("server is too old to set charset")
-                self.query('SET NAMES %s' % charset)
-                self.store_result()
-        self.string_decoder.charset = charset
-        self.unicode_literal.charset = charset
-
-    def set_sql_mode(self, sql_mode):
-        """Set the connection sql_mode. See MySQL documentation for
-        legal values."""
-        if self._server_version < (4, 1):
-            raise NotSupportedError("server is too old to set sql_mode")
-        self.query("SET SESSION sql_mode='%s'" % sql_mode)
-        self.store_result()
-        
-    def show_warnings(self):
-        """Return detailed information about warnings as a
-        sequence of tuples of (Level, Code, Message). This
-        is only supported in MySQL-4.1 and up. If your server
-        is an earlier version, an empty sequence is returned."""
-        if self._server_version < (4,1): return ()
-        self.query("SHOW WARNINGS")
-        r = self.store_result()
-        warnings = r.fetch_row(0)
-        return warnings
-    
-    Warning = Warning
-    Error = Error
-    InterfaceError = InterfaceError
-    DatabaseError = DatabaseError
-    DataError = DataError
-    OperationalError = OperationalError
-    IntegrityError = IntegrityError
-    InternalError = InternalError
-    ProgrammingError = ProgrammingError
-    NotSupportedError = NotSupportedError
-
-    errorhandler = defaulterrorhandler
+"""
+
+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
+
+        autocommit
+          If False (default), autocommit is disabled.
+          If True, autocommit is enabled.
+          If None, autocommit isn't set and server default is used.
+
+        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
+
+        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
+
+        # PEP-249 requires autocommit to be initially off
+        autocommit = kwargs2.pop('autocommit', False)
+
+        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:
+            if autocommit is not None:
+                self.autocommit(autocommit)
+        self.messages = []
+
+    def autocommit(self, on):
+        on = bool(on)
+        if self.get_autocommit() != on:
+            _mysql.connection.autocommit(self, on)
+
+    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):
+        if self.get_autocommit():
+            self.query("BEGIN")
+        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
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/CLIENT.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/CLIENT.py


+ 0 - 0
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/CR.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/CR.py


+ 0 - 0
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/ER.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/ER.py


+ 0 - 0
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/FIELD_TYPE.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/FIELD_TYPE.py


+ 0 - 0
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/FLAG.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/FLAG.py


+ 0 - 0
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/REFRESH.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/REFRESH.py


+ 0 - 0
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/constants/__init__.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/constants/__init__.py


+ 189 - 171
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/converters.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/converters.py

@@ -1,171 +1,189 @@
-"""MySQLdb type conversion module
-
-This module handles all the type conversions for MySQL. If the default
-type conversions aren't what you need, you can make your own. The
-dictionary conversions maps some kind of type to a conversion function
-which returns the corresponding value:
-
-Key: FIELD_TYPE.* (from MySQLdb.constants)
-
-Conversion function:
-
-    Arguments: string
-
-    Returns: Python object
-
-Key: Python type object (from types) or class
-
-Conversion function:
-
-    Arguments: Python object of indicated type or class AND 
-               conversion dictionary
-
-    Returns: SQL literal value
-
-    Notes: Most conversion functions can ignore the dictionary, but
-           it is a required parameter. It is necessary for converting
-           things like sequences and instances.
-
-Don't modify conversions if you can avoid it. Instead, make copies
-(with the copy() method), modify the copies, and then pass them to
-MySQL.connect().
-
-"""
-
-from _mysql import string_literal, escape_sequence, escape_dict, escape, NULL
-from constants import FIELD_TYPE, FLAG
-from times import *
-import types
-import array
-
-try:
-    set
-except NameError:
-    from sets import Set as set
-
-def Bool2Str(s, d): return str(int(s))
-
-def Str2Set(s):
-    return set([ i for i in s.split(',') if i ])
-
-def Set2Str(s, d):
-    return string_literal(','.join(s), d)
-    
-def Thing2Str(s, d):
-    """Convert something into a string via str()."""
-    return str(s)
-
-def Unicode2Str(s, d):
-    """Convert a unicode object to a string using the default encoding.
-    This is only used as a placeholder for the real function, which
-    is connection-dependent."""
-    return s.encode()
-
-Long2Int = Thing2Str
-
-def Float2Str(o, d):
-    return '%.15g' % o
-
-def None2NULL(o, d):
-    """Convert None to NULL."""
-    return NULL # duh
-
-def Thing2Literal(o, d):
-    
-    """Convert something into a SQL string literal.  If using
-    MySQL-3.23 or newer, string_literal() is a method of the
-    _mysql.MYSQL object, and this function will be overridden with
-    that method when the connection is created."""
-
-    return string_literal(o, d)
-
-
-def Instance2Str(o, d):
-
-    """
-
-    Convert an Instance to a string representation.  If the __str__()
-    method produces acceptable output, then you don't need to add the
-    class to conversions; it will be handled by the default
-    converter. If the exact class is not found in d, it will use the
-    first class it can find for which o is an instance.
-
-    """
-
-    if d.has_key(o.__class__):
-        return d[o.__class__](o, d)
-    cl = filter(lambda x,o=o:
-                type(x) is types.ClassType
-                and isinstance(o, x), d.keys())
-    if not cl and hasattr(types, 'ObjectType'):
-        cl = filter(lambda x,o=o:
-                    type(x) is types.TypeType
-                    and isinstance(o, x)
-                    and d[x] is not Instance2Str,
-                    d.keys())
-    if not cl:
-        return d[types.StringType](o,d)
-    d[o.__class__] = d[cl[0]]
-    return d[cl[0]](o, d)
-
-def char_array(s):
-    return array.array('c', s)
-
-def array2Str(o, d):
-    return Thing2Literal(o.tostring(), d)
-
-conversions = {
-    types.IntType: Thing2Str,
-    types.LongType: Long2Int,
-    types.FloatType: Float2Str,
-    types.NoneType: None2NULL,
-    types.TupleType: escape_sequence,
-    types.ListType: escape_sequence,
-    types.DictType: escape_dict,
-    types.InstanceType: Instance2Str,
-    array.ArrayType: array2Str,
-    types.StringType: Thing2Literal, # default
-    types.UnicodeType: Unicode2Str,
-    types.ObjectType: Instance2Str,
-    types.BooleanType: Bool2Str,
-    DateTimeType: DateTime2literal,
-    DateTimeDeltaType: DateTimeDelta2literal,
-    set: Set2Str,
-    FIELD_TYPE.TINY: int,
-    FIELD_TYPE.SHORT: int,
-    FIELD_TYPE.LONG: long,
-    FIELD_TYPE.FLOAT: float,
-    FIELD_TYPE.DOUBLE: float,
-    FIELD_TYPE.DECIMAL: float,
-    FIELD_TYPE.NEWDECIMAL: float,
-    FIELD_TYPE.LONGLONG: long,
-    FIELD_TYPE.INT24: int,
-    FIELD_TYPE.YEAR: int,
-    FIELD_TYPE.SET: Str2Set,
-    FIELD_TYPE.TIMESTAMP: mysql_timestamp_converter,
-    FIELD_TYPE.DATETIME: DateTime_or_None,
-    FIELD_TYPE.TIME: TimeDelta_or_None,
-    FIELD_TYPE.DATE: Date_or_None,
-    FIELD_TYPE.BLOB: [
-        (FLAG.BINARY, str),
-        ],
-    FIELD_TYPE.STRING: [
-        (FLAG.BINARY, str),
-        ],
-    FIELD_TYPE.VAR_STRING: [
-        (FLAG.BINARY, str),
-        ],
-    FIELD_TYPE.VARCHAR: [
-        (FLAG.BINARY, str),
-        ],
-    }
-
-try:
-    from decimal import Decimal
-    conversions[FIELD_TYPE.DECIMAL] = Decimal
-    conversions[FIELD_TYPE.NEWDECIMAL] = Decimal
-except ImportError:
-    pass
-
-
-
+"""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:
+    ArrayType = array.ArrayType
+except AttributeError:
+    ArrayType = array.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:
+        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[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)
+
+def quote_tuple(t, d):
+    return "(%s)" % (','.join(escape_sequence(t, d)))
+
+conversions = {
+    IntType: Thing2Str,
+    LongType: Long2Int,
+    FloatType: Float2Str,
+    NoneType: None2NULL,
+    TupleType: quote_tuple,
+    ListType: quote_tuple,
+    DictType: escape_dict,
+    InstanceType: Instance2Str,
+    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
+
+
+

+ 541 - 504
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/cursors.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/cursors.py

@@ -1,504 +1,541 @@
-"""MySQLdb Cursors
-
-This module implements Cursors of various types for MySQLdb. By
-default, MySQLdb uses the Cursor class.
-
-"""
-
-import re
-
-restr = (r"\svalues\s*"
-        r"(\(((?<!\\)'[^\)]*?\)[^\)]*(?<!\\)?'"
-        r"|[^\(\)]|"
-        r"(?:\([^\)]*\))"
-        r")+\))")
-
-insert_values= re.compile(restr)
-from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
-     DatabaseError, OperationalError, IntegrityError, InternalError, \
-     NotSupportedError, ProgrammingError
-
-
-class BaseCursor(object):
-    
-    """A base for Cursor classes. Useful attributes:
-    
-    description
-        A tuple of DB API 7-tuples describing the columns in
-        the last executed query; see PEP-249 for details.
-
-    description_flags
-        Tuple of column flags for last query, one entry per column
-        in the result set. Values correspond to those in
-        MySQLdb.constants.FLAG. See MySQL documentation (C API)
-        for more information. Non-standard extension.
-    
-    arraysize
-        default number of rows fetchmany() will fetch
-
-    """
-
-    from _mysql_exceptions import MySQLError, Warning, Error, InterfaceError, \
-         DatabaseError, DataError, OperationalError, IntegrityError, \
-         InternalError, ProgrammingError, NotSupportedError
-    
-    _defer_warnings = False
-    
-    def __init__(self, connection):
-        from weakref import proxy
-    
-        self.connection = proxy(connection)
-        self.description = None
-        self.description_flags = None
-        self.rowcount = -1
-        self.arraysize = 1
-        self._executed = None
-        self.lastrowid = None
-        self.messages = []
-        self.errorhandler = connection.errorhandler
-        self._result = None
-        self._warnings = 0
-        self._info = None
-        self.rownumber = None
-        
-    def __del__(self):
-        self.close()
-        self.errorhandler = None
-        self._result = None
-        
-    def close(self):
-        """Close the cursor. No further queries will be possible."""
-        if not self.connection: return
-        while self.nextset(): pass
-        self.connection = None
-
-    def _check_executed(self):
-        if not self._executed:
-            self.errorhandler(self, ProgrammingError, "execute() first")
-
-    def _warning_check(self):
-        from warnings import warn
-        if self._warnings:
-            warnings = self._get_db().show_warnings()
-            if warnings:
-                # This is done in two loops in case
-                # Warnings are set to raise exceptions.
-                for w in warnings:
-                    self.messages.append((self.Warning, w))
-                for w in warnings:
-                    warn(w[-1], self.Warning, 3)
-            elif self._info:
-                self.messages.append((self.Warning, self._info))
-                warn(self._info, self.Warning, 3)
-
-    def nextset(self):
-        """Advance to the next result set.
-
-        Returns None if there are no more result sets.
-        """
-        if self._executed:
-            self.fetchall()
-        del self.messages[:]
-        
-        db = self._get_db()
-        nr = db.next_result()
-        if nr == -1:
-            return None
-        self._do_get_result()
-        self._post_get_result()
-        self._warning_check()
-        return 1
-
-    def _post_get_result(self): pass
-    
-    def _do_get_result(self):
-        db = self._get_db()
-        self._result = self._get_result()
-        self.rowcount = db.affected_rows()
-        self.rownumber = 0
-        self.description = self._result and self._result.describe() or None
-        self.description_flags = self._result and self._result.field_flags() or None
-        self.lastrowid = db.insert_id()
-        self._warnings = db.warning_count()
-        self._info = db.info()
-    
-    def setinputsizes(self, *args):
-        """Does nothing, required by DB API."""
-      
-    def setoutputsizes(self, *args):
-        """Does nothing, required by DB API."""
-
-    def _get_db(self):
-        if not self.connection:
-            self.errorhandler(self, ProgrammingError, "cursor closed")
-        return self.connection
-    
-    def execute(self, query, args=None):
-
-        """Execute a query.
-        
-        query -- string, query to execute on server
-        args -- optional sequence or mapping, parameters to use with query.
-
-        Note: If args is a sequence, then %s must be used as the
-        parameter placeholder in the query. If a mapping is used,
-        %(key)s must be used as the placeholder.
-
-        Returns long integer rows affected, if any
-
-        """
-        from types import ListType, TupleType
-        from sys import exc_info
-        del self.messages[:]
-        db = self._get_db()
-        charset = db.character_set_name()
-        if isinstance(query, unicode):
-            query = query.encode(charset)
-        if args is not None:
-            query = query % db.literal(args)
-        try:
-            r = self._query(query)
-        except TypeError, m:
-            if m.args[0] in ("not enough arguments for format string",
-                             "not all arguments converted"):
-                self.messages.append((ProgrammingError, m.args[0]))
-                self.errorhandler(self, ProgrammingError, m.args[0])
-            else:
-                self.messages.append((TypeError, m))
-                self.errorhandler(self, TypeError, m)
-        except:
-            exc, value, tb = exc_info()
-            del tb
-            self.messages.append((exc, value))
-            self.errorhandler(self, exc, value)
-        self._executed = query
-        if not self._defer_warnings: self._warning_check()
-        return r
-
-    def executemany(self, query, args):
-
-        """Execute a multi-row query.
-        
-        query -- string, query to execute on server
-
-        args
-
-            Sequence of sequences or mappings, parameters to use with
-            query.
-            
-        Returns long integer rows affected, if any.
-        
-        This method improves performance on multiple-row INSERT and
-        REPLACE. Otherwise it is equivalent to looping over args with
-        execute().
-
-        """
-        del self.messages[:]
-        db = self._get_db()
-        if not args: return
-        charset = db.character_set_name()
-        if isinstance(query, unicode): query = query.encode(charset)
-        m = insert_values.search(query)
-        if not m:
-            r = 0
-            for a in args:
-                r = r + self.execute(query, a)
-            return r
-        p = m.start(1)
-        e = m.end(1)
-        qv = m.group(1)
-        try:
-            q = [ qv % db.literal(a) for a in args ]
-        except TypeError, msg:
-            if msg.args[0] in ("not enough arguments for format string",
-                               "not all arguments converted"):
-                self.errorhandler(self, ProgrammingError, msg.args[0])
-            else:
-                self.errorhandler(self, TypeError, msg)
-        except:
-            from sys import exc_info
-            exc, value, tb = exc_info()
-            del tb
-            self.errorhandler(self, exc, value)
-        r = self._query('\n'.join([query[:p], ',\n'.join(q), query[e:]]))
-        if not self._defer_warnings: self._warning_check()
-        return r
-    
-    def callproc(self, procname, args=()):
-
-        """Execute stored procedure procname with args
-        
-        procname -- string, name of procedure to execute on server
-
-        args -- Sequence of parameters to use with procedure
-
-        Returns the original args.
-
-        Compatibility warning: PEP-249 specifies that any modified
-        parameters must be returned. This is currently impossible
-        as they are only available by storing them in a server
-        variable and then retrieved by a query. Since stored
-        procedures return zero or more result sets, there is no
-        reliable way to get at OUT or INOUT parameters via callproc.
-        The server variables are named @_procname_n, where procname
-        is the parameter above and n is the position of the parameter
-        (from zero). Once all result sets generated by the procedure
-        have been fetched, you can issue a SELECT @_procname_0, ...
-        query using .execute() to get any OUT or INOUT values.
-
-        Compatibility warning: The act of calling a stored procedure
-        itself creates an empty result set. This appears after any
-        result sets generated by the procedure. This is non-standard
-        behavior with respect to the DB-API. Be sure to use nextset()
-        to advance through all result sets; otherwise you may get
-        disconnected.
-        """
-
-        from types import UnicodeType
-        db = self._get_db()
-        charset = db.character_set_name()
-        for index, arg in enumerate(args):
-            q = "SET @_%s_%d=%s" % (procname, index,
-                                         db.literal(arg))
-            if isinstance(q, unicode):
-                q = q.encode(charset)
-            self._query(q)
-            self.nextset()
-            
-        q = "CALL %s(%s)" % (procname,
-                             ','.join(['@_%s_%d' % (procname, i)
-                                       for i in range(len(args))]))
-        if type(q) is UnicodeType:
-            q = q.encode(charset)
-        self._query(q)
-        self._executed = q
-        if not self._defer_warnings: self._warning_check()
-        return args
-    
-    def _do_query(self, q):
-        db = self._get_db()
-        self._last_executed = q
-        db.query(q)
-        self._do_get_result()
-        return self.rowcount
-
-    def _query(self, q): return self._do_query(q)
-    
-    def _fetch_row(self, size=1):
-        if not self._result:
-            return ()
-        return self._result.fetch_row(size, self._fetch_type)
-
-    def __iter__(self):
-        return iter(self.fetchone, None)
-
-    Warning = Warning
-    Error = Error
-    InterfaceError = InterfaceError
-    DatabaseError = DatabaseError
-    DataError = DataError
-    OperationalError = OperationalError
-    IntegrityError = IntegrityError
-    InternalError = InternalError
-    ProgrammingError = ProgrammingError
-    NotSupportedError = NotSupportedError
-   
-
-class CursorStoreResultMixIn(object):
-
-    """This is a MixIn class which causes the entire result set to be
-    stored on the client side, i.e. it uses mysql_store_result(). If the
-    result set can be very large, consider adding a LIMIT clause to your
-    query, or using CursorUseResultMixIn instead."""
-
-    def _get_result(self): return self._get_db().store_result()
-
-    def _query(self, q):
-        rowcount = self._do_query(q)
-        self._post_get_result()
-        return rowcount
-
-    def _post_get_result(self):
-        self._rows = self._fetch_row(0)
-        self._result = None
-
-    def fetchone(self):
-        """Fetches a single row from the cursor. None indicates that
-        no more rows are available."""
-        self._check_executed()
-        if self.rownumber >= len(self._rows): return None
-        result = self._rows[self.rownumber]
-        self.rownumber = self.rownumber+1
-        return result
-
-    def fetchmany(self, size=None):
-        """Fetch up to size rows from the cursor. Result set may be smaller
-        than size. If size is not defined, cursor.arraysize is used."""
-        self._check_executed()
-        end = self.rownumber + (size or self.arraysize)
-        result = self._rows[self.rownumber:end]
-        self.rownumber = min(end, len(self._rows))
-        return result
-
-    def fetchall(self):
-        """Fetchs all available rows from the cursor."""
-        self._check_executed()
-        if self.rownumber:
-            result = self._rows[self.rownumber:]
-        else:
-            result = self._rows
-        self.rownumber = len(self._rows)
-        return result
-    
-    def scroll(self, value, mode='relative'):
-        """Scroll the cursor in the result set to a new position according
-        to mode.
-        
-        If mode is 'relative' (default), value is taken as offset to
-        the current position in the result set, if set to 'absolute',
-        value states an absolute target position."""
-        self._check_executed()
-        if mode == 'relative':
-            r = self.rownumber + value
-        elif mode == 'absolute':
-            r = value
-        else:
-            self.errorhandler(self, ProgrammingError,
-                              "unknown scroll mode %s" % `mode`)
-        if r < 0 or r >= len(self._rows):
-            self.errorhandler(self, IndexError, "out of range")
-        self.rownumber = r
-
-    def __iter__(self):
-        self._check_executed()
-        result = self.rownumber and self._rows[self.rownumber:] or self._rows
-        return iter(result)
-    
-
-class CursorUseResultMixIn(object):
-
-    """This is a MixIn class which causes the result set to be stored
-    in the server and sent row-by-row to client side, i.e. it uses
-    mysql_use_result(). You MUST retrieve the entire result set and
-    close() the cursor before additional queries can be peformed on
-    the connection."""
-
-    _defer_warnings = True
-    
-    def _get_result(self): return self._get_db().use_result()
-
-    def fetchone(self):
-        """Fetches a single row from the cursor."""
-        self._check_executed()
-        r = self._fetch_row(1)
-        if not r:
-            self._warning_check()
-            return None
-        self.rownumber = self.rownumber + 1
-        return r[0]
-             
-    def fetchmany(self, size=None):
-        """Fetch up to size rows from the cursor. Result set may be smaller
-        than size. If size is not defined, cursor.arraysize is used."""
-        self._check_executed()
-        r = self._fetch_row(size or self.arraysize)
-        self.rownumber = self.rownumber + len(r)
-        if not r:
-            self._warning_check()
-        return r
-         
-    def fetchall(self):
-        """Fetchs all available rows from the cursor."""
-        self._check_executed()
-        r = self._fetch_row(0)
-        self.rownumber = self.rownumber + len(r)
-        self._warning_check()
-        return r
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        row = self.fetchone()
-        if row is None:
-            raise StopIteration
-        return row
-    
-
-class CursorTupleRowsMixIn(object):
-
-    """This is a MixIn class that causes all rows to be returned as tuples,
-    which is the standard form required by DB API."""
-
-    _fetch_type = 0
-
-
-class CursorDictRowsMixIn(object):
-
-    """This is a MixIn class that causes all rows to be returned as
-    dictionaries. This is a non-standard feature."""
-
-    _fetch_type = 1
-
-    def fetchoneDict(self):
-        """Fetch a single row as a dictionary. Deprecated:
-        Use fetchone() instead. Will be removed in 1.3."""
-        from warnings import warn
-        warn("fetchoneDict() is non-standard and will be removed in 1.3",
-             DeprecationWarning, 2)
-        return self.fetchone()
-
-    def fetchmanyDict(self, size=None):
-        """Fetch several rows as a list of dictionaries. Deprecated:
-        Use fetchmany() instead. Will be removed in 1.3."""
-        from warnings import warn
-        warn("fetchmanyDict() is non-standard and will be removed in 1.3",
-             DeprecationWarning, 2)
-        return self.fetchmany(size)
-
-    def fetchallDict(self):
-        """Fetch all available rows as a list of dictionaries. Deprecated:
-        Use fetchall() instead. Will be removed in 1.3."""
-        from warnings import warn
-        warn("fetchallDict() is non-standard and will be removed in 1.3",
-             DeprecationWarning, 2)
-        return self.fetchall()
-
-
-class CursorOldDictRowsMixIn(CursorDictRowsMixIn):
-
-    """This is a MixIn class that returns rows as dictionaries with
-    the same key convention as the old Mysqldb (MySQLmodule). Don't
-    use this."""
-
-    _fetch_type = 2
-
-
-class Cursor(CursorStoreResultMixIn, CursorTupleRowsMixIn,
-             BaseCursor):
-
-    """This is the standard Cursor class that returns rows as tuples
-    and stores the result set in the client."""
-
-
-class DictCursor(CursorStoreResultMixIn, CursorDictRowsMixIn,
-                 BaseCursor):
-
-     """This is a Cursor class that returns rows as dictionaries and
-    stores the result set in the client."""
-   
-
-class SSCursor(CursorUseResultMixIn, CursorTupleRowsMixIn,
-               BaseCursor):
-
-    """This is a Cursor class that returns rows as tuples and stores
-    the result set in the server."""
-
-
-class SSDictCursor(CursorUseResultMixIn, CursorDictRowsMixIn,
-                   BaseCursor):
-
-    """This is a Cursor class that returns rows as dictionaries and
-    stores the result set in the server."""
-
-
+"""MySQLdb Cursors
+
+This module implements Cursors of various types for MySQLdb. By
+default, MySQLdb uses the Cursor class.
+
+"""
+
+import re
+import sys
+try:
+    from types import ListType, TupleType, UnicodeType
+except ImportError:
+    # Python 3
+    ListType = list
+    TupleType = tuple
+    UnicodeType = str
+
+restr = r"""
+    \s
+    values
+    \s*
+    (
+        \(
+            [^()']*
+            (?:
+                (?:
+                        (?:\(
+                            # ( - editor hightlighting helper
+                            .*
+                        \))
+                    |
+                        '
+                            [^\\']*
+                            (?:\\.[^\\']*)*
+                        '
+                )
+                [^()']*
+            )*
+        \)
+    )
+"""
+
+insert_values = re.compile(restr, re.S | re.I | re.X)
+
+from _mysql_exceptions import Warning, Error, InterfaceError, DataError, \
+     DatabaseError, OperationalError, IntegrityError, InternalError, \
+     NotSupportedError, ProgrammingError
+
+
+class BaseCursor(object):
+    
+    """A base for Cursor classes. Useful attributes:
+    
+    description
+        A tuple of DB API 7-tuples describing the columns in
+        the last executed query; see PEP-249 for details.
+
+    description_flags
+        Tuple of column flags for last query, one entry per column
+        in the result set. Values correspond to those in
+        MySQLdb.constants.FLAG. See MySQL documentation (C API)
+        for more information. Non-standard extension.
+    
+    arraysize
+        default number of rows fetchmany() will fetch
+
+    """
+
+    from _mysql_exceptions import MySQLError, Warning, Error, InterfaceError, \
+         DatabaseError, DataError, OperationalError, IntegrityError, \
+         InternalError, ProgrammingError, NotSupportedError
+    
+    _defer_warnings = False
+    
+    def __init__(self, connection):
+        from weakref import proxy
+    
+        self.connection = proxy(connection)
+        self.description = None
+        self.description_flags = None
+        self.rowcount = -1
+        self.arraysize = 1
+        self._executed = None
+        self.lastrowid = None
+        self.messages = []
+        self.errorhandler = connection.errorhandler
+        self._result = None
+        self._warnings = 0
+        self._info = None
+        self.rownumber = None
+        
+    def __del__(self):
+        self.close()
+        self.errorhandler = None
+        self._result = None
+
+    def close(self):
+        """Close the cursor. No further queries will be possible."""
+        if not self.connection: return
+        while self.nextset(): pass
+        self.connection = None
+
+    def _check_executed(self):
+        if not self._executed:
+            self.errorhandler(self, ProgrammingError, "execute() first")
+
+    def _warning_check(self):
+        from warnings import warn
+        if self._warnings:
+            warnings = self._get_db().show_warnings()
+            if warnings:
+                # This is done in two loops in case
+                # Warnings are set to raise exceptions.
+                for w in warnings:
+                    self.messages.append((self.Warning, w))
+                for w in warnings:
+                    warn(w[-1], self.Warning, 3)
+            elif self._info:
+                self.messages.append((self.Warning, self._info))
+                warn(self._info, self.Warning, 3)
+
+    def nextset(self):
+        """Advance to the next result set.
+
+        Returns None if there are no more result sets.
+        """
+        if self._executed:
+            self.fetchall()
+        del self.messages[:]
+        
+        db = self._get_db()
+        nr = db.next_result()
+        if nr == -1:
+            return None
+        self._do_get_result()
+        self._post_get_result()
+        self._warning_check()
+        return 1
+
+    def _post_get_result(self): pass
+    
+    def _do_get_result(self):
+        db = self._get_db()
+        self._result = self._get_result()
+        self.rowcount = db.affected_rows()
+        self.rownumber = 0
+        self.description = self._result and self._result.describe() or None
+        self.description_flags = self._result and self._result.field_flags() or None
+        self.lastrowid = db.insert_id()
+        self._warnings = db.warning_count()
+        self._info = db.info()
+    
+    def setinputsizes(self, *args):
+        """Does nothing, required by DB API."""
+      
+    def setoutputsizes(self, *args):
+        """Does nothing, required by DB API."""
+
+    def _get_db(self):
+        if not self.connection:
+            self.errorhandler(self, ProgrammingError, "cursor closed")
+        return self.connection
+    
+    def execute(self, query, args=None):
+
+        """Execute a query.
+        
+        query -- string, query to execute on server
+        args -- optional sequence or mapping, parameters to use with query.
+
+        Note: If args is a sequence, then %s must be used as the
+        parameter placeholder in the query. If a mapping is used,
+        %(key)s must be used as the placeholder.
+
+        Returns long integer rows affected, if any
+
+        """
+        del self.messages[:]
+        db = self._get_db()
+        if isinstance(query, unicode):
+            query = query.encode(db.unicode_literal.charset)
+        if args is not None:
+            if isinstance(args, dict):
+                query = query % dict((key, db.literal(item))
+                                     for key, item in args.iteritems())
+            else:
+                query = query % tuple([db.literal(item) for item in args])
+        try:
+            r = None
+            r = self._query(query)
+        except TypeError, m:
+            if m.args[0] in ("not enough arguments for format string",
+                             "not all arguments converted"):
+                self.messages.append((ProgrammingError, m.args[0]))
+                self.errorhandler(self, ProgrammingError, m.args[0])
+            else:
+                self.messages.append((TypeError, m))
+                self.errorhandler(self, TypeError, m)
+        except (SystemExit, KeyboardInterrupt):
+            raise
+        except:
+            exc, value, tb = sys.exc_info()
+            del tb
+            self.messages.append((exc, value))
+            self.errorhandler(self, exc, value)
+        self._executed = query
+        if not self._defer_warnings: self._warning_check()
+        return r
+
+    def executemany(self, query, args):
+
+        """Execute a multi-row query.
+        
+        query -- string, query to execute on server
+
+        args
+
+            Sequence of sequences or mappings, parameters to use with
+            query.
+            
+        Returns long integer rows affected, if any.
+        
+        This method improves performance on multiple-row INSERT and
+        REPLACE. Otherwise it is equivalent to looping over args with
+        execute().
+
+        """
+        del self.messages[:]
+        db = self._get_db()
+        if not args: return
+        if isinstance(query, unicode):
+            query = query.encode(db.unicode_literal.charset)
+        m = insert_values.search(query)
+        if not m:
+            r = 0
+            for a in args:
+                r = r + self.execute(query, a)
+            return r
+        p = m.start(1)
+        e = m.end(1)
+        qv = m.group(1)
+        try:
+            q = []
+            for a in args:
+                if isinstance(a, dict):
+                    q.append(qv % dict((key, db.literal(item))
+                                       for key, item in a.iteritems()))
+                else:
+                    q.append(qv % tuple([db.literal(item) for item in a]))
+        except TypeError, msg:
+            if msg.args[0] in ("not enough arguments for format string",
+                               "not all arguments converted"):
+                self.errorhandler(self, ProgrammingError, msg.args[0])
+            else:
+                self.errorhandler(self, TypeError, msg)
+        except (SystemExit, KeyboardInterrupt):
+            raise
+        except:
+            exc, value, tb = sys.exc_info()
+            del tb
+            self.errorhandler(self, exc, value)
+        r = self._query('\n'.join([query[:p], ',\n'.join(q), query[e:]]))
+        if not self._defer_warnings: self._warning_check()
+        return r
+    
+    def callproc(self, procname, args=()):
+
+        """Execute stored procedure procname with args
+        
+        procname -- string, name of procedure to execute on server
+
+        args -- Sequence of parameters to use with procedure
+
+        Returns the original args.
+
+        Compatibility warning: PEP-249 specifies that any modified
+        parameters must be returned. This is currently impossible
+        as they are only available by storing them in a server
+        variable and then retrieved by a query. Since stored
+        procedures return zero or more result sets, there is no
+        reliable way to get at OUT or INOUT parameters via callproc.
+        The server variables are named @_procname_n, where procname
+        is the parameter above and n is the position of the parameter
+        (from zero). Once all result sets generated by the procedure
+        have been fetched, you can issue a SELECT @_procname_0, ...
+        query using .execute() to get any OUT or INOUT values.
+
+        Compatibility warning: The act of calling a stored procedure
+        itself creates an empty result set. This appears after any
+        result sets generated by the procedure. This is non-standard
+        behavior with respect to the DB-API. Be sure to use nextset()
+        to advance through all result sets; otherwise you may get
+        disconnected.
+        """
+
+        db = self._get_db()
+        for index, arg in enumerate(args):
+            q = "SET @_%s_%d=%s" % (procname, index,
+                                         db.literal(arg))
+            if isinstance(q, unicode):
+                q = q.encode(db.unicode_literal.charset)
+            self._query(q)
+            self.nextset()
+            
+        q = "CALL %s(%s)" % (procname,
+                             ','.join(['@_%s_%d' % (procname, i)
+                                       for i in range(len(args))]))
+        if type(q) is UnicodeType:
+            q = q.encode(db.unicode_literal.charset)
+        self._query(q)
+        self._executed = q
+        if not self._defer_warnings: self._warning_check()
+        return args
+    
+    def _do_query(self, q):
+        db = self._get_db()
+        self._last_executed = q
+        db.query(q)
+        self._do_get_result()
+        return self.rowcount
+
+    def _query(self, q): return self._do_query(q)
+    
+    def _fetch_row(self, size=1):
+        if not self._result:
+            return ()
+        return self._result.fetch_row(size, self._fetch_type)
+
+    def __iter__(self):
+        return iter(self.fetchone, None)
+
+    Warning = Warning
+    Error = Error
+    InterfaceError = InterfaceError
+    DatabaseError = DatabaseError
+    DataError = DataError
+    OperationalError = OperationalError
+    IntegrityError = IntegrityError
+    InternalError = InternalError
+    ProgrammingError = ProgrammingError
+    NotSupportedError = NotSupportedError
+   
+
+class CursorStoreResultMixIn(object):
+
+    """This is a MixIn class which causes the entire result set to be
+    stored on the client side, i.e. it uses mysql_store_result(). If the
+    result set can be very large, consider adding a LIMIT clause to your
+    query, or using CursorUseResultMixIn instead."""
+
+    def _get_result(self): return self._get_db().store_result()
+
+    def _query(self, q):
+        rowcount = self._do_query(q)
+        self._post_get_result()
+        return rowcount
+
+    def _post_get_result(self):
+        self._rows = self._fetch_row(0)
+        self._result = None
+
+    def fetchone(self):
+        """Fetches a single row from the cursor. None indicates that
+        no more rows are available."""
+        self._check_executed()
+        if self.rownumber >= len(self._rows): return None
+        result = self._rows[self.rownumber]
+        self.rownumber = self.rownumber+1
+        return result
+
+    def fetchmany(self, size=None):
+        """Fetch up to size rows from the cursor. Result set may be smaller
+        than size. If size is not defined, cursor.arraysize is used."""
+        self._check_executed()
+        end = self.rownumber + (size or self.arraysize)
+        result = self._rows[self.rownumber:end]
+        self.rownumber = min(end, len(self._rows))
+        return result
+
+    def fetchall(self):
+        """Fetchs all available rows from the cursor."""
+        self._check_executed()
+        if self.rownumber:
+            result = self._rows[self.rownumber:]
+        else:
+            result = self._rows
+        self.rownumber = len(self._rows)
+        return result
+    
+    def scroll(self, value, mode='relative'):
+        """Scroll the cursor in the result set to a new position according
+        to mode.
+        
+        If mode is 'relative' (default), value is taken as offset to
+        the current position in the result set, if set to 'absolute',
+        value states an absolute target position."""
+        self._check_executed()
+        if mode == 'relative':
+            r = self.rownumber + value
+        elif mode == 'absolute':
+            r = value
+        else:
+            self.errorhandler(self, ProgrammingError,
+                              "unknown scroll mode %s" % repr(mode))
+        if r < 0 or r >= len(self._rows):
+            self.errorhandler(self, IndexError, "out of range")
+        self.rownumber = r
+
+    def __iter__(self):
+        self._check_executed()
+        result = self.rownumber and self._rows[self.rownumber:] or self._rows
+        return iter(result)
+    
+
+class CursorUseResultMixIn(object):
+
+    """This is a MixIn class which causes the result set to be stored
+    in the server and sent row-by-row to client side, i.e. it uses
+    mysql_use_result(). You MUST retrieve the entire result set and
+    close() the cursor before additional queries can be peformed on
+    the connection."""
+
+    _defer_warnings = True
+    
+    def _get_result(self): return self._get_db().use_result()
+
+    def fetchone(self):
+        """Fetches a single row from the cursor."""
+        self._check_executed()
+        r = self._fetch_row(1)
+        if not r:
+            self._warning_check()
+            return None
+        self.rownumber = self.rownumber + 1
+        return r[0]
+             
+    def fetchmany(self, size=None):
+        """Fetch up to size rows from the cursor. Result set may be smaller
+        than size. If size is not defined, cursor.arraysize is used."""
+        self._check_executed()
+        r = self._fetch_row(size or self.arraysize)
+        self.rownumber = self.rownumber + len(r)
+        if not r:
+            self._warning_check()
+        return r
+         
+    def fetchall(self):
+        """Fetchs all available rows from the cursor."""
+        self._check_executed()
+        r = self._fetch_row(0)
+        self.rownumber = self.rownumber + len(r)
+        self._warning_check()
+        return r
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        row = self.fetchone()
+        if row is None:
+            raise StopIteration
+        return row
+    
+
+class CursorTupleRowsMixIn(object):
+
+    """This is a MixIn class that causes all rows to be returned as tuples,
+    which is the standard form required by DB API."""
+
+    _fetch_type = 0
+
+
+class CursorDictRowsMixIn(object):
+
+    """This is a MixIn class that causes all rows to be returned as
+    dictionaries. This is a non-standard feature."""
+
+    _fetch_type = 1
+
+    def fetchoneDict(self):
+        """Fetch a single row as a dictionary. Deprecated:
+        Use fetchone() instead. Will be removed in 1.3."""
+        from warnings import warn
+        warn("fetchoneDict() is non-standard and will be removed in 1.3",
+             DeprecationWarning, 2)
+        return self.fetchone()
+
+    def fetchmanyDict(self, size=None):
+        """Fetch several rows as a list of dictionaries. Deprecated:
+        Use fetchmany() instead. Will be removed in 1.3."""
+        from warnings import warn
+        warn("fetchmanyDict() is non-standard and will be removed in 1.3",
+             DeprecationWarning, 2)
+        return self.fetchmany(size)
+
+    def fetchallDict(self):
+        """Fetch all available rows as a list of dictionaries. Deprecated:
+        Use fetchall() instead. Will be removed in 1.3."""
+        from warnings import warn
+        warn("fetchallDict() is non-standard and will be removed in 1.3",
+             DeprecationWarning, 2)
+        return self.fetchall()
+
+
+class CursorOldDictRowsMixIn(CursorDictRowsMixIn):
+
+    """This is a MixIn class that returns rows as dictionaries with
+    the same key convention as the old Mysqldb (MySQLmodule). Don't
+    use this."""
+
+    _fetch_type = 2
+
+
+class Cursor(CursorStoreResultMixIn, CursorTupleRowsMixIn,
+             BaseCursor):
+
+    """This is the standard Cursor class that returns rows as tuples
+    and stores the result set in the client."""
+
+
+class DictCursor(CursorStoreResultMixIn, CursorDictRowsMixIn,
+                 BaseCursor):
+
+     """This is a Cursor class that returns rows as dictionaries and
+    stores the result set in the client."""
+   
+
+class SSCursor(CursorUseResultMixIn, CursorTupleRowsMixIn,
+               BaseCursor):
+
+    """This is a Cursor class that returns rows as tuples and stores
+    the result set in the server."""
+
+
+class SSDictCursor(CursorUseResultMixIn, CursorDictRowsMixIn,
+                   BaseCursor):
+
+    """This is a Cursor class that returns rows as dictionaries and
+    stores the result set in the server."""
+
+

+ 4 - 0
desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/release.py

@@ -0,0 +1,4 @@
+
+__author__ = "Andy Dustman <farcepest@gmail.com>"
+version_info = (1,2,5,'final',1)
+__version__ = "1.2.5"

+ 126 - 101
desktop/core/ext-py/MySQL-python-1.2.3c1/MySQLdb/times.py → desktop/core/ext-py/MySQL-python-1.2.5/MySQLdb/times.py

@@ -1,101 +1,126 @@
-"""times module
-
-This module provides some Date and Time classes for dealing with MySQL data.
-
-Use Python datetime module to handle date and time columns."""
-
-import math
-from time import localtime
-from datetime import date, datetime, time, timedelta
-from _mysql import string_literal
-
-Date = date
-Time = time
-TimeDelta = timedelta
-Timestamp = datetime
-
-DateTimeDeltaType = timedelta
-DateTimeType = datetime
-
-def DateFromTicks(ticks):
-    """Convert UNIX ticks into a date instance."""
-    return date(*localtime(ticks)[:3])
-
-def TimeFromTicks(ticks):
-    """Convert UNIX ticks into a time instance."""
-    return time(*localtime(ticks)[3:6])
-
-def TimestampFromTicks(ticks):
-    """Convert UNIX ticks into a datetime instance."""
-    return datetime(*localtime(ticks)[:6])
-
-format_TIME = format_DATE = str
-
-def format_TIMEDELTA(v):
-    seconds = int(v.seconds) % 60
-    minutes = int(v.seconds / 60) % 60
-    hours = int(v.seconds / 3600) % 24
-    return '%d %d:%d:%d' % (v.days, hours, minutes, seconds)
-
-def format_TIMESTAMP(d):
-    return d.strftime("%Y-%m-%d %H:%M:%S")
-
-
-def DateTime_or_None(s):
-    if ' ' in s:
-        sep = ' '
-    elif 'T' in s:
-        sep = 'T'
-    else:
-        return Date_or_None(s)
-
-    try:
-        d, t = s.split(sep, 1)
-        return datetime(*[ int(x) for x in d.split('-')+t.split(':') ])
-    except:
-        return Date_or_None(s)
-
-def TimeDelta_or_None(s):
-    try:
-        h, m, s = s.split(':')
-        h, m, s = int(h), int(m), float(s)
-        td = timedelta(hours=abs(h), minutes=m, seconds=int(s),
-                       microseconds=int(math.modf(s)[0] * 1000000))
-        if h < 0:
-            return -td
-        else:
-            return td
-    except ValueError:
-        # unpacking or int/float conversion failed
-        return None
-
-def Time_or_None(s):
-    try:
-        h, m, s = s.split(':')
-        h, m, s = int(h), int(m), float(s)
-        return time(hour=h, minute=m, second=int(s),
-                    microsecond=int(math.modf(s)[0] * 1000000))
-    except ValueError:
-        return None
-
-def Date_or_None(s):
-    try: return date(*[ int(x) for x in s.split('-',2)])
-    except: return None
-
-def DateTime2literal(d, c):
-    """Format a DateTime object as an ISO timestamp."""
-    return string_literal(format_TIMESTAMP(d),c)
-    
-def DateTimeDelta2literal(d, c):
-    """Format a DateTimeDelta object as a time."""
-    return string_literal(format_TIMEDELTA(d),c)
-
-def mysql_timestamp_converter(s):
-    """Convert a MySQL TIMESTAMP to a Timestamp object."""
-    # MySQL>4.1 returns TIMESTAMP in the same format as DATETIME
-    if s[4] == '-': return DateTime_or_None(s)
-    s = s + "0"*(14-len(s)) # padding
-    parts = map(int, filter(None, (s[:4],s[4:6],s[6:8],
-                                   s[8:10],s[10:12],s[12:14])))
-    try: return Timestamp(*parts)
-    except: return None
+"""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)
+        if '.' in t:
+            t, ms = t.split('.',1)
+            ms = ms.ljust(6, '0')
+        else:
+            ms = 0
+        return datetime(*[ int(x) for x in d.split('-')+t.split(':')+[ms] ])
+    except (SystemExit, KeyboardInterrupt):
+        raise
+    except:
+        return Date_or_None(s)
+
+def TimeDelta_or_None(s):
+    try:
+        h, m, s = s.split(':')
+        if '.' in s:
+            s, ms = s.split('.')
+            ms = ms.ljust(6, '0')
+        else:
+            ms = 0
+        h, m, s, ms = int(h), int(m), int(s), int(ms)
+        td = timedelta(hours=abs(h), minutes=m, seconds=s,
+                       microseconds=ms)
+        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(':')
+        if '.' in s:
+            s, ms = s.split('.')
+            ms = ms.ljust(6, '0')
+        else:
+            ms = 0
+        h, m, s, ms = int(h), int(m), int(s), int(ms)
+        return time(hour=h, minute=m, second=s,
+                    microsecond=ms)
+    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

+ 43 - 45
desktop/core/ext-py/MySQL-python-1.2.3c1/PKG-INFO → desktop/core/ext-py/MySQL-python-1.2.5/PKG-INFO

@@ -1,45 +1,43 @@
-Metadata-Version: 1.0
-Name: MySQL-python
-Version: 1.2.3c1
-Summary: Python interface to MySQL
-Home-page: http://sourceforge.net/projects/mysql-python
-Author: Andy Dustman
-Author-email: adustman@users.sourceforge.net
-License: GPL
-Download-URL: http://osdn.dl.sourceforge.net/sourceforge/mysql-python/MySQL-python-1.2.3c1.tar.gz
-Description: 
-        =========================
-        Python interface to MySQL
-        =========================
-        
-        MySQLdb is an interface to the popular MySQL_ database server for
-        Python.  The design goals are:
-        
-        - Compliance with Python database API version 2.0 [PEP-0249]_
-        
-        - Thread-safety
-        
-        - Thread-friendliness (threads will not block each other)
-        
-        MySQL-3.23 through 5.0 and Python-2.3 through 2.6 are currently
-        supported. Python-3.0 will be supported in a future release.
-        
-        MySQLdb is `Free Software`_.
-        
-        .. _MySQL: http://www.mysql.com/
-        .. _`Free Software`: http://www.gnu.org/
-        .. [PEP-0249] http://www.python.org/peps/pep-0249.html
-Platform: ALL
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Other Environment
-Classifier: License :: OSI Approved :: GNU General Public License (GPL)
-Classifier: Operating System :: MacOS :: MacOS X
-Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
-Classifier: Operating System :: OS Independent
-Classifier: Operating System :: POSIX
-Classifier: Operating System :: POSIX :: Linux
-Classifier: Operating System :: Unix
-Classifier: Programming Language :: C
-Classifier: Programming Language :: Python
-Classifier: Topic :: Database
-Classifier: Topic :: Database :: Database Engines/Servers
+Metadata-Version: 1.1
+Name: MySQL-python
+Version: 1.2.5
+Summary: Python interface to MySQL
+Home-page: https://github.com/farcepest/MySQLdb1
+Author: Andy Dustman
+Author-email: farcepest@gmail.com
+License: GPL
+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.
+        PyPy is supported.
+        
+        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

+ 41 - 0
desktop/core/ext-py/MySQL-python-1.2.5/README.md

@@ -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. 
+
+[![Build Status](https://secure.travis-ci.org/farcepest/MySQLdb1.png)](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/

+ 3168 - 2894
desktop/core/ext-py/MySQL-python-1.2.3c1/_mysql.c → desktop/core/ext-py/MySQL-python-1.2.5/_mysql.c

@@ -1,2894 +1,3168 @@
-/*
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version. Alternatively, you may use the original license
-reproduced below.
-
-Copyright 1999 by Comstar.net, Inc., Atlanta, GA, US.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Comstar.net, Inc.
-or COMSTAR not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior permission.
-
-COMSTAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL COMSTAR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
-USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-*/
-
-#include "pymemcompat.h"
-#include "structmember.h"
-#if defined(MS_WINDOWS)
-#include <winsock2.h>
-#include <windows.h>
-#include <config-win.h>
-#else
-#include "my_config.h"
-#endif
-#include "mysql.h"
-#include "mysqld_error.h"
-#include "errmsg.h"
-
-#if PY_VERSION_HEX < 0x02020000
-# define MyTuple_Resize(t,n,d) _PyTuple_Resize(t, n, d)
-# define MyMember(a,b,c,d,e) {a,b,c,d}
-# define MyMemberlist(x) struct memberlist x
-# define MyAlloc(s,t) PyObject_New(s,&t)
-# define MyFree(o) PyObject_Del(o)
-#else
-# define MyTuple_Resize(t,n,d) _PyTuple_Resize(t, n)
-# define MyMember(a,b,c,d,e) {a,b,c,d,e}
-# define MyMemberlist(x) struct PyMemberDef x
-# define MyAlloc(s,t) (s *) t.tp_alloc(&t,0)
-# define MyFree(ob) ob->ob_type->tp_free((PyObject *)ob) 
-#endif
-
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-typedef int Py_ssize_t;
-#define PY_SSIZE_T_MAX INT_MAX
-#define PY_SSIZE_T_MIN INT_MIN
-#endif
-
-static PyObject *_mysql_MySQLError;
-static PyObject *_mysql_Warning;
-static PyObject *_mysql_Error;
-static PyObject *_mysql_DatabaseError;
-static PyObject *_mysql_InterfaceError; 
-static PyObject *_mysql_DataError;
-static PyObject *_mysql_OperationalError; 
-static PyObject *_mysql_IntegrityError; 
-static PyObject *_mysql_InternalError; 
-static PyObject *_mysql_ProgrammingError;
-static PyObject *_mysql_NotSupportedError;
- 
-typedef struct {
-	PyObject_HEAD
-	MYSQL connection;
-	int open;
-	PyObject *converter;
-} _mysql_ConnectionObject;
-
-#define check_connection(c) if (!(c->open)) return _mysql_Exception(c)
-#define result_connection(r) ((_mysql_ConnectionObject *)r->conn)
-#define check_result_connection(r) check_connection(result_connection(r))
-
-extern PyTypeObject _mysql_ConnectionObject_Type;
-
-typedef struct {
-	PyObject_HEAD
-	PyObject *conn;
-	MYSQL_RES *result;
-	int nfields;
-	int use;
-	PyObject *converter;
-} _mysql_ResultObject;
-
-extern PyTypeObject _mysql_ResultObject_Type;
-
-static int _mysql_server_init_done = 0;
-#if MYSQL_VERSION_ID >= 40000
-#define check_server_init(x) if (!_mysql_server_init_done) { if (mysql_server_init(0, NULL, NULL)) { _mysql_Exception(NULL); return x; } else { _mysql_server_init_done = 1;} }
-#else
-#define check_server_init(x) if (!_mysql_server_init_done) _mysql_server_init_done = 1
-#endif
-
-#if MYSQL_VERSION_ID >= 50500
-#define HAVE_OPENSSL 1
-#endif
-
-
-PyObject *
-_mysql_Exception(_mysql_ConnectionObject *c)
-{
-	PyObject *t, *e;
-	int merr;
-
-	if (!(t = PyTuple_New(2))) return NULL;
-	if (!_mysql_server_init_done) {
-		e = _mysql_InternalError;
-		PyTuple_SET_ITEM(t, 0, PyInt_FromLong(-1L));
-		PyTuple_SET_ITEM(t, 1, PyString_FromString("server not initialized"));
-		PyErr_SetObject(e, t);
-		Py_DECREF(t);
-		return NULL;
-	}
-	merr = mysql_errno(&(c->connection));
-	if (!merr)
-		e = _mysql_InterfaceError;
-	else if (merr > CR_MAX_ERROR) {
-		PyTuple_SET_ITEM(t, 0, PyInt_FromLong(-1L));
-		PyTuple_SET_ITEM(t, 1, PyString_FromString("error totally whack"));
-		PyErr_SetObject(_mysql_InterfaceError, t);
-		Py_DECREF(t);
-		return NULL;
-	}
-	else switch (merr) {
-	case CR_COMMANDS_OUT_OF_SYNC:
-	case ER_DB_CREATE_EXISTS:
-	case ER_SYNTAX_ERROR:
-	case ER_PARSE_ERROR:
-	case ER_NO_SUCH_TABLE:
-	case ER_WRONG_DB_NAME:
-	case ER_WRONG_TABLE_NAME:
-	case ER_FIELD_SPECIFIED_TWICE:
-	case ER_INVALID_GROUP_FUNC_USE:
-	case ER_UNSUPPORTED_EXTENSION:
-	case ER_TABLE_MUST_HAVE_COLUMNS:
-#ifdef ER_CANT_DO_THIS_DURING_AN_TRANSACTION
-	case ER_CANT_DO_THIS_DURING_AN_TRANSACTION:
-#endif
-		e = _mysql_ProgrammingError;
-		break;
-#ifdef WARN_DATA_TRUNCATED
-	case WARN_DATA_TRUNCATED:
-#ifdef WARN_NULL_TO_NOTNULL
-	case WARN_NULL_TO_NOTNULL:
-#endif
-#ifdef ER_WARN_DATA_OUT_OF_RANGE
-	case ER_WARN_DATA_OUT_OF_RANGE:
-#endif
-#ifdef ER_NO_DEFAULT
-	case ER_NO_DEFAULT:
-#endif
-#ifdef ER_PRIMARY_CANT_HAVE_NULL
-	case ER_PRIMARY_CANT_HAVE_NULL:
-#endif
-#ifdef ER_DATA_TOO_LONG
-	case ER_DATA_TOO_LONG:
-#endif
-#ifdef ER_DATETIME_FUNCTION_OVERFLOW
-	case ER_DATETIME_FUNCTION_OVERFLOW:
-#endif
-		e = _mysql_DataError;
-		break;
-#endif
-	case ER_DUP_ENTRY:
-#ifdef ER_DUP_UNIQUE
-	case ER_DUP_UNIQUE:
-#endif
-#ifdef ER_NO_REFERENCED_ROW
-	case ER_NO_REFERENCED_ROW:
-#endif
-#ifdef ER_NO_REFERENCED_ROW_2
-	case ER_NO_REFERENCED_ROW_2:
-#endif
-#ifdef ER_ROW_IS_REFERENCED
-	case ER_ROW_IS_REFERENCED:
-#endif
-#ifdef ER_ROW_IS_REFERENCED_2
-	case ER_ROW_IS_REFERENCED_2:
-#endif
-#ifdef ER_CANNOT_ADD_FOREIGN
-	case ER_CANNOT_ADD_FOREIGN:
-#endif
-		e = _mysql_IntegrityError;
-		break;
-#ifdef ER_WARNING_NOT_COMPLETE_ROLLBACK
-	case ER_WARNING_NOT_COMPLETE_ROLLBACK:
-#endif
-#ifdef ER_NOT_SUPPORTED_YET
-	case ER_NOT_SUPPORTED_YET:
-#endif
-#ifdef ER_FEATURE_DISABLED
-	case ER_FEATURE_DISABLED:
-#endif
-#ifdef ER_UNKNOWN_STORAGE_ENGINE
-	case ER_UNKNOWN_STORAGE_ENGINE:
-#endif
-		e = _mysql_NotSupportedError;
-		break;
-	default:
-		if (merr < 1000)
-			e = _mysql_InternalError;
-		else
-			e = _mysql_OperationalError;
-		break;
-	}
-	PyTuple_SET_ITEM(t, 0, PyInt_FromLong((long)merr));
-	PyTuple_SET_ITEM(t, 1, PyString_FromString(mysql_error(&(c->connection))));
-	PyErr_SetObject(e, t);
-	Py_DECREF(t);
-	return NULL;
-}
-	  
-static char _mysql_server_init__doc__[] =
-"Initialize embedded server. If this client is not linked against\n\
-the embedded server library, this function does nothing.\n\
-\n\
-args -- sequence of command-line arguments\n\
-groups -- sequence of groups to use in defaults files\n\
-";
-
-static PyObject *_mysql_server_init(
-	PyObject *self,
-	PyObject *args,
-	PyObject *kwargs) {
-	static char *kwlist[] = {"args", "groups", NULL};
-	char **cmd_args_c=NULL, **groups_c=NULL, *s;
-	int cmd_argc=0, i, groupc;
-	PyObject *cmd_args=NULL, *groups=NULL, *ret=NULL, *item;
-
-	if (_mysql_server_init_done) {
-		PyErr_SetString(_mysql_ProgrammingError,
-				"already initialized");
-		return NULL;
-	}
-	  
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwlist,
-					 &cmd_args, &groups))
-		return NULL;
-
-#if MYSQL_VERSION_ID >= 40000
-	if (cmd_args) {
-		if (!PySequence_Check(cmd_args)) {
-			PyErr_SetString(PyExc_TypeError,
-					"args must be a sequence");
-			goto finish;
-		}
-		cmd_argc = PySequence_Size(cmd_args);
-		if (cmd_argc == -1) {
-			PyErr_SetString(PyExc_TypeError,
-					"args could not be sized");
-			goto finish;
-		}
-		cmd_args_c = (char **) PyMem_Malloc(cmd_argc*sizeof(char *));
-		for (i=0; i< cmd_argc; i++) {
-			item = PySequence_GetItem(cmd_args, i);
-			s = PyString_AsString(item);
-			Py_DECREF(item);
-			if (!s) {
-				PyErr_SetString(PyExc_TypeError,
-						"args must contain strings");
-				goto finish;
-			}
-			cmd_args_c[i] = s;
-		}
-	}
-	if (groups) {
-		if (!PySequence_Check(groups)) {
-			PyErr_SetString(PyExc_TypeError,
-					"groups must be a sequence");
-			goto finish;
-		}
-		groupc = PySequence_Size(groups);
-		if (groupc == -1) {
-			PyErr_SetString(PyExc_TypeError,
-					"groups could not be sized");
-			goto finish;
-		}
-		groups_c = (char **) PyMem_Malloc((1+groupc)*sizeof(char *));
-		for (i=0; i< groupc; i++) {
-			item = PySequence_GetItem(groups, i);
-			s = PyString_AsString(item);
-			Py_DECREF(item);
-			if (!s) {
-				PyErr_SetString(PyExc_TypeError,
-						"groups must contain strings");
-				goto finish;
-			}
-			groups_c[i] = s;
-		}
-		groups_c[groupc] = (char *)NULL;
-	}
-	/* even though this may block, don't give up the interpreter lock
-	   so that the server can't be initialized multiple times. */
-	if (mysql_server_init(cmd_argc, cmd_args_c, groups_c)) {
-		_mysql_Exception(NULL);
-		goto finish;
-	}
-#endif
-	ret = Py_None;
-	Py_INCREF(Py_None);
-	_mysql_server_init_done = 1;
-  finish:
-	PyMem_Free(groups_c);
-	PyMem_Free(cmd_args_c);
-	return ret;
-}
-
-static char _mysql_server_end__doc__[] =
-"Shut down embedded server. If not using an embedded server, this\n\
-does nothing.";
-
-static PyObject *_mysql_server_end(
-	PyObject *self,
-	PyObject *args) {
-	if (_mysql_server_init_done) {
-#if MYSQL_VERSION_ID >= 40000
-		mysql_server_end();
-#endif
-		_mysql_server_init_done = 0;
-		Py_INCREF(Py_None);
-		return Py_None;
-	}
-	return _mysql_Exception(NULL);
-}
-	 
-#if MYSQL_VERSION_ID >= 32314
-static char _mysql_thread_safe__doc__[] =
-"Indicates whether the client is compiled as thread-safe.";
-
-static PyObject *_mysql_thread_safe(
-	PyObject *self,
-	PyObject *args) {
-	PyObject *flag;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_server_init(NULL);
-	if (!(flag=PyInt_FromLong((long)mysql_thread_safe()))) return NULL;
-	return flag;
-}
-#endif
-
-static char _mysql_ResultObject__doc__[] =
-"result(connection, use=0, converter={}) -- Result set from a query.\n\
-\n\
-Creating instances of this class directly is an excellent way to\n\
-shoot yourself in the foot. If using _mysql.connection directly,\n\
-use connection.store_result() or connection.use_result() instead.\n\
-If using MySQLdb.Connection, this is done by the cursor class.\n\
-Just forget you ever saw this. Forget... FOR-GET...";
-
-static int
-_mysql_ResultObject_Initialize(
-	_mysql_ResultObject *self,
-	PyObject *args,
-	PyObject *kwargs)
-{
-	static char *kwlist[] = {"connection", "use", "converter", NULL};
-	MYSQL_RES *result; 
-	_mysql_ConnectionObject *conn=NULL;
-	int use=0; 
-	PyObject *conv=NULL;
-	int n, i;
-	MYSQL_FIELD *fields;
-
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO", kwlist,
-					  &conn, &use, &conv))
-		return -1;
-	if (!conv) conv = PyDict_New();
-	if (!conv) return -1;
-	self->conn = (PyObject *) conn;
-	Py_INCREF(conn);
-	self->use = use;
-	Py_BEGIN_ALLOW_THREADS ;
-	if (use)
-		result = mysql_use_result(&(conn->connection));
-	else
-		result = mysql_store_result(&(conn->connection));
-	self->result = result;
-	Py_END_ALLOW_THREADS ;
-	if (!result) {
-		self->converter = PyTuple_New(0);
-		return 0;
-	}
-	n = mysql_num_fields(result);
-	self->nfields = n;
-	if (!(self->converter = PyTuple_New(n))) return -1;
-	fields = mysql_fetch_fields(result);
-	for (i=0; i<n; i++) {
-		PyObject *tmp, *fun;
-		tmp = PyInt_FromLong((long) fields[i].type);
-		if (!tmp) return -1;
-		fun = PyObject_GetItem(conv, tmp);
-		Py_DECREF(tmp);
-		if (!fun) {
-			PyErr_Clear();
-			fun = Py_None;
-			Py_INCREF(Py_None);
-		}
-		if (PySequence_Check(fun)) {
-			int j, n2=PySequence_Size(fun);
-			PyObject *fun2=NULL;
-			for (j=0; j<n2; j++) {
-				PyObject *t = PySequence_GetItem(fun, j);
-				if (!t) continue;
-				if (!PyTuple_Check(t)) goto cleanup;
-				if (PyTuple_GET_SIZE(t) == 2) {
-					long mask;
-					PyObject *pmask=NULL;
-					pmask = PyTuple_GET_ITEM(t, 0);
-					fun2 = PyTuple_GET_ITEM(t, 1);
-					if (PyInt_Check(pmask)) {
-						mask = PyInt_AS_LONG(pmask);
-						if (mask & fields[i].flags) {
-							Py_DECREF(t);
-							break;
-						}
-						else {
-							goto cleanup;
-						}
-					} else {
-						Py_DECREF(t);
-						break;
-					}
-				}
-			  cleanup:
-				Py_DECREF(t);
-			}
-			if (!fun2) fun2 = Py_None;
-			Py_INCREF(fun2);
-			Py_DECREF(fun);
-			fun = fun2;
-		}
-		PyTuple_SET_ITEM(self->converter, i, fun);
-	}
-	return 0;
-}
-
-#if PY_VERSION_HEX >= 0x02020000
-static int _mysql_ResultObject_traverse(
-	_mysql_ResultObject *self,
-	visitproc visit,
-	void *arg)
-{
-	int r;
-	if (self->converter) {
-		if (!(r = visit(self->converter, arg))) return r;
-	}
-	if (self->conn)
-		return visit(self->conn, arg);
-	return 0;
-}
-#endif
-
-static int _mysql_ResultObject_clear(
-	_mysql_ResultObject *self)
-{
-	Py_XDECREF(self->converter);
-	self->converter = NULL;
-	Py_XDECREF(self->conn);
-	self->conn = NULL;
-	return 0;
-}
-
-static int
-_mysql_ConnectionObject_Initialize(
-	_mysql_ConnectionObject *self,
-	PyObject *args,
-	PyObject *kwargs)
-{
-	MYSQL *conn = NULL;
-	PyObject *conv = NULL;
-	PyObject *ssl = NULL;
-#if HAVE_OPENSSL
-	char *key = NULL, *cert = NULL, *ca = NULL,
-		*capath = NULL, *cipher = NULL;
-#endif
-	char *host = NULL, *user = NULL, *passwd = NULL,
-		*db = NULL, *unix_socket = NULL;
-	unsigned int port = 0;
-	unsigned int client_flag = 0;
-	static char *kwlist[] = { "host", "user", "passwd", "db", "port",
-				  "unix_socket", "conv",
-				  "connect_timeout", "compress",
-				  "named_pipe", "init_command",
-				  "read_default_file", "read_default_group",
-				  "client_flag", "ssl",
-				  "local_infile",
-				  NULL } ;
-	int connect_timeout = 0;
-	int compress = -1, named_pipe = -1, local_infile = -1;
-	char *init_command=NULL,
-	     *read_default_file=NULL,
-	     *read_default_group=NULL;
-	
-	self->converter = NULL;
-	self->open = 0;
-	check_server_init(-1);
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ssssisOiiisssiOi:connect",
-					 kwlist,
-					 &host, &user, &passwd, &db,
-					 &port, &unix_socket, &conv,
-					 &connect_timeout,
-					 &compress, &named_pipe,
-					 &init_command, &read_default_file,
-					 &read_default_group,
-					 &client_flag, &ssl,
-					 &local_infile /* DO NOT PATCH FOR RECONNECT, IDIOTS
-					 IF YOU DO THIS, I WILL NOT SUPPORT YOUR PACKAGES. */
-					 ))
-		return -1;
-
-	if (!conv) 
-		conv = PyDict_New();
-#if PY_VERSION_HEX > 0x02000100
-	else
-		Py_INCREF(conv);
-#endif
-	if (!conv)
-		return -1;
-	self->converter = conv;
-
-#define _stringsuck(d,t,s) {t=PyMapping_GetItemString(s,#d);\
-        if(t){d=PyString_AsString(t);Py_DECREF(t);}\
-        PyErr_Clear();}
-	
-	if (ssl) {
-#if HAVE_OPENSSL
-		PyObject *value = NULL;
-		_stringsuck(ca, value, ssl);
-		_stringsuck(capath, value, ssl);
-		_stringsuck(cert, value, ssl);
-		_stringsuck(key, value, ssl);
-		_stringsuck(cipher, value, ssl);
-#else
-		PyErr_SetString(_mysql_NotSupportedError,
-				"client library does not have SSL support");
-		return -1;
-#endif
-	}
-
-	Py_BEGIN_ALLOW_THREADS ;
-	conn = mysql_init(&(self->connection));
-	if (connect_timeout) {
-		unsigned int timeout = connect_timeout;
-		mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT, 
-				(char *)&timeout);
-	}
-	if (compress != -1) {
-		mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0);
-		client_flag |= CLIENT_COMPRESS;
-	}
-	if (named_pipe != -1)
-		mysql_options(&(self->connection), MYSQL_OPT_NAMED_PIPE, 0);
-	if (init_command != NULL)
-		mysql_options(&(self->connection), MYSQL_INIT_COMMAND, init_command);
-	if (read_default_file != NULL)
-		mysql_options(&(self->connection), MYSQL_READ_DEFAULT_FILE, read_default_file);
-	if (read_default_group != NULL)
-		mysql_options(&(self->connection), MYSQL_READ_DEFAULT_GROUP, read_default_group);
-
-	if (local_infile != -1)
-		mysql_options(&(self->connection), MYSQL_OPT_LOCAL_INFILE, (char *) &local_infile);
-
-#if HAVE_OPENSSL
-	if (ssl)
-		mysql_ssl_set(&(self->connection),
-			      key, cert, ca, capath, cipher);
-#endif
-
-	conn = mysql_real_connect(&(self->connection), host, user, passwd, db,
-				  port, unix_socket, client_flag);
-
-	Py_END_ALLOW_THREADS ;
-
-	if (!conn) {
-		_mysql_Exception(self);
-		return -1;
-	}
-	/*
-	  PyType_GenericAlloc() automatically sets up GC allocation and
-	  tracking for GC objects, at least in 2.2.1, so it does not need to
-	  be done here. tp_dealloc still needs to call PyObject_GC_UnTrack(),
-	  however.
-	*/
-	self->open = 1;
-	return 0;
-}
-
-static char _mysql_connect__doc__[] =
-"Returns a MYSQL connection object. Exclusive use of\n\
-keyword parameters strongly recommended. Consult the\n\
-MySQL C API documentation for more details.\n\
-\n\
-host\n\
-  string, host to connect\n\
-\n\
-user\n\
-  string, user to connect as\n\
-\n\
-passwd\n\
-  string, password to use\n\
-\n\
-db\n\
-  string, database to use\n\
-\n\
-port\n\
-  integer, TCP/IP port to connect to\n\
-\n\
-unix_socket\n\
-  string, location of unix_socket (UNIX-ish only)\n\
-\n\
-conv\n\
-  mapping, maps MySQL FIELD_TYPE.* to Python functions which\n\
-  convert a string to the appropriate Python type\n\
-\n\
-connect_timeout\n\
-  number of seconds to wait before the connection\n\
-  attempt fails.\n\
-\n\
-compress\n\
-  if set, gzip compression is enabled\n\
-\n\
-named_pipe\n\
-  if set, connect to server via named pipe (Windows only)\n\
-\n\
-init_command\n\
-  command which is run once the connection is created\n\
-\n\
-read_default_file\n\
-  see the MySQL documentation for mysql_options()\n\
-\n\
-read_default_group\n\
-  see the MySQL documentation for mysql_options()\n\
-\n\
-client_flag\n\
-  client flags from MySQLdb.constants.CLIENT\n\
-\n\
-load_infile\n\
-  int, non-zero enables LOAD LOCAL INFILE, zero disables\n\
-\n\
-";
-
-static PyObject *
-_mysql_connect(
-	PyObject *self,
-	PyObject *args,
-	PyObject *kwargs)
-{
-	_mysql_ConnectionObject *c=NULL;
-	
-	c = MyAlloc(_mysql_ConnectionObject, _mysql_ConnectionObject_Type);
-	if (c == NULL) return NULL;
-	if (_mysql_ConnectionObject_Initialize(c, args, kwargs)) {
-		Py_DECREF(c);
-		c = NULL;
-	}
-	return (PyObject *) c;
-}
-
-#if PY_VERSION_HEX >= 0x02020000
-static int _mysql_ConnectionObject_traverse(
-	_mysql_ConnectionObject *self,
-	visitproc visit,
-	void *arg)
-{
-	if (self->converter)
-		return visit(self->converter, arg);
-	return 0;
-}
-#endif
-
-static int _mysql_ConnectionObject_clear(
-	_mysql_ConnectionObject *self)
-{
-	Py_XDECREF(self->converter);
-	self->converter = NULL;
-	return 0;
-}
-
-static char _mysql_ConnectionObject_close__doc__[] =
-"Close the connection. No further activity possible.";
-
-static PyObject *
-_mysql_ConnectionObject_close(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (args) {
-		if (!PyArg_ParseTuple(args, "")) return NULL;
-	}
-	if (self->open) {
-		Py_BEGIN_ALLOW_THREADS
-		mysql_close(&(self->connection));
-		Py_END_ALLOW_THREADS
-		self->open = 0;
-	} else {
-		PyErr_SetString(_mysql_ProgrammingError,
-				"closing a closed connection");
-		return NULL;
-	}
-	_mysql_ConnectionObject_clear(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ConnectionObject_affected_rows__doc__ [] =
-"Return number of rows affected by the last query.\n\
-Non-standard. Use Cursor.rowcount.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_affected_rows(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	return PyLong_FromUnsignedLongLong(mysql_affected_rows(&(self->connection)));
-}
-
-static char _mysql_debug__doc__[] =
-"Does a DBUG_PUSH with the given string.\n\
-mysql_debug() uses the Fred Fish debug library.\n\
-To use this function, you must compile the client library to\n\
-support debugging.\n\
-";
-static PyObject *
-_mysql_debug(
-	PyObject *self,
-	PyObject *args)
-{
-	char *debug;
-	if (!PyArg_ParseTuple(args, "s", &debug)) return NULL;
-	mysql_debug(debug);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ConnectionObject_dump_debug_info__doc__[] =
-"Instructs the server to write some debug information to the\n\
-log. The connected user must have the process privilege for\n\
-this to work. Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_dump_debug_info(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	int err;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	err = mysql_dump_debug_info(&(self->connection));
-	Py_END_ALLOW_THREADS
-	if (err) return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ConnectionObject_autocommit__doc__[] =
-"Set the autocommit mode. True values enable; False value disable.\n\
-";
-static PyObject *
-_mysql_ConnectionObject_autocommit(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	int flag, err;
-	if (!PyArg_ParseTuple(args, "i", &flag)) return NULL;
-	Py_BEGIN_ALLOW_THREADS
-#if MYSQL_VERSION_ID >= 40100
-	err = mysql_autocommit(&(self->connection), flag);
-#else
-	{
-		char query[256];
-		snprintf(query, 256, "SET AUTOCOMMIT=%d", flag);
-		err = mysql_query(&(self->connection), query);
-	}
-#endif
-	Py_END_ALLOW_THREADS
-	if (err) return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}		
-
-static char _mysql_ConnectionObject_commit__doc__[] =
-"Commits the current transaction\n\
-";
-static PyObject *
-_mysql_ConnectionObject_commit(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	int err;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	Py_BEGIN_ALLOW_THREADS
-#if MYSQL_VERSION_ID >= 40100
-	err = mysql_commit(&(self->connection));
-#else
-	err = mysql_query(&(self->connection), "COMMIT");
-#endif
-	Py_END_ALLOW_THREADS
-	if (err) return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}		
-
-static char _mysql_ConnectionObject_rollback__doc__[] =
-"Rolls backs the current transaction\n\
-";
-static PyObject *
-_mysql_ConnectionObject_rollback(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	int err;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	Py_BEGIN_ALLOW_THREADS
-#if MYSQL_VERSION_ID >= 40100
-	err = mysql_rollback(&(self->connection));
-#else
-	err = mysql_query(&(self->connection), "ROLLBACK");
-#endif
-	Py_END_ALLOW_THREADS
-	if (err) return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}		
-
-static char _mysql_ConnectionObject_next_result__doc__[] =
-"If more query results exist, next_result() reads the next query\n\
-results and returns the status back to application.\n\
-\n\
-After calling next_result() the state of the connection is as if\n\
-you had called query() for the next query. This means that you can\n\
-now call store_result(), warning_count(), affected_rows()\n\
-, and so forth. \n\
-\n\
-Returns 0 if there are more results; -1 if there are no more results\n\
-\n\
-Non-standard.\n\
-";
-static PyObject *
-_mysql_ConnectionObject_next_result(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	int err;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	Py_BEGIN_ALLOW_THREADS
-#if MYSQL_VERSION_ID >= 40100
-	err = mysql_next_result(&(self->connection));
-#else
-	err = -1;
-#endif
-	Py_END_ALLOW_THREADS
-	if (err > 0) return _mysql_Exception(self);
-	return PyInt_FromLong(err);
-}		
-
-#if MYSQL_VERSION_ID >= 40100
-
-static char _mysql_ConnectionObject_set_server_option__doc__[] =
-"set_server_option(option) -- Enables or disables an option\n\
-for the connection.\n\
-\n\
-Non-standard.\n\
-";
-static PyObject *
-_mysql_ConnectionObject_set_server_option(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	int err, flags=0;
-	if (!PyArg_ParseTuple(args, "i", &flags))
-		return NULL;
-	Py_BEGIN_ALLOW_THREADS
-	err = mysql_set_server_option(&(self->connection), flags);
-	Py_END_ALLOW_THREADS
-	if (err) return _mysql_Exception(self);
-	return PyInt_FromLong(err);
-}		
-
-static char _mysql_ConnectionObject_sqlstate__doc__[] =
-"Returns a string containing the SQLSTATE error code\n\
-for the last error. The error code consists of five characters.\n\
-'00000' means \"no error.\" The values are specified by ANSI SQL\n\
-and ODBC. For a list of possible values, see section 23\n\
-Error Handling in MySQL in the MySQL Manual.\n\
-\n\
-Note that not all MySQL errors are yet mapped to SQLSTATE's.\n\
-The value 'HY000' (general error) is used for unmapped errors.\n\
-\n\
-Non-standard.\n\
-";
-static PyObject *
-_mysql_ConnectionObject_sqlstate(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	return PyString_FromString(mysql_sqlstate(&(self->connection)));
-}		
-
-static char _mysql_ConnectionObject_warning_count__doc__[] =
-"Returns the number of warnings generated during execution\n\
-of the previous SQL statement.\n\
-\n\
-Non-standard.\n\
-";
-static PyObject *
-_mysql_ConnectionObject_warning_count(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	return PyInt_FromLong(mysql_warning_count(&(self->connection)));
-}		
-
-#endif
-
-static char _mysql_ConnectionObject_errno__doc__[] =
-"Returns the error code for the most recently invoked API function\n\
-that can succeed or fail. A return value of zero means that no error\n\
-occurred.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_errno(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	return PyInt_FromLong((long)mysql_errno(&(self->connection)));
-}
-
-static char _mysql_ConnectionObject_error__doc__[] =
-"Returns the error message for the most recently invoked API function\n\
-that can succeed or fail. An empty string ("") is returned if no error\n\
-occurred.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_error(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	return PyString_FromString(mysql_error(&(self->connection)));
-}
-
-static char _mysql_escape_string__doc__[] =
-"escape_string(s) -- quote any SQL-interpreted characters in string s.\n\
-\n\
-Use connection.escape_string(s), if you use it at all.\n\
-_mysql.escape_string(s) cannot handle character sets. You are\n\
-probably better off using connection.escape(o) instead, since\n\
-it will escape entire sequences as well as strings.";
-
-static PyObject *
-_mysql_escape_string(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	PyObject *str;
-	char *in, *out;
-	int len, size;
-	if (!PyArg_ParseTuple(args, "s#:escape_string", &in, &size)) return NULL;
-	str = PyString_FromStringAndSize((char *) NULL, size*2+1);
-	if (!str) return PyErr_NoMemory();
-	out = PyString_AS_STRING(str);
-#if MYSQL_VERSION_ID < 32321
-	len = mysql_escape_string(out, in, size);
-#else
-	check_server_init(NULL);
-	if (self && self->open)
-		len = mysql_real_escape_string(&(self->connection), out, in, size);
-	else
-		len = mysql_escape_string(out, in, size);
-#endif
-	if (_PyString_Resize(&str, len) < 0) return NULL;
-	return (str);
-}
-
-static char _mysql_string_literal__doc__[] =
-"string_literal(obj) -- converts object obj into a SQL string literal.\n\
-This means, any special SQL characters are escaped, and it is enclosed\n\
-within single quotes. In other words, it performs:\n\
-\n\
-\"'%s'\" % escape_string(str(obj))\n\
-\n\
-Use connection.string_literal(obj), if you use it at all.\n\
-_mysql.string_literal(obj) cannot handle character sets.";
-
-static PyObject *
-_mysql_string_literal(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	PyObject *str, *s, *o, *d;
-	char *in, *out;
-	int len, size;
-	if (!PyArg_ParseTuple(args, "O|O:string_literal", &o, &d)) return NULL;
-	s = PyObject_Str(o);
-	if (!s) return NULL;
-	in = PyString_AsString(s);
-	size = PyString_GET_SIZE(s);
-	str = PyString_FromStringAndSize((char *) NULL, size*2+3);
-	if (!str) return PyErr_NoMemory();
-	out = PyString_AS_STRING(str);
-#if MYSQL_VERSION_ID < 32321
-	len = mysql_escape_string(out+1, in, size);
-#else
-	check_server_init(NULL);
-	if (self && self->open)
-		len = mysql_real_escape_string(&(self->connection), out+1, in, size);
-	else
-		len = mysql_escape_string(out+1, in, size);
-#endif
-	*out = *(out+len+1) = '\'';
-	if (_PyString_Resize(&str, len+2) < 0) return NULL;
-	Py_DECREF(s);
-	return (str);
-}
-
-static PyObject *_mysql_NULL;
-
-static PyObject *
-_escape_item(
-	PyObject *item,
-	PyObject *d)
-{
-	PyObject *quoted=NULL, *itemtype, *itemconv;
-	if (!(itemtype = PyObject_Type(item)))
-		goto error;
-	itemconv = PyObject_GetItem(d, itemtype);
-	Py_DECREF(itemtype);
-	if (!itemconv) {
-		PyErr_Clear();
-		itemconv = PyObject_GetItem(d,
-				 (PyObject *) &PyString_Type);
-	}
-	if (!itemconv) {
-		PyErr_SetString(PyExc_TypeError,
-				"no default type converter defined");
-		goto error;
-	}
-	quoted = PyObject_CallFunction(itemconv, "OO", item, d);
-	Py_DECREF(itemconv);
-error:
-	return quoted;
-}
-
-static char _mysql_escape__doc__[] =
-"escape(obj, dict) -- escape any special characters in object obj\n\
-using mapping dict to provide quoting functions for each type.\n\
-Returns a SQL literal string.";
-static PyObject *
-_mysql_escape(
-	PyObject *self,
-	PyObject *args)
-{
-	PyObject *o=NULL, *d=NULL;
-	if (!PyArg_ParseTuple(args, "O|O:escape", &o, &d))
-		return NULL;
-	if (d) {
-		if (!PyMapping_Check(d)) {
-			PyErr_SetString(PyExc_TypeError,
-					"argument 2 must be a mapping");
-			return NULL;
-		}
-		return _escape_item(o, d);
-	} else {
-		if (!self) {
-			PyErr_SetString(PyExc_TypeError,
-					"argument 2 must be a mapping");
-			return NULL;
-		}
-		return _escape_item(o,
-			   ((_mysql_ConnectionObject *) self)->converter);
-	}
-}
-
-static char _mysql_escape_sequence__doc__[] =
-"escape_sequence(seq, dict) -- escape any special characters in sequence\n\
-seq using mapping dict to provide quoting functions for each type.\n\
-Returns a tuple of escaped items.";
-static PyObject *
-_mysql_escape_sequence(
-	PyObject *self,
-	PyObject *args)
-{
-	PyObject *o=NULL, *d=NULL, *r=NULL, *item, *quoted; 
-	int i, n;
-	if (!PyArg_ParseTuple(args, "OO:escape_sequence", &o, &d))
-		goto error;
-	if (!PyMapping_Check(d)) {
-              PyErr_SetString(PyExc_TypeError,
-                              "argument 2 must be a mapping");
-              return NULL;
-        }
-	if ((n = PyObject_Length(o)) == -1) goto error;
-	if (!(r = PyTuple_New(n))) goto error;
-	for (i=0; i<n; i++) {
-		item = PySequence_GetItem(o, i);
-		if (!item) goto error;
-		quoted = _escape_item(item, d);
-		Py_DECREF(item);
-		if (!quoted) goto error;
-		PyTuple_SET_ITEM(r, i, quoted);
-	}
-	return r;
-  error:
-	Py_XDECREF(r);
-	return NULL;
-}
-
-static char _mysql_escape_dict__doc__[] =
-"escape_sequence(d, dict) -- escape any special characters in\n\
-dictionary d using mapping dict to provide quoting functions for each type.\n\
-Returns a dictionary of escaped items.";
-static PyObject *
-_mysql_escape_dict(
-	PyObject *self,
-	PyObject *args)
-{
-	PyObject *o=NULL, *d=NULL, *r=NULL, *item, *quoted, *pkey; 
-	Py_ssize_t ppos = 0;
-	if (!PyArg_ParseTuple(args, "O!O:escape_dict", &PyDict_Type, &o, &d))
-		goto error;
-	if (!PyMapping_Check(d)) {
-              PyErr_SetString(PyExc_TypeError,
-                              "argument 2 must be a mapping");
-              return NULL;
-        }
-	if (!(r = PyDict_New())) goto error;
-	while (PyDict_Next(o, &ppos, &pkey, &item)) {
-		quoted = _escape_item(item, d);
-		if (!quoted) goto error;
-		if (PyDict_SetItem(r, pkey, quoted)==-1) goto error;
-		Py_DECREF(quoted);
-	}
-	return r;
-  error:
-	Py_XDECREF(r);
-	return NULL;
-}
-				
-static char _mysql_ResultObject_describe__doc__[] =
-"Returns the sequence of 7-tuples required by the DB-API for\n\
-the Cursor.description attribute.\n\
-";
-
-static PyObject *
-_mysql_ResultObject_describe(
-	_mysql_ResultObject *self,
-	PyObject *args)
-{
-	PyObject *d;
-	MYSQL_FIELD *fields;
-	unsigned int i, n;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_result_connection(self);
-	n = mysql_num_fields(self->result);
-	fields = mysql_fetch_fields(self->result);
-	if (!(d = PyTuple_New(n))) return NULL;
-	for (i=0; i<n; i++) {
-		PyObject *t;
-		t = Py_BuildValue("(siiiiii)",
-				  fields[i].name,
-				  (long) fields[i].type,
-				  (long) fields[i].max_length,
-				  (long) fields[i].length,
-				  (long) fields[i].length,
-				  (long) fields[i].decimals,
-				  (long) !(IS_NOT_NULL(fields[i].flags)));
-		if (!t) goto error;
-		PyTuple_SET_ITEM(d, i, t);
-	}
-	return d;
-  error:
-	Py_XDECREF(d);
-	return NULL;
-}
-	
-static char _mysql_ResultObject_field_flags__doc__[] =
-"Returns a tuple of field flags, one for each column in the result.\n\
-" ;
-
-static PyObject *
-_mysql_ResultObject_field_flags(
-	_mysql_ResultObject *self,
-	PyObject *args)
-{
-	PyObject *d;
-	MYSQL_FIELD *fields;
-	unsigned int i, n;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_result_connection(self);
-	n = mysql_num_fields(self->result);
-	fields = mysql_fetch_fields(self->result);
-	if (!(d = PyTuple_New(n))) return NULL;
-	for (i=0; i<n; i++) {
-		PyObject *f;
-		if (!(f = PyInt_FromLong((long)fields[i].flags))) goto error;
-		PyTuple_SET_ITEM(d, i, f);
-	}
-	return d;
-  error:
-	Py_XDECREF(d);
-	return NULL;
-}
-
-static PyObject *
-_mysql_field_to_python(
-	PyObject *converter,
-	char *rowitem,
-	unsigned long length)
-{
-	PyObject *v;
-	if (rowitem) {
-		if (converter != Py_None)
-			v = PyObject_CallFunction(converter,
-						  "s#",
-						  rowitem,
-						  (int)length);
-		else
-			v = PyString_FromStringAndSize(rowitem,
-						       (int)length);
-		if (!v)
-			return NULL;
-	} else {
-		Py_INCREF(Py_None);
-		v = Py_None;
-	}
-	return v;
-}
-
-static PyObject *
-_mysql_row_to_tuple(
-	_mysql_ResultObject *self,
-	MYSQL_ROW row)
-{
-	unsigned int n, i;
-	unsigned long *length;
-	PyObject *r, *c;
-
-	n = mysql_num_fields(self->result);
-	if (!(r = PyTuple_New(n))) return NULL;
-	length = mysql_fetch_lengths(self->result);
-	for (i=0; i<n; i++) {
-		PyObject *v;
-		c = PyTuple_GET_ITEM(self->converter, i);
-		v = _mysql_field_to_python(c, row[i], length[i]);
-		if (!v) goto error;
-		PyTuple_SET_ITEM(r, i, v);
-	}
-	return r;
-  error:
-	Py_XDECREF(r);
-	return NULL;
-}
-
-static PyObject *
-_mysql_row_to_dict(
-	_mysql_ResultObject *self,
-	MYSQL_ROW row)
-{
-	unsigned int n, i;
-	unsigned long *length;
-	PyObject *r, *c;
-        MYSQL_FIELD *fields;
-
-	n = mysql_num_fields(self->result);
-	if (!(r = PyDict_New())) return NULL;
-	length = mysql_fetch_lengths(self->result);
-        fields = mysql_fetch_fields(self->result);
-	for (i=0; i<n; i++) {
-		PyObject *v;
-		c = PyTuple_GET_ITEM(self->converter, i);
-		v = _mysql_field_to_python(c, row[i], length[i]);
-		if (!v) goto error;
-		if (!PyMapping_HasKeyString(r, fields[i].name)) {
-			PyMapping_SetItemString(r, fields[i].name, v);
-		} else {
-			int len;
-			char buf[256];
-			strncpy(buf, fields[i].table, 256);
-			len = strlen(buf);
-			strncat(buf, ".", 256-len);
-			len = strlen(buf);
-			strncat(buf, fields[i].name, 256-len);
-			PyMapping_SetItemString(r, buf, v);
-		}
-		Py_DECREF(v);
-	}
-	return r;
-  error:
-	Py_XDECREF(r);
-	return NULL;
-}
-
-static PyObject *
-_mysql_row_to_dict_old(
-	_mysql_ResultObject *self,
-	MYSQL_ROW row)
-{
-	unsigned int n, i;
-	unsigned long *length;
-	PyObject *r, *c;
-        MYSQL_FIELD *fields;
-
-	n = mysql_num_fields(self->result);
-	if (!(r = PyDict_New())) return NULL;
-	length = mysql_fetch_lengths(self->result);
-        fields = mysql_fetch_fields(self->result);
-	for (i=0; i<n; i++) {
-		PyObject *v;
-		c = PyTuple_GET_ITEM(self->converter, i);
-		v = _mysql_field_to_python(c, row[i], length[i]);
-		if (!v) goto error;
-		{
-			int len=0;
-			char buf[256]="";
-			if (strlen(fields[i].table)) {
-				strncpy(buf, fields[i].table, 256);
-				len = strlen(buf);
-				strncat(buf, ".", 256-len);
-				len = strlen(buf);
-			}
-			strncat(buf, fields[i].name, 256-len);
-			PyMapping_SetItemString(r, buf, v);
-		}
-		Py_DECREF(v);
-	}
-	return r;
-  error:
-	Py_XDECREF(r);
-	return NULL;
-}
-
-typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW);
-
-int
-_mysql__fetch_row(
-	_mysql_ResultObject *self,
-	PyObject **r,
-	int skiprows,
-	int maxrows,
-	_PYFUNC *convert_row)
-{
-	unsigned int i;
-	MYSQL_ROW row;
-
-	for (i = skiprows; i<(skiprows+maxrows); i++) {
-		PyObject *v;
-		if (!self->use)
-			row = mysql_fetch_row(self->result);
-		else {
-			Py_BEGIN_ALLOW_THREADS;
-			row = mysql_fetch_row(self->result);
-			Py_END_ALLOW_THREADS;
-		}
-		if (!row && mysql_errno(&(((_mysql_ConnectionObject *)(self->conn))->connection))) {
-			_mysql_Exception((_mysql_ConnectionObject *)self->conn);
-			goto error;
-		}
-		if (!row) {
-			if (MyTuple_Resize(r, i, 0) == -1) goto error;
-			break;
-		}
-		v = convert_row(self, row);
-		if (!v) goto error;
-		PyTuple_SET_ITEM(*r, i, v);
-	}
-	return i-skiprows;
-  error:
-	return -1;
-}
-
-static char _mysql_ResultObject_fetch_row__doc__[] =
-"fetch_row([maxrows, how]) -- Fetches up to maxrows as a tuple.\n\
-The rows are formatted according to how:\n\
-\n\
-    0 -- tuples (default)\n\
-    1 -- dictionaries, key=column or table.column if duplicated\n\
-    2 -- dictionaries, key=table.column\n\
-";
-
-static PyObject *
-_mysql_ResultObject_fetch_row(
-	_mysql_ResultObject *self,
-	PyObject *args,
-	PyObject *kwargs)
-{
-	typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW);
-	static char *kwlist[] = { "maxrows", "how", NULL };
-	static _PYFUNC *row_converters[] =
-	{
-		_mysql_row_to_tuple,
-		_mysql_row_to_dict,
-		_mysql_row_to_dict_old
-	};
-	_PYFUNC *convert_row;
-	unsigned int maxrows=1, how=0, skiprows=0, rowsadded;
-	PyObject *r=NULL;
-
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:fetch_row", kwlist,
-					 &maxrows, &how))
-		return NULL;
-	check_result_connection(self);
-	if (how < 0 || how >= sizeof(row_converters)) {
-		PyErr_SetString(PyExc_ValueError, "how out of range");
-		return NULL;
-	}
-	convert_row = row_converters[how];
-	if (maxrows) {
-		if (!(r = PyTuple_New(maxrows))) goto error;
-		rowsadded = _mysql__fetch_row(self, &r, skiprows, maxrows, 
-				convert_row);
-		if (rowsadded == -1) goto error;
-	} else {
-		if (self->use) {
-			maxrows = 1000;
-			if (!(r = PyTuple_New(maxrows))) goto error;
-			while (1) {
-				rowsadded = _mysql__fetch_row(self, &r, skiprows,
-						maxrows, convert_row);
-				if (rowsadded == -1) goto error;
-				skiprows += rowsadded;
-				if (rowsadded < maxrows) break;
-				if (MyTuple_Resize(&r, skiprows+maxrows, 0) == -1)
-				        goto error;
-			}
-		} else {
-			/* XXX if overflow, maxrows<0? */
-			maxrows = (int) mysql_num_rows(self->result);
-			if (!(r = PyTuple_New(maxrows))) goto error;
-			rowsadded = _mysql__fetch_row(self, &r, 0,
-					maxrows, convert_row);
-			if (rowsadded == -1) goto error;
-		}
-	}
-	return r;
-  error:
-	Py_XDECREF(r);
-	return NULL;
-}
-
-#if MYSQL_VERSION_ID >= 32303
-
-static char _mysql_ConnectionObject_change_user__doc__[] =
-"Changes the user and causes the database specified by db to\n\
-become the default (current) database on the connection\n\
-specified by mysql. In subsequent queries, this database is\n\
-the default for table references that do not include an\n\
-explicit database specifier.\n\
-\n\
-This function was introduced in MySQL Version 3.23.3.\n\
-\n\
-Fails unless the connected user can be authenticated or if he\n\
-doesn't have permission to use the database. In this case the\n\
-user and database are not changed.\n\
-\n\
-The db parameter may be set to None if you don't want to have\n\
-a default database.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_change_user(
-	_mysql_ConnectionObject *self,
-	PyObject *args,
-	PyObject *kwargs)
-{
-	char *user, *pwd=NULL, *db=NULL;
-	int r;
-        static char *kwlist[] = { "user", "passwd", "db", NULL } ;
-
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ss:change_user",
-					 kwlist, &user, &pwd, &db))
-		return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-		r = mysql_change_user(&(self->connection), user, pwd, db);
-	Py_END_ALLOW_THREADS
-	if (r) 	return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-#endif
-
-static char _mysql_ConnectionObject_character_set_name__doc__[] =
-"Returns the default character set for the current connection.\n\
-Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_character_set_name(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	const char *s;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-#if MYSQL_VERSION_ID >= 32321
-	s = mysql_character_set_name(&(self->connection));
-#else
-	s = "latin1";
-#endif
-	return PyString_FromString(s);
-}
-
-#if MYSQL_VERSION_ID >= 50007
-static char _mysql_ConnectionObject_set_character_set__doc__[] =
-"Sets the default character set for the current connection.\n\
-Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_set_character_set(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	const char *s;
-	int err;
-	if (!PyArg_ParseTuple(args, "s", &s)) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	err = mysql_set_character_set(&(self->connection), s);
-	Py_END_ALLOW_THREADS
-	if (err) return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-#endif
-
-#if MYSQL_VERSION_ID >= 50010
-static char _mysql_ConnectionObject_get_character_set_info__doc__[] =
-"Returns a dict with information about the current character set:\n\
-\n\
-collation\n\
-    collation name\n\
-name\n\
-    character set name\n\
-comment\n\
-    comment or descriptive name\n\
-dir\n\
-    character set directory\n\
-mbminlen\n\
-    min. length for multibyte string\n\
-mbmaxlen\n\
-    max. length for multibyte string\n\
-\n\
-Not all keys may be present, particularly dir.\n\
-\n\
-Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_get_character_set_info(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	PyObject *result;
-	MY_CHARSET_INFO cs;
-	
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	mysql_get_character_set_info(&(self->connection), &cs);
-	if (!(result = PyDict_New())) return NULL;
-	if (cs.csname)
-		PyDict_SetItemString(result, "name", PyString_FromString(cs.csname));
-	if (cs.name)
-		PyDict_SetItemString(result, "collation", PyString_FromString(cs.name));
-	if (cs.comment)
-		PyDict_SetItemString(result, "comment", PyString_FromString(cs.comment));
-	if (cs.dir)
-		PyDict_SetItemString(result, "dir", PyString_FromString(cs.dir));
-	PyDict_SetItemString(result, "mbminlen", PyInt_FromLong(cs.mbminlen));
-	PyDict_SetItemString(result, "mbmaxlen", PyInt_FromLong(cs.mbmaxlen));
-	return result;
-}
-#endif
-
-static char _mysql_get_client_info__doc__[] =
-"get_client_info() -- Returns a string that represents\n\
-the client library version.";
-static PyObject *
-_mysql_get_client_info(
-	PyObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_server_init(NULL);
-	return PyString_FromString(mysql_get_client_info());
-}
-
-static char _mysql_ConnectionObject_get_host_info__doc__[] =
-"Returns a string that represents the MySQL client library\n\
-version. Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_get_host_info(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	return PyString_FromString(mysql_get_host_info(&(self->connection)));
-}
-
-static char _mysql_ConnectionObject_get_proto_info__doc__[] =
-"Returns an unsigned integer representing the protocol version\n\
-used by the current connection. Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_get_proto_info(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	return PyInt_FromLong((long)mysql_get_proto_info(&(self->connection)));
-}
-
-static char _mysql_ConnectionObject_get_server_info__doc__[] =
-"Returns a string that represents the server version number.\n\
-Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_get_server_info(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	return PyString_FromString(mysql_get_server_info(&(self->connection)));
-}
-
-static char _mysql_ConnectionObject_info__doc__[] =
-"Retrieves a string providing information about the most\n\
-recently executed query. Non-standard. Use messages or\n\
-Cursor.messages.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_info(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	const char *s;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	s = mysql_info(&(self->connection));
-	if (s) return PyString_FromString(s);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ConnectionObject_insert_id__doc__[] =
-"Returns the ID generated for an AUTO_INCREMENT column by the previous\n\
-query. Use this function after you have performed an INSERT query into a\n\
-table that contains an AUTO_INCREMENT field.\n\
-\n\
-Note that this returns 0 if the previous query does not\n\
-generate an AUTO_INCREMENT value. If you need to save the value for\n\
-later, be sure to call this immediately after the query\n\
-that generates the value.\n\
-\n\
-The ID is updated after INSERT and UPDATE statements that generate\n\
-an AUTO_INCREMENT value or that set a column value to\n\
-LAST_INSERT_ID(expr). See section 6.3.5.2 Miscellaneous Functions\n\
-in the MySQL documentation.\n\
-\n\
-Also note that the value of the SQL LAST_INSERT_ID() function always\n\
-contains the most recently generated AUTO_INCREMENT value, and is not\n\
-reset between queries because the value of that function is maintained\n\
-in the server.\n\
-" ;
-
-static PyObject *
-_mysql_ConnectionObject_insert_id(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	my_ulonglong r;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	r = mysql_insert_id(&(self->connection));
-	Py_END_ALLOW_THREADS
-	return PyLong_FromUnsignedLongLong(r);
-}
-
-static char _mysql_ConnectionObject_kill__doc__[] =
-"Asks the server to kill the thread specified by pid.\n\
-Non-standard.";
-
-static PyObject *
-_mysql_ConnectionObject_kill(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	unsigned long pid;
-	int r;
-	if (!PyArg_ParseTuple(args, "i:kill", &pid)) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	r = mysql_kill(&(self->connection), pid);
-	Py_END_ALLOW_THREADS
-	if (r) return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ConnectionObject_field_count__doc__[] =
-"Returns the number of columns for the most recent query on the\n\
-connection. Non-standard. Will probably give you bogus results\n\
-on most cursor classes. Use Cursor.rowcount.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_field_count(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-#if MYSQL_VERSION_ID < 32224
-	return PyInt_FromLong((long)mysql_num_fields(&(self->connection)));
-#else
-	return PyInt_FromLong((long)mysql_field_count(&(self->connection)));
-#endif
-}	
-
-static char _mysql_ResultObject_num_fields__doc__[] =
-"Returns the number of fields (column) in the result." ;
-
-static PyObject *
-_mysql_ResultObject_num_fields(
-	_mysql_ResultObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_result_connection(self);
-	return PyInt_FromLong((long)mysql_num_fields(self->result));
-}	
-
-static char _mysql_ResultObject_num_rows__doc__[] =
-"Returns the number of rows in the result set. Note that if\n\
-use=1, this will not return a valid value until the entire result\n\
-set has been read.\n\
-";
-
-static PyObject *
-_mysql_ResultObject_num_rows(
-	_mysql_ResultObject *self,
-	PyObject *args)
-{
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_result_connection(self);
-	return PyLong_FromUnsignedLongLong(mysql_num_rows(self->result));
-}	
-
-static char _mysql_ConnectionObject_ping__doc__[] =
-"Checks whether or not the connection to the server is\n\
-working. If it has gone down, an automatic reconnection is\n\
-attempted.\n\
-\n\
-This function can be used by clients that remain idle for a\n\
-long while, to check whether or not the server has closed the\n\
-connection and reconnect if necessary.\n\
-\n\
-New in 1.2.2: Accepts an optional reconnect parameter. If True,\n\
-then the client will attempt reconnection. Note that this setting\n\
-is persistent. By default, this is on in MySQL<5.0.3, and off\n\
-thereafter.\n\
-\n\
-Non-standard. You should assume that ping() performs an\n\
-implicit rollback; use only when starting a new transaction.\n\
-You have been warned.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_ping(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	int r, reconnect = -1;
-	if (!PyArg_ParseTuple(args, "|I", &reconnect)) return NULL;
-	check_connection(self);
-	if ( reconnect != -1 ) self->connection.reconnect = reconnect;
-	Py_BEGIN_ALLOW_THREADS
-	r = mysql_ping(&(self->connection));
-	Py_END_ALLOW_THREADS
-	if (r) 	return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ConnectionObject_query__doc__[] =
-"Execute a query. store_result() or use_result() will get the\n\
-result set, if any. Non-standard. Use cursor() to create a cursor,\n\
-then cursor.execute().\n\
-" ;
-
-static PyObject *
-_mysql_ConnectionObject_query(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	char *query;
-	int len, r;
-	if (!PyArg_ParseTuple(args, "s#:query", &query, &len)) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	r = mysql_real_query(&(self->connection), query, len);
-	Py_END_ALLOW_THREADS
-	if (r) return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-
-static char _mysql_ConnectionObject_select_db__doc__[] =
-"Causes the database specified by db to become the default\n\
-(current) database on the connection specified by mysql. In subsequent\n\
-queries, this database is the default for table references that do not\n\
-include an explicit database specifier.\n\
-\n\
-Fails unless the connected user can be authenticated as having\n\
-permission to use the database.\n\
-\n\
-Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_select_db(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	char *db;
-	int r;
-	if (!PyArg_ParseTuple(args, "s:select_db", &db)) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	r = mysql_select_db(&(self->connection), db);
-	Py_END_ALLOW_THREADS
-	if (r) 	return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ConnectionObject_shutdown__doc__[] =
-"Asks the database server to shut down. The connected user must\n\
-have shutdown privileges. Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_shutdown(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	int r;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	r = mysql_shutdown(&(self->connection)
-#if MYSQL_VERSION_ID >= 40103
-		, SHUTDOWN_DEFAULT
-#endif
-		);
-	Py_END_ALLOW_THREADS
-	if (r) return _mysql_Exception(self);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ConnectionObject_stat__doc__[] =
-"Returns a character string containing information similar to\n\
-that provided by the mysqladmin status command. This includes\n\
-uptime in seconds and the number of running threads,\n\
-questions, reloads, and open tables. Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_stat(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	const char *s;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	s = mysql_stat(&(self->connection));
-	Py_END_ALLOW_THREADS
-	if (!s) return _mysql_Exception(self);
-	return PyString_FromString(s);
-}
-
-static char _mysql_ConnectionObject_store_result__doc__[] =
-"Returns a result object acquired by mysql_store_result\n\
-(results stored in the client). If no results are available,\n\
-None is returned. Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_store_result(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	PyObject *arglist=NULL, *kwarglist=NULL, *result=NULL;
-	_mysql_ResultObject *r=NULL;
-
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	arglist = Py_BuildValue("(OiO)", self, 0, self->converter);
-	if (!arglist) goto error;
-	kwarglist = PyDict_New();
-	if (!kwarglist) goto error;
-	r = MyAlloc(_mysql_ResultObject, _mysql_ResultObject_Type);
-	if (!r) goto error;
-	if (_mysql_ResultObject_Initialize(r, arglist, kwarglist))
-		goto error;
-	result = (PyObject *) r;
-	if (!(r->result)) {
-		Py_DECREF(result);
-		Py_INCREF(Py_None);
-		result = Py_None;
-	}
-  error:
-	Py_XDECREF(arglist);
-	Py_XDECREF(kwarglist);
-	return result;
-}
-
-static char _mysql_ConnectionObject_thread_id__doc__[] =
-"Returns the thread ID of the current connection. This value\n\
-can be used as an argument to kill() to kill the thread.\n\
-\n\
-If the connection is lost and you reconnect with ping(), the\n\
-thread ID will change. This means you should not get the\n\
-thread ID and store it for later. You should get it when you\n\
-need it.\n\
-\n\
-Non-standard.";
-
-static PyObject *
-_mysql_ConnectionObject_thread_id(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	unsigned long pid;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	Py_BEGIN_ALLOW_THREADS
-	pid = mysql_thread_id(&(self->connection));
-	Py_END_ALLOW_THREADS
-	return PyInt_FromLong((long)pid);
-}
-
-static char _mysql_ConnectionObject_use_result__doc__[] =
-"Returns a result object acquired by mysql_use_result\n\
-(results stored in the server). If no results are available,\n\
-None is returned. Non-standard.\n\
-";
-
-static PyObject *
-_mysql_ConnectionObject_use_result(
-	_mysql_ConnectionObject *self,
-	PyObject *args)
-{
-	PyObject *arglist=NULL, *kwarglist=NULL, *result=NULL;
-	_mysql_ResultObject *r=NULL;
-
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_connection(self);
-	arglist = Py_BuildValue("(OiO)", self, 1, self->converter);
-	if (!arglist) return NULL;
-	kwarglist = PyDict_New();
-	if (!kwarglist) goto error;
-	r = MyAlloc(_mysql_ResultObject, _mysql_ResultObject_Type);
-	if (!r) goto error;
-	result = (PyObject *) r;
-	if (_mysql_ResultObject_Initialize(r, arglist, kwarglist))
-		goto error;
-	if (!(r->result)) {
-		Py_DECREF(result);
-		Py_INCREF(Py_None);
-		result = Py_None;
-	}
-  error:
-	Py_DECREF(arglist);
-	Py_XDECREF(kwarglist);
-	return result;
-}
-
-static void
-_mysql_ConnectionObject_dealloc(
-	_mysql_ConnectionObject *self)
-{
-	PyObject *o;
-
-	PyObject_GC_UnTrack(self);
-	if (self->open) {
-		o = _mysql_ConnectionObject_close(self, NULL);
-		Py_XDECREF(o);
-	}
-	MyFree(self);
-}
-
-static PyObject *
-_mysql_ConnectionObject_repr(
-	_mysql_ConnectionObject *self)
-{
-	char buf[300];
-	if (self->open)
-		sprintf(buf, "<_mysql.connection open to '%.256s' at %lx>",
-			self->connection.host,
-			(long)self);
-	else
-		sprintf(buf, "<_mysql.connection closed at %lx>",
-			(long)self);
-	return PyString_FromString(buf);
-}
-
-static char _mysql_ResultObject_data_seek__doc__[] =
-"data_seek(n) -- seek to row n of result set";
-static PyObject *
-_mysql_ResultObject_data_seek(
-     _mysql_ResultObject *self,
-     PyObject *args)
-{
-	unsigned int row;
-	if (!PyArg_ParseTuple(args, "i:data_seek", &row)) return NULL;
-	check_result_connection(self);
-	mysql_data_seek(self->result, row);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ResultObject_row_seek__doc__[] =
-"row_seek(n) -- seek by offset n rows of result set";
-static PyObject *
-_mysql_ResultObject_row_seek(
-     _mysql_ResultObject *self,
-     PyObject *args)
-{
-	int offset;
-        MYSQL_ROW_OFFSET r;
-	if (!PyArg_ParseTuple(args, "i:row_seek", &offset)) return NULL;
-	check_result_connection(self);
-	if (self->use) {
-		PyErr_SetString(_mysql_ProgrammingError,
-				"cannot be used with connection.use_result()");
-		return NULL;
-	}
-	r = mysql_row_tell(self->result);
-	mysql_row_seek(self->result, r+offset);
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static char _mysql_ResultObject_row_tell__doc__[] =
-"row_tell() -- return the current row number of the result set.";
-static PyObject *
-_mysql_ResultObject_row_tell(
-	_mysql_ResultObject *self,
-	PyObject *args)
-{
-	MYSQL_ROW_OFFSET r;
-	if (!PyArg_ParseTuple(args, "")) return NULL;
-	check_result_connection(self);
-	if (self->use) {
-		PyErr_SetString(_mysql_ProgrammingError,
-				"cannot be used with connection.use_result()");
-		return NULL;
-	}
-	r = mysql_row_tell(self->result);
-	return PyInt_FromLong(r-self->result->data->data);
-}
-
-static void
-_mysql_ResultObject_dealloc(
-	_mysql_ResultObject *self)
-{
-	PyObject_GC_UnTrack((PyObject *)self);
-	mysql_free_result(self->result);
-	_mysql_ResultObject_clear(self);
-	MyFree(self);
-}
-
-static PyObject *
-_mysql_ResultObject_repr(
-	_mysql_ResultObject *self)
-{
-	char buf[300];
-	sprintf(buf, "<_mysql.result object at %lx>",
-		(long)self);
-	return PyString_FromString(buf);
-}
-
-static PyMethodDef _mysql_ConnectionObject_methods[] = {
-	{
-		"affected_rows",
-		(PyCFunction)_mysql_ConnectionObject_affected_rows,
-		METH_VARARGS,
-		_mysql_ConnectionObject_affected_rows__doc__
-	},
-	{
-		"autocommit",
-		(PyCFunction)_mysql_ConnectionObject_autocommit,
-		METH_VARARGS,
-		_mysql_ConnectionObject_autocommit__doc__
-	},
-	{
-		"commit",
-		(PyCFunction)_mysql_ConnectionObject_commit,
-		METH_VARARGS,
-		_mysql_ConnectionObject_commit__doc__
-	},
-	{
-		"rollback",
-		(PyCFunction)_mysql_ConnectionObject_rollback,
-		METH_VARARGS,
-		_mysql_ConnectionObject_rollback__doc__
-	},
-	{
-		"next_result",
-		(PyCFunction)_mysql_ConnectionObject_next_result,
-		METH_VARARGS,
-		_mysql_ConnectionObject_next_result__doc__
-	},
-#if MYSQL_VERSION_ID >= 40100
-	{
-		"set_server_option",
-		(PyCFunction)_mysql_ConnectionObject_set_server_option,
-		METH_VARARGS,
-		_mysql_ConnectionObject_set_server_option__doc__
-	},
-	{
-		"sqlstate",
-		(PyCFunction)_mysql_ConnectionObject_sqlstate,
-		METH_VARARGS,
-		_mysql_ConnectionObject_sqlstate__doc__
-	},
-	{
-		"warning_count",
-		(PyCFunction)_mysql_ConnectionObject_warning_count,
-		METH_VARARGS,
-		_mysql_ConnectionObject_warning_count__doc__
-	},
-#endif
-#if MYSQL_VERSION_ID >= 32303
-	{
-		"change_user",
-		(PyCFunction)_mysql_ConnectionObject_change_user,
-		METH_VARARGS | METH_KEYWORDS,
-		_mysql_ConnectionObject_change_user__doc__
-	},
-#endif
-	{
-		"character_set_name",
-		(PyCFunction)_mysql_ConnectionObject_character_set_name,
-		METH_VARARGS,
-		_mysql_ConnectionObject_character_set_name__doc__
-	},
-#if MYSQL_VERSION_ID >= 50007
-	{
-		"set_character_set",
-		(PyCFunction)_mysql_ConnectionObject_set_character_set,
-		METH_VARARGS,
-		_mysql_ConnectionObject_set_character_set__doc__
-	},
-#endif
-#if MYSQL_VERSION_ID >= 50010
-	{
-		"get_character_set_info",
-		(PyCFunction)_mysql_ConnectionObject_get_character_set_info,
-		METH_VARARGS,
-		_mysql_ConnectionObject_get_character_set_info__doc__
-	},
-#endif
-	{
-		"close",
-		(PyCFunction)_mysql_ConnectionObject_close,
-		METH_VARARGS,
-		_mysql_ConnectionObject_close__doc__
-	},
-	{
-		"dump_debug_info",
-		(PyCFunction)_mysql_ConnectionObject_dump_debug_info,
-		METH_VARARGS,
-		_mysql_ConnectionObject_dump_debug_info__doc__
-	},
-	{
-		"escape",
-		(PyCFunction)_mysql_escape,
-		METH_VARARGS,
-		_mysql_escape__doc__
-	},
-	{
-		"escape_string",
-		(PyCFunction)_mysql_escape_string,
-		METH_VARARGS,
-		_mysql_escape_string__doc__
-	},
-	{
-		"error",
-		(PyCFunction)_mysql_ConnectionObject_error,
-		METH_VARARGS,
-		_mysql_ConnectionObject_error__doc__
-	},
-	{
-		"errno",
-		(PyCFunction)_mysql_ConnectionObject_errno,
-		METH_VARARGS,
-		_mysql_ConnectionObject_errno__doc__
-	},
-	{
-		"field_count",
-		(PyCFunction)_mysql_ConnectionObject_field_count,
-		METH_VARARGS,
-		_mysql_ConnectionObject_field_count__doc__
-	}, 
-	{
-		"get_host_info",
-		(PyCFunction)_mysql_ConnectionObject_get_host_info,
-		METH_VARARGS,
-		_mysql_ConnectionObject_get_host_info__doc__
-	},
-	{
-		"get_proto_info",
-		(PyCFunction)_mysql_ConnectionObject_get_proto_info,
-		METH_VARARGS,
-		_mysql_ConnectionObject_get_proto_info__doc__
-	},
-	{
-		"get_server_info",
-		(PyCFunction)_mysql_ConnectionObject_get_server_info,
-		METH_VARARGS,
-		_mysql_ConnectionObject_get_server_info__doc__
-	},
-	{
-		"info",
-		(PyCFunction)_mysql_ConnectionObject_info,
-		METH_VARARGS,
-		_mysql_ConnectionObject_info__doc__
-	},
-	{
-		"insert_id",
-		(PyCFunction)_mysql_ConnectionObject_insert_id,
-		METH_VARARGS,
-		_mysql_ConnectionObject_insert_id__doc__
-	},
-	{
-		"kill",
-		(PyCFunction)_mysql_ConnectionObject_kill,
-		METH_VARARGS,
-		_mysql_ConnectionObject_kill__doc__
-	},
-	{
-		"ping",
-		(PyCFunction)_mysql_ConnectionObject_ping,
-		METH_VARARGS,
-		_mysql_ConnectionObject_ping__doc__
-	},
-	{
-		"query",
-		(PyCFunction)_mysql_ConnectionObject_query,
-		METH_VARARGS,
-		_mysql_ConnectionObject_query__doc__
-	},
-	{
-		"select_db",
-		(PyCFunction)_mysql_ConnectionObject_select_db,
-		METH_VARARGS,
-		_mysql_ConnectionObject_select_db__doc__
-	},
-	{
-		"shutdown",
-		(PyCFunction)_mysql_ConnectionObject_shutdown,
-		METH_VARARGS,
-		_mysql_ConnectionObject_shutdown__doc__
-	},
-	{
-		"stat",
-		(PyCFunction)_mysql_ConnectionObject_stat,
-		METH_VARARGS,
-		_mysql_ConnectionObject_stat__doc__
-	},
-	{
-		"store_result",
-		(PyCFunction)_mysql_ConnectionObject_store_result,
-		METH_VARARGS,
-		_mysql_ConnectionObject_store_result__doc__
-	},
-	{
-		"string_literal",
-		(PyCFunction)_mysql_string_literal,
-		METH_VARARGS,
-		_mysql_string_literal__doc__},
-	{
-		"thread_id",
-		(PyCFunction)_mysql_ConnectionObject_thread_id,
-		METH_VARARGS,
-		_mysql_ConnectionObject_thread_id__doc__
-	},
-	{
-		"use_result",
-		(PyCFunction)_mysql_ConnectionObject_use_result,
-		METH_VARARGS,
-		_mysql_ConnectionObject_use_result__doc__
-	},
-	{NULL,              NULL} /* sentinel */
-};
-
-static MyMemberlist(_mysql_ConnectionObject_memberlist)[] = {
-	MyMember(
-		"open",
-		T_INT,
-		offsetof(_mysql_ConnectionObject,open),
-		RO,
-		"True if connection is open"
-		),
-	MyMember(
-		"converter",
-		T_OBJECT,
-		offsetof(_mysql_ConnectionObject,converter),
-		0,
-		"Type conversion mapping"
-		),
-	MyMember(
-		"server_capabilities",
-		T_UINT,
-		offsetof(_mysql_ConnectionObject,connection.server_capabilities),
-		RO,
-		"Capabilites of server; consult MySQLdb.constants.CLIENT"
-		),
-	MyMember(
-		 "port",
-		 T_UINT,
-		 offsetof(_mysql_ConnectionObject,connection.port),
-		 RO,
-		 "TCP/IP port of the server connection"
-		 ),
-	MyMember(
-		 "client_flag",
-		 T_UINT,
-		 RO,
-		 offsetof(_mysql_ConnectionObject,connection.client_flag),
-		 "Client flags; refer to MySQLdb.constants.CLIENT"
-		 ),
-	{NULL} /* Sentinel */
-};
-
-static PyMethodDef _mysql_ResultObject_methods[] = {
-	{
-		"data_seek",
-		(PyCFunction)_mysql_ResultObject_data_seek,
-		METH_VARARGS,
-		_mysql_ResultObject_data_seek__doc__
-	},
-	{
-		"row_seek",
-		(PyCFunction)_mysql_ResultObject_row_seek,
-		METH_VARARGS,
-		_mysql_ResultObject_row_seek__doc__
-	},
-	{
-		"row_tell",
-		(PyCFunction)_mysql_ResultObject_row_tell,
-		METH_VARARGS,
-		_mysql_ResultObject_row_tell__doc__
-	},
-	{
-		"describe",
-		(PyCFunction)_mysql_ResultObject_describe,
-		METH_VARARGS,
-		_mysql_ResultObject_describe__doc__
-	},
-	{
-		"fetch_row",
-		(PyCFunction)_mysql_ResultObject_fetch_row,
-		METH_VARARGS | METH_KEYWORDS,
-		_mysql_ResultObject_fetch_row__doc__
-	},
-	{
-		"field_flags",
-		(PyCFunction)_mysql_ResultObject_field_flags,
-		METH_VARARGS,
-		_mysql_ResultObject_field_flags__doc__
-	},
-	{
-		"num_fields",
-		(PyCFunction)_mysql_ResultObject_num_fields,
-		METH_VARARGS,
-		_mysql_ResultObject_num_fields__doc__
-	},
-	{
-		"num_rows",
-		(PyCFunction)_mysql_ResultObject_num_rows,
-		METH_VARARGS,
-		_mysql_ResultObject_num_rows__doc__
-	},
-	{NULL,              NULL} /* sentinel */
-};
-
-static MyMemberlist(_mysql_ResultObject_memberlist)[] = {
-	MyMember(
-		"converter",
-		T_OBJECT,
-		offsetof(_mysql_ResultObject,converter),
-		RO,
-		"Type conversion mapping"
-		),
-	{NULL} /* Sentinel */
-};
-                                                                        
-static PyObject *
-_mysql_ConnectionObject_getattr(
-	_mysql_ConnectionObject *self,
-	char *name)
-{
-	PyObject *res;
-
-	res = Py_FindMethod(_mysql_ConnectionObject_methods, (PyObject *)self, name);
-	if (res != NULL)
-		return res;
-	PyErr_Clear();
-	if (strcmp(name, "closed") == 0)
-		return PyInt_FromLong((long)!(self->open));
-#if PY_VERSION_HEX < 0x02020000
-	return PyMember_Get((char *)self, _mysql_ConnectionObject_memberlist, name);
-#else
-	{
-		MyMemberlist(*l);
-		for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++) {
-			if (strcmp(l->name, name) == 0)
-				return PyMember_GetOne((char *)self, l);
-		}
-		PyErr_SetString(PyExc_AttributeError, name);
-		return NULL;
-	}
-#endif
-}
-
-static PyObject *
-_mysql_ResultObject_getattr(
-	_mysql_ResultObject *self,
-	char *name)
-{
-	PyObject *res;
-
-	res = Py_FindMethod(_mysql_ResultObject_methods, (PyObject *)self, name);
-	if (res != NULL)
-		return res;
-	PyErr_Clear();
-#if PY_VERSION_HEX < 0x02020000
-	return PyMember_Get((char *)self, _mysql_ResultObject_memberlist, name);
-#else
-	{
-		MyMemberlist(*l);
-		for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++) {
-			if (strcmp(l->name, name) == 0)
-				return PyMember_GetOne((char *)self, l);
-		}
-		PyErr_SetString(PyExc_AttributeError, name);
-		return NULL;
-	}
-#endif
-}
-
-static int
-_mysql_ConnectionObject_setattr(
-	_mysql_ConnectionObject *self,
-	char *name,
-	PyObject *v)
-{
-	if (v == NULL) {
-		PyErr_SetString(PyExc_AttributeError,
-				"can't delete connection attributes");
-		return -1;
-	}
-#if PY_VERSION_HEX < 0x02020000
-	return PyMember_Set((char *)self, _mysql_ConnectionObject_memberlist, name, v);
-#else
-        {
-		MyMemberlist(*l);
-		for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++)
-			if (strcmp(l->name, name) == 0)
-				return PyMember_SetOne((char *)self, l, v);
-	}
-        PyErr_SetString(PyExc_AttributeError, name);
-        return -1;
-#endif
-}
-
-static int
-_mysql_ResultObject_setattr(
-	_mysql_ResultObject *self,
-	char *name,
-	PyObject *v)
-{
-	if (v == NULL) {
-		PyErr_SetString(PyExc_AttributeError,
-				"can't delete connection attributes");
-		return -1;
-	}
-#if PY_VERSION_HEX < 0x02020000
-	return PyMember_Set((char *)self, _mysql_ResultObject_memberlist, name, v);
-#else
-        {
-		MyMemberlist(*l);
-		for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++)
-			if (strcmp(l->name, name) == 0)
-				return PyMember_SetOne((char *)self, l, v);
-	}
-        PyErr_SetString(PyExc_AttributeError, name);
-        return -1;
-#endif
-}
-
-PyTypeObject _mysql_ConnectionObject_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
-	"_mysql.connection", /* (char *)tp_name For printing */
-	sizeof(_mysql_ConnectionObject),
-	0,
-	(destructor)_mysql_ConnectionObject_dealloc, /* tp_dealloc */
-	0, /*tp_print*/
-	(getattrfunc)_mysql_ConnectionObject_getattr, /* tp_getattr */
-	(setattrfunc)_mysql_ConnectionObject_setattr, /* tp_setattr */
-	0, /*tp_compare*/
-	(reprfunc)_mysql_ConnectionObject_repr, /* tp_repr */
-	
-	/* Method suites for standard classes */
-	
-	0, /* (PyNumberMethods *) tp_as_number */
-	0, /* (PySequenceMethods *) tp_as_sequence */
-	0, /* (PyMappingMethods *) tp_as_mapping */
-	
-	/* More standard operations (here for binary compatibility) */
-	
-	0, /* (hashfunc) tp_hash */
-	0, /* (ternaryfunc) tp_call */
-	0, /* (reprfunc) tp_str */
-	0, /* (getattrofunc) tp_getattro */
-	0, /* (setattrofunc) tp_setattro */
-	
-	/* Functions to access object as input/output buffer */
-	0, /* (PyBufferProcs *) tp_as_buffer */
-	
-	/* Flags to define presence of optional/expanded features */
-#if PY_VERSION_HEX < 0x02020000
-	Py_TPFLAGS_DEFAULT, /* (long) tp_flags */
-#else
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
-#endif
-	_mysql_connect__doc__, /* (char *) tp_doc Documentation string */
-#if PY_VERSION_HEX >= 0x02000000	
-	/* Assigned meaning in release 2.0 */
-#if PY_VERSION_HEX >= 0x02020000
-	/* call function for all accessible objects */
-	(traverseproc) _mysql_ConnectionObject_traverse, /* tp_traverse */
-	
-	/* delete references to contained objects */
-	(inquiry) _mysql_ConnectionObject_clear, /* tp_clear */
-#else
-	/* not supporting pre-2.2 GC */
-	0,
-	0,
-#endif
-#if PY_VERSION_HEX >= 0x02010000	
-	/* Assigned meaning in release 2.1 */
-	/* rich comparisons */
-	0, /* (richcmpfunc) tp_richcompare */
-	
-	/* weak reference enabler */
-	0, /* (long) tp_weaklistoffset */
-#if PY_VERSION_HEX >= 0x02020000
-	/* Added in release 2.2 */
-	/* Iterators */
-	0, /* (getiterfunc) tp_iter */
-	0, /* (iternextfunc) tp_iternext */
-	
-	/* Attribute descriptor and subclassing stuff */
-	(struct PyMethodDef *)_mysql_ConnectionObject_methods, /* tp_methods */
-	(MyMemberlist(*))_mysql_ConnectionObject_memberlist, /* tp_members */
-	0, /* (struct getsetlist *) tp_getset; */
-	0, /* (struct _typeobject *) tp_base; */
-	0, /* (PyObject *) tp_dict */
-	0, /* (descrgetfunc) tp_descr_get */
-	0, /* (descrsetfunc) tp_descr_set */
-	0, /* (long) tp_dictoffset */
-	(initproc)_mysql_ConnectionObject_Initialize, /* tp_init */
-	NULL, /* tp_alloc */
-	NULL, /* tp_new */
-	NULL, /* tp_free Low-level free-memory routine */ 
-	0, /* (PyObject *) tp_bases */
-	0, /* (PyObject *) tp_mro method resolution order */
-	0, /* (PyObject *) tp_defined */
-#endif /* python 2.2 */
-#endif /* python 2.1 */
-#endif /* python 2.0 */
-} ;
-
-PyTypeObject _mysql_ResultObject_Type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
-	"_mysql.result",
-	sizeof(_mysql_ResultObject),
-	0,
-	(destructor)_mysql_ResultObject_dealloc, /* tp_dealloc */
-	0, /*tp_print*/
-	(getattrfunc)_mysql_ResultObject_getattr, /* tp_getattr */
-	(setattrfunc)_mysql_ResultObject_setattr, /* tp_setattr */
-	0, /*tp_compare*/
-	(reprfunc)_mysql_ResultObject_repr, /* tp_repr */
-	
-	/* Method suites for standard classes */
-	
-	0, /* (PyNumberMethods *) tp_as_number */
-	0, /* (PySequenceMethods *) tp_as_sequence */
-	0, /* (PyMappingMethods *) tp_as_mapping */
-	
-	/* More standard operations (here for binary compatibility) */
-	
-	0, /* (hashfunc) tp_hash */
-	0, /* (ternaryfunc) tp_call */
-	0, /* (reprfunc) tp_str */
-	0, /* (getattrofunc) tp_getattro */
-	0, /* (setattrofunc) tp_setattro */
-	
-	/* Functions to access object as input/output buffer */
-	0, /* (PyBufferProcs *) tp_as_buffer */
-	
-	/* Flags to define presence of optional/expanded features */
-#if PY_VERSION_HEX < 0x02020000
-	Py_TPFLAGS_DEFAULT, /* (long) tp_flags */
-#else
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
-#endif
-	
-	_mysql_ResultObject__doc__, /* (char *) tp_doc Documentation string */
-#if PY_VERSION_HEX >= 0x02000000	
-	/* Assigned meaning in release 2.0 */
-#if PY_VERSION_HEX >= 0x02020000
-	/* call function for all accessible objects */
-	(traverseproc) _mysql_ResultObject_traverse, /* tp_traverse */
-	
-	/* delete references to contained objects */
-	(inquiry) _mysql_ResultObject_clear, /* tp_clear */
-#else
-	/* not supporting pre-2.2 GC */
-	0,
-	0,
-#endif
-#if PY_VERSION_HEX >= 0x02010000	
-	/* Assigned meaning in release 2.1 */
-	/* rich comparisons */
-	0, /* (richcmpfunc) tp_richcompare */
-	
-	/* weak reference enabler */
-	0, /* (long) tp_weaklistoffset */
-#if PY_VERSION_HEX >= 0x02020000
-	/* Added in release 2.2 */
-	/* Iterators */
-	0, /* (getiterfunc) tp_iter */
-	0, /* (iternextfunc) tp_iternext */
-	
-	/* Attribute descriptor and subclassing stuff */
-	(struct PyMethodDef *) _mysql_ResultObject_methods, /* tp_methods */
-	(MyMemberlist(*)) _mysql_ResultObject_memberlist, /*tp_members */
-	0, /* (struct getsetlist *) tp_getset; */
-	0, /* (struct _typeobject *) tp_base; */
-	0, /* (PyObject *) tp_dict */
-	0, /* (descrgetfunc) tp_descr_get */
-	0, /* (descrsetfunc) tp_descr_set */
-	0, /* (long) tp_dictoffset */
-	(initproc)_mysql_ResultObject_Initialize, /* tp_init */
-	NULL, /* tp_alloc */
-	NULL, /* tp_new */
-	NULL, /* tp_free Low-level free-memory routine */
-	0, /* (PyObject *) tp_bases */
-	0, /* (PyObject *) tp_mro method resolution order */
-	0, /* (PyObject *) tp_defined */
-#endif /* python 2.2 */
-#endif /* python 2.1 */
-#endif /* python 2.0 */
-};
-
-static PyMethodDef
-_mysql_methods[] = {
-	{ 
-		"connect",
-		(PyCFunction)_mysql_connect,
-		METH_VARARGS | METH_KEYWORDS,
-		_mysql_connect__doc__
-	},
-	{ 
-		"debug",
-		(PyCFunction)_mysql_debug, 
-		METH_VARARGS,
-		_mysql_debug__doc__
-	},
-	{
-		"escape", 
-		(PyCFunction)_mysql_escape, 
-		METH_VARARGS,
-		_mysql_escape__doc__
-	},
-	{
-		"escape_sequence",
-		(PyCFunction)_mysql_escape_sequence,
-		METH_VARARGS,
-		_mysql_escape_sequence__doc__
-	},
-	{
-		"escape_dict",
-		(PyCFunction)_mysql_escape_dict,
-		METH_VARARGS,
-		_mysql_escape_dict__doc__
-	},
-	{ 
-		"escape_string",
-		(PyCFunction)_mysql_escape_string,
-		METH_VARARGS,
-		_mysql_escape_string__doc__
-	},
-	{ 
-		"string_literal",
-		(PyCFunction)_mysql_string_literal,
-		METH_VARARGS,
-		_mysql_string_literal__doc__
-	},
-	{
-		"get_client_info",
-		(PyCFunction)_mysql_get_client_info,
-		METH_VARARGS,
-		_mysql_get_client_info__doc__
-	},
-#if MYSQL_VERSION_ID >= 32314
-	{
-		"thread_safe",
-		(PyCFunction)_mysql_thread_safe,
-		METH_VARARGS,
-		_mysql_thread_safe__doc__
-	},
-#endif
-	{
-		"server_init",
-		(PyCFunction)_mysql_server_init,
-		METH_VARARGS | METH_KEYWORDS,
-		_mysql_server_init__doc__
-	},
-	{
-		"server_end",
-		(PyCFunction)_mysql_server_end,
-		METH_VARARGS,
-		_mysql_server_end__doc__
-	},
-	{NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-_mysql_NewException(
-	PyObject *dict,
-	PyObject *edict,
-	char *name)
-{
-	PyObject *e;
-
-	if (!(e = PyDict_GetItemString(edict, name)))
-		return NULL;
-	if (PyDict_SetItemString(dict, name, e)) return NULL;
-	return e;
-}
-
-#define QUOTE(X) _QUOTE(X)
-#define _QUOTE(X) #X
-
-static char _mysql___doc__[] =
-"an adaptation of the MySQL C API (mostly)\n\
-\n\
-You probably are better off using MySQLdb instead of using this\n\
-module directly.\n\
-\n\
-In general, renaming goes from mysql_* to _mysql.*. _mysql.connect()\n\
-returns a connection object (MYSQL). Functions which expect MYSQL * as\n\
-an argument are now methods of the connection object. A number of things\n\
-return result objects (MYSQL_RES). Functions which expect MYSQL_RES * as\n\
-an argument are now methods of the result object. Deprecated functions\n\
-(as of 3.23) are NOT implemented.\n\
-";
-
-DL_EXPORT(void)
-init_mysql(void)
-{
-	PyObject *dict, *module, *emod, *edict;
-	module = Py_InitModule4("_mysql", _mysql_methods, _mysql___doc__,
-				(PyObject *)NULL, PYTHON_API_VERSION);
-	if (!module) return; /* this really should never happen */
-	_mysql_ConnectionObject_Type.ob_type = &PyType_Type;
-	_mysql_ResultObject_Type.ob_type = &PyType_Type;
-#if PY_VERSION_HEX >= 0x02020000
-	_mysql_ConnectionObject_Type.tp_alloc = PyType_GenericAlloc;
-	_mysql_ConnectionObject_Type.tp_new = PyType_GenericNew;
-	_mysql_ConnectionObject_Type.tp_free = _PyObject_GC_Del; 
-	_mysql_ResultObject_Type.tp_alloc = PyType_GenericAlloc;
-	_mysql_ResultObject_Type.tp_new = PyType_GenericNew;
-	_mysql_ResultObject_Type.tp_free = _PyObject_GC_Del;
-#endif
-
-	if (!(dict = PyModule_GetDict(module))) goto error;
-	if (PyDict_SetItemString(dict, "version_info",
-			       PyRun_String(QUOTE(version_info), Py_eval_input,
-				       dict, dict)))
-		goto error;
-	if (PyDict_SetItemString(dict, "__version__",
-			       PyString_FromString(QUOTE(__version__))))
-		goto error;
-	if (PyDict_SetItemString(dict, "connection",
-			       (PyObject *)&_mysql_ConnectionObject_Type))
-		goto error;
-	Py_INCREF(&_mysql_ConnectionObject_Type);
-	if (PyDict_SetItemString(dict, "result",
-			       (PyObject *)&_mysql_ResultObject_Type))
-		goto error;	
-	Py_INCREF(&_mysql_ResultObject_Type);
-	if (!(emod = PyImport_ImportModule("_mysql_exceptions")))
-		goto error;
-	if (!(edict = PyModule_GetDict(emod))) goto error;
-	if (!(_mysql_MySQLError =
-	      _mysql_NewException(dict, edict, "MySQLError")))
-		goto error;
-	if (!(_mysql_Warning =
-	      _mysql_NewException(dict, edict, "Warning")))
-		goto error;
-	if (!(_mysql_Error =
-	      _mysql_NewException(dict, edict, "Error")))
-		goto error;
-	if (!(_mysql_InterfaceError =
-	      _mysql_NewException(dict, edict, "InterfaceError")))
-		goto error;
-	if (!(_mysql_DatabaseError =
-	      _mysql_NewException(dict, edict, "DatabaseError")))
-		goto error;
-	if (!(_mysql_DataError =
-	      _mysql_NewException(dict, edict, "DataError")))
-		goto error;
-	if (!(_mysql_OperationalError =
-	      _mysql_NewException(dict, edict, "OperationalError")))
-		goto error;
-	if (!(_mysql_IntegrityError =
-	      _mysql_NewException(dict, edict, "IntegrityError")))
-		goto error;
-	if (!(_mysql_InternalError =
-	      _mysql_NewException(dict, edict, "InternalError")))
-		goto error;
-	if (!(_mysql_ProgrammingError =
-	      _mysql_NewException(dict, edict, "ProgrammingError")))
-		goto error;
-	if (!(_mysql_NotSupportedError =
-	      _mysql_NewException(dict, edict, "NotSupportedError")))
-		goto error;
-	Py_DECREF(emod);
-	if (!(_mysql_NULL = PyString_FromString("NULL")))
-		goto error;
-	if (PyDict_SetItemString(dict, "NULL", _mysql_NULL)) goto error;
-  error:
-	if (PyErr_Occurred())
-		PyErr_SetString(PyExc_ImportError,
-				"_mysql: init failed");
-	return;
-}
-
-
+/*
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version. Alternatively, you may use the original license
+reproduced below.
+
+Copyright 1999 by Comstar.net, Inc., Atlanta, GA, US.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Comstar.net, Inc.
+or COMSTAR not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+COMSTAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL COMSTAR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include "Python.h"
+#if PY_MAJOR_VERSION >= 3
+#define IS_PY3K
+#define PyInt_FromLong(n) PyLong_FromLong(n)
+#define PyInt_Check(n) PyLong_Check(n)
+#define PyInt_AS_LONG(n) PyLong_AS_LONG(n)
+#endif
+#if PY_VERSION_HEX > 0x02060000
+#include "bytesobject.h"
+#endif
+#include "pymemcompat.h"
+#include "structmember.h"
+#if defined(MS_WINDOWS)
+#include <config-win.h>
+#else
+#include "my_config.h"
+#endif
+#include "mysql.h"
+#include "mysqld_error.h"
+#include "errmsg.h"
+
+#if PY_VERSION_HEX < 0x02020000
+# define MyTuple_Resize(t,n,d) _PyTuple_Resize(t, n, d)
+# define MyMember(a,b,c,d,e) {a,b,c,d}
+# define MyMemberlist(x) struct memberlist x
+# define MyAlloc(s,t) PyObject_New(s,&t)
+# define MyFree(o) PyObject_Del(o)
+#else
+# define MyTuple_Resize(t,n,d) _PyTuple_Resize(t, n)
+# define MyMember(a,b,c,d,e) {a,b,c,d,e}
+# define MyMemberlist(x) struct PyMemberDef x
+# define MyAlloc(s,t) (s *) t.tp_alloc(&t,0)
+#ifdef IS_PY3K
+# define MyFree(o) PyObject_Del(o)
+#else
+# define MyFree(ob) ob->ob_type->tp_free((PyObject *)ob)
+#endif
+#endif
+
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+static PyObject *_mysql_MySQLError;
+static PyObject *_mysql_Warning;
+static PyObject *_mysql_Error;
+static PyObject *_mysql_DatabaseError;
+static PyObject *_mysql_InterfaceError; 
+static PyObject *_mysql_DataError;
+static PyObject *_mysql_OperationalError; 
+static PyObject *_mysql_IntegrityError; 
+static PyObject *_mysql_InternalError; 
+static PyObject *_mysql_ProgrammingError;
+static PyObject *_mysql_NotSupportedError;
+ 
+typedef struct {
+	PyObject_HEAD
+	MYSQL connection;
+	int open;
+	PyObject *converter;
+} _mysql_ConnectionObject;
+
+#define check_connection(c) if (!(c->open)) return _mysql_Exception(c)
+#define result_connection(r) ((_mysql_ConnectionObject *)r->conn)
+#define check_result_connection(r) check_connection(result_connection(r))
+
+extern PyTypeObject _mysql_ConnectionObject_Type;
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *conn;
+	MYSQL_RES *result;
+	int nfields;
+	int use;
+	PyObject *converter;
+} _mysql_ResultObject;
+
+extern PyTypeObject _mysql_ResultObject_Type;
+
+static int _mysql_server_init_done = 0;
+#if MYSQL_VERSION_ID >= 40000
+#define check_server_init(x) if (!_mysql_server_init_done) { if (mysql_server_init(0, NULL, NULL)) { _mysql_Exception(NULL); return x; } else { _mysql_server_init_done = 1;} }
+#else
+#define check_server_init(x) if (!_mysql_server_init_done) _mysql_server_init_done = 1
+#endif
+
+#if MYSQL_VERSION_ID >= 50500
+#define HAVE_OPENSSL 1
+#endif
+
+/* According to https://dev.mysql.com/doc/refman/5.1/en/mysql-options.html
+   The MYSQL_OPT_READ_TIMEOUT apear in the version 5.1.12 */
+#if MYSQL_VERSION_ID > 50112
+#define HAVE_MYSQL_OPT_TIMEOUTS 1
+#endif
+
+PyObject *
+_mysql_Exception(_mysql_ConnectionObject *c)
+{
+	PyObject *t, *e;
+	int merr;
+
+	if (!(t = PyTuple_New(2))) return NULL;
+	if (!_mysql_server_init_done) {
+		e = _mysql_InternalError;
+		PyTuple_SET_ITEM(t, 0, PyInt_FromLong(-1L));
+#ifdef IS_PY3K
+		PyTuple_SET_ITEM(t, 1, PyUnicode_FromString("server not initialized"));
+#else
+		PyTuple_SET_ITEM(t, 1, PyString_FromString("server not initialized"));
+#endif
+		PyErr_SetObject(e, t);
+		Py_DECREF(t);
+		return NULL;
+	}
+	merr = mysql_errno(&(c->connection));
+	if (!merr)
+		e = _mysql_InterfaceError;
+	else if (merr > CR_MAX_ERROR) {
+		PyTuple_SET_ITEM(t, 0, PyInt_FromLong(-1L));
+#ifdef IS_PY3K
+		PyTuple_SET_ITEM(t, 1, PyUnicode_FromString("error totally whack"));
+#else
+		PyTuple_SET_ITEM(t, 1, PyString_FromString("error totally whack"));
+#endif
+		PyErr_SetObject(_mysql_InterfaceError, t);
+		Py_DECREF(t);
+		return NULL;
+	}
+	else switch (merr) {
+	case CR_COMMANDS_OUT_OF_SYNC:
+	case ER_DB_CREATE_EXISTS:
+	case ER_SYNTAX_ERROR:
+	case ER_PARSE_ERROR:
+	case ER_NO_SUCH_TABLE:
+	case ER_WRONG_DB_NAME:
+	case ER_WRONG_TABLE_NAME:
+	case ER_FIELD_SPECIFIED_TWICE:
+	case ER_INVALID_GROUP_FUNC_USE:
+	case ER_UNSUPPORTED_EXTENSION:
+	case ER_TABLE_MUST_HAVE_COLUMNS:
+#ifdef ER_CANT_DO_THIS_DURING_AN_TRANSACTION
+	case ER_CANT_DO_THIS_DURING_AN_TRANSACTION:
+#endif
+		e = _mysql_ProgrammingError;
+		break;
+#ifdef WARN_DATA_TRUNCATED
+	case WARN_DATA_TRUNCATED:
+#ifdef WARN_NULL_TO_NOTNULL
+	case WARN_NULL_TO_NOTNULL:
+#endif
+#ifdef ER_WARN_DATA_OUT_OF_RANGE
+	case ER_WARN_DATA_OUT_OF_RANGE:
+#endif
+#ifdef ER_NO_DEFAULT
+	case ER_NO_DEFAULT:
+#endif
+#ifdef ER_PRIMARY_CANT_HAVE_NULL
+	case ER_PRIMARY_CANT_HAVE_NULL:
+#endif
+#ifdef ER_DATA_TOO_LONG
+	case ER_DATA_TOO_LONG:
+#endif
+#ifdef ER_DATETIME_FUNCTION_OVERFLOW
+	case ER_DATETIME_FUNCTION_OVERFLOW:
+#endif
+		e = _mysql_DataError;
+		break;
+#endif
+	case ER_DUP_ENTRY:
+#ifdef ER_DUP_UNIQUE
+	case ER_DUP_UNIQUE:
+#endif
+#ifdef ER_NO_REFERENCED_ROW
+	case ER_NO_REFERENCED_ROW:
+#endif
+#ifdef ER_NO_REFERENCED_ROW_2
+	case ER_NO_REFERENCED_ROW_2:
+#endif
+#ifdef ER_ROW_IS_REFERENCED
+	case ER_ROW_IS_REFERENCED:
+#endif
+#ifdef ER_ROW_IS_REFERENCED_2
+	case ER_ROW_IS_REFERENCED_2:
+#endif
+#ifdef ER_CANNOT_ADD_FOREIGN
+	case ER_CANNOT_ADD_FOREIGN:
+#endif
+		e = _mysql_IntegrityError;
+		break;
+#ifdef ER_WARNING_NOT_COMPLETE_ROLLBACK
+	case ER_WARNING_NOT_COMPLETE_ROLLBACK:
+#endif
+#ifdef ER_NOT_SUPPORTED_YET
+	case ER_NOT_SUPPORTED_YET:
+#endif
+#ifdef ER_FEATURE_DISABLED
+	case ER_FEATURE_DISABLED:
+#endif
+#ifdef ER_UNKNOWN_STORAGE_ENGINE
+	case ER_UNKNOWN_STORAGE_ENGINE:
+#endif
+		e = _mysql_NotSupportedError;
+		break;
+	default:
+		if (merr < 1000)
+			e = _mysql_InternalError;
+		else
+			e = _mysql_OperationalError;
+		break;
+	}
+	PyTuple_SET_ITEM(t, 0, PyInt_FromLong((long)merr));
+#ifdef IS_PY3K
+	PyTuple_SET_ITEM(t, 1, PyUnicode_FromString(mysql_error(&(c->connection))));
+#else
+	PyTuple_SET_ITEM(t, 1, PyString_FromString(mysql_error(&(c->connection))));
+#endif
+	PyErr_SetObject(e, t);
+	Py_DECREF(t);
+	return NULL;
+}
+	  
+static char _mysql_server_init__doc__[] =
+"Initialize embedded server. If this client is not linked against\n\
+the embedded server library, this function does nothing.\n\
+\n\
+args -- sequence of command-line arguments\n\
+groups -- sequence of groups to use in defaults files\n\
+";
+
+static PyObject *_mysql_server_init(
+	PyObject *self,
+	PyObject *args,
+	PyObject *kwargs) {
+	static char *kwlist[] = {"args", "groups", NULL};
+	char **cmd_args_c=NULL, **groups_c=NULL, *s;
+	int cmd_argc=0, i, groupc;
+	PyObject *cmd_args=NULL, *groups=NULL, *ret=NULL, *item;
+
+	if (_mysql_server_init_done) {
+		PyErr_SetString(_mysql_ProgrammingError,
+				"already initialized");
+		return NULL;
+	}
+	  
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwlist,
+					 &cmd_args, &groups))
+		return NULL;
+
+#if MYSQL_VERSION_ID >= 40000
+	if (cmd_args) {
+		if (!PySequence_Check(cmd_args)) {
+			PyErr_SetString(PyExc_TypeError,
+					"args must be a sequence");
+			goto finish;
+		}
+		cmd_argc = PySequence_Size(cmd_args);
+		if (cmd_argc == -1) {
+			PyErr_SetString(PyExc_TypeError,
+					"args could not be sized");
+			goto finish;
+		}
+		cmd_args_c = (char **) PyMem_Malloc(cmd_argc*sizeof(char *));
+		for (i=0; i< cmd_argc; i++) {
+			item = PySequence_GetItem(cmd_args, i);
+#ifdef IS_PY3K
+			s = PyUnicode_AS_DATA(item);
+#else
+			s = PyString_AsString(item);
+#endif
+
+			Py_DECREF(item);
+			if (!s) {
+				PyErr_SetString(PyExc_TypeError,
+						"args must contain strings");
+				goto finish;
+			}
+			cmd_args_c[i] = s;
+		}
+	}
+	if (groups) {
+		if (!PySequence_Check(groups)) {
+			PyErr_SetString(PyExc_TypeError,
+					"groups must be a sequence");
+			goto finish;
+		}
+		groupc = PySequence_Size(groups);
+		if (groupc == -1) {
+			PyErr_SetString(PyExc_TypeError,
+					"groups could not be sized");
+			goto finish;
+		}
+		groups_c = (char **) PyMem_Malloc((1+groupc)*sizeof(char *));
+		for (i=0; i< groupc; i++) {
+			item = PySequence_GetItem(groups, i);
+#ifdef IS_PY3K
+			s = PyUnicode_AS_DATA(item);
+#else
+			s = PyString_AsString(item);
+#endif
+			Py_DECREF(item);
+			if (!s) {
+				PyErr_SetString(PyExc_TypeError,
+						"groups must contain strings");
+				goto finish;
+			}
+			groups_c[i] = s;
+		}
+		groups_c[groupc] = (char *)NULL;
+	}
+	/* even though this may block, don't give up the interpreter lock
+	   so that the server can't be initialized multiple times. */
+	if (mysql_server_init(cmd_argc, cmd_args_c, groups_c)) {
+		_mysql_Exception(NULL);
+		goto finish;
+	}
+#endif
+	ret = Py_None;
+	Py_INCREF(Py_None);
+	_mysql_server_init_done = 1;
+  finish:
+	PyMem_Free(groups_c);
+	PyMem_Free(cmd_args_c);
+	return ret;
+}
+
+static char _mysql_server_end__doc__[] =
+"Shut down embedded server. If not using an embedded server, this\n\
+does nothing.";
+
+static PyObject *_mysql_server_end(
+	PyObject *self,
+	PyObject *args) {
+	if (_mysql_server_init_done) {
+#if MYSQL_VERSION_ID >= 40000
+		mysql_server_end();
+#endif
+		_mysql_server_init_done = 0;
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return _mysql_Exception(NULL);
+}
+	 
+#if MYSQL_VERSION_ID >= 32314
+static char _mysql_thread_safe__doc__[] =
+"Indicates whether the client is compiled as thread-safe.";
+
+static PyObject *_mysql_thread_safe(
+	PyObject *self,
+	PyObject *args) {
+	PyObject *flag;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_server_init(NULL);
+	if (!(flag=PyInt_FromLong((long)mysql_thread_safe()))) return NULL;
+	return flag;
+}
+#endif
+
+static char _mysql_ResultObject__doc__[] =
+"result(connection, use=0, converter={}) -- Result set from a query.\n\
+\n\
+Creating instances of this class directly is an excellent way to\n\
+shoot yourself in the foot. If using _mysql.connection directly,\n\
+use connection.store_result() or connection.use_result() instead.\n\
+If using MySQLdb.Connection, this is done by the cursor class.\n\
+Just forget you ever saw this. Forget... FOR-GET...";
+
+static int
+_mysql_ResultObject_Initialize(
+	_mysql_ResultObject *self,
+	PyObject *args,
+	PyObject *kwargs)
+{
+	static char *kwlist[] = {"connection", "use", "converter", NULL};
+	MYSQL_RES *result; 
+	_mysql_ConnectionObject *conn=NULL;
+	int use=0; 
+	PyObject *conv=NULL;
+	int n, i;
+	MYSQL_FIELD *fields;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iO", kwlist,
+					  &conn, &use, &conv))
+		return -1;
+	if (!conv) {
+		if (!(conv = PyDict_New()))
+			return -1;
+	}
+	else
+		Py_INCREF(conv);
+
+	self->conn = (PyObject *) conn;
+	Py_INCREF(conn);
+	self->use = use;
+	Py_BEGIN_ALLOW_THREADS ;
+	if (use)
+		result = mysql_use_result(&(conn->connection));
+	else
+		result = mysql_store_result(&(conn->connection));
+	self->result = result;
+	Py_END_ALLOW_THREADS ;
+	if (!result) {
+		if (mysql_field_count(&(conn->connection)) > 0) {
+		    _mysql_Exception(conn);
+		    return -1;
+		}
+		self->converter = PyTuple_New(0);
+		Py_DECREF(conv);
+		return 0;
+	}
+	n = mysql_num_fields(result);
+	self->nfields = n;
+	if (!(self->converter = PyTuple_New(n))) {
+		Py_DECREF(conv);
+		return -1;
+	}
+	fields = mysql_fetch_fields(result);
+	for (i=0; i<n; i++) {
+		PyObject *tmp, *fun;
+		tmp = PyInt_FromLong((long) fields[i].type);
+		if (!tmp) {
+			Py_DECREF(conv);
+			return -1;
+		}
+		fun = PyObject_GetItem(conv, tmp);
+		Py_DECREF(tmp);
+		if (!fun) {
+			if (PyErr_Occurred()) {
+				if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
+					Py_DECREF(conv);
+					return -1;
+				}
+				PyErr_Clear();
+			}
+			fun = Py_None;
+			Py_INCREF(Py_None);
+		}
+		else if (PySequence_Check(fun)) {
+			int j, n2=PySequence_Size(fun);
+			PyObject *fun2=NULL;
+			for (j=0; j<n2; j++) {
+				PyObject *t = PySequence_GetItem(fun, j);
+				if (!t) {
+					Py_DECREF(fun);
+					Py_DECREF(conv);
+					return -1;
+				}
+				if (PyTuple_Check(t) && PyTuple_GET_SIZE(t) == 2) {
+					long mask, flags;
+					PyObject *pmask=NULL;
+					pmask = PyTuple_GET_ITEM(t, 0);
+					fun2 = PyTuple_GET_ITEM(t, 1);
+					Py_XINCREF(fun2);
+					if (PyInt_Check(pmask)) {
+						mask = PyInt_AS_LONG(pmask);
+						flags = fields[i].flags;
+						if (fields[i].charsetnr != 63) { /* maaagic */
+							flags &= ~BINARY_FLAG;
+						}
+						if (mask & flags) {
+							Py_DECREF(t);
+							break;
+						}
+						else {
+							fun2 = NULL;
+						}
+					} else {
+						Py_DECREF(t);
+						break;
+					}
+				}
+				Py_DECREF(t);
+			}
+			if (!fun2) {
+				fun2 = Py_None;
+				Py_INCREF(fun2);
+			}
+			Py_DECREF(fun);
+			fun = fun2;
+		}
+		PyTuple_SET_ITEM(self->converter, i, fun);
+	}
+
+	Py_DECREF(conv);
+	return 0;
+}
+
+#if PY_VERSION_HEX >= 0x02020000
+static int _mysql_ResultObject_traverse(
+	_mysql_ResultObject *self,
+	visitproc visit,
+	void *arg)
+{
+	int r;
+	if (self->converter) {
+		if (!(r = visit(self->converter, arg))) return r;
+	}
+	if (self->conn)
+		return visit(self->conn, arg);
+	return 0;
+}
+#endif
+
+static int _mysql_ResultObject_clear(
+	_mysql_ResultObject *self)
+{
+	Py_XDECREF(self->converter);
+	self->converter = NULL;
+	Py_XDECREF(self->conn);
+	self->conn = NULL;
+	return 0;
+}
+
+static int
+_mysql_ConnectionObject_Initialize(
+	_mysql_ConnectionObject *self,
+	PyObject *args,
+	PyObject *kwargs)
+{
+	MYSQL *conn = NULL;
+	PyObject *conv = NULL;
+	PyObject *ssl = NULL;
+#if HAVE_OPENSSL
+	char *key = NULL, *cert = NULL, *ca = NULL,
+		*capath = NULL, *cipher = NULL;
+#endif
+	char *host = NULL, *user = NULL, *passwd = NULL,
+		*db = NULL, *unix_socket = NULL;
+	unsigned int port = 0;
+	unsigned int client_flag = 0;
+	static char *kwlist[] = { "host", "user", "passwd", "db", "port",
+				  "unix_socket", "conv",
+				  "connect_timeout", "compress",
+				  "named_pipe", "init_command",
+				  "read_default_file", "read_default_group",
+				  "client_flag", "ssl",
+				  "local_infile",
+#ifdef HAVE_MYSQL_OPT_TIMEOUTS
+                                  "read_timeout",
+                                  "write_timeout",
+#endif
+				  NULL } ;
+	int connect_timeout = 0;
+#ifdef HAVE_MYSQL_OPT_TIMEOUTS
+        int read_timeout = 0;
+        int write_timeout = 0;
+#endif
+	int compress = -1, named_pipe = -1, local_infile = -1;
+	char *init_command=NULL,
+	     *read_default_file=NULL,
+	     *read_default_group=NULL;
+	
+	self->converter = NULL;
+	self->open = 0;
+	check_server_init(-1);
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+#ifdef HAVE_MYSQL_OPT_TIMEOUTS
+                                         "|ssssisOiiisssiOiii:connect",
+#else
+                                         "|ssssisOiiisssiOi:connect",
+#endif
+					 kwlist,
+					 &host, &user, &passwd, &db,
+					 &port, &unix_socket, &conv,
+					 &connect_timeout,
+					 &compress, &named_pipe,
+					 &init_command, &read_default_file,
+					 &read_default_group,
+					 &client_flag, &ssl,
+                     &local_infile
+#ifdef HAVE_MYSQL_OPT_TIMEOUTS
+                     , &read_timeout
+                     , &write_timeout
+#endif
+	))
+		return -1;
+
+#ifdef IS_PY3K
+#define _stringsuck(d,t,s) {t=PyMapping_GetItemString(s,#d);\
+        if(t){d=PyUnicode_AS_DATA(t);Py_DECREF(t);}\
+        PyErr_Clear();}
+#else
+#define _stringsuck(d,t,s) {t=PyMapping_GetItemString(s,#d);\
+        if(t){d=PyString_AsString(t);Py_DECREF(t);}\
+        PyErr_Clear();}
+#endif
+
+	if (ssl) {
+#if HAVE_OPENSSL
+		PyObject *value = NULL;
+		_stringsuck(ca, value, ssl);
+		_stringsuck(capath, value, ssl);
+		_stringsuck(cert, value, ssl);
+		_stringsuck(key, value, ssl);
+		_stringsuck(cipher, value, ssl);
+#else
+		PyErr_SetString(_mysql_NotSupportedError,
+				"client library does not have SSL support");
+		return -1;
+#endif
+	}
+
+	Py_BEGIN_ALLOW_THREADS ;
+	conn = mysql_init(&(self->connection));
+	if (connect_timeout) {
+		unsigned int timeout = connect_timeout;
+		mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT, 
+				(char *)&timeout);
+	}
+#ifdef HAVE_MYSQL_OPT_TIMEOUTS
+	if (read_timeout) {
+		unsigned int timeout = read_timeout;
+		mysql_options(&(self->connection), MYSQL_OPT_READ_TIMEOUT,
+				(char *)&timeout);
+	}
+	if (write_timeout) {
+		unsigned int timeout = write_timeout;
+		mysql_options(&(self->connection), MYSQL_OPT_WRITE_TIMEOUT,
+				(char *)&timeout);
+	}
+#endif
+	if (compress != -1) {
+		mysql_options(&(self->connection), MYSQL_OPT_COMPRESS, 0);
+		client_flag |= CLIENT_COMPRESS;
+	}
+	if (named_pipe != -1)
+		mysql_options(&(self->connection), MYSQL_OPT_NAMED_PIPE, 0);
+	if (init_command != NULL)
+		mysql_options(&(self->connection), MYSQL_INIT_COMMAND, init_command);
+	if (read_default_file != NULL)
+		mysql_options(&(self->connection), MYSQL_READ_DEFAULT_FILE, read_default_file);
+	if (read_default_group != NULL)
+		mysql_options(&(self->connection), MYSQL_READ_DEFAULT_GROUP, read_default_group);
+
+	if (local_infile != -1)
+		mysql_options(&(self->connection), MYSQL_OPT_LOCAL_INFILE, (char *) &local_infile);
+
+#if HAVE_OPENSSL
+	if (ssl)
+		mysql_ssl_set(&(self->connection),
+			      key, cert, ca, capath, cipher);
+#endif
+
+	conn = mysql_real_connect(&(self->connection), host, user, passwd, db,
+				  port, unix_socket, client_flag);
+
+	Py_END_ALLOW_THREADS ;
+
+	if (!conn) {
+		_mysql_Exception(self);
+		return -1;
+	}
+
+        /* Internal references to python-land objects */
+	if (!conv)
+		conv = PyDict_New();
+	else
+		Py_INCREF(conv);
+
+	if (!conv)
+		return -1;
+	self->converter = conv;
+
+	/*
+	  PyType_GenericAlloc() automatically sets up GC allocation and
+	  tracking for GC objects, at least in 2.2.1, so it does not need to
+	  be done here. tp_dealloc still needs to call PyObject_GC_UnTrack(),
+	  however.
+	*/
+	self->open = 1;
+	return 0;
+}
+
+static char _mysql_connect__doc__[] =
+"Returns a MYSQL connection object. Exclusive use of\n\
+keyword parameters strongly recommended. Consult the\n\
+MySQL C API documentation for more details.\n\
+\n\
+host\n\
+  string, host to connect\n\
+\n\
+user\n\
+  string, user to connect as\n\
+\n\
+passwd\n\
+  string, password to use\n\
+\n\
+db\n\
+  string, database to use\n\
+\n\
+port\n\
+  integer, TCP/IP port to connect to\n\
+\n\
+unix_socket\n\
+  string, location of unix_socket (UNIX-ish only)\n\
+\n\
+conv\n\
+  mapping, maps MySQL FIELD_TYPE.* to Python functions which\n\
+  convert a string to the appropriate Python type\n\
+\n\
+connect_timeout\n\
+  number of seconds to wait before the connection\n\
+  attempt fails.\n\
+\n\
+compress\n\
+  if set, gzip compression is enabled\n\
+\n\
+named_pipe\n\
+  if set, connect to server via named pipe (Windows only)\n\
+\n\
+init_command\n\
+  command which is run once the connection is created\n\
+\n\
+read_default_file\n\
+  see the MySQL documentation for mysql_options()\n\
+\n\
+read_default_group\n\
+  see the MySQL documentation for mysql_options()\n\
+\n\
+client_flag\n\
+  client flags from MySQLdb.constants.CLIENT\n\
+\n\
+load_infile\n\
+  int, non-zero enables LOAD LOCAL INFILE, zero disables\n\
+\n\
+";
+
+static PyObject *
+_mysql_connect(
+	PyObject *self,
+	PyObject *args,
+	PyObject *kwargs)
+{
+	_mysql_ConnectionObject *c=NULL;
+	
+	c = MyAlloc(_mysql_ConnectionObject, _mysql_ConnectionObject_Type);
+	if (c == NULL) return NULL;
+	if (_mysql_ConnectionObject_Initialize(c, args, kwargs)) {
+		Py_DECREF(c);
+		c = NULL;
+	}
+	return (PyObject *) c;
+}
+
+#if PY_VERSION_HEX >= 0x02020000
+static int _mysql_ConnectionObject_traverse(
+	_mysql_ConnectionObject *self,
+	visitproc visit,
+	void *arg)
+{
+	if (self->converter)
+		return visit(self->converter, arg);
+	return 0;
+}
+#endif
+
+static int _mysql_ConnectionObject_clear(
+	_mysql_ConnectionObject *self)
+{
+	Py_XDECREF(self->converter);
+	self->converter = NULL;
+	return 0;
+}
+
+static char _mysql_ConnectionObject_close__doc__[] =
+"Close the connection. No further activity possible.";
+
+static PyObject *
+_mysql_ConnectionObject_close(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (args) {
+		if (!PyArg_ParseTuple(args, "")) return NULL;
+	}
+	if (self->open) {
+		Py_BEGIN_ALLOW_THREADS
+		mysql_close(&(self->connection));
+		Py_END_ALLOW_THREADS
+		self->open = 0;
+	} else {
+		PyErr_SetString(_mysql_ProgrammingError,
+				"closing a closed connection");
+		return NULL;
+	}
+	_mysql_ConnectionObject_clear(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_affected_rows__doc__ [] =
+"Return number of rows affected by the last query.\n\
+Non-standard. Use Cursor.rowcount.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_affected_rows(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	return PyLong_FromUnsignedLongLong(mysql_affected_rows(&(self->connection)));
+}
+
+static char _mysql_debug__doc__[] =
+"Does a DBUG_PUSH with the given string.\n\
+mysql_debug() uses the Fred Fish debug library.\n\
+To use this function, you must compile the client library to\n\
+support debugging.\n\
+";
+static PyObject *
+_mysql_debug(
+	PyObject *self,
+	PyObject *args)
+{
+	char *debug;
+	if (!PyArg_ParseTuple(args, "s", &debug)) return NULL;
+	mysql_debug(debug);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_dump_debug_info__doc__[] =
+"Instructs the server to write some debug information to the\n\
+log. The connected user must have the process privilege for\n\
+this to work. Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_dump_debug_info(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	int err;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	err = mysql_dump_debug_info(&(self->connection));
+	Py_END_ALLOW_THREADS
+	if (err) return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_autocommit__doc__[] =
+"Set the autocommit mode. True values enable; False value disable.\n\
+";
+static PyObject *
+_mysql_ConnectionObject_autocommit(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	int flag, err;
+	if (!PyArg_ParseTuple(args, "i", &flag)) return NULL;
+	Py_BEGIN_ALLOW_THREADS
+#if MYSQL_VERSION_ID >= 40100
+	err = mysql_autocommit(&(self->connection), flag);
+#else
+	{
+		char query[256];
+		snprintf(query, 256, "SET AUTOCOMMIT=%d", flag);
+		err = mysql_query(&(self->connection), query);
+	}
+#endif
+	Py_END_ALLOW_THREADS
+	if (err) return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_get_autocommit__doc__[] =
+"Get the autocommit mode. True when enable; False when disable.\n";
+
+static PyObject *
+_mysql_ConnectionObject_get_autocommit(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (self->connection.server_status & SERVER_STATUS_AUTOCOMMIT) {
+		Py_RETURN_TRUE;
+	}
+	Py_RETURN_FALSE;
+}
+
+static char _mysql_ConnectionObject_commit__doc__[] =
+"Commits the current transaction\n\
+";
+static PyObject *
+_mysql_ConnectionObject_commit(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	int err;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	Py_BEGIN_ALLOW_THREADS
+#if MYSQL_VERSION_ID >= 40100
+	err = mysql_commit(&(self->connection));
+#else
+	err = mysql_query(&(self->connection), "COMMIT");
+#endif
+	Py_END_ALLOW_THREADS
+	if (err) return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}		
+
+static char _mysql_ConnectionObject_rollback__doc__[] =
+"Rolls backs the current transaction\n\
+";
+static PyObject *
+_mysql_ConnectionObject_rollback(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	int err;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	Py_BEGIN_ALLOW_THREADS
+#if MYSQL_VERSION_ID >= 40100
+	err = mysql_rollback(&(self->connection));
+#else
+	err = mysql_query(&(self->connection), "ROLLBACK");
+#endif
+	Py_END_ALLOW_THREADS
+	if (err) return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}		
+
+static char _mysql_ConnectionObject_next_result__doc__[] =
+"If more query results exist, next_result() reads the next query\n\
+results and returns the status back to application.\n\
+\n\
+After calling next_result() the state of the connection is as if\n\
+you had called query() for the next query. This means that you can\n\
+now call store_result(), warning_count(), affected_rows()\n\
+, and so forth. \n\
+\n\
+Returns 0 if there are more results; -1 if there are no more results\n\
+\n\
+Non-standard.\n\
+";
+static PyObject *
+_mysql_ConnectionObject_next_result(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	int err;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	Py_BEGIN_ALLOW_THREADS
+#if MYSQL_VERSION_ID >= 40100
+	err = mysql_next_result(&(self->connection));
+#else
+	err = -1;
+#endif
+	Py_END_ALLOW_THREADS
+	if (err > 0) return _mysql_Exception(self);
+	return PyInt_FromLong(err);
+}		
+
+#if MYSQL_VERSION_ID >= 40100
+
+static char _mysql_ConnectionObject_set_server_option__doc__[] =
+"set_server_option(option) -- Enables or disables an option\n\
+for the connection.\n\
+\n\
+Non-standard.\n\
+";
+static PyObject *
+_mysql_ConnectionObject_set_server_option(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	int err, flags=0;
+	if (!PyArg_ParseTuple(args, "i", &flags))
+		return NULL;
+	Py_BEGIN_ALLOW_THREADS
+	err = mysql_set_server_option(&(self->connection), flags);
+	Py_END_ALLOW_THREADS
+	if (err) return _mysql_Exception(self);
+	return PyInt_FromLong(err);
+}		
+
+static char _mysql_ConnectionObject_sqlstate__doc__[] =
+"Returns a string containing the SQLSTATE error code\n\
+for the last error. The error code consists of five characters.\n\
+'00000' means \"no error.\" The values are specified by ANSI SQL\n\
+and ODBC. For a list of possible values, see section 23\n\
+Error Handling in MySQL in the MySQL Manual.\n\
+\n\
+Note that not all MySQL errors are yet mapped to SQLSTATE's.\n\
+The value 'HY000' (general error) is used for unmapped errors.\n\
+\n\
+Non-standard.\n\
+";
+static PyObject *
+_mysql_ConnectionObject_sqlstate(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+#ifdef IS_PY3K
+	return PyUnicode_FromString(mysql_sqlstate(&(self->connection)));
+#else
+	return PyString_FromString(mysql_sqlstate(&(self->connection)));
+#endif
+}
+
+static char _mysql_ConnectionObject_warning_count__doc__[] =
+"Returns the number of warnings generated during execution\n\
+of the previous SQL statement.\n\
+\n\
+Non-standard.\n\
+";
+static PyObject *
+_mysql_ConnectionObject_warning_count(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	return PyInt_FromLong(mysql_warning_count(&(self->connection)));
+}		
+
+#endif
+
+static char _mysql_ConnectionObject_errno__doc__[] =
+"Returns the error code for the most recently invoked API function\n\
+that can succeed or fail. A return value of zero means that no error\n\
+occurred.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_errno(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	return PyInt_FromLong((long)mysql_errno(&(self->connection)));
+}
+
+static char _mysql_ConnectionObject_error__doc__[] =
+"Returns the error message for the most recently invoked API function\n\
+that can succeed or fail. An empty string ("") is returned if no error\n\
+occurred.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_error(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+#ifdef IS_PY3K
+	return PyUnicode_FromString(mysql_error(&(self->connection)));
+#else
+	return PyString_FromString(mysql_error(&(self->connection)));
+#endif
+}
+
+static char _mysql_escape_string__doc__[] =
+"escape_string(s) -- quote any SQL-interpreted characters in string s.\n\
+\n\
+Use connection.escape_string(s), if you use it at all.\n\
+_mysql.escape_string(s) cannot handle character sets. You are\n\
+probably better off using connection.escape(o) instead, since\n\
+it will escape entire sequences as well as strings.";
+
+static PyObject *
+_mysql_escape_string(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	PyObject *str;
+	char *in, *out;
+	int len, size;
+	if (!PyArg_ParseTuple(args, "s#:escape_string", &in, &size)) return NULL;
+#ifdef IS_PY3K
+	str = PyUnicode_FromStringAndSize((char *) NULL, size*2+1);
+#else
+	str = PyString_FromStringAndSize((char *) NULL, size*2+1);
+#endif
+	if (!str) return PyErr_NoMemory();
+#ifdef IS_PY3K
+    out = PyUnicode_AS_DATA(str);
+#else
+    out = PyString_AS_STRING(str);
+#endif
+#if MYSQL_VERSION_ID < 32321
+	len = mysql_escape_string(out, in, size);
+#else
+	check_server_init(NULL);
+	if (self && self->open)
+		len = mysql_real_escape_string(&(self->connection), out, in, size);
+	else
+		len = mysql_escape_string(out, in, size);
+#endif
+#ifdef IS_PY3K
+	if (PyUnicode_Resize(&str, len) < 0) return NULL;
+#else
+	if (_PyString_Resize(&str, len) < 0) return NULL;
+#endif
+	return (str);
+}
+
+static char _mysql_string_literal__doc__[] =
+"string_literal(obj) -- converts object obj into a SQL string literal.\n\
+This means, any special SQL characters are escaped, and it is enclosed\n\
+within single quotes. In other words, it performs:\n\
+\n\
+\"'%s'\" % escape_string(str(obj))\n\
+\n\
+Use connection.string_literal(obj), if you use it at all.\n\
+_mysql.string_literal(obj) cannot handle character sets.";
+
+static PyObject *
+_mysql_string_literal(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	PyObject *str, *s, *o, *d;
+	char *in, *out;
+	int len, size;
+	if (!PyArg_ParseTuple(args, "O|O:string_literal", &o, &d)) return NULL;
+	s = PyObject_Str(o);
+	if (!s) return NULL;
+#ifdef IS_PY3K
+	in = PyUnicode_AS_DATA(s);
+	size = PyUnicode_GetSize(s);
+	str = PyUnicode_FromStringAndSize((char *) NULL, size*2+3);
+	if (!str) return PyErr_NoMemory();
+	out = PyUnicode_AS_DATA(str);
+#else
+	in = PyString_AsString(s);
+	size = PyString_GET_SIZE(s);
+	str = PyString_FromStringAndSize((char *) NULL, size*2+3);
+	if (!str) return PyErr_NoMemory();
+	out = PyString_AS_STRING(str);
+#endif
+#if MYSQL_VERSION_ID < 32321
+	len = mysql_escape_string(out+1, in, size);
+#else
+	check_server_init(NULL);
+	if (self && self->open)
+		len = mysql_real_escape_string(&(self->connection), out+1, in, size);
+	else
+		len = mysql_escape_string(out+1, in, size);
+#endif
+	*out = *(out+len+1) = '\'';
+#ifdef IS_PY3K
+	if (PyUnicode_Resize(&str, len+2) < 0) return NULL;
+#else
+	if (_PyString_Resize(&str, len+2) < 0) return NULL;
+#endif
+	Py_DECREF(s);
+	return (str);
+}
+
+static PyObject *_mysql_NULL;
+
+static PyObject *
+_escape_item(
+	PyObject *item,
+	PyObject *d)
+{
+	PyObject *quoted=NULL, *itemtype, *itemconv;
+	if (!(itemtype = PyObject_Type(item)))
+		goto error;
+	itemconv = PyObject_GetItem(d, itemtype);
+	Py_DECREF(itemtype);
+	if (!itemconv) {
+		PyErr_Clear();
+		itemconv = PyObject_GetItem(d,
+#ifdef IS_PY3K
+				 (PyObject *) &PyUnicode_Type);
+#else
+				 (PyObject *) &PyString_Type);
+#endif
+	}
+	if (!itemconv) {
+		PyErr_SetString(PyExc_TypeError,
+				"no default type converter defined");
+		goto error;
+	}
+	Py_INCREF(d);
+	quoted = PyObject_CallFunction(itemconv, "OO", item, d);
+	Py_DECREF(d);
+	Py_DECREF(itemconv);
+error:
+	return quoted;
+}
+
+static char _mysql_escape__doc__[] =
+"escape(obj, dict) -- escape any special characters in object obj\n\
+using mapping dict to provide quoting functions for each type.\n\
+Returns a SQL literal string.";
+static PyObject *
+_mysql_escape(
+	PyObject *self,
+	PyObject *args)
+{
+	PyObject *o=NULL, *d=NULL;
+	if (!PyArg_ParseTuple(args, "O|O:escape", &o, &d))
+		return NULL;
+	if (d) {
+		if (!PyMapping_Check(d)) {
+			PyErr_SetString(PyExc_TypeError,
+					"argument 2 must be a mapping");
+			return NULL;
+		}
+		return _escape_item(o, d);
+	} else {
+		if (!self) {
+			PyErr_SetString(PyExc_TypeError,
+					"argument 2 must be a mapping");
+			return NULL;
+		}
+		return _escape_item(o,
+			   ((_mysql_ConnectionObject *) self)->converter);
+	}
+}
+
+static char _mysql_escape_sequence__doc__[] =
+"escape_sequence(seq, dict) -- escape any special characters in sequence\n\
+seq using mapping dict to provide quoting functions for each type.\n\
+Returns a tuple of escaped items.";
+static PyObject *
+_mysql_escape_sequence(
+	PyObject *self,
+	PyObject *args)
+{
+	PyObject *o=NULL, *d=NULL, *r=NULL, *item, *quoted; 
+	int i, n;
+	if (!PyArg_ParseTuple(args, "OO:escape_sequence", &o, &d))
+		goto error;
+	if (!PyMapping_Check(d)) {
+              PyErr_SetString(PyExc_TypeError,
+                              "argument 2 must be a mapping");
+              return NULL;
+        }
+	if ((n = PyObject_Length(o)) == -1) goto error;
+	if (!(r = PyTuple_New(n))) goto error;
+	for (i=0; i<n; i++) {
+		item = PySequence_GetItem(o, i);
+		if (!item) goto error;
+		quoted = _escape_item(item, d);
+		Py_DECREF(item);
+		if (!quoted) goto error;
+		PyTuple_SET_ITEM(r, i, quoted);
+	}
+	return r;
+  error:
+	Py_XDECREF(r);
+	return NULL;
+}
+
+static char _mysql_escape_dict__doc__[] =
+"escape_sequence(d, dict) -- escape any special characters in\n\
+dictionary d using mapping dict to provide quoting functions for each type.\n\
+Returns a dictionary of escaped items.";
+static PyObject *
+_mysql_escape_dict(
+	PyObject *self,
+	PyObject *args)
+{
+	PyObject *o=NULL, *d=NULL, *r=NULL, *item, *quoted, *pkey; 
+	Py_ssize_t ppos = 0;
+	if (!PyArg_ParseTuple(args, "O!O:escape_dict", &PyDict_Type, &o, &d))
+		goto error;
+	if (!PyMapping_Check(d)) {
+              PyErr_SetString(PyExc_TypeError,
+                              "argument 2 must be a mapping");
+              return NULL;
+        }
+	if (!(r = PyDict_New())) goto error;
+	while (PyDict_Next(o, &ppos, &pkey, &item)) {
+		quoted = _escape_item(item, d);
+		if (!quoted) goto error;
+		if (PyDict_SetItem(r, pkey, quoted)==-1) goto error;
+		Py_DECREF(quoted);
+	}
+	return r;
+  error:
+	Py_XDECREF(r);
+	return NULL;
+}
+				
+static char _mysql_ResultObject_describe__doc__[] =
+"Returns the sequence of 7-tuples required by the DB-API for\n\
+the Cursor.description attribute.\n\
+";
+
+static PyObject *
+_mysql_ResultObject_describe(
+	_mysql_ResultObject *self,
+	PyObject *args)
+{
+	PyObject *d;
+	MYSQL_FIELD *fields;
+	unsigned int i, n;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_result_connection(self);
+	n = mysql_num_fields(self->result);
+	fields = mysql_fetch_fields(self->result);
+	if (!(d = PyTuple_New(n))) return NULL;
+	for (i=0; i<n; i++) {
+		PyObject *t;
+		t = Py_BuildValue("(siiiiii)",
+				  fields[i].name,
+				  (long) fields[i].type,
+				  (long) fields[i].max_length,
+				  (long) fields[i].length,
+				  (long) fields[i].length,
+				  (long) fields[i].decimals,
+				  (long) !(IS_NOT_NULL(fields[i].flags)));
+		if (!t) goto error;
+		PyTuple_SET_ITEM(d, i, t);
+	}
+	return d;
+  error:
+	Py_XDECREF(d);
+	return NULL;
+}
+	
+static char _mysql_ResultObject_field_flags__doc__[] =
+"Returns a tuple of field flags, one for each column in the result.\n\
+" ;
+
+static PyObject *
+_mysql_ResultObject_field_flags(
+	_mysql_ResultObject *self,
+	PyObject *args)
+{
+	PyObject *d;
+	MYSQL_FIELD *fields;
+	unsigned int i, n;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_result_connection(self);
+	n = mysql_num_fields(self->result);
+	fields = mysql_fetch_fields(self->result);
+	if (!(d = PyTuple_New(n))) return NULL;
+	for (i=0; i<n; i++) {
+		PyObject *f;
+		if (!(f = PyInt_FromLong((long)fields[i].flags))) goto error;
+		PyTuple_SET_ITEM(d, i, f);
+	}
+	return d;
+  error:
+	Py_XDECREF(d);
+	return NULL;
+}
+
+static PyObject *
+_mysql_field_to_python(
+	PyObject *converter,
+	char *rowitem,
+	unsigned long length)
+{
+	PyObject *v;
+	if (rowitem) {
+		if (converter != Py_None)
+			v = PyObject_CallFunction(converter,
+						  "s#",
+						  rowitem,
+						  (int)length);
+		else
+#ifdef IS_PY3K
+			v = PyUnicode_FromStringAndSize(rowitem,
+						       (int)length);
+#else
+			v = PyString_FromStringAndSize(rowitem,
+						       (int)length);
+#endif
+		if (!v)
+			return NULL;
+	} else {
+		Py_INCREF(Py_None);
+		v = Py_None;
+	}
+	return v;
+}
+
+static PyObject *
+_mysql_row_to_tuple(
+	_mysql_ResultObject *self,
+	MYSQL_ROW row)
+{
+	unsigned int n, i;
+	unsigned long *length;
+	PyObject *r, *c;
+
+	n = mysql_num_fields(self->result);
+	if (!(r = PyTuple_New(n))) return NULL;
+	length = mysql_fetch_lengths(self->result);
+	for (i=0; i<n; i++) {
+		PyObject *v;
+		c = PyTuple_GET_ITEM(self->converter, i);
+		v = _mysql_field_to_python(c, row[i], length[i]);
+		if (!v) goto error;
+		PyTuple_SET_ITEM(r, i, v);
+	}
+	return r;
+  error:
+	Py_XDECREF(r);
+	return NULL;
+}
+
+static PyObject *
+_mysql_row_to_dict(
+	_mysql_ResultObject *self,
+	MYSQL_ROW row)
+{
+	unsigned int n, i;
+	unsigned long *length;
+	PyObject *r, *c;
+        MYSQL_FIELD *fields;
+
+	n = mysql_num_fields(self->result);
+	if (!(r = PyDict_New())) return NULL;
+	length = mysql_fetch_lengths(self->result);
+        fields = mysql_fetch_fields(self->result);
+	for (i=0; i<n; i++) {
+		PyObject *v;
+		c = PyTuple_GET_ITEM(self->converter, i);
+		v = _mysql_field_to_python(c, row[i], length[i]);
+		if (!v) goto error;
+		if (!PyMapping_HasKeyString(r, fields[i].name)) {
+			PyMapping_SetItemString(r, fields[i].name, v);
+		} else {
+			int len;
+			char buf[256];
+			strncpy(buf, fields[i].table, 256);
+			len = strlen(buf);
+			strncat(buf, ".", 256-len);
+			len = strlen(buf);
+			strncat(buf, fields[i].name, 256-len);
+			PyMapping_SetItemString(r, buf, v);
+		}
+		Py_DECREF(v);
+	}
+	return r;
+  error:
+	Py_XDECREF(r);
+	return NULL;
+}
+
+static PyObject *
+_mysql_row_to_dict_old(
+	_mysql_ResultObject *self,
+	MYSQL_ROW row)
+{
+	unsigned int n, i;
+	unsigned long *length;
+	PyObject *r, *c;
+        MYSQL_FIELD *fields;
+
+	n = mysql_num_fields(self->result);
+	if (!(r = PyDict_New())) return NULL;
+	length = mysql_fetch_lengths(self->result);
+        fields = mysql_fetch_fields(self->result);
+	for (i=0; i<n; i++) {
+		PyObject *v;
+		c = PyTuple_GET_ITEM(self->converter, i);
+		v = _mysql_field_to_python(c, row[i], length[i]);
+		if (!v) goto error;
+		{
+			int len=0;
+			char buf[256]="";
+			if (strlen(fields[i].table)) {
+				strncpy(buf, fields[i].table, 256);
+				len = strlen(buf);
+				strncat(buf, ".", 256-len);
+				len = strlen(buf);
+			}
+			strncat(buf, fields[i].name, 256-len);
+			PyMapping_SetItemString(r, buf, v);
+		}
+		Py_DECREF(v);
+	}
+	return r;
+  error:
+	Py_XDECREF(r);
+	return NULL;
+}
+
+typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW);
+
+int
+_mysql__fetch_row(
+	_mysql_ResultObject *self,
+	PyObject **r,
+	int skiprows,
+	int maxrows,
+	_PYFUNC *convert_row)
+{
+	unsigned int i;
+	MYSQL_ROW row;
+
+	for (i = skiprows; i<(skiprows+maxrows); i++) {
+		PyObject *v;
+		if (!self->use)
+			row = mysql_fetch_row(self->result);
+		else {
+			Py_BEGIN_ALLOW_THREADS;
+			row = mysql_fetch_row(self->result);
+			Py_END_ALLOW_THREADS;
+		}
+		if (!row && mysql_errno(&(((_mysql_ConnectionObject *)(self->conn))->connection))) {
+			_mysql_Exception((_mysql_ConnectionObject *)self->conn);
+			goto error;
+		}
+		if (!row) {
+			if (MyTuple_Resize(r, i, 0) == -1) goto error;
+			break;
+		}
+		v = convert_row(self, row);
+		if (!v) goto error;
+		PyTuple_SET_ITEM(*r, i, v);
+	}
+	return i-skiprows;
+  error:
+	return -1;
+}
+
+static char _mysql_ResultObject_fetch_row__doc__[] =
+"fetch_row([maxrows, how]) -- Fetches up to maxrows as a tuple.\n\
+The rows are formatted according to how:\n\
+\n\
+    0 -- tuples (default)\n\
+    1 -- dictionaries, key=column or table.column if duplicated\n\
+    2 -- dictionaries, key=table.column\n\
+";
+
+static PyObject *
+_mysql_ResultObject_fetch_row(
+	_mysql_ResultObject *self,
+	PyObject *args,
+	PyObject *kwargs)
+{
+	typedef PyObject *_PYFUNC(_mysql_ResultObject *, MYSQL_ROW);
+	static char *kwlist[] = { "maxrows", "how", NULL };
+	static _PYFUNC *row_converters[] =
+	{
+		_mysql_row_to_tuple,
+		_mysql_row_to_dict,
+		_mysql_row_to_dict_old
+	};
+	_PYFUNC *convert_row;
+	unsigned int maxrows=1, how=0, skiprows=0, rowsadded;
+	PyObject *r=NULL;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii:fetch_row", kwlist,
+					 &maxrows, &how))
+		return NULL;
+	check_result_connection(self);
+	if (how < 0 || how >= sizeof(row_converters)) {
+		PyErr_SetString(PyExc_ValueError, "how out of range");
+		return NULL;
+	}
+	convert_row = row_converters[how];
+	if (maxrows) {
+		if (!(r = PyTuple_New(maxrows))) goto error;
+		rowsadded = _mysql__fetch_row(self, &r, skiprows, maxrows, 
+				convert_row);
+		if (rowsadded == -1) goto error;
+	} else {
+		if (self->use) {
+			maxrows = 1000;
+			if (!(r = PyTuple_New(maxrows))) goto error;
+			while (1) {
+				rowsadded = _mysql__fetch_row(self, &r, skiprows,
+						maxrows, convert_row);
+				if (rowsadded == -1) goto error;
+				skiprows += rowsadded;
+				if (rowsadded < maxrows) break;
+				if (MyTuple_Resize(&r, skiprows+maxrows, 0) == -1)
+				        goto error;
+			}
+		} else {
+			/* XXX if overflow, maxrows<0? */
+			maxrows = (int) mysql_num_rows(self->result);
+			if (!(r = PyTuple_New(maxrows))) goto error;
+			rowsadded = _mysql__fetch_row(self, &r, 0,
+					maxrows, convert_row);
+			if (rowsadded == -1) goto error;
+		}
+	}
+	return r;
+  error:
+	Py_XDECREF(r);
+	return NULL;
+}
+
+#if MYSQL_VERSION_ID >= 32303
+
+static char _mysql_ConnectionObject_change_user__doc__[] =
+"Changes the user and causes the database specified by db to\n\
+become the default (current) database on the connection\n\
+specified by mysql. In subsequent queries, this database is\n\
+the default for table references that do not include an\n\
+explicit database specifier.\n\
+\n\
+This function was introduced in MySQL Version 3.23.3.\n\
+\n\
+Fails unless the connected user can be authenticated or if he\n\
+doesn't have permission to use the database. In this case the\n\
+user and database are not changed.\n\
+\n\
+The db parameter may be set to None if you don't want to have\n\
+a default database.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_change_user(
+	_mysql_ConnectionObject *self,
+	PyObject *args,
+	PyObject *kwargs)
+{
+	char *user, *pwd=NULL, *db=NULL;
+	int r;
+        static char *kwlist[] = { "user", "passwd", "db", NULL } ;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ss:change_user",
+					 kwlist, &user, &pwd, &db))
+		return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+		r = mysql_change_user(&(self->connection), user, pwd, db);
+	Py_END_ALLOW_THREADS
+	if (r) 	return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+static char _mysql_ConnectionObject_character_set_name__doc__[] =
+"Returns the default character set for the current connection.\n\
+Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_character_set_name(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	const char *s;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+#if MYSQL_VERSION_ID >= 32321
+	s = mysql_character_set_name(&(self->connection));
+#else
+	s = "latin1";
+#endif
+#ifdef IS_PY3K
+	return PyUnicode_FromString(s);
+#else
+	return PyString_FromString(s);
+#endif
+}
+
+#if MYSQL_VERSION_ID >= 50007
+static char _mysql_ConnectionObject_set_character_set__doc__[] =
+"Sets the default character set for the current connection.\n\
+Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_set_character_set(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	const char *s;
+	int err;
+	if (!PyArg_ParseTuple(args, "s", &s)) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	err = mysql_set_character_set(&(self->connection), s);
+	Py_END_ALLOW_THREADS
+	if (err) return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+#endif
+
+#if MYSQL_VERSION_ID >= 50010
+static char _mysql_ConnectionObject_get_character_set_info__doc__[] =
+"Returns a dict with information about the current character set:\n\
+\n\
+collation\n\
+    collation name\n\
+name\n\
+    character set name\n\
+comment\n\
+    comment or descriptive name\n\
+dir\n\
+    character set directory\n\
+mbminlen\n\
+    min. length for multibyte string\n\
+mbmaxlen\n\
+    max. length for multibyte string\n\
+\n\
+Not all keys may be present, particularly dir.\n\
+\n\
+Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_get_character_set_info(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	PyObject *result;
+	MY_CHARSET_INFO cs;
+	
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	mysql_get_character_set_info(&(self->connection), &cs);
+	if (!(result = PyDict_New())) return NULL;
+#ifdef IS_PY3K
+	if (cs.csname)
+		PyDict_SetItemString(result, "name", PyUnicode_FromString(cs.csname));
+	if (cs.name)
+		PyDict_SetItemString(result, "collation", PyUnicode_FromString(cs.name));
+	if (cs.comment)
+		PyDict_SetItemString(result, "comment", PyUnicode_FromString(cs.comment));
+	if (cs.dir)
+		PyDict_SetItemString(result, "dir", PyUnicode_FromString(cs.dir));
+	PyDict_SetItemString(result, "mbminlen", PyInt_FromLong(cs.mbminlen));
+	PyDict_SetItemString(result, "mbmaxlen", PyInt_FromLong(cs.mbmaxlen));
+#else
+	if (cs.csname)
+		PyDict_SetItemString(result, "name", PyString_FromString(cs.csname));
+	if (cs.name)
+		PyDict_SetItemString(result, "collation", PyString_FromString(cs.name));
+	if (cs.comment)
+		PyDict_SetItemString(result, "comment", PyString_FromString(cs.comment));
+	if (cs.dir)
+		PyDict_SetItemString(result, "dir", PyString_FromString(cs.dir));
+	PyDict_SetItemString(result, "mbminlen", PyInt_FromLong(cs.mbminlen));
+	PyDict_SetItemString(result, "mbmaxlen", PyInt_FromLong(cs.mbmaxlen));
+#endif
+	return result;
+}
+#endif
+
+static char _mysql_get_client_info__doc__[] =
+"get_client_info() -- Returns a string that represents\n\
+the client library version.";
+static PyObject *
+_mysql_get_client_info(
+	PyObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_server_init(NULL);
+#ifdef IS_PY3K
+	return PyUnicode_FromString(mysql_get_client_info());
+#else
+	return PyString_FromString(mysql_get_client_info());
+#endif
+}
+
+static char _mysql_ConnectionObject_get_host_info__doc__[] =
+"Returns a string that represents the MySQL client library\n\
+version. Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_get_host_info(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+#ifdef IS_PY3K
+	return PyUnicode_FromString(mysql_get_host_info(&(self->connection)));
+#else
+	return PyString_FromString(mysql_get_host_info(&(self->connection)));
+#endif
+}
+
+static char _mysql_ConnectionObject_get_proto_info__doc__[] =
+"Returns an unsigned integer representing the protocol version\n\
+used by the current connection. Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_get_proto_info(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	return PyInt_FromLong((long)mysql_get_proto_info(&(self->connection)));
+}
+
+static char _mysql_ConnectionObject_get_server_info__doc__[] =
+"Returns a string that represents the server version number.\n\
+Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_get_server_info(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+#ifdef IS_PY3K
+	return PyUnicode_FromString(mysql_get_server_info(&(self->connection)));
+#else
+	return PyString_FromString(mysql_get_server_info(&(self->connection)));
+#endif
+}
+
+static char _mysql_ConnectionObject_info__doc__[] =
+"Retrieves a string providing information about the most\n\
+recently executed query. Non-standard. Use messages or\n\
+Cursor.messages.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_info(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	const char *s;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	s = mysql_info(&(self->connection));
+#ifdef IS_PY3K
+	if (s) return PyUnicode_FromString(s);
+#else
+	if (s) return PyString_FromString(s);
+#endif
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_insert_id__doc__[] =
+"Returns the ID generated for an AUTO_INCREMENT column by the previous\n\
+query. Use this function after you have performed an INSERT query into a\n\
+table that contains an AUTO_INCREMENT field.\n\
+\n\
+Note that this returns 0 if the previous query does not\n\
+generate an AUTO_INCREMENT value. If you need to save the value for\n\
+later, be sure to call this immediately after the query\n\
+that generates the value.\n\
+\n\
+The ID is updated after INSERT and UPDATE statements that generate\n\
+an AUTO_INCREMENT value or that set a column value to\n\
+LAST_INSERT_ID(expr). See section 6.3.5.2 Miscellaneous Functions\n\
+in the MySQL documentation.\n\
+\n\
+Also note that the value of the SQL LAST_INSERT_ID() function always\n\
+contains the most recently generated AUTO_INCREMENT value, and is not\n\
+reset between queries because the value of that function is maintained\n\
+in the server.\n\
+" ;
+
+static PyObject *
+_mysql_ConnectionObject_insert_id(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	my_ulonglong r;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	r = mysql_insert_id(&(self->connection));
+	Py_END_ALLOW_THREADS
+	return PyLong_FromUnsignedLongLong(r);
+}
+
+static char _mysql_ConnectionObject_kill__doc__[] =
+"Asks the server to kill the thread specified by pid.\n\
+Non-standard.";
+
+static PyObject *
+_mysql_ConnectionObject_kill(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	unsigned long pid;
+	int r;
+	if (!PyArg_ParseTuple(args, "k:kill", &pid)) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	r = mysql_kill(&(self->connection), pid);
+	Py_END_ALLOW_THREADS
+	if (r) return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_field_count__doc__[] =
+"Returns the number of columns for the most recent query on the\n\
+connection. Non-standard. Will probably give you bogus results\n\
+on most cursor classes. Use Cursor.rowcount.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_field_count(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+#if MYSQL_VERSION_ID < 32224
+	return PyInt_FromLong((long)mysql_num_fields(&(self->connection)));
+#else
+	return PyInt_FromLong((long)mysql_field_count(&(self->connection)));
+#endif
+}	
+
+static char _mysql_ResultObject_num_fields__doc__[] =
+"Returns the number of fields (column) in the result." ;
+
+static PyObject *
+_mysql_ResultObject_num_fields(
+	_mysql_ResultObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_result_connection(self);
+	return PyInt_FromLong((long)mysql_num_fields(self->result));
+}	
+
+static char _mysql_ResultObject_num_rows__doc__[] =
+"Returns the number of rows in the result set. Note that if\n\
+use=1, this will not return a valid value until the entire result\n\
+set has been read.\n\
+";
+
+static PyObject *
+_mysql_ResultObject_num_rows(
+	_mysql_ResultObject *self,
+	PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_result_connection(self);
+	return PyLong_FromUnsignedLongLong(mysql_num_rows(self->result));
+}	
+
+static char _mysql_ConnectionObject_ping__doc__[] =
+"Checks whether or not the connection to the server is\n\
+working. If it has gone down, an automatic reconnection is\n\
+attempted.\n\
+\n\
+This function can be used by clients that remain idle for a\n\
+long while, to check whether or not the server has closed the\n\
+connection and reconnect if necessary.\n\
+\n\
+New in 1.2.2: Accepts an optional reconnect parameter. If True,\n\
+then the client will attempt reconnection. Note that this setting\n\
+is persistent. By default, this is on in MySQL<5.0.3, and off\n\
+thereafter.\n\
+\n\
+Non-standard. You should assume that ping() performs an\n\
+implicit rollback; use only when starting a new transaction.\n\
+You have been warned.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_ping(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	int r, reconnect = -1;
+	if (!PyArg_ParseTuple(args, "|I", &reconnect)) return NULL;
+	check_connection(self);
+	if ( reconnect != -1 ) self->connection.reconnect = reconnect;
+	Py_BEGIN_ALLOW_THREADS
+	r = mysql_ping(&(self->connection));
+	Py_END_ALLOW_THREADS
+	if (r) 	return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_query__doc__[] =
+"Execute a query. store_result() or use_result() will get the\n\
+result set, if any. Non-standard. Use cursor() to create a cursor,\n\
+then cursor.execute().\n\
+" ;
+
+static PyObject *
+_mysql_ConnectionObject_query(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	char *query;
+	int len, r;
+	if (!PyArg_ParseTuple(args, "s#:query", &query, &len)) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	r = mysql_real_query(&(self->connection), query, len);
+	Py_END_ALLOW_THREADS
+	if (r) return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
+static char _mysql_ConnectionObject_select_db__doc__[] =
+"Causes the database specified by db to become the default\n\
+(current) database on the connection specified by mysql. In subsequent\n\
+queries, this database is the default for table references that do not\n\
+include an explicit database specifier.\n\
+\n\
+Fails unless the connected user can be authenticated as having\n\
+permission to use the database.\n\
+\n\
+Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_select_db(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	char *db;
+	int r;
+	if (!PyArg_ParseTuple(args, "s:select_db", &db)) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	r = mysql_select_db(&(self->connection), db);
+	Py_END_ALLOW_THREADS
+	if (r) 	return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_shutdown__doc__[] =
+"Asks the database server to shut down. The connected user must\n\
+have shutdown privileges. Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_shutdown(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	int r;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	r = mysql_shutdown(&(self->connection)
+#if MYSQL_VERSION_ID >= 40103
+		, SHUTDOWN_DEFAULT
+#endif
+		);
+	Py_END_ALLOW_THREADS
+	if (r) return _mysql_Exception(self);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ConnectionObject_stat__doc__[] =
+"Returns a character string containing information similar to\n\
+that provided by the mysqladmin status command. This includes\n\
+uptime in seconds and the number of running threads,\n\
+questions, reloads, and open tables. Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_stat(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	const char *s;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	s = mysql_stat(&(self->connection));
+	Py_END_ALLOW_THREADS
+	if (!s) return _mysql_Exception(self);
+#ifdef IS_PY3K
+	return PyUnicode_FromString(s);
+#else
+	return PyString_FromString(s);
+#endif
+
+}
+
+static char _mysql_ConnectionObject_store_result__doc__[] =
+"Returns a result object acquired by mysql_store_result\n\
+(results stored in the client). If no results are available,\n\
+None is returned. Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_store_result(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	PyObject *arglist=NULL, *kwarglist=NULL, *result=NULL;
+	_mysql_ResultObject *r=NULL;
+
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	arglist = Py_BuildValue("(OiO)", self, 0, self->converter);
+	if (!arglist) goto error;
+	kwarglist = PyDict_New();
+	if (!kwarglist) goto error;
+	r = MyAlloc(_mysql_ResultObject, _mysql_ResultObject_Type);
+	if (!r) goto error;
+	if (_mysql_ResultObject_Initialize(r, arglist, kwarglist))
+		goto error;
+	result = (PyObject *) r;
+	if (!(r->result)) {
+		Py_DECREF(result);
+		Py_INCREF(Py_None);
+		result = Py_None;
+	}
+  error:
+	Py_XDECREF(arglist);
+	Py_XDECREF(kwarglist);
+	return result;
+}
+
+static char _mysql_ConnectionObject_thread_id__doc__[] =
+"Returns the thread ID of the current connection. This value\n\
+can be used as an argument to kill() to kill the thread.\n\
+\n\
+If the connection is lost and you reconnect with ping(), the\n\
+thread ID will change. This means you should not get the\n\
+thread ID and store it for later. You should get it when you\n\
+need it.\n\
+\n\
+Non-standard.";
+
+static PyObject *
+_mysql_ConnectionObject_thread_id(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	unsigned long pid;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	Py_BEGIN_ALLOW_THREADS
+	pid = mysql_thread_id(&(self->connection));
+	Py_END_ALLOW_THREADS
+	return PyInt_FromLong((long)pid);
+}
+
+static char _mysql_ConnectionObject_use_result__doc__[] =
+"Returns a result object acquired by mysql_use_result\n\
+(results stored in the server). If no results are available,\n\
+None is returned. Non-standard.\n\
+";
+
+static PyObject *
+_mysql_ConnectionObject_use_result(
+	_mysql_ConnectionObject *self,
+	PyObject *args)
+{
+	PyObject *arglist=NULL, *kwarglist=NULL, *result=NULL;
+	_mysql_ResultObject *r=NULL;
+
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_connection(self);
+	arglist = Py_BuildValue("(OiO)", self, 1, self->converter);
+	if (!arglist) return NULL;
+	kwarglist = PyDict_New();
+	if (!kwarglist) goto error;
+	r = MyAlloc(_mysql_ResultObject, _mysql_ResultObject_Type);
+	if (!r) goto error;
+	result = (PyObject *) r;
+	if (_mysql_ResultObject_Initialize(r, arglist, kwarglist))
+		goto error;
+	if (!(r->result)) {
+		Py_DECREF(result);
+		Py_INCREF(Py_None);
+		result = Py_None;
+	}
+  error:
+	Py_DECREF(arglist);
+	Py_XDECREF(kwarglist);
+	return result;
+}
+
+static void
+_mysql_ConnectionObject_dealloc(
+	_mysql_ConnectionObject *self)
+{
+	PyObject *o;
+
+	PyObject_GC_UnTrack(self);
+	if (self->open) {
+		o = _mysql_ConnectionObject_close(self, NULL);
+		Py_XDECREF(o);
+	}
+	MyFree(self);
+}
+
+static PyObject *
+_mysql_ConnectionObject_repr(
+	_mysql_ConnectionObject *self)
+{
+	char buf[300];
+	if (self->open)
+		sprintf(buf, "<_mysql.connection open to '%.256s' at %lx>",
+			self->connection.host,
+			(long)self);
+	else
+		sprintf(buf, "<_mysql.connection closed at %lx>",
+			(long)self);
+#ifdef IS_PY3K
+	return PyUnicode_FromString(buf);
+#else
+	return PyString_FromString(buf);
+#endif
+}
+
+static char _mysql_ResultObject_data_seek__doc__[] =
+"data_seek(n) -- seek to row n of result set";
+static PyObject *
+_mysql_ResultObject_data_seek(
+     _mysql_ResultObject *self,
+     PyObject *args)
+{
+	unsigned int row;
+	if (!PyArg_ParseTuple(args, "i:data_seek", &row)) return NULL;
+	check_result_connection(self);
+	mysql_data_seek(self->result, row);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ResultObject_row_seek__doc__[] =
+"row_seek(n) -- seek by offset n rows of result set";
+static PyObject *
+_mysql_ResultObject_row_seek(
+     _mysql_ResultObject *self,
+     PyObject *args)
+{
+	int offset;
+        MYSQL_ROW_OFFSET r;
+	if (!PyArg_ParseTuple(args, "i:row_seek", &offset)) return NULL;
+	check_result_connection(self);
+	if (self->use) {
+		PyErr_SetString(_mysql_ProgrammingError,
+				"cannot be used with connection.use_result()");
+		return NULL;
+	}
+	r = mysql_row_tell(self->result);
+	mysql_row_seek(self->result, r+offset);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static char _mysql_ResultObject_row_tell__doc__[] =
+"row_tell() -- return the current row number of the result set.";
+static PyObject *
+_mysql_ResultObject_row_tell(
+	_mysql_ResultObject *self,
+	PyObject *args)
+{
+	MYSQL_ROW_OFFSET r;
+	if (!PyArg_ParseTuple(args, "")) return NULL;
+	check_result_connection(self);
+	if (self->use) {
+		PyErr_SetString(_mysql_ProgrammingError,
+				"cannot be used with connection.use_result()");
+		return NULL;
+	}
+	r = mysql_row_tell(self->result);
+	return PyInt_FromLong(r-self->result->data->data);
+}
+
+static void
+_mysql_ResultObject_dealloc(
+	_mysql_ResultObject *self)
+{
+	PyObject_GC_UnTrack((PyObject *)self);
+	mysql_free_result(self->result);
+	_mysql_ResultObject_clear(self);
+	MyFree(self);
+}
+
+static PyObject *
+_mysql_ResultObject_repr(
+	_mysql_ResultObject *self)
+{
+	char buf[300];
+	sprintf(buf, "<_mysql.result object at %lx>",
+		(long)self);
+#ifdef IS_PY3K
+	return PyUnicode_FromString(buf);
+#else
+	return PyString_FromString(buf);
+#endif
+}
+
+static PyMethodDef _mysql_ConnectionObject_methods[] = {
+	{
+		"affected_rows",
+		(PyCFunction)_mysql_ConnectionObject_affected_rows,
+		METH_VARARGS,
+		_mysql_ConnectionObject_affected_rows__doc__
+	},
+	{
+		"autocommit",
+		(PyCFunction)_mysql_ConnectionObject_autocommit,
+		METH_VARARGS,
+		_mysql_ConnectionObject_autocommit__doc__
+	},
+	{
+		"get_autocommit",
+		(PyCFunction)_mysql_ConnectionObject_get_autocommit,
+		METH_NOARGS,
+		_mysql_ConnectionObject_get_autocommit__doc__
+	},
+	{
+		"commit",
+		(PyCFunction)_mysql_ConnectionObject_commit,
+		METH_VARARGS,
+		_mysql_ConnectionObject_commit__doc__
+	},
+	{
+		"rollback",
+		(PyCFunction)_mysql_ConnectionObject_rollback,
+		METH_VARARGS,
+		_mysql_ConnectionObject_rollback__doc__
+	},
+	{
+		"next_result",
+		(PyCFunction)_mysql_ConnectionObject_next_result,
+		METH_VARARGS,
+		_mysql_ConnectionObject_next_result__doc__
+	},
+#if MYSQL_VERSION_ID >= 40100
+	{
+		"set_server_option",
+		(PyCFunction)_mysql_ConnectionObject_set_server_option,
+		METH_VARARGS,
+		_mysql_ConnectionObject_set_server_option__doc__
+	},
+	{
+		"sqlstate",
+		(PyCFunction)_mysql_ConnectionObject_sqlstate,
+		METH_VARARGS,
+		_mysql_ConnectionObject_sqlstate__doc__
+	},
+	{
+		"warning_count",
+		(PyCFunction)_mysql_ConnectionObject_warning_count,
+		METH_VARARGS,
+		_mysql_ConnectionObject_warning_count__doc__
+	},
+#endif
+#if MYSQL_VERSION_ID >= 32303
+	{
+		"change_user",
+		(PyCFunction)_mysql_ConnectionObject_change_user,
+		METH_VARARGS | METH_KEYWORDS,
+		_mysql_ConnectionObject_change_user__doc__
+	},
+#endif
+	{
+		"character_set_name",
+		(PyCFunction)_mysql_ConnectionObject_character_set_name,
+		METH_VARARGS,
+		_mysql_ConnectionObject_character_set_name__doc__
+	},
+#if MYSQL_VERSION_ID >= 50007
+	{
+		"set_character_set",
+		(PyCFunction)_mysql_ConnectionObject_set_character_set,
+		METH_VARARGS,
+		_mysql_ConnectionObject_set_character_set__doc__
+	},
+#endif
+#if MYSQL_VERSION_ID >= 50010
+	{
+		"get_character_set_info",
+		(PyCFunction)_mysql_ConnectionObject_get_character_set_info,
+		METH_VARARGS,
+		_mysql_ConnectionObject_get_character_set_info__doc__
+	},
+#endif
+	{
+		"close",
+		(PyCFunction)_mysql_ConnectionObject_close,
+		METH_VARARGS,
+		_mysql_ConnectionObject_close__doc__
+	},
+	{
+		"dump_debug_info",
+		(PyCFunction)_mysql_ConnectionObject_dump_debug_info,
+		METH_VARARGS,
+		_mysql_ConnectionObject_dump_debug_info__doc__
+	},
+	{
+		"escape",
+		(PyCFunction)_mysql_escape,
+		METH_VARARGS,
+		_mysql_escape__doc__
+	},
+	{
+		"escape_string",
+		(PyCFunction)_mysql_escape_string,
+		METH_VARARGS,
+		_mysql_escape_string__doc__
+	},
+	{
+		"error",
+		(PyCFunction)_mysql_ConnectionObject_error,
+		METH_VARARGS,
+		_mysql_ConnectionObject_error__doc__
+	},
+	{
+		"errno",
+		(PyCFunction)_mysql_ConnectionObject_errno,
+		METH_VARARGS,
+		_mysql_ConnectionObject_errno__doc__
+	},
+	{
+		"field_count",
+		(PyCFunction)_mysql_ConnectionObject_field_count,
+		METH_VARARGS,
+		_mysql_ConnectionObject_field_count__doc__
+	}, 
+	{
+		"get_host_info",
+		(PyCFunction)_mysql_ConnectionObject_get_host_info,
+		METH_VARARGS,
+		_mysql_ConnectionObject_get_host_info__doc__
+	},
+	{
+		"get_proto_info",
+		(PyCFunction)_mysql_ConnectionObject_get_proto_info,
+		METH_VARARGS,
+		_mysql_ConnectionObject_get_proto_info__doc__
+	},
+	{
+		"get_server_info",
+		(PyCFunction)_mysql_ConnectionObject_get_server_info,
+		METH_VARARGS,
+		_mysql_ConnectionObject_get_server_info__doc__
+	},
+	{
+		"info",
+		(PyCFunction)_mysql_ConnectionObject_info,
+		METH_VARARGS,
+		_mysql_ConnectionObject_info__doc__
+	},
+	{
+		"insert_id",
+		(PyCFunction)_mysql_ConnectionObject_insert_id,
+		METH_VARARGS,
+		_mysql_ConnectionObject_insert_id__doc__
+	},
+	{
+		"kill",
+		(PyCFunction)_mysql_ConnectionObject_kill,
+		METH_VARARGS,
+		_mysql_ConnectionObject_kill__doc__
+	},
+	{
+		"ping",
+		(PyCFunction)_mysql_ConnectionObject_ping,
+		METH_VARARGS,
+		_mysql_ConnectionObject_ping__doc__
+	},
+	{
+		"query",
+		(PyCFunction)_mysql_ConnectionObject_query,
+		METH_VARARGS,
+		_mysql_ConnectionObject_query__doc__
+	},
+	{
+		"select_db",
+		(PyCFunction)_mysql_ConnectionObject_select_db,
+		METH_VARARGS,
+		_mysql_ConnectionObject_select_db__doc__
+	},
+	{
+		"shutdown",
+		(PyCFunction)_mysql_ConnectionObject_shutdown,
+		METH_VARARGS,
+		_mysql_ConnectionObject_shutdown__doc__
+	},
+	{
+		"stat",
+		(PyCFunction)_mysql_ConnectionObject_stat,
+		METH_VARARGS,
+		_mysql_ConnectionObject_stat__doc__
+	},
+	{
+		"store_result",
+		(PyCFunction)_mysql_ConnectionObject_store_result,
+		METH_VARARGS,
+		_mysql_ConnectionObject_store_result__doc__
+	},
+	{
+		"string_literal",
+		(PyCFunction)_mysql_string_literal,
+		METH_VARARGS,
+		_mysql_string_literal__doc__},
+	{
+		"thread_id",
+		(PyCFunction)_mysql_ConnectionObject_thread_id,
+		METH_VARARGS,
+		_mysql_ConnectionObject_thread_id__doc__
+	},
+	{
+		"use_result",
+		(PyCFunction)_mysql_ConnectionObject_use_result,
+		METH_VARARGS,
+		_mysql_ConnectionObject_use_result__doc__
+	},
+	{NULL,              NULL} /* sentinel */
+};
+
+static MyMemberlist(_mysql_ConnectionObject_memberlist)[] = {
+	MyMember(
+		"open",
+		T_INT,
+		offsetof(_mysql_ConnectionObject,open),
+		READONLY,
+		"True if connection is open"
+		),
+	MyMember(
+		"converter",
+		T_OBJECT,
+		offsetof(_mysql_ConnectionObject,converter),
+		0,
+		"Type conversion mapping"
+		),
+	MyMember(
+		"server_capabilities",
+		T_UINT,
+		offsetof(_mysql_ConnectionObject,connection.server_capabilities),
+		READONLY,
+		"Capabilites of server; consult MySQLdb.constants.CLIENT"
+		),
+	MyMember(
+		 "port",
+		 T_UINT,
+		 offsetof(_mysql_ConnectionObject,connection.port),
+		 READONLY,
+		 "TCP/IP port of the server connection"
+		 ),
+	MyMember(
+		 "client_flag",
+		 T_UINT,
+		 READONLY,
+		 offsetof(_mysql_ConnectionObject,connection.client_flag),
+		 "Client flags; refer to MySQLdb.constants.CLIENT"
+		 ),
+	{NULL} /* Sentinel */
+};
+
+static PyMethodDef _mysql_ResultObject_methods[] = {
+	{
+		"data_seek",
+		(PyCFunction)_mysql_ResultObject_data_seek,
+		METH_VARARGS,
+		_mysql_ResultObject_data_seek__doc__
+	},
+	{
+		"row_seek",
+		(PyCFunction)_mysql_ResultObject_row_seek,
+		METH_VARARGS,
+		_mysql_ResultObject_row_seek__doc__
+	},
+	{
+		"row_tell",
+		(PyCFunction)_mysql_ResultObject_row_tell,
+		METH_VARARGS,
+		_mysql_ResultObject_row_tell__doc__
+	},
+	{
+		"describe",
+		(PyCFunction)_mysql_ResultObject_describe,
+		METH_VARARGS,
+		_mysql_ResultObject_describe__doc__
+	},
+	{
+		"fetch_row",
+		(PyCFunction)_mysql_ResultObject_fetch_row,
+		METH_VARARGS | METH_KEYWORDS,
+		_mysql_ResultObject_fetch_row__doc__
+	},
+	{
+		"field_flags",
+		(PyCFunction)_mysql_ResultObject_field_flags,
+		METH_VARARGS,
+		_mysql_ResultObject_field_flags__doc__
+	},
+	{
+		"num_fields",
+		(PyCFunction)_mysql_ResultObject_num_fields,
+		METH_VARARGS,
+		_mysql_ResultObject_num_fields__doc__
+	},
+	{
+		"num_rows",
+		(PyCFunction)_mysql_ResultObject_num_rows,
+		METH_VARARGS,
+		_mysql_ResultObject_num_rows__doc__
+	},
+	{NULL,              NULL} /* sentinel */
+};
+
+static MyMemberlist(_mysql_ResultObject_memberlist)[] = {
+	MyMember(
+		"converter",
+		T_OBJECT,
+		offsetof(_mysql_ResultObject,converter),
+		READONLY,
+		"Type conversion mapping"
+		),
+	{NULL} /* Sentinel */
+};
+
+static PyObject *
+_mysql_ConnectionObject_getattr(
+	_mysql_ConnectionObject *self,
+	char *name)
+{
+#ifndef IS_PY3K
+	PyObject *res;
+
+	res = Py_FindMethod(_mysql_ConnectionObject_methods, (PyObject *)self, name);
+	if (res != NULL)
+		return res;
+	PyErr_Clear();
+#endif
+	if (strcmp(name, "closed") == 0)
+		return PyInt_FromLong((long)!(self->open));
+#if PY_VERSION_HEX < 0x02020000
+	return PyMember_Get((char *)self, _mysql_ConnectionObject_memberlist, name);
+#else
+	{
+		MyMemberlist(*l);
+		for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++) {
+			if (strcmp(l->name, name) == 0)
+				return PyMember_GetOne((char *)self, l);
+		}
+		PyErr_SetString(PyExc_AttributeError, name);
+		return NULL;
+	}
+#endif
+}
+
+static PyObject *
+_mysql_ResultObject_getattr(
+	_mysql_ResultObject *self,
+	char *name)
+{
+#ifndef IS_PY3K
+	PyObject *res;
+
+	res = Py_FindMethod(_mysql_ResultObject_methods, (PyObject *)self, name);
+	if (res != NULL)
+		return res;
+	PyErr_Clear();
+#endif
+#if PY_VERSION_HEX < 0x02020000
+	return PyMember_Get((char *)self, _mysql_ResultObject_memberlist, name);
+#else
+	{
+		MyMemberlist(*l);
+		for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++) {
+			if (strcmp(l->name, name) == 0)
+				return PyMember_GetOne((char *)self, l);
+		}
+		PyErr_SetString(PyExc_AttributeError, name);
+		return NULL;
+	}
+#endif
+}
+
+static int
+_mysql_ConnectionObject_setattr(
+	_mysql_ConnectionObject *self,
+	char *name,
+	PyObject *v)
+{
+	if (v == NULL) {
+		PyErr_SetString(PyExc_AttributeError,
+				"can't delete connection attributes");
+		return -1;
+	}
+#if PY_VERSION_HEX < 0x02020000
+	return PyMember_Set((char *)self, _mysql_ConnectionObject_memberlist, name, v);
+#else
+        {
+		MyMemberlist(*l);
+		for (l = _mysql_ConnectionObject_memberlist; l->name != NULL; l++)
+			if (strcmp(l->name, name) == 0)
+				return PyMember_SetOne((char *)self, l, v);
+	}
+        PyErr_SetString(PyExc_AttributeError, name);
+        return -1;
+#endif
+}
+
+static int
+_mysql_ResultObject_setattr(
+	_mysql_ResultObject *self,
+	char *name,
+	PyObject *v)
+{
+	if (v == NULL) {
+		PyErr_SetString(PyExc_AttributeError,
+				"can't delete connection attributes");
+		return -1;
+	}
+#if PY_VERSION_HEX < 0x02020000
+	return PyMember_Set((char *)self, _mysql_ResultObject_memberlist, name, v);
+#else
+        {
+		MyMemberlist(*l);
+		for (l = _mysql_ResultObject_memberlist; l->name != NULL; l++)
+			if (strcmp(l->name, name) == 0)
+				return PyMember_SetOne((char *)self, l, v);
+	}
+        PyErr_SetString(PyExc_AttributeError, name);
+        return -1;
+#endif
+}
+
+PyTypeObject _mysql_ConnectionObject_Type = {
+#ifdef IS_PY3K
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
+	PyObject_HEAD_INIT(NULL)
+	0,
+#endif
+	"_mysql.connection", /* (char *)tp_name For printing */
+	sizeof(_mysql_ConnectionObject),
+	0,
+	(destructor)_mysql_ConnectionObject_dealloc, /* tp_dealloc */
+	0, /*tp_print*/
+	(getattrfunc)_mysql_ConnectionObject_getattr, /* tp_getattr */
+	(setattrfunc)_mysql_ConnectionObject_setattr, /* tp_setattr */
+	0, /*tp_compare*/
+	(reprfunc)_mysql_ConnectionObject_repr, /* tp_repr */
+	
+	/* Method suites for standard classes */
+	
+	0, /* (PyNumberMethods *) tp_as_number */
+	0, /* (PySequenceMethods *) tp_as_sequence */
+	0, /* (PyMappingMethods *) tp_as_mapping */
+	
+	/* More standard operations (here for binary compatibility) */
+	
+	0, /* (hashfunc) tp_hash */
+	0, /* (ternaryfunc) tp_call */
+	0, /* (reprfunc) tp_str */
+	0, /* (getattrofunc) tp_getattro */
+	0, /* (setattrofunc) tp_setattro */
+	
+	/* Functions to access object as input/output buffer */
+	0, /* (PyBufferProcs *) tp_as_buffer */
+	
+	/* Flags to define presence of optional/expanded features */
+#if PY_VERSION_HEX < 0x02020000
+	Py_TPFLAGS_DEFAULT, /* (long) tp_flags */
+#else
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
+#endif
+	_mysql_connect__doc__, /* (char *) tp_doc Documentation string */
+#if PY_VERSION_HEX >= 0x02000000	
+	/* Assigned meaning in release 2.0 */
+#if PY_VERSION_HEX >= 0x02020000
+	/* call function for all accessible objects */
+	(traverseproc) _mysql_ConnectionObject_traverse, /* tp_traverse */
+	
+	/* delete references to contained objects */
+	(inquiry) _mysql_ConnectionObject_clear, /* tp_clear */
+#else
+	/* not supporting pre-2.2 GC */
+	0,
+	0,
+#endif
+#if PY_VERSION_HEX >= 0x02010000	
+	/* Assigned meaning in release 2.1 */
+	/* rich comparisons */
+	0, /* (richcmpfunc) tp_richcompare */
+	
+	/* weak reference enabler */
+	0, /* (long) tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+	/* Added in release 2.2 */
+	/* Iterators */
+	0, /* (getiterfunc) tp_iter */
+	0, /* (iternextfunc) tp_iternext */
+	
+	/* Attribute descriptor and subclassing stuff */
+	(struct PyMethodDef *)_mysql_ConnectionObject_methods, /* tp_methods */
+	(MyMemberlist(*))_mysql_ConnectionObject_memberlist, /* tp_members */
+	0, /* (struct getsetlist *) tp_getset; */
+	0, /* (struct _typeobject *) tp_base; */
+	0, /* (PyObject *) tp_dict */
+	0, /* (descrgetfunc) tp_descr_get */
+	0, /* (descrsetfunc) tp_descr_set */
+	0, /* (long) tp_dictoffset */
+	(initproc)_mysql_ConnectionObject_Initialize, /* tp_init */
+	NULL, /* tp_alloc */
+	NULL, /* tp_new */
+	NULL, /* tp_free Low-level free-memory routine */ 
+	0, /* (PyObject *) tp_bases */
+	0, /* (PyObject *) tp_mro method resolution order */
+	0, /* (PyObject *) tp_defined */
+#endif /* python 2.2 */
+#endif /* python 2.1 */
+#endif /* python 2.0 */
+} ;
+
+PyTypeObject _mysql_ResultObject_Type = {
+#ifdef IS_PY3K
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
+	PyObject_HEAD_INIT(NULL)
+	0,
+#endif
+	"_mysql.result",
+	sizeof(_mysql_ResultObject),
+	0,
+	(destructor)_mysql_ResultObject_dealloc, /* tp_dealloc */
+	0, /*tp_print*/
+	(getattrfunc)_mysql_ResultObject_getattr, /* tp_getattr */
+	(setattrfunc)_mysql_ResultObject_setattr, /* tp_setattr */
+	0, /*tp_compare*/
+	(reprfunc)_mysql_ResultObject_repr, /* tp_repr */
+	
+	/* Method suites for standard classes */
+	
+	0, /* (PyNumberMethods *) tp_as_number */
+	0, /* (PySequenceMethods *) tp_as_sequence */
+	0, /* (PyMappingMethods *) tp_as_mapping */
+	
+	/* More standard operations (here for binary compatibility) */
+	
+	0, /* (hashfunc) tp_hash */
+	0, /* (ternaryfunc) tp_call */
+	0, /* (reprfunc) tp_str */
+	0, /* (getattrofunc) tp_getattro */
+	0, /* (setattrofunc) tp_setattro */
+	
+	/* Functions to access object as input/output buffer */
+	0, /* (PyBufferProcs *) tp_as_buffer */
+	
+	/* Flags to define presence of optional/expanded features */
+#if PY_VERSION_HEX < 0x02020000
+	Py_TPFLAGS_DEFAULT, /* (long) tp_flags */
+#else
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
+#endif
+	
+	_mysql_ResultObject__doc__, /* (char *) tp_doc Documentation string */
+#if PY_VERSION_HEX >= 0x02000000	
+	/* Assigned meaning in release 2.0 */
+#if PY_VERSION_HEX >= 0x02020000
+	/* call function for all accessible objects */
+	(traverseproc) _mysql_ResultObject_traverse, /* tp_traverse */
+	
+	/* delete references to contained objects */
+	(inquiry) _mysql_ResultObject_clear, /* tp_clear */
+#else
+	/* not supporting pre-2.2 GC */
+	0,
+	0,
+#endif
+#if PY_VERSION_HEX >= 0x02010000	
+	/* Assigned meaning in release 2.1 */
+	/* rich comparisons */
+	0, /* (richcmpfunc) tp_richcompare */
+	
+	/* weak reference enabler */
+	0, /* (long) tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+	/* Added in release 2.2 */
+	/* Iterators */
+	0, /* (getiterfunc) tp_iter */
+	0, /* (iternextfunc) tp_iternext */
+	
+	/* Attribute descriptor and subclassing stuff */
+	(struct PyMethodDef *) _mysql_ResultObject_methods, /* tp_methods */
+	(MyMemberlist(*)) _mysql_ResultObject_memberlist, /*tp_members */
+	0, /* (struct getsetlist *) tp_getset; */
+	0, /* (struct _typeobject *) tp_base; */
+	0, /* (PyObject *) tp_dict */
+	0, /* (descrgetfunc) tp_descr_get */
+	0, /* (descrsetfunc) tp_descr_set */
+	0, /* (long) tp_dictoffset */
+	(initproc)_mysql_ResultObject_Initialize, /* tp_init */
+	NULL, /* tp_alloc */
+	NULL, /* tp_new */
+	NULL, /* tp_free Low-level free-memory routine */
+	0, /* (PyObject *) tp_bases */
+	0, /* (PyObject *) tp_mro method resolution order */
+	0, /* (PyObject *) tp_defined */
+#endif /* python 2.2 */
+#endif /* python 2.1 */
+#endif /* python 2.0 */
+};
+
+static PyMethodDef
+_mysql_methods[] = {
+	{ 
+		"connect",
+		(PyCFunction)_mysql_connect,
+		METH_VARARGS | METH_KEYWORDS,
+		_mysql_connect__doc__
+	},
+	{ 
+		"debug",
+		(PyCFunction)_mysql_debug, 
+		METH_VARARGS,
+		_mysql_debug__doc__
+	},
+	{
+		"escape", 
+		(PyCFunction)_mysql_escape, 
+		METH_VARARGS,
+		_mysql_escape__doc__
+	},
+	{
+		"escape_sequence",
+		(PyCFunction)_mysql_escape_sequence,
+		METH_VARARGS,
+		_mysql_escape_sequence__doc__
+	},
+	{
+		"escape_dict",
+		(PyCFunction)_mysql_escape_dict,
+		METH_VARARGS,
+		_mysql_escape_dict__doc__
+	},
+	{ 
+		"escape_string",
+		(PyCFunction)_mysql_escape_string,
+		METH_VARARGS,
+		_mysql_escape_string__doc__
+	},
+	{ 
+		"string_literal",
+		(PyCFunction)_mysql_string_literal,
+		METH_VARARGS,
+		_mysql_string_literal__doc__
+	},
+	{
+		"get_client_info",
+		(PyCFunction)_mysql_get_client_info,
+		METH_VARARGS,
+		_mysql_get_client_info__doc__
+	},
+#if MYSQL_VERSION_ID >= 32314
+	{
+		"thread_safe",
+		(PyCFunction)_mysql_thread_safe,
+		METH_VARARGS,
+		_mysql_thread_safe__doc__
+	},
+#endif
+	{
+		"server_init",
+		(PyCFunction)_mysql_server_init,
+		METH_VARARGS | METH_KEYWORDS,
+		_mysql_server_init__doc__
+	},
+	{
+		"server_end",
+		(PyCFunction)_mysql_server_end,
+		METH_VARARGS,
+		_mysql_server_end__doc__
+	},
+	{NULL, NULL} /* sentinel */
+};
+
+static PyObject *
+_mysql_NewException(
+	PyObject *dict,
+	PyObject *edict,
+	char *name)
+{
+	PyObject *e;
+
+	if (!(e = PyDict_GetItemString(edict, name)))
+		return NULL;
+	if (PyDict_SetItemString(dict, name, e)) return NULL;
+#ifdef PYPY_VERSION
+	Py_INCREF(e);
+#endif
+	return e;
+}
+
+#define QUOTE(X) _QUOTE(X)
+#define _QUOTE(X) #X
+
+static char _mysql___doc__[] =
+"an adaptation of the MySQL C API (mostly)\n\
+\n\
+You probably are better off using MySQLdb instead of using this\n\
+module directly.\n\
+\n\
+In general, renaming goes from mysql_* to _mysql.*. _mysql.connect()\n\
+returns a connection object (MYSQL). Functions which expect MYSQL * as\n\
+an argument are now methods of the connection object. A number of things\n\
+return result objects (MYSQL_RES). Functions which expect MYSQL_RES * as\n\
+an argument are now methods of the result object. Deprecated functions\n\
+(as of 3.23) are NOT implemented.\n\
+";
+
+#ifdef IS_PY3K
+static struct PyModuleDef _mysqlmodule = {
+   PyModuleDef_HEAD_INIT,
+   "_mysql",   /* name of module */
+   _mysql___doc__, /* module documentation, may be NULL */
+   -1,       /* size of per-interpreter state of the module,
+                or -1 if the module keeps state in global variables. */
+   _mysql_methods
+};
+
+PyMODINIT_FUNC
+PyInit__mysql(void)
+#else
+DL_EXPORT(void)
+init_mysql(void)
+#endif
+{
+	PyObject *dict, *module, *emod, *edict;
+#ifdef IS_PY3K
+    module = PyModule_Create(&_mysqlmodule);
+	if (!module) return module; /* this really should never happen */
+#else
+	module = Py_InitModule4("_mysql", _mysql_methods, _mysql___doc__,
+				(PyObject *)NULL, PYTHON_API_VERSION);
+	if (!module) return; /* this really should never happen */
+#endif
+#ifdef IS_PY3K
+	Py_TYPE(&_mysql_ConnectionObject_Type) = &PyType_Type;
+	Py_TYPE(&_mysql_ResultObject_Type) = &PyType_Type;
+#else
+	_mysql_ConnectionObject_Type.ob_type = &PyType_Type;
+	_mysql_ResultObject_Type.ob_type = &PyType_Type;
+#endif
+#if PY_VERSION_HEX >= 0x02020000
+	_mysql_ConnectionObject_Type.tp_alloc = PyType_GenericAlloc;
+	_mysql_ConnectionObject_Type.tp_new = PyType_GenericNew;
+#ifndef IS_PY3K
+	_mysql_ConnectionObject_Type.tp_free = _PyObject_GC_Del;
+#endif
+	_mysql_ResultObject_Type.tp_alloc = PyType_GenericAlloc;
+	_mysql_ResultObject_Type.tp_new = PyType_GenericNew;
+#ifndef IS_PY3K
+	_mysql_ResultObject_Type.tp_free = _PyObject_GC_Del;
+#endif
+#endif
+
+	if (!(dict = PyModule_GetDict(module))) goto error;
+	if (PyDict_SetItemString(dict, "version_info",
+			       PyRun_String(QUOTE(version_info), Py_eval_input,
+				       dict, dict)))
+		goto error;
+	if (PyDict_SetItemString(dict, "__version__",
+#ifdef IS_PY3K
+			       PyUnicode_FromString(QUOTE(__version__))))
+#else
+			       PyString_FromString(QUOTE(__version__))))
+#endif
+		goto error;
+	if (PyDict_SetItemString(dict, "connection",
+			       (PyObject *)&_mysql_ConnectionObject_Type))
+		goto error;
+	Py_INCREF(&_mysql_ConnectionObject_Type);
+	if (PyDict_SetItemString(dict, "result",
+			       (PyObject *)&_mysql_ResultObject_Type))
+		goto error;	
+	Py_INCREF(&_mysql_ResultObject_Type);
+	if (!(emod = PyImport_ImportModule("_mysql_exceptions"))) {
+	    PyErr_Print();
+		goto error;
+	}
+	if (!(edict = PyModule_GetDict(emod))) goto error;
+	if (!(_mysql_MySQLError =
+	      _mysql_NewException(dict, edict, "MySQLError")))
+		goto error;
+	if (!(_mysql_Warning =
+	      _mysql_NewException(dict, edict, "Warning")))
+		goto error;
+	if (!(_mysql_Error =
+	      _mysql_NewException(dict, edict, "Error")))
+		goto error;
+	if (!(_mysql_InterfaceError =
+	      _mysql_NewException(dict, edict, "InterfaceError")))
+		goto error;
+	if (!(_mysql_DatabaseError =
+	      _mysql_NewException(dict, edict, "DatabaseError")))
+		goto error;
+	if (!(_mysql_DataError =
+	      _mysql_NewException(dict, edict, "DataError")))
+		goto error;
+	if (!(_mysql_OperationalError =
+	      _mysql_NewException(dict, edict, "OperationalError")))
+		goto error;
+	if (!(_mysql_IntegrityError =
+	      _mysql_NewException(dict, edict, "IntegrityError")))
+		goto error;
+	if (!(_mysql_InternalError =
+	      _mysql_NewException(dict, edict, "InternalError")))
+		goto error;
+	if (!(_mysql_ProgrammingError =
+	      _mysql_NewException(dict, edict, "ProgrammingError")))
+		goto error;
+	if (!(_mysql_NotSupportedError =
+	      _mysql_NewException(dict, edict, "NotSupportedError")))
+		goto error;
+	Py_DECREF(emod);
+#ifdef IS_PY3K
+	if (!(_mysql_NULL = PyUnicode_FromString("NULL")))
+		goto error;
+#else
+	if (!(_mysql_NULL = PyString_FromString("NULL")))
+		goto error;
+#endif
+	if (PyDict_SetItemString(dict, "NULL", _mysql_NULL)) goto error;
+  error:
+	if (PyErr_Occurred()) {
+		PyErr_SetString(PyExc_ImportError,
+				"_mysql: init failed");
+		module = NULL;
+    }
+#ifdef IS_PY3K
+    return module;
+#endif
+}
+
+

+ 6 - 2
desktop/core/ext-py/MySQL-python-1.2.3c1/_mysql_exceptions.py → desktop/core/ext-py/MySQL-python-1.2.5/_mysql_exceptions.py

@@ -5,7 +5,12 @@ These classes are dictated by the DB API v2.0:
     http://www.python.org/topics/database/DatabaseAPI-2.0.html
 """
 
-from exceptions import Exception, StandardError, Warning
+try:
+    from exceptions import Exception, StandardError, Warning
+except ImportError:
+    # Python 3
+    StandardError = Exception
+
 
 class MySQLError(StandardError):
     
@@ -80,4 +85,3 @@ class NotSupportedError(DatabaseError):
     has transactions turned off."""
 
 
-del Exception, StandardError

+ 0 - 0
desktop/core/ext-py/MySQL-python-1.2.3c1/doc/FAQ.txt → desktop/core/ext-py/MySQL-python-1.2.5/doc/FAQ.rst


+ 59 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/MySQLdb.constants.rst

@@ -0,0 +1,59 @@
+constants Package
+=================
+
+:mod:`constants` Package
+------------------------
+
+.. automodule:: MySQLdb.constants
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`CLIENT` Module
+--------------------
+
+.. automodule:: MySQLdb.constants.CLIENT
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`CR` Module
+----------------
+
+.. automodule:: MySQLdb.constants.CR
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`ER` Module
+----------------
+
+.. automodule:: MySQLdb.constants.ER
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`FIELD_TYPE` Module
+------------------------
+
+.. automodule:: MySQLdb.constants.FIELD_TYPE
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`FLAG` Module
+------------------
+
+.. automodule:: MySQLdb.constants.FLAG
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`REFRESH` Module
+---------------------
+
+.. automodule:: MySQLdb.constants.REFRESH
+    :members:
+    :undoc-members:
+    :show-inheritance:
+

+ 50 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/MySQLdb.rst

@@ -0,0 +1,50 @@
+MySQLdb Package
+===============
+
+:mod:`MySQLdb` Package
+----------------------
+
+.. automodule:: MySQLdb.__init__
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`connections` Module
+-------------------------
+
+.. automodule:: MySQLdb.connections
+    :members: Connection
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`converters` Module
+------------------------
+
+.. automodule:: MySQLdb.converters
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`cursors` Module
+---------------------
+
+.. automodule:: MySQLdb.cursors
+    :members: Cursor
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`times` Module
+-------------------
+
+.. automodule:: MySQLdb.times
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+Subpackages
+-----------
+
+.. toctree::
+
+    MySQLdb.constants
+

+ 143 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/FAQ.txt

@@ -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
+

+ 59 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/MySQLdb.constants.txt

@@ -0,0 +1,59 @@
+constants Package
+=================
+
+:mod:`constants` Package
+------------------------
+
+.. automodule:: MySQLdb.constants
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`CLIENT` Module
+--------------------
+
+.. automodule:: MySQLdb.constants.CLIENT
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`CR` Module
+----------------
+
+.. automodule:: MySQLdb.constants.CR
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`ER` Module
+----------------
+
+.. automodule:: MySQLdb.constants.ER
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`FIELD_TYPE` Module
+------------------------
+
+.. automodule:: MySQLdb.constants.FIELD_TYPE
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`FLAG` Module
+------------------
+
+.. automodule:: MySQLdb.constants.FLAG
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`REFRESH` Module
+---------------------
+
+.. automodule:: MySQLdb.constants.REFRESH
+    :members:
+    :undoc-members:
+    :show-inheritance:
+

+ 50 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/MySQLdb.txt

@@ -0,0 +1,50 @@
+MySQLdb Package
+===============
+
+:mod:`MySQLdb` Package
+----------------------
+
+.. automodule:: MySQLdb.__init__
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`connections` Module
+-------------------------
+
+.. automodule:: MySQLdb.connections
+    :members: Connection
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`converters` Module
+------------------------
+
+.. automodule:: MySQLdb.converters
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`cursors` Module
+---------------------
+
+.. automodule:: MySQLdb.cursors
+    :members: Cursor
+    :undoc-members:
+    :show-inheritance:
+
+:mod:`times` Module
+-------------------
+
+.. automodule:: MySQLdb.times
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+Subpackages
+-----------
+
+.. toctree::
+
+    MySQLdb.constants
+

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/_mysql.txt

@@ -0,0 +1,7 @@
+_mysql Module
+=============
+
+.. automodule:: _mysql
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/_mysql_exceptions.txt

@@ -0,0 +1,7 @@
+_mysql_exceptions Module
+========================
+
+.. automodule:: _mysql_exceptions
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/distribute_setup.txt

@@ -0,0 +1,7 @@
+distribute_setup Module
+=======================
+
+.. automodule:: distribute_setup
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 24 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/index.txt

@@ -0,0 +1,24 @@
+.. MySQLdb documentation master file, created by
+   sphinx-quickstart on Sun Oct 07 19:36:17 2012.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to MySQLdb's documentation!
+===================================
+
+Contents:
+
+.. toctree::
+    :maxdepth: 3
+
+    user_guide
+    MySQLdb
+    FAQ
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/modules.txt

@@ -0,0 +1,7 @@
+MySQLdb
+=======
+
+.. toctree::
+   :maxdepth: 4
+
+   MySQLdb

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/setup.txt

@@ -0,0 +1,7 @@
+setup Module
+============
+
+.. automodule:: setup
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/setup_common.txt

@@ -0,0 +1,7 @@
+setup_common Module
+===================
+
+.. automodule:: setup_common
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/setup_posix.txt

@@ -0,0 +1,7 @@
+setup_posix Module
+==================
+
+.. automodule:: setup_posix
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/setup_windows.txt

@@ -0,0 +1,7 @@
+setup_windows Module
+====================
+
+.. automodule:: setup_windows
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 1 - 1
desktop/core/ext-py/MySQL-python-1.2.3c1/doc/MySQLdb.txt → desktop/core/ext-py/MySQL-python-1.2.5/doc/_build/_sources/user_guide.txt

@@ -715,4 +715,4 @@ server.
 
 :Title: MySQLdb: a Python interface for MySQL
 :Author: Andy Dustman
-:Version: $Revision: 421 $
+:Version: $Revision$

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_mysql.rst

@@ -0,0 +1,7 @@
+_mysql Module
+=============
+
+.. automodule:: _mysql
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/_mysql_exceptions.rst

@@ -0,0 +1,7 @@
+_mysql_exceptions Module
+========================
+
+.. automodule:: _mysql_exceptions
+    :members:
+    :undoc-members:
+    :show-inheritance:

+ 242 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/conf.py

@@ -0,0 +1,242 @@
+# -*- coding: utf-8 -*-
+#
+# MySQLdb documentation build configuration file, created by
+# sphinx-quickstart on Sun Oct 07 19:36:17 2012.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'MySQLdb'
+copyright = u'2012, Andy Dustman'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.2'
+# The full version, including alpha/beta/rc tags.
+release = '1.2.4b4'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'MySQLdbdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'MySQLdb.tex', u'MySQLdb Documentation',
+   u'Andy Dustman', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'mysqldb', u'MySQLdb Documentation',
+     [u'Andy Dustman'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('index', 'MySQLdb', u'MySQLdb Documentation',
+   u'Andy Dustman', 'MySQLdb', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'

+ 24 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/index.rst

@@ -0,0 +1,24 @@
+.. MySQLdb documentation master file, created by
+   sphinx-quickstart on Sun Oct 07 19:36:17 2012.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to MySQLdb's documentation!
+===================================
+
+Contents:
+
+.. toctree::
+    :maxdepth: 3
+
+    user_guide
+    MySQLdb
+    FAQ
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+

+ 7 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/modules.rst

@@ -0,0 +1,7 @@
+MySQLdb
+=======
+
+.. toctree::
+   :maxdepth: 4
+
+   MySQLdb

+ 718 - 0
desktop/core/ext-py/MySQL-python-1.2.5/doc/user_guide.rst

@@ -0,0 +1,718 @@
+====================
+MySQLdb User's Guide
+====================
+
+.. contents::
+..
+
+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 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_autocommit()``		    ``conn.autocommit()`` 
+ ``mysql_character_set_name()``	    ``conn.character_set_name()``
+ ``mysql_close()``                  ``conn.close()`` 
+ ``mysql_commit()``		    ``conn.commit()``
+ ``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_character_set_info()`` ``conn.get_character_set_info()``
+ ``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()``		    various options to ``_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_rollback()``		    ``conn.rollback()``
+ ``mysql_row_seek()``		    ``result.row_seek()`` 
+ ``mysql_row_tell()``		    ``result.row_tell()`` 
+ ``mysql_select_db()``		    ``conn.select_db()`` 
+ ``mysql_set_character_set()``	    ``conn.set_character_set()``
+ ``mysql_ssl_set()``                ``ssl`` option to ``_mysql.connect()``
+ ``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()``
+ ``mysql_warning_count()``          ``conn.warning_count()`` 
+ ``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.*
+
+         use_unicode
+            If True, CHAR and VARCHAR and TEXT columns are returned as
+            Unicode strings, using the configured character set. It is
+            best to set the default encoding in the server
+            configuration, or client configuration (read with
+            read_default_file).  If you change the character set after
+            connecting (MySQL-4.1 and later), you'll need to put the
+            correct character set name in connection.charset.
+
+	    If False, text-like columns are returned as normal strings,
+	    but you can always write Unicode strings.
+
+	    *This must be a keyword parameter.*
+
+	 charset
+	    If present, the connection character set will be changed
+	    to this character set, if they are not equal. Support for
+	    changing the character set requires MySQL-4.1 and later
+	    server; if the server is too old, UnsupportedError will be
+	    raised. This option implies use_unicode=True, but you can
+	    override this with use_unicode=False, though you probably
+	    shouldn't.
+
+	    If not present, the default character set is used.
+
+	    *This must be a keyword parameter.*
+
+	 sql_mode
+	    If present, the session SQL mode will be set to the given
+	    string. For more information on sql_mode, see the MySQL
+	    documentation. Only available for 4.1 and newer servers.
+
+	    If not present, the session SQL mode will be unchanged.
+
+	    *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
+
+charset
+      The character set used by the connection. In MySQL-4.1 and newer,
+      it is possible (but not recommended) to change the connection's
+      character set with an SQL statement. If you do this, you'll also
+      need to change this attribute. Otherwise, you'll get encoding
+      errors.
+
+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(procname, args)
+      Calls stored procedure procname with the sequence of arguments
+      in args. Returns the original arguments. Stored procedure
+      support only works with MySQL-5.0 and newer.
+
+      **Compatibility note:** PEP-249_ specifies that if there are
+      OUT or INOUT parameters, the modified values are to be
+      returned. This is not consistently possible with MySQL. Stored
+      procedure arguments must be passed as server variables, and
+      can only be returned with a SELECT statement. Since a stored
+      procedure may return zero or more result sets, it is impossible
+      for MySQLdb to determine if there are result sets to fetch
+      before the modified parmeters are accessible.
+
+      The parameters are stored in the server as @_*procname*_*n*,
+      where *n* is the position of the parameter. I.e., if you
+      cursor.callproc('foo', (a, b, c)), the parameters will be
+      accessible by a SELECT statement as @_foo_0, @_foo_1, and
+      @_foo_2.
+
+      **Compatibility note:** It appears that the mere act of
+      executing the CALL statement produces an empty result set, which
+      appears after any result sets which might be generated by the
+      stored procedure. Thus, you will always need to use nextset() to
+      advance result sets.
+
+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.
+
+info()
+      Returns some information about the last query. Normally
+      you don't need to check this. If there are any MySQL 
+      warnings, it will cause a Warning to be issued through
+      the Python warning module. By default, Warning causes a
+      message to appear on the console. However, it is possible
+      to filter these out or cause Warning to be raised as exception.
+      See the MySQL docs for ``mysql_info()``, and the Python warning
+      module. (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.
+      
+
+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. Due to the design of the parser, (max_price)
+is interpreted as using algebraic grouping and simply as max_price and
+not a tuple. Adding a comma, i.e. (max_price,) forces it to make a
+tuple.
+
+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 1. 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.
+
+
+Embedded Server
+---------------
+
+Instead of connecting to a stand-alone server over the network,
+the embedded server support lets you run a full server right in
+your Python code or application server.
+
+If you have built MySQLdb with embedded server support, there
+are two additional functions you will need to make use of:
+
+  server_init(args, groups)
+    Initialize embedded server. If this client is not linked against
+    the embedded server library, this function does nothing.
+
+    args
+	sequence of command-line arguments
+    groups
+	sequence of groups to use in defaults files
+
+  server_end()
+    Shut down embedded server. If not using an embedded server, this
+    does nothing.
+
+See the MySQL documentation for more information on the embedded
+server.
+
+
+
+:Title: MySQLdb: a Python interface for MySQL
+:Author: Andy Dustman
+:Version: $Revision$

+ 58 - 60
desktop/core/ext-py/MySQL-python-1.2.3c1/metadata.cfg → desktop/core/ext-py/MySQL-python-1.2.5/metadata.cfg

@@ -1,60 +1,58 @@
-[metadata]
-version: 1.2.3c1
-version_info: (1,2,3,'gamma',1)
-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]_
-        \n
-        - Thread-safety
-        \n
-        - Thread-friendliness (threads will not block each other) 
-        \n
-        MySQL-3.23 through 5.0 and Python-2.3 through 2.6 are currently
-        supported. Python-3.0 will be supported in a future release.
-        \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: adustman@users.sourceforge.net
-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
-
+[metadata]
+version: 1.2.5
+version_info: (1,2,5,'final',1)
+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.
+        PyPy is supported.
+        \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: https://github.com/farcepest/MySQLdb1
+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
desktop/core/ext-py/MySQL-python-1.2.3c1/pymemcompat.h → desktop/core/ext-py/MySQL-python-1.2.5/pymemcompat.h


+ 18 - 18
desktop/core/ext-py/MySQL-python-1.2.3c1/setup.cfg → desktop/core/ext-py/MySQL-python-1.2.5/setup.cfg

@@ -1,18 +1,18 @@
-[test]
-test_suite = nose.collector
-
-[bdist_rpm]
-vendor = MySQL-python SourceForge Project
-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]
-
+[test]
+test_suite = nose.collector
+
+[build_ext]
+
+[bdist_rpm]
+doc_files = README MANIFEST doc/*.txt
+vendor = MySQL-python SourceForge Project
+packager = Andy Dustman <adustman@users.sourceforge.net>
+distribution-name = Red Stains Linux
+requires = python
+build-requires = python-devel mysql-devel zlib-devel openssl-devel
+
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+

+ 21 - 0
desktop/core/ext-py/MySQL-python-1.2.5/setup.py

@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+import os
+import sys
+
+import distutils.errors
+import setuptools
+
+if not hasattr(sys, "hexversion") or sys.hexversion < 0x02040000:
+    raise distutils.errors.DistutilsError("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'] = [
+    setuptools.Extension(sources=['_mysql.c'], **options)]
+metadata['long_description'] = metadata['long_description'].replace(r'\n', '')
+setuptools.setup(**metadata)

+ 8 - 3
desktop/core/ext-py/MySQL-python-1.2.3c1/setup_common.py → desktop/core/ext-py/MySQL-python-1.2.5/setup_common.py

@@ -1,4 +1,9 @@
-from ConfigParser import SafeConfigParser
+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()
@@ -7,8 +12,8 @@ def get_metadata_and_options():
     metadata = dict(config.items('metadata'))
     options = dict(config.items('options'))
 
-    metadata['py_modules'] = filter(None, metadata['py_modules'].split('\n'))
-    metadata['classifiers'] = filter(None, metadata['classifiers'].split('\n'))
+    metadata['py_modules'] = list(filter(None, metadata['py_modules'].split('\n')))
+    metadata['classifiers'] = list(filter(None, metadata['classifiers'].split('\n')))
 
     return metadata, options
 

+ 103 - 94
desktop/core/ext-py/MySQL-python-1.2.3c1/setup_posix.py → desktop/core/ext-py/MySQL-python-1.2.5/setup_posix.py

@@ -1,94 +1,103 @@
-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():
-    import os, sys
-    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 ]
-    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,
-        include_dirs = include_dirs,
-        extra_objects = extra_objects,
-        define_macros = define_macros,
-        )
-    return metadata, ext_options
-
-if __name__ == "__main__":
-    print """You shouldn't be running this directly; it is used by setup.py."""
-
+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))
+        if client in libraries:
+            libraries.remove(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.""")
+

+ 7 - 8
desktop/core/ext-py/MySQL-python-1.2.3c1/setup_windows.py → desktop/core/ext-py/MySQL-python-1.2.5/setup_windows.py

@@ -1,23 +1,22 @@
+import os, sys
+
 def get_config():
-    import os, sys, _winreg
     from setup_common import get_metadata_and_options, enabled, create_release_file
 
     metadata, options = get_metadata_and_options()
 
-    serverKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, options['registry_key'])
-    mysql_root, dummy = _winreg.QueryValueEx(serverKey,'Location')
+    connector = options["connector"]
 
     extra_objects = []
-    static = enabled(options, 'static')
-    # XXX static doesn't actually do anything on Windows
+
     if enabled(options, 'embedded'):
         client = "mysqld"
     else:
         client = "mysqlclient"
 
-    library_dirs = [ os.path.join(mysql_root, r'lib\opt') ]
+    library_dirs = [ os.path.join(connector, r'lib\opt') ]
     libraries = [ 'kernel32', 'advapi32', 'wsock32', client ]
-    include_dirs = [ os.path.join(mysql_root, r'include') ]
+    include_dirs = [ os.path.join(connector, r'include') ]
     extra_compile_args = [ '/Zl' ]
     
     name = "MySQL-python"
@@ -43,5 +42,5 @@ def get_config():
     return metadata, ext_options
 
 if __name__ == "__main__":
-    print """You shouldn't be running this directly; it is used by setup.py."""
+    sys.stderr.write("""You shouldn't be running this directly; it is used by setup.py.""")
     

+ 3 - 4
desktop/core/ext-py/MySQL-python-1.2.3c1/site.cfg → desktop/core/ext-py/MySQL-python-1.2.5/site.cfg

@@ -12,7 +12,6 @@ static = False
 # setup that requires it.
 #mysql_config = /usr/local/bin/mysql_config
 
-# The Windows registry key for MySQL.
-# This has to be set for Windows builds to work.
-# Only change this if you have a different version.
-registry_key = SOFTWARE\MySQL AB\MySQL Server 5.0
+# 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

+ 281 - 289
desktop/core/ext-py/MySQL-python-1.2.3c1/tests/capabilities.py → desktop/core/ext-py/MySQL-python-1.2.5/tests/capabilities.py

@@ -1,289 +1,281 @@
-#!/usr/bin/env python -O
-""" Script to test database capabilities and the DB-API interface
-    for functionality and memory leaks.
-
-    Adapted from a script by M-A Lemburg.
-    
-"""
-from time import time
-import array
-import unittest
-
-
-class DatabaseTest(unittest.TestCase):
-
-    db_module = None
-    connect_args = ()
-    connect_kwargs = dict()
-    create_table_extra = ''
-    rows = 10
-    debug = False
-    
-    def setUp(self):
-        import gc
-        db = self.db_module.connect(*self.connect_args, **self.connect_kwargs)
-        self.connection = db
-        self.cursor = db.cursor()
-        self.BLOBText = ''.join([chr(i) for i in range(256)] * 100);
-        self.BLOBUText = u''.join([unichr(i) for i in range(16384)])
-        self.BLOBBinary = self.db_module.Binary(''.join([chr(i) for i in range(256)] * 16))
-
-    leak_test = True
-    
-    def tearDown(self):
-        if self.leak_test:
-            import gc
-            del self.cursor
-            orphans = gc.collect()
-            self.failIf(orphans, "%d orphaned objects found after deleting cursor" % orphans)
-            
-            del self.connection
-            orphans = gc.collect()
-            self.failIf(orphans, "%d orphaned objects found after deleting connection" % orphans)
-            
-    def table_exists(self, name):
-        try:
-            self.cursor.execute('select * from %s where 1=0' % name)
-        except:
-            return False
-        else:
-            return True
-
-    def quote_identifier(self, ident):
-        return '"%s"' % ident
-    
-    def new_table_name(self):
-        i = id(self.cursor)
-        while True:
-            name = self.quote_identifier('tb%08x' % i)
-            if not self.table_exists(name):
-                return name
-            i = i + 1
-
-    def create_table(self, columndefs):
-
-        """ Create a table using a list of column definitions given in
-            columndefs.
-        
-            generator must be a function taking arguments (row_number,
-            col_number) returning a suitable data object for insertion
-            into the table.
-
-        """
-        self.table = self.new_table_name()
-        self.cursor.execute('CREATE TABLE %s (%s) %s' % 
-                            (self.table,
-                             ',\n'.join(columndefs),
-                             self.create_table_extra))
-
-    def check_data_integrity(self, columndefs, generator):
-        # insert
-        self.create_table(columndefs)
-        insert_statement = ('INSERT INTO %s VALUES (%s)' % 
-                            (self.table,
-                             ','.join(['%s'] * len(columndefs))))
-        data = [ [ generator(i,j) for j in range(len(columndefs)) ]
-                 for i in range(self.rows) ]
-        if self.debug:
-            print data
-        self.cursor.executemany(insert_statement, data)
-        self.connection.commit()
-        # verify
-        self.cursor.execute('select * from %s' % self.table)
-        l = self.cursor.fetchall()
-        if self.debug:
-            print l
-        self.assertEquals(len(l), self.rows)
-        try:
-            for i in range(self.rows):
-                for j in range(len(columndefs)):
-                    self.assertEquals(l[i][j], generator(i,j))
-        finally:
-            if not self.debug:
-                self.cursor.execute('drop table %s' % (self.table))
-
-    def test_transactions(self):
-        columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
-        def generator(row, col):
-            if col == 0: return row
-            else: return ('%i' % (row%10))*255
-        self.create_table(columndefs)
-        insert_statement = ('INSERT INTO %s VALUES (%s)' % 
-                            (self.table,
-                             ','.join(['%s'] * len(columndefs))))
-        data = [ [ generator(i,j) for j in range(len(columndefs)) ]
-                 for i in range(self.rows) ]
-        self.cursor.executemany(insert_statement, data)
-        # verify
-        self.connection.commit()
-        self.cursor.execute('select * from %s' % self.table)
-        l = self.cursor.fetchall()
-        self.assertEquals(len(l), self.rows)
-        for i in range(self.rows):
-            for j in range(len(columndefs)):
-                self.assertEquals(l[i][j], generator(i,j))
-        delete_statement = 'delete from %s where col1=%%s' % self.table
-        self.cursor.execute(delete_statement, (0,))
-        self.cursor.execute('select col1 from %s where col1=%s' % \
-                            (self.table, 0))
-        l = self.cursor.fetchall()
-        self.failIf(l, "DELETE didn't work")
-        self.connection.rollback()
-        self.cursor.execute('select col1 from %s where col1=%s' % \
-                            (self.table, 0))
-        l = self.cursor.fetchall()
-        self.failUnless(len(l) == 1, "ROLLBACK didn't work")
-        self.cursor.execute('drop table %s' % (self.table))
-
-    def test_truncation(self):
-        columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
-        def generator(row, col):
-            if col == 0: return row
-            else: return ('%i' % (row%10))*((255-self.rows/2)+row)
-        self.create_table(columndefs)
-        insert_statement = ('INSERT INTO %s VALUES (%s)' % 
-                            (self.table,
-                             ','.join(['%s'] * len(columndefs))))
-
-        try:
-            self.cursor.execute(insert_statement, (0, '0'*256))
-        except Warning:
-            if self.debug: print self.cursor.messages
-        except self.connection.DataError:
-            pass
-        else:
-            self.fail("Over-long column did not generate warnings/exception with single insert")
-
-        self.connection.rollback()
-        
-        try:
-            for i in range(self.rows):
-                data = []
-                for j in range(len(columndefs)):
-                    data.append(generator(i,j))
-                self.cursor.execute(insert_statement,tuple(data))
-        except Warning:
-            if self.debug: print self.cursor.messages
-        except self.connection.DataError:
-            pass
-        else:
-            self.fail("Over-long columns did not generate warnings/exception with execute()")
-
-        self.connection.rollback()
-        
-        try:
-            data = [ [ generator(i,j) for j in range(len(columndefs)) ]
-                     for i in range(self.rows) ]
-            self.cursor.executemany(insert_statement, data)
-        except Warning:
-            if self.debug: print self.cursor.messages
-        except self.connection.DataError:
-            pass
-        else:
-            self.fail("Over-long columns did not generate warnings/exception with executemany()")
-
-        self.connection.rollback()
-        self.cursor.execute('drop table %s' % (self.table))
-
-    def test_CHAR(self):
-        # Character data
-        def generator(row,col):
-            return ('%i' % ((row+col) % 10)) * 255
-        self.check_data_integrity(
-            ('col1 char(255)','col2 char(255)'),
-            generator)
-
-    def test_INT(self):
-        # Number data
-        def generator(row,col):
-            return row*row
-        self.check_data_integrity(
-            ('col1 INT',),
-            generator)
-
-    def test_DECIMAL(self):
-        # DECIMAL
-        def generator(row,col):
-            from decimal import Decimal
-            return Decimal("%d.%02d" % (row, col))
-        self.check_data_integrity(
-            ('col1 DECIMAL(5,2)',),
-            generator)
-
-    def test_DATE(self):
-        ticks = time()
-        def generator(row,col):
-            return self.db_module.DateFromTicks(ticks+row*86400-col*1313)
-        self.check_data_integrity(
-                 ('col1 DATE',),
-                 generator)
-
-    def test_TIME(self):
-        ticks = time()
-        def generator(row,col):
-            return self.db_module.TimeFromTicks(ticks+row*86400-col*1313)
-        self.check_data_integrity(
-                 ('col1 TIME',),
-                 generator)
-
-    def test_DATETIME(self):
-        ticks = time()
-        def generator(row,col):
-            return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313)
-        self.check_data_integrity(
-                 ('col1 DATETIME',),
-                 generator)
-
-    def test_TIMESTAMP(self):
-        ticks = time()
-        def generator(row,col):
-            return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313)
-        self.check_data_integrity(
-                 ('col1 TIMESTAMP',),
-                 generator)
-
-    def test_fractional_TIMESTAMP(self):
-        ticks = time()
-        def generator(row,col):
-            return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313+row*0.7*col/3.0)
-        self.check_data_integrity(
-                 ('col1 TIMESTAMP',),
-                 generator)
-
-    def test_LONG(self):
-        def generator(row,col):
-            if col == 0:
-                return row
-            else:
-                return self.BLOBUText # 'BLOB Text ' * 1024
-        self.check_data_integrity(
-                 ('col1 INT','col2 LONG'),
-                 generator)
-
-    def test_TEXT(self):
-        def generator(row,col):
-            return self.BLOBUText # 'BLOB Text ' * 1024
-        self.check_data_integrity(
-                 ('col2 TEXT',),
-                 generator)
-
-    def test_LONG_BYTE(self):
-        def generator(row,col):
-            if col == 0:
-                return row
-            else:
-                return self.BLOBBinary # 'BLOB\000Binary ' * 1024
-        self.check_data_integrity(
-                 ('col1 INT','col2 LONG BYTE'),
-                 generator)
-
-    def test_BLOB(self):
-        def generator(row,col):
-            if col == 0:
-                return row
-            else:
-                return self.BLOBBinary # 'BLOB\000Binary ' * 1024
-        self.check_data_integrity(
-                 ('col1 INT','col2 BLOB'),
-                 generator)
-
+#!/usr/bin/env python -O
+""" Script to test database capabilities and the DB-API interface
+    for functionality and memory leaks.
+
+    Adapted from a script by M-A Lemburg.
+    
+"""
+from time import time
+import array
+import unittest
+from configdb import connection_factory
+
+
+class DatabaseTest(unittest.TestCase):
+
+    db_module = None
+    connect_args = ()
+    connect_kwargs = dict()
+    create_table_extra = ''
+    rows = 10
+    debug = False
+    
+    def setUp(self):
+        import gc
+        db = connection_factory(**self.connect_kwargs)
+        self.connection = db
+        self.cursor = db.cursor()
+        # TODO: this needs to be re-evaluated for Python 3
+        self.BLOBText = ''.join([chr(i) for i in range(256)] * 100);
+        self.BLOBUText = u''.join([unichr(i) for i in range(16384)])
+        self.BLOBBinary = self.db_module.Binary(''.join([chr(i) for i in range(256)] * 16))
+
+    leak_test = True
+    
+    def tearDown(self):
+        if self.leak_test:
+            import gc
+            del self.cursor
+            orphans = gc.collect()
+            self.failIf(orphans, "%d orphaned objects found after deleting cursor" % orphans)
+            
+            del self.connection
+            orphans = gc.collect()
+            self.failIf(orphans, "%d orphaned objects found after deleting connection" % orphans)
+            
+    def table_exists(self, name):
+        try:
+            self.cursor.execute('select * from %s where 1=0' % name)
+        except:
+            return False
+        else:
+            return True
+
+    def quote_identifier(self, ident):
+        return '"%s"' % ident
+    
+    def new_table_name(self):
+        i = id(self.cursor)
+        while True:
+            name = self.quote_identifier('tb%08x' % i)
+            if not self.table_exists(name):
+                return name
+            i = i + 1
+
+    def create_table(self, columndefs):
+
+        """ Create a table using a list of column definitions given in
+            columndefs.
+        
+            generator must be a function taking arguments (row_number,
+            col_number) returning a suitable data object for insertion
+            into the table.
+
+        """
+        self.table = self.new_table_name()
+        self.cursor.execute('CREATE TABLE %s (%s) %s' % 
+                            (self.table,
+                             ',\n'.join(columndefs),
+                             self.create_table_extra))
+
+    def check_data_integrity(self, columndefs, generator):
+        # insert
+        self.create_table(columndefs)
+        insert_statement = ('INSERT INTO %s VALUES (%s)' % 
+                            (self.table,
+                             ','.join(['%s'] * len(columndefs))))
+        data = [ [ generator(i,j) for j in range(len(columndefs)) ]
+                 for i in range(self.rows) ]
+        self.cursor.executemany(insert_statement, data)
+        self.connection.commit()
+        # verify
+        self.cursor.execute('select * from %s' % self.table)
+        l = self.cursor.fetchall()
+        self.assertEquals(len(l), self.rows)
+        try:
+            for i in range(self.rows):
+                for j in range(len(columndefs)):
+                    self.assertEquals(l[i][j], generator(i,j))
+        finally:
+            if not self.debug:
+                self.cursor.execute('drop table %s' % (self.table))
+
+    def test_transactions(self):
+        columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
+        def generator(row, col):
+            if col == 0: return row
+            else: return ('%i' % (row%10))*255
+        self.create_table(columndefs)
+        insert_statement = ('INSERT INTO %s VALUES (%s)' % 
+                            (self.table,
+                             ','.join(['%s'] * len(columndefs))))
+        data = [ [ generator(i,j) for j in range(len(columndefs)) ]
+                 for i in range(self.rows) ]
+        self.cursor.executemany(insert_statement, data)
+        # verify
+        self.connection.commit()
+        self.cursor.execute('select * from %s' % self.table)
+        l = self.cursor.fetchall()
+        self.assertEquals(len(l), self.rows)
+        for i in range(self.rows):
+            for j in range(len(columndefs)):
+                self.assertEquals(l[i][j], generator(i,j))
+        delete_statement = 'delete from %s where col1=%%s' % self.table
+        self.cursor.execute(delete_statement, (0,))
+        self.cursor.execute('select col1 from %s where col1=%s' % \
+                            (self.table, 0))
+        l = self.cursor.fetchall()
+        self.assertFalse(l, "DELETE didn't work")
+        self.connection.rollback()
+        self.cursor.execute('select col1 from %s where col1=%s' % \
+                            (self.table, 0))
+        l = self.cursor.fetchall()
+        self.assertTrue(len(l) == 1, "ROLLBACK didn't work")
+        self.cursor.execute('drop table %s' % (self.table))
+
+    def test_truncation(self):
+        columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
+        def generator(row, col):
+            if col == 0: return row
+            else: return ('%i' % (row%10))*((255-self.rows/2)+row)
+        self.create_table(columndefs)
+        insert_statement = ('INSERT INTO %s VALUES (%s)' % 
+                            (self.table,
+                             ','.join(['%s'] * len(columndefs))))
+
+        try:
+            self.cursor.execute(insert_statement, (0, '0'*256))
+        except self.connection.DataError:
+            pass
+        else:
+            self.fail("Over-long column did not generate warnings/exception with single insert")
+
+        self.connection.rollback()
+        
+        try:
+            for i in range(self.rows):
+                data = []
+                for j in range(len(columndefs)):
+                    data.append(generator(i,j))
+                self.cursor.execute(insert_statement,tuple(data))
+        except self.connection.DataError:
+            pass
+        else:
+            self.fail("Over-long columns did not generate warnings/exception with execute()")
+
+        self.connection.rollback()
+        
+        try:
+            data = [ [ generator(i,j) for j in range(len(columndefs)) ]
+                     for i in range(self.rows) ]
+            self.cursor.executemany(insert_statement, data)
+        except self.connection.DataError:
+            pass
+        else:
+            self.fail("Over-long columns did not generate warnings/exception with executemany()")
+
+        self.connection.rollback()
+        self.cursor.execute('drop table %s' % (self.table))
+
+    def test_CHAR(self):
+        # Character data
+        def generator(row,col):
+            return ('%i' % ((row+col) % 10)) * 255
+        self.check_data_integrity(
+            ('col1 char(255)','col2 char(255)'),
+            generator)
+
+    def test_INT(self):
+        # Number data
+        def generator(row,col):
+            return row*row
+        self.check_data_integrity(
+            ('col1 INT',),
+            generator)
+
+    def test_DECIMAL(self):
+        # DECIMAL
+        def generator(row,col):
+            from decimal import Decimal
+            return Decimal("%d.%02d" % (row, col))
+        self.check_data_integrity(
+            ('col1 DECIMAL(5,2)',),
+            generator)
+
+    def test_DATE(self):
+        ticks = time()
+        def generator(row,col):
+            return self.db_module.DateFromTicks(ticks+row*86400-col*1313)
+        self.check_data_integrity(
+                 ('col1 DATE',),
+                 generator)
+
+    def test_TIME(self):
+        ticks = time()
+        def generator(row,col):
+            return self.db_module.TimeFromTicks(ticks+row*86400-col*1313)
+        self.check_data_integrity(
+                 ('col1 TIME',),
+                 generator)
+
+    def test_DATETIME(self):
+        ticks = time()
+        def generator(row,col):
+            return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313)
+        self.check_data_integrity(
+                 ('col1 DATETIME',),
+                 generator)
+
+    def test_TIMESTAMP(self):
+        ticks = time()
+        def generator(row,col):
+            return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313)
+        self.check_data_integrity(
+                 ('col1 TIMESTAMP',),
+                 generator)
+
+    def test_fractional_TIMESTAMP(self):
+        ticks = time()
+        def generator(row,col):
+            return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313+row*0.7*col/3.0)
+        self.check_data_integrity(
+                 ('col1 TIMESTAMP',),
+                 generator)
+
+    def test_LONG(self):
+        def generator(row,col):
+            if col == 0:
+                return row
+            else:
+                return self.BLOBUText # 'BLOB Text ' * 1024
+        self.check_data_integrity(
+                 ('col1 INT','col2 LONG'),
+                 generator)
+
+    def test_TEXT(self):
+        def generator(row,col):
+            return self.BLOBUText # 'BLOB Text ' * 1024
+        self.check_data_integrity(
+                 ('col2 TEXT',),
+                 generator)
+
+    def test_LONG_BYTE(self):
+        def generator(row,col):
+            if col == 0:
+                return row
+            else:
+                return self.BLOBBinary # 'BLOB\000Binary ' * 1024
+        self.check_data_integrity(
+                 ('col1 INT','col2 LONG BYTE'),
+                 generator)
+
+    def test_BLOB(self):
+        def generator(row,col):
+            if col == 0:
+                return row
+            else:
+                return self.BLOBBinary # 'BLOB\000Binary ' * 1024
+        self.check_data_integrity(
+                 ('col1 INT','col2 BLOB'),
+                 generator)
+

+ 25 - 0
desktop/core/ext-py/MySQL-python-1.2.5/tests/configdb.py

@@ -0,0 +1,25 @@
+"""Configure database connection for tests."""
+
+from os import environ, path
+
+tests_path = path.dirname(__file__)
+conf_file = environ.get('TESTDB', 'default.cnf')
+conf_path = path.join(tests_path, conf_file)
+connect_kwargs = dict(
+    read_default_file = conf_path,
+    read_default_group = "MySQLdb-tests",
+)
+
+def connection_kwargs(kwargs):
+    db_kwargs = connect_kwargs.copy()
+    db_kwargs.update(kwargs)
+    return db_kwargs
+
+def connection_factory(**kwargs):
+    import MySQLdb
+    db_kwargs = connection_kwargs(kwargs)
+    db = MySQLdb.connect(**db_kwargs)
+    return db
+
+
+

+ 48 - 48
desktop/core/ext-py/MySQL-python-1.2.3c1/tests/dbapi20.py → desktop/core/ext-py/MySQL-python-1.2.5/tests/dbapi20.py

@@ -11,8 +11,8 @@
     -- Ian Bicking
 '''
 
-__rcs_id__  = '$Id: dbapi20.py 613 2009-03-08 17:45:52Z adustman $'
-__version__ = '$Revision: 613 $'[11:-2]
+__rcs_id__  = '$Id$'
+__version__ = '$Revision$'[11:-2]
 __author__ = 'Stuart Bishop <zen@shangri-la.dropbear.id.au>'
 
 import unittest
@@ -159,7 +159,7 @@ class DatabaseAPI20Test(unittest.TestCase):
             # Must exist
             threadsafety = self.driver.threadsafety
             # Must be a valid value
-            self.failUnless(threadsafety in (0,1,2,3))
+            self.assertTrue(threadsafety in (0,1,2,3))
         except AttributeError:
             self.fail("Driver doesn't define threadsafety")
 
@@ -168,7 +168,7 @@ class DatabaseAPI20Test(unittest.TestCase):
             # Must exist
             paramstyle = self.driver.paramstyle
             # Must be a valid value
-            self.failUnless(paramstyle in (
+            self.assertTrue(paramstyle in (
                 'qmark','numeric','named','format','pyformat'
                 ))
         except AttributeError:
@@ -177,27 +177,27 @@ class DatabaseAPI20Test(unittest.TestCase):
     def test_Exceptions(self):
         # Make sure required exceptions exist, and are in the
         # defined heirarchy.
-        self.failUnless(issubclass(self.driver.Warning,StandardError))
-        self.failUnless(issubclass(self.driver.Error,StandardError))
-        self.failUnless(
+        self.assertTrue(issubclass(self.driver.Warning,StandardError))
+        self.assertTrue(issubclass(self.driver.Error,StandardError))
+        self.assertTrue(
             issubclass(self.driver.InterfaceError,self.driver.Error)
             )
-        self.failUnless(
+        self.assertTrue(
             issubclass(self.driver.DatabaseError,self.driver.Error)
             )
-        self.failUnless(
+        self.assertTrue(
             issubclass(self.driver.OperationalError,self.driver.Error)
             )
-        self.failUnless(
+        self.assertTrue(
             issubclass(self.driver.IntegrityError,self.driver.Error)
             )
-        self.failUnless(
+        self.assertTrue(
             issubclass(self.driver.InternalError,self.driver.Error)
             )
-        self.failUnless(
+        self.assertTrue(
             issubclass(self.driver.ProgrammingError,self.driver.Error)
             )
-        self.failUnless(
+        self.assertTrue(
             issubclass(self.driver.NotSupportedError,self.driver.Error)
             )
 
@@ -210,15 +210,15 @@ class DatabaseAPI20Test(unittest.TestCase):
         # by default.
         con = self._connect()
         drv = self.driver
-        self.failUnless(con.Warning is drv.Warning)
-        self.failUnless(con.Error is drv.Error)
-        self.failUnless(con.InterfaceError is drv.InterfaceError)
-        self.failUnless(con.DatabaseError is drv.DatabaseError)
-        self.failUnless(con.OperationalError is drv.OperationalError)
-        self.failUnless(con.IntegrityError is drv.IntegrityError)
-        self.failUnless(con.InternalError is drv.InternalError)
-        self.failUnless(con.ProgrammingError is drv.ProgrammingError)
-        self.failUnless(con.NotSupportedError is drv.NotSupportedError)
+        self.assertTrue(con.Warning is drv.Warning)
+        self.assertTrue(con.Error is drv.Error)
+        self.assertTrue(con.InterfaceError is drv.InterfaceError)
+        self.assertTrue(con.DatabaseError is drv.DatabaseError)
+        self.assertTrue(con.OperationalError is drv.OperationalError)
+        self.assertTrue(con.IntegrityError is drv.IntegrityError)
+        self.assertTrue(con.InternalError is drv.InternalError)
+        self.assertTrue(con.ProgrammingError is drv.ProgrammingError)
+        self.assertTrue(con.NotSupportedError is drv.NotSupportedError)
 
 
     def test_commit(self):
@@ -310,12 +310,12 @@ class DatabaseAPI20Test(unittest.TestCase):
             cur.execute("insert into %sbooze values ('Victoria Bitter')" % (
                 self.table_prefix
                 ))
-            self.failUnless(cur.rowcount in (-1,1),
+            self.assertTrue(cur.rowcount in (-1,1),
                 'cursor.rowcount should == number or rows inserted, or '
                 'set to -1 after executing an insert statement'
                 )
             cur.execute("select name from %sbooze" % self.table_prefix)
-            self.failUnless(cur.rowcount in (-1,1),
+            self.assertTrue(cur.rowcount in (-1,1),
                 'cursor.rowcount should == number of rows returned, or '
                 'set to -1 after executing a select statement'
                 )
@@ -378,7 +378,7 @@ class DatabaseAPI20Test(unittest.TestCase):
         cur.execute("insert into %sbooze values ('Victoria Bitter')" % (
             self.table_prefix
             ))
-        self.failUnless(cur.rowcount in (-1,1))
+        self.assertTrue(cur.rowcount in (-1,1))
 
         if self.driver.paramstyle == 'qmark':
             cur.execute(
@@ -407,7 +407,7 @@ class DatabaseAPI20Test(unittest.TestCase):
                 )
         else:
             self.fail('Invalid paramstyle')
-        self.failUnless(cur.rowcount in (-1,1))
+        self.assertTrue(cur.rowcount in (-1,1))
 
         cur.execute('select name from %sbooze' % self.table_prefix)
         res = cur.fetchall()
@@ -459,7 +459,7 @@ class DatabaseAPI20Test(unittest.TestCase):
                     )
             else:
                 self.fail('Unknown paramstyle')
-            self.failUnless(cur.rowcount in (-1,2),
+            self.assertTrue(cur.rowcount in (-1,2),
                 'insert using cursor.executemany set cursor.rowcount to '
                 'incorrect value %r' % cur.rowcount
                 )
@@ -494,7 +494,7 @@ class DatabaseAPI20Test(unittest.TestCase):
                 'cursor.fetchone should return None if a query retrieves '
                 'no rows'
                 )
-            self.failUnless(cur.rowcount in (-1,0))
+            self.assertTrue(cur.rowcount in (-1,0))
 
             # cursor.fetchone should raise an Error if called after
             # executing a query that cannnot return rows
@@ -514,7 +514,7 @@ class DatabaseAPI20Test(unittest.TestCase):
             self.assertEqual(cur.fetchone(),None,
                 'cursor.fetchone should return None if no more rows available'
                 )
-            self.failUnless(cur.rowcount in (-1,1))
+            self.assertTrue(cur.rowcount in (-1,1))
         finally:
             con.close()
 
@@ -570,7 +570,7 @@ class DatabaseAPI20Test(unittest.TestCase):
                 'cursor.fetchmany should return an empty sequence after '
                 'results are exhausted'
             )
-            self.failUnless(cur.rowcount in (-1,6))
+            self.assertTrue(cur.rowcount in (-1,6))
 
             # Same as above, using cursor.arraysize
             cur.arraysize=4
@@ -583,12 +583,12 @@ class DatabaseAPI20Test(unittest.TestCase):
             self.assertEqual(len(r),2)
             r = cur.fetchmany() # Should be an empty sequence
             self.assertEqual(len(r),0)
-            self.failUnless(cur.rowcount in (-1,6))
+            self.assertTrue(cur.rowcount in (-1,6))
 
             cur.arraysize=6
             cur.execute('select name from %sbooze' % self.table_prefix)
             rows = cur.fetchmany() # Should get all rows
-            self.failUnless(cur.rowcount in (-1,6))
+            self.assertTrue(cur.rowcount in (-1,6))
             self.assertEqual(len(rows),6)
             self.assertEqual(len(rows),6)
             rows = [r[0] for r in rows]
@@ -605,7 +605,7 @@ class DatabaseAPI20Test(unittest.TestCase):
                 'cursor.fetchmany should return an empty sequence if '
                 'called after the whole result set has been fetched'
                 )
-            self.failUnless(cur.rowcount in (-1,6))
+            self.assertTrue(cur.rowcount in (-1,6))
 
             self.executeDDL2(cur)
             cur.execute('select name from %sbarflys' % self.table_prefix)
@@ -614,7 +614,7 @@ class DatabaseAPI20Test(unittest.TestCase):
                 'cursor.fetchmany should return an empty sequence if '
                 'query retrieved no rows'
                 )
-            self.failUnless(cur.rowcount in (-1,0))
+            self.assertTrue(cur.rowcount in (-1,0))
 
         finally:
             con.close()
@@ -638,7 +638,7 @@ class DatabaseAPI20Test(unittest.TestCase):
 
             cur.execute('select name from %sbooze' % self.table_prefix)
             rows = cur.fetchall()
-            self.failUnless(cur.rowcount in (-1,len(self.samples)))
+            self.assertTrue(cur.rowcount in (-1,len(self.samples)))
             self.assertEqual(len(rows),len(self.samples),
                 'cursor.fetchall did not retrieve all rows'
                 )
@@ -654,12 +654,12 @@ class DatabaseAPI20Test(unittest.TestCase):
                 'cursor.fetchall should return an empty list if called '
                 'after the whole result set has been fetched'
                 )
-            self.failUnless(cur.rowcount in (-1,len(self.samples)))
+            self.assertTrue(cur.rowcount in (-1,len(self.samples)))
 
             self.executeDDL2(cur)
             cur.execute('select name from %sbarflys' % self.table_prefix)
             rows = cur.fetchall()
-            self.failUnless(cur.rowcount in (-1,0))
+            self.assertTrue(cur.rowcount in (-1,0))
             self.assertEqual(len(rows),0,
                 'cursor.fetchall should return an empty list if '
                 'a select query returns no rows'
@@ -681,7 +681,7 @@ class DatabaseAPI20Test(unittest.TestCase):
             rows23 = cur.fetchmany(2)
             rows4  = cur.fetchone()
             rows56 = cur.fetchall()
-            self.failUnless(cur.rowcount in (-1,6))
+            self.assertTrue(cur.rowcount in (-1,6))
             self.assertEqual(len(rows23),2,
                 'fetchmany returned incorrect number of rows'
                 )
@@ -706,7 +706,7 @@ class DatabaseAPI20Test(unittest.TestCase):
             that returns two result sets, first the 
 	    number of rows in booze then "name from booze"
         '''
-        raise NotImplementedError,'Helper not implemented'
+        raise NotImplementedError('Helper not implemented')
         #sql="""
         #    create procedure deleteme as
         #    begin
@@ -718,7 +718,7 @@ class DatabaseAPI20Test(unittest.TestCase):
 
     def help_nextset_tearDown(self,cur):
         'If cleaning up is needed after nextSetTest'
-        raise NotImplementedError,'Helper not implemented'
+        raise NotImplementedError('Helper not implemented')
         #cur.execute("drop procedure deleteme")
 
     def test_nextset(self):
@@ -751,14 +751,14 @@ class DatabaseAPI20Test(unittest.TestCase):
             con.close()
 
     def test_nextset(self):
-        raise NotImplementedError,'Drivers need to override this test'
+        raise NotImplementedError('Drivers need to override this test')
 
     def test_arraysize(self):
         # Not much here - rest of the tests for this are in test_fetchmany
         con = self._connect()
         try:
             cur = con.cursor()
-            self.failUnless(hasattr(cur,'arraysize'),
+            self.assertTrue(hasattr(cur,'arraysize'),
                 'cursor.arraysize must be defined'
                 )
         finally:
@@ -786,7 +786,7 @@ class DatabaseAPI20Test(unittest.TestCase):
 
     def test_setoutputsize(self):
         # Real test for setoutputsize is driver dependant
-        raise NotImplementedError,'Driver need to override this test'
+        raise NotImplementedError('Driver need to override this test')
 
     def test_None(self):
         con = self._connect()
@@ -827,27 +827,27 @@ class DatabaseAPI20Test(unittest.TestCase):
         b = self.driver.Binary('')
 
     def test_STRING(self):
-        self.failUnless(hasattr(self.driver,'STRING'),
+        self.assertTrue(hasattr(self.driver,'STRING'),
             'module.STRING must be defined'
             )
 
     def test_BINARY(self):
-        self.failUnless(hasattr(self.driver,'BINARY'),
+        self.assertTrue(hasattr(self.driver,'BINARY'),
             'module.BINARY must be defined.'
             )
 
     def test_NUMBER(self):
-        self.failUnless(hasattr(self.driver,'NUMBER'),
+        self.assertTrue(hasattr(self.driver,'NUMBER'),
             'module.NUMBER must be defined.'
             )
 
     def test_DATETIME(self):
-        self.failUnless(hasattr(self.driver,'DATETIME'),
+        self.assertTrue(hasattr(self.driver,'DATETIME'),
             'module.DATETIME must be defined.'
             )
 
     def test_ROWID(self):
-        self.failUnless(hasattr(self.driver,'ROWID'),
+        self.assertTrue(hasattr(self.driver,'ROWID'),
             'module.ROWID must be defined.'
             )
 

+ 102 - 93
desktop/core/ext-py/MySQL-python-1.2.3c1/tests/test_MySQLdb_capabilities.py → desktop/core/ext-py/MySQL-python-1.2.5/tests/test_MySQLdb_capabilities.py

@@ -1,93 +1,102 @@
-#!/usr/bin/env python
-import capabilities
-import unittest
-import MySQLdb
-import warnings
-
-warnings.filterwarnings('error')
-
-class test_MySQLdb(capabilities.DatabaseTest):
-
-    db_module = MySQLdb
-    connect_args = ()
-    connect_kwargs = dict(db='test', read_default_file='~/.my.cnf',
-                          charset='utf8', sql_mode="ANSI,STRICT_TRANS_TABLES,TRADITIONAL")
-    create_table_extra = "ENGINE=INNODB CHARACTER SET UTF8"
-    leak_test = False
-    
-    def quote_identifier(self, ident):
-        return "`%s`" % ident
-
-    def test_TIME(self):
-        from datetime import timedelta
-        def generator(row,col):
-            return timedelta(0, row*8000)
-        self.check_data_integrity(
-                 ('col1 TIME',),
-                 generator)
-
-    def test_TINYINT(self):
-        # Number data
-        def generator(row,col):
-            v = (row*row) % 256
-            if v > 127:
-                v = v-256
-            return v
-        self.check_data_integrity(
-            ('col1 TINYINT',),
-            generator)
-        
-    def test_stored_procedures(self):
-        db = self.connection
-        c = self.cursor
-        self.create_table(('pos INT', 'tree CHAR(20)'))
-        c.executemany("INSERT INTO %s (pos,tree) VALUES (%%s,%%s)" % self.table,
-                      list(enumerate('ash birch cedar larch pine'.split())))
-        db.commit()
-        
-        c.execute("""
-        CREATE PROCEDURE test_sp(IN t VARCHAR(255))
-        BEGIN
-            SELECT pos FROM %s WHERE tree = t;
-        END
-        """ % self.table)
-        db.commit()
-
-        c.callproc('test_sp', ('larch',))
-        rows = c.fetchall()
-        self.assertEquals(len(rows), 1)
-        self.assertEquals(rows[0][0], 3)
-        c.nextset()
-        
-        c.execute("DROP PROCEDURE test_sp")
-        c.execute('drop table %s' % (self.table))
-
-    def test_small_CHAR(self):
-        # Character data
-        def generator(row,col):
-            i = (row*col+62)%256
-            if i == 62: return ''
-            if i == 63: return None
-            return chr(i)
-        self.check_data_integrity(
-            ('col1 char(1)','col2 char(1)'),
-            generator)
-    
-    def test_bug_2671682(self):
-        from MySQLdb.constants import ER
-        try:
-            self.cursor.execute("describe some_non_existent_table");
-        except self.connection.ProgrammingError, msg:
-            self.failUnless(msg[0] == ER.NO_SUCH_TABLE)
-    
-    def test_ping(self):
-        self.connection.ping()
-        
-        
-if __name__ == '__main__':
-    if test_MySQLdb.leak_test:
-        import gc
-        gc.enable()
-        gc.set_debug(gc.DEBUG_LEAK)
-    unittest.main()
-    print '''"Huh-huh, he said 'unit'." -- Butthead'''
+#!/usr/bin/env python
+import capabilities
+import unittest
+import MySQLdb
+import warnings
+
+warnings.filterwarnings('ignore')
+
+class test_MySQLdb(capabilities.DatabaseTest):
+
+    db_module = MySQLdb
+    connect_args = ()
+    connect_kwargs = dict(use_unicode=True, sql_mode="ANSI,STRICT_TRANS_TABLES,TRADITIONAL")
+    create_table_extra = "ENGINE=INNODB CHARACTER SET UTF8"
+    leak_test = False
+    
+    def quote_identifier(self, ident):
+        return "`%s`" % ident
+
+    def test_TIME(self):
+        from datetime import timedelta
+        def generator(row,col):
+            return timedelta(0, row*8000)
+        self.check_data_integrity(
+                 ('col1 TIME',),
+                 generator)
+
+    def test_TINYINT(self):
+        # Number data
+        def generator(row,col):
+            v = (row*row) % 256
+            if v > 127:
+                v = v-256
+            return v
+        self.check_data_integrity(
+            ('col1 TINYINT',),
+            generator)
+        
+    def test_stored_procedures(self):
+        db = self.connection
+        c = self.cursor
+        self.create_table(('pos INT', 'tree CHAR(20)'))
+        c.executemany("INSERT INTO %s (pos,tree) VALUES (%%s,%%s)" % self.table,
+                      list(enumerate('ash birch cedar larch pine'.split())))
+        db.commit()
+        
+        c.execute("""
+        CREATE PROCEDURE test_sp(IN t VARCHAR(255))
+        BEGIN
+            SELECT pos FROM %s WHERE tree = t;
+        END
+        """ % self.table)
+        db.commit()
+
+        c.callproc('test_sp', ('larch',))
+        rows = c.fetchall()
+        self.assertEquals(len(rows), 1)
+        self.assertEquals(rows[0][0], 3)
+        c.nextset()
+        
+        c.execute("DROP PROCEDURE test_sp")
+        c.execute('drop table %s' % (self.table))
+
+    def test_small_CHAR(self):
+        # Character data
+        def generator(row,col):
+            i = (row*col+62)%256
+            if i == 62: return ''
+            if i == 63: return None
+            return chr(i)
+        self.check_data_integrity(
+            ('col1 char(1)','col2 char(1)'),
+            generator)
+    
+    def test_bug_2671682(self):
+        from MySQLdb.constants import ER
+        try:
+            self.cursor.execute("describe some_non_existent_table");
+        except self.connection.ProgrammingError, msg:
+            self.assertEquals(msg[0], ER.NO_SUCH_TABLE)
+
+    def test_bug_3514287(self):
+        c = self.cursor
+        try:
+            c.execute("""create table bug_3541287 (
+                c1 CHAR(10),
+                t1 TIMESTAMP)""")
+            c.execute("insert into bug_3541287 (c1,t1) values (%s, NOW())",
+                ("blah",))
+        finally:
+            c.execute("drop table if exists bug_3541287")
+
+    def test_ping(self):
+        self.connection.ping()
+        
+        
+if __name__ == '__main__':
+    if test_MySQLdb.leak_test:
+        import gc
+        gc.enable()
+        gc.set_debug(gc.DEBUG_LEAK)
+    unittest.main()

+ 204 - 205
desktop/core/ext-py/MySQL-python-1.2.3c1/tests/test_MySQLdb_dbapi20.py → desktop/core/ext-py/MySQL-python-1.2.5/tests/test_MySQLdb_dbapi20.py

@@ -1,205 +1,204 @@
-#!/usr/bin/env python
-import dbapi20
-import unittest
-import MySQLdb
-
-class test_MySQLdb(dbapi20.DatabaseAPI20Test):
-    driver = MySQLdb
-    connect_args = ()
-    connect_kw_args = dict(db='test',
-                           read_default_file='~/.my.cnf',
-                           charset='utf8',
-                           sql_mode="ANSI,STRICT_TRANS_TABLES,TRADITIONAL")
-
-    def test_setoutputsize(self): pass
-    def test_setoutputsize_basic(self): pass
-    def test_nextset(self): pass
-
-    """The tests on fetchone and fetchall and rowcount bogusly
-    test for an exception if the statement cannot return a
-    result set. MySQL always returns a result set; it's just that
-    some things return empty result sets."""
-    
-    def test_fetchall(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            # cursor.fetchall should raise an Error if called
-            # without executing a query that may return rows (such
-            # as a select)
-            self.assertRaises(self.driver.Error, cur.fetchall)
-
-            self.executeDDL1(cur)
-            for sql in self._populate():
-                cur.execute(sql)
-
-            # cursor.fetchall should raise an Error if called
-            # after executing a a statement that cannot return rows
-##             self.assertRaises(self.driver.Error,cur.fetchall)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            rows = cur.fetchall()
-            self.failUnless(cur.rowcount in (-1,len(self.samples)))
-            self.assertEqual(len(rows),len(self.samples),
-                'cursor.fetchall did not retrieve all rows'
-                )
-            rows = [r[0] for r in rows]
-            rows.sort()
-            for i in range(0,len(self.samples)):
-                self.assertEqual(rows[i],self.samples[i],
-                'cursor.fetchall retrieved incorrect rows'
-                )
-            rows = cur.fetchall()
-            self.assertEqual(
-                len(rows),0,
-                'cursor.fetchall should return an empty list if called '
-                'after the whole result set has been fetched'
-                )
-            self.failUnless(cur.rowcount in (-1,len(self.samples)))
-
-            self.executeDDL2(cur)
-            cur.execute('select name from %sbarflys' % self.table_prefix)
-            rows = cur.fetchall()
-            self.failUnless(cur.rowcount in (-1,0))
-            self.assertEqual(len(rows),0,
-                'cursor.fetchall should return an empty list if '
-                'a select query returns no rows'
-                )
-            
-        finally:
-            con.close()
-                
-    def test_fetchone(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-
-            # cursor.fetchone should raise an Error if called before
-            # executing a select-type query
-            self.assertRaises(self.driver.Error,cur.fetchone)
-
-            # cursor.fetchone should raise an Error if called after
-            # executing a query that cannnot return rows
-            self.executeDDL1(cur)
-##             self.assertRaises(self.driver.Error,cur.fetchone)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            self.assertEqual(cur.fetchone(),None,
-                'cursor.fetchone should return None if a query retrieves '
-                'no rows'
-                )
-            self.failUnless(cur.rowcount in (-1,0))
-
-            # cursor.fetchone should raise an Error if called after
-            # executing a query that cannnot return rows
-            cur.execute("insert into %sbooze values ('Victoria Bitter')" % (
-                self.table_prefix
-                ))
-##             self.assertRaises(self.driver.Error,cur.fetchone)
-
-            cur.execute('select name from %sbooze' % self.table_prefix)
-            r = cur.fetchone()
-            self.assertEqual(len(r),1,
-                'cursor.fetchone should have retrieved a single row'
-                )
-            self.assertEqual(r[0],'Victoria Bitter',
-                'cursor.fetchone retrieved incorrect data'
-                )
-##             self.assertEqual(cur.fetchone(),None,
-##                 'cursor.fetchone should return None if no more rows available'
-##                 )
-            self.failUnless(cur.rowcount in (-1,1))
-        finally:
-            con.close()
-
-    # Same complaint as for fetchall and fetchone
-    def test_rowcount(self):
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            self.executeDDL1(cur)
-##             self.assertEqual(cur.rowcount,-1,
-##                 'cursor.rowcount should be -1 after executing no-result '
-##                 'statements'
-##                 )
-            cur.execute("insert into %sbooze values ('Victoria Bitter')" % (
-                self.table_prefix
-                ))
-##             self.failUnless(cur.rowcount in (-1,1),
-##                 'cursor.rowcount should == number or rows inserted, or '
-##                 'set to -1 after executing an insert statement'
-##                 )
-            cur.execute("select name from %sbooze" % self.table_prefix)
-            self.failUnless(cur.rowcount in (-1,1),
-                'cursor.rowcount should == number of rows returned, or '
-                'set to -1 after executing a select statement'
-                )
-            self.executeDDL2(cur)
-##             self.assertEqual(cur.rowcount,-1,
-##                 'cursor.rowcount not being reset to -1 after executing '
-##                 'no-result statements'
-##                 )
-        finally:
-            con.close()
-
-    def test_callproc(self):
-        pass # performed in test_MySQL_capabilities
-
-    def help_nextset_setUp(self,cur):
-        ''' Should create a procedure called deleteme
-            that returns two result sets, first the 
-	    number of rows in booze then "name from booze"
-        '''
-        sql="""
-           create procedure deleteme()
-           begin
-               select count(*) from %(tp)sbooze;
-               select name from %(tp)sbooze;
-           end
-        """ % dict(tp=self.table_prefix)
-        cur.execute(sql)
-
-    def help_nextset_tearDown(self,cur):
-        'If cleaning up is needed after nextSetTest'
-        cur.execute("drop procedure deleteme")
-
-    def test_nextset(self):
-        from warnings import warn
-        con = self._connect()
-        try:
-            cur = con.cursor()
-            if not hasattr(cur,'nextset'):
-                return
-
-            try:
-                self.executeDDL1(cur)
-                sql=self._populate()
-                for sql in self._populate():
-                    cur.execute(sql)
-
-                self.help_nextset_setUp(cur)
-
-                cur.callproc('deleteme')
-                numberofrows=cur.fetchone()
-                assert numberofrows[0]== len(self.samples)
-                assert cur.nextset()
-                names=cur.fetchall()
-                assert len(names) == len(self.samples)
-                s=cur.nextset()
-                if s:
-                    empty = cur.fetchall()
-                    self.assertEquals(len(empty), 0,
-                                      "non-empty result set after other result sets")
-                    #warn("Incompatibility: MySQL returns an empty result set for the CALL itself",
-                    #     Warning)
-                #assert s == None,'No more return sets, should return None'
-            finally:
-                self.help_nextset_tearDown(cur)
-
-        finally:
-            con.close()
-
-    
-if __name__ == '__main__':
-    unittest.main()
-    print '''"Huh-huh, he said 'unit'." -- Butthead'''
+#!/usr/bin/env python
+import dbapi20
+import unittest
+import MySQLdb
+from configdb import connection_kwargs
+import warnings
+warnings.simplefilter("ignore")
+
+class test_MySQLdb(dbapi20.DatabaseAPI20Test):
+    driver = MySQLdb
+    connect_args = ()
+    connect_kw_args = connection_kwargs(dict(sql_mode="ANSI,STRICT_TRANS_TABLES,TRADITIONAL"))
+
+    def test_setoutputsize(self): pass
+    def test_setoutputsize_basic(self): pass
+    def test_nextset(self): pass
+
+    """The tests on fetchone and fetchall and rowcount bogusly
+    test for an exception if the statement cannot return a
+    result set. MySQL always returns a result set; it's just that
+    some things return empty result sets."""
+    
+    def test_fetchall(self):
+        con = self._connect()
+        try:
+            cur = con.cursor()
+            # cursor.fetchall should raise an Error if called
+            # without executing a query that may return rows (such
+            # as a select)
+            self.assertRaises(self.driver.Error, cur.fetchall)
+
+            self.executeDDL1(cur)
+            for sql in self._populate():
+                cur.execute(sql)
+
+            # cursor.fetchall should raise an Error if called
+            # after executing a a statement that cannot return rows
+##             self.assertRaises(self.driver.Error,cur.fetchall)
+
+            cur.execute('select name from %sbooze' % self.table_prefix)
+            rows = cur.fetchall()
+            self.assertTrue(cur.rowcount in (-1,len(self.samples)))
+            self.assertEqual(len(rows),len(self.samples),
+                'cursor.fetchall did not retrieve all rows'
+                )
+            rows = [r[0] for r in rows]
+            rows.sort()
+            for i in range(0,len(self.samples)):
+                self.assertEqual(rows[i],self.samples[i],
+                'cursor.fetchall retrieved incorrect rows'
+                )
+            rows = cur.fetchall()
+            self.assertEqual(
+                len(rows),0,
+                'cursor.fetchall should return an empty list if called '
+                'after the whole result set has been fetched'
+                )
+            self.assertTrue(cur.rowcount in (-1,len(self.samples)))
+
+            self.executeDDL2(cur)
+            cur.execute('select name from %sbarflys' % self.table_prefix)
+            rows = cur.fetchall()
+            self.assertTrue(cur.rowcount in (-1,0))
+            self.assertEqual(len(rows),0,
+                'cursor.fetchall should return an empty list if '
+                'a select query returns no rows'
+                )
+            
+        finally:
+            con.close()
+                
+    def test_fetchone(self):
+        con = self._connect()
+        try:
+            cur = con.cursor()
+
+            # cursor.fetchone should raise an Error if called before
+            # executing a select-type query
+            self.assertRaises(self.driver.Error,cur.fetchone)
+
+            # cursor.fetchone should raise an Error if called after
+            # executing a query that cannnot return rows
+            self.executeDDL1(cur)
+##             self.assertRaises(self.driver.Error,cur.fetchone)
+
+            cur.execute('select name from %sbooze' % self.table_prefix)
+            self.assertEqual(cur.fetchone(),None,
+                'cursor.fetchone should return None if a query retrieves '
+                'no rows'
+                )
+            self.assertTrue(cur.rowcount in (-1,0))
+
+            # cursor.fetchone should raise an Error if called after
+            # executing a query that cannnot return rows
+            cur.execute("insert into %sbooze values ('Victoria Bitter')" % (
+                self.table_prefix
+                ))
+##             self.assertRaises(self.driver.Error,cur.fetchone)
+
+            cur.execute('select name from %sbooze' % self.table_prefix)
+            r = cur.fetchone()
+            self.assertEqual(len(r),1,
+                'cursor.fetchone should have retrieved a single row'
+                )
+            self.assertEqual(r[0],'Victoria Bitter',
+                'cursor.fetchone retrieved incorrect data'
+                )
+##             self.assertEqual(cur.fetchone(),None,
+##                 'cursor.fetchone should return None if no more rows available'
+##                 )
+            self.assertTrue(cur.rowcount in (-1,1))
+        finally:
+            con.close()
+
+    # Same complaint as for fetchall and fetchone
+    def test_rowcount(self):
+        con = self._connect()
+        try:
+            cur = con.cursor()
+            self.executeDDL1(cur)
+##             self.assertEqual(cur.rowcount,-1,
+##                 'cursor.rowcount should be -1 after executing no-result '
+##                 'statements'
+##                 )
+            cur.execute("insert into %sbooze values ('Victoria Bitter')" % (
+                self.table_prefix
+                ))
+##             self.assertTrue(cur.rowcount in (-1,1),
+##                 'cursor.rowcount should == number or rows inserted, or '
+##                 'set to -1 after executing an insert statement'
+##                 )
+            cur.execute("select name from %sbooze" % self.table_prefix)
+            self.assertTrue(cur.rowcount in (-1,1),
+                'cursor.rowcount should == number of rows returned, or '
+                'set to -1 after executing a select statement'
+                )
+            self.executeDDL2(cur)
+##             self.assertEqual(cur.rowcount,-1,
+##                 'cursor.rowcount not being reset to -1 after executing '
+##                 'no-result statements'
+##                 )
+        finally:
+            con.close()
+
+    def test_callproc(self):
+        pass # performed in test_MySQL_capabilities
+
+    def help_nextset_setUp(self,cur):
+        ''' Should create a procedure called deleteme
+            that returns two result sets, first the 
+	    number of rows in booze then "name from booze"
+        '''
+        sql="""
+           create procedure deleteme()
+           begin
+               select count(*) from %(tp)sbooze;
+               select name from %(tp)sbooze;
+           end
+        """ % dict(tp=self.table_prefix)
+        cur.execute(sql)
+
+    def help_nextset_tearDown(self,cur):
+        'If cleaning up is needed after nextSetTest'
+        cur.execute("drop procedure deleteme")
+
+    def test_nextset(self):
+        from warnings import warn
+        con = self._connect()
+        try:
+            cur = con.cursor()
+            if not hasattr(cur,'nextset'):
+                return
+
+            try:
+                self.executeDDL1(cur)
+                sql=self._populate()
+                for sql in self._populate():
+                    cur.execute(sql)
+
+                self.help_nextset_setUp(cur)
+
+                cur.callproc('deleteme')
+                numberofrows=cur.fetchone()
+                assert numberofrows[0]== len(self.samples)
+                assert cur.nextset()
+                names=cur.fetchall()
+                assert len(names) == len(self.samples)
+                s=cur.nextset()
+                if s:
+                    empty = cur.fetchall()
+                    self.assertEquals(len(empty), 0,
+                                      "non-empty result set after other result sets")
+                    #warn("Incompatibility: MySQL returns an empty result set for the CALL itself",
+                    #     Warning)
+                #assert s == None,'No more return sets, should return None'
+            finally:
+                self.help_nextset_tearDown(cur)
+
+        finally:
+            con.close()
+
+    
+if __name__ == '__main__':
+    unittest.main()

+ 4 - 2
desktop/core/ext-py/MySQL-python-1.2.3c1/tests/test_MySQLdb_nonstandard.py → desktop/core/ext-py/MySQL-python-1.2.5/tests/test_MySQLdb_nonstandard.py

@@ -3,7 +3,9 @@ import unittest
 import _mysql
 import MySQLdb
 from MySQLdb.constants import FIELD_TYPE
-
+from configdb import connection_factory
+import warnings
+warnings.simplefilter("ignore")
 
 class TestDBAPISet(unittest.TestCase):
     def test_set_equality(self):
@@ -44,7 +46,7 @@ class CoreAPI(unittest.TestCase):
     """Test _mysql interaction internals."""
 
     def setUp(self):
-        self.conn = _mysql.connect(db='test', read_default_file="~/.my.cnf")
+        self.conn = connection_factory(use_unicode=True)
 
     def tearDown(self):
         self.conn.close()