mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-15 11:10:58 +08:00
Initial revision
This commit is contained in:
318
MySQLdb/CompatMysqldb.py
Executable file
318
MySQLdb/CompatMysqldb.py
Executable file
@ -0,0 +1,318 @@
|
||||
"""
|
||||
Original author: James Henstridge <james@daa.com.au>
|
||||
Adapted by: Andy Dustman <andy@dustman.net>
|
||||
|
||||
This is the original Mysqldb.py module which came with MySQLmodule-1.4,
|
||||
only it has been adapted to use _mysql instead MySQL. It is intended
|
||||
for backwards compatibility purposes only. But as a bonus, transactions
|
||||
will work if your database server and table types support them. It is
|
||||
called CompatMysqldb instead of Mysqldb so as not to interfere with an
|
||||
existing Mysqldb, or MySQLdb on case-insensitive brain-dead operating
|
||||
systems.
|
||||
|
||||
Under no circumstances should you bug James Henstridge about this!!!
|
||||
|
||||
-----
|
||||
|
||||
This is a class that implements an interface to mySQL databases, conforming
|
||||
to the API published by the Python db-sig at
|
||||
http://www.python.org/sigs/db-sig/DatabaseAPI.html
|
||||
|
||||
It is really just a wrapper for an older python interface to mySQL databases
|
||||
called mySQL, which I modified to facilitate use of a cursor. That module was
|
||||
Joseph Skinner's port of the mSQL module by David Gibson, which was a modified
|
||||
version of Anthony Baxter's msql module.
|
||||
|
||||
As an example, to add some extra (unprivelledged) users to your database system,
|
||||
and delete them again:
|
||||
|
||||
>>> import Mysqldb
|
||||
>>> conn = Mysqldb.mysqldb('mysql@localhost root rootpasswd')
|
||||
>>> curs = conn.cursor()
|
||||
>>> curs.execute("insert into user (host, user) values ('%s', '%s')",
|
||||
... [('localhost', 'linus'), ('somewhere.com.au', 'james')])
|
||||
2
|
||||
>>> curs.execute("select * from user")
|
||||
>>> curs.fetchall()
|
||||
-- record listing --
|
||||
>>> curs.execute("delete from user where host = 'somewhere.com.au' or user = 'linus'")
|
||||
2
|
||||
>>> curs.close()
|
||||
>>> conn.close()
|
||||
|
||||
The argument to mysqldb.mysqldb is of the form 'db@host user pass',
|
||||
'db@host user', 'db@host', 'db', 'db user pass' or 'db user'.
|
||||
|
||||
As always, the source is a good manual :-)
|
||||
|
||||
James Henstridge <james@daa.com.au>
|
||||
"""
|
||||
|
||||
import _mysql
|
||||
MySQL = _mysql
|
||||
from string import upper, split, join
|
||||
|
||||
error = 'mysqldb.error'
|
||||
|
||||
from MySQLdb.constants import FIELD_TYPE
|
||||
_type_conv = { FIELD_TYPE.TINY: int,
|
||||
FIELD_TYPE.SHORT: int,
|
||||
FIELD_TYPE.LONG: long,
|
||||
FIELD_TYPE.FLOAT: float,
|
||||
FIELD_TYPE.DOUBLE: float,
|
||||
FIELD_TYPE.LONGLONG: long,
|
||||
FIELD_TYPE.INT24: int,
|
||||
FIELD_TYPE.YEAR: int }
|
||||
|
||||
def isDDL(q):
|
||||
return upper(split(q)[0]) in ('CREATE', 'ALTER', 'GRANT', 'REVOKE',
|
||||
'DROP', 'SET')
|
||||
def isDML(q):
|
||||
return upper(split(q)[0]) in ('DELETE', 'INSERT', 'UPDATE', 'LOAD')
|
||||
def isDQL(q):
|
||||
return upper(split(q)[0]) in ('SELECT', 'SHOW', 'DESC', 'DESCRIBE')
|
||||
|
||||
class DBAPITypeObject:
|
||||
|
||||
def __init__(self,*values):
|
||||
self.values = values
|
||||
|
||||
def __cmp__(self,other):
|
||||
if other in self.values:
|
||||
return 0
|
||||
if other < self.values:
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
|
||||
_Set = DBAPITypeObject
|
||||
|
||||
STRING = _Set(FIELD_TYPE.CHAR, FIELD_TYPE.ENUM, FIELD_TYPE.INTERVAL,
|
||||
FIELD_TYPE.SET, FIELD_TYPE.STRING, FIELD_TYPE.VAR_STRING)
|
||||
BINARY = _Set(FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB, FIELD_TYPE.MEDIUM_BLOB,
|
||||
FIELD_TYPE.TINY_BLOB)
|
||||
NUMBER = _Set(FIELD_TYPE.DECIMAL, FIELD_TYPE.DOUBLE, FIELD_TYPE.FLOAT,
|
||||
FIELD_TYPE.INT24, FIELD_TYPE.LONG, FIELD_TYPE.LONGLONG,
|
||||
FIELD_TYPE.TINY, FIELD_TYPE.YEAR)
|
||||
DATE = _Set(FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE)
|
||||
TIME = _Set(FIELD_TYPE.TIME)
|
||||
TIMESTAMP = _Set(FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME)
|
||||
ROWID = _Set()
|
||||
|
||||
class Connection:
|
||||
"""This is the connection object for the mySQL database interface."""
|
||||
def __init__(self, host, user, passwd, db):
|
||||
from MySQLdb.constants import CLIENT
|
||||
kwargs = {}
|
||||
kwargs['conv'] = _type_conv
|
||||
if host: kwargs['host'] = host
|
||||
if user: kwargs['user'] = user
|
||||
if passwd: kwargs['passwd'] = passwd
|
||||
if db: kwargs['db'] = db
|
||||
try:
|
||||
self.__conn = apply(MySQL.connect, (), kwargs)
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
self.__curs = Cursor(self.__conn)
|
||||
self.__transactional = self.__conn.server_capabilities & CLIENT.TRANSACTIONS
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def __getattr__(self, key):
|
||||
return getattr(self.__curs, key)
|
||||
|
||||
def __setattr__(self, key, val):
|
||||
if key in ('arraysize', 'description', 'insert_id'):
|
||||
setattr(self.__curs, key, val)
|
||||
else:
|
||||
self.__dict__[key] = val
|
||||
|
||||
def close(self):
|
||||
self.__conn = None
|
||||
|
||||
def cursor(self):
|
||||
if self.__conn == None: raise error, "Connection is closed."
|
||||
return Cursor(self.__conn)
|
||||
|
||||
def commit(self):
|
||||
"""Commit the current transaction."""
|
||||
if self.__transactional:
|
||||
self.__conn.query("COMMIT")
|
||||
|
||||
def rollback(self):
|
||||
"""Rollback the current transaction."""
|
||||
if self.__transactional:
|
||||
self.__conn.query("ROLLBACK")
|
||||
else: raise error, "Not supported by server"
|
||||
|
||||
def callproc(self, params=None): pass
|
||||
|
||||
# These functions are just here so that every action that is
|
||||
# covered by mySQL is covered by mysqldb. They are not standard
|
||||
# DB API. The list* methods are not included, since they can be
|
||||
# done with the SQL SHOW command.
|
||||
def create(self, dbname):
|
||||
"""This is not a standard part of Python DB API."""
|
||||
self.__conn.query("CREATE DATABASE %s" % dbname)
|
||||
self.__conn.store_result()
|
||||
return None
|
||||
def drop(self, dbname):
|
||||
"""This is not a standard part of Python DB API."""
|
||||
self.__conn.query("DROP DATABASE %s" % dbname)
|
||||
self.__conn.store_result()
|
||||
return None
|
||||
def reload(self):
|
||||
"""This is not a standard part of Python DB API."""
|
||||
self.__conn.query("RELOAD TABLES")
|
||||
self.__conn.store_result()
|
||||
return None
|
||||
def shutdown(self):
|
||||
"""This is not a standard part of Python DB API."""
|
||||
return self.__conn.shutdown()
|
||||
|
||||
|
||||
class Cursor:
|
||||
"""A cursor object for use with connecting to mySQL databases."""
|
||||
def __init__(self, conn):
|
||||
self.__conn = conn
|
||||
self.__res = None
|
||||
self.arraysize = 1
|
||||
self.__dict__['description'] = None
|
||||
self.__open = 1
|
||||
self.insert_id = 0
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def __setattr__(self, key, val):
|
||||
if key == 'description':
|
||||
raise error, "description is a read-only attribute."
|
||||
else:
|
||||
self.__dict__[key] = val
|
||||
|
||||
def __delattr__(self, key):
|
||||
if key in ('description', 'arraysize', 'insert_id'):
|
||||
raise error, "%s can't be deleted." % (key,)
|
||||
else:
|
||||
del self.__dict__[key]
|
||||
|
||||
def close(self):
|
||||
self.__conn = None
|
||||
self.__res = None
|
||||
self.__open = 0
|
||||
|
||||
def execute(self, op, params=None):
|
||||
if not self.__open: raise error, "Cursor has been closed."
|
||||
if params:
|
||||
if type(params[0]) not in (type(()), type([])):
|
||||
params = [params]
|
||||
if isDDL(op):
|
||||
self.__dict__['description'] = None
|
||||
try:
|
||||
for x in params:
|
||||
self.__res = \
|
||||
self.__conn.query(op % x)
|
||||
self.insert_id = self.__res.insert_id()
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
return 1
|
||||
if isDML(op):
|
||||
self.__dict__['description'] = None
|
||||
af = 0
|
||||
try:
|
||||
for x in params:
|
||||
self.__res = \
|
||||
self.__conn.query(op % x)
|
||||
af =af+self.__res.affectedrows()
|
||||
self.insert_id = self.__res.insert_id()
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
return af
|
||||
if isDQL(op):
|
||||
try:
|
||||
self.__res = self.__conn.query(
|
||||
op % params[-1])
|
||||
self.insert_id = self.__res.insert_id()
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
self.__dict__['description'] = self.__res.describe()
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
self.__conn.query(op)
|
||||
self.__res = self.__conn.store_result()
|
||||
self.insert_id = self.__conn.insert_id()
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
self.__dict__['description'] = None
|
||||
if isDDL(op):
|
||||
return 1
|
||||
elif self.__conn.affected_rows() != -1:
|
||||
return self.__conn.affected_rows()
|
||||
else:
|
||||
self.__dict__['description'] = self.__res.describe()
|
||||
return None
|
||||
def fetchone(self):
|
||||
if not self.__res: raise error, "no query made yet."
|
||||
try:
|
||||
return self.__res.fetch_row(1)[0]
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
|
||||
def fetchmany(self, size=None):
|
||||
if not self.__res: raise error, "no query made yet."
|
||||
try:
|
||||
return self.__res.fetch_row(size or self.arraysize)
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
|
||||
def fetchall(self):
|
||||
if not self.__res: raise error, "no query made yet."
|
||||
try:
|
||||
return self.__res.fetch_row(0)
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
|
||||
def fetchoneDict(self):
|
||||
"""This is not a standard part of Python DB API."""
|
||||
if not self.__res: raise error, "no query made yet."
|
||||
try:
|
||||
return self.__res.fetch_row(1, 2)[0]
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
|
||||
def fetchmanyDict(self, size=None):
|
||||
"""This is not a standard part of Python DB API."""
|
||||
if not self.__res: raise error, "no query made yet."
|
||||
try:
|
||||
return self.__res.fetch_row(size or self.arraysize, 2)
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
|
||||
def fetchallDict(self):
|
||||
"""This is not a standard part of Python DB API."""
|
||||
if not self.__res: raise error, "no query made yet."
|
||||
try:
|
||||
return self.__res.fetch_row(0,2)
|
||||
except MySQL.Error, msg:
|
||||
raise error, msg
|
||||
|
||||
def setinputsizes(self, sizes): pass
|
||||
def setoutputsize(self, size, col=None): pass
|
||||
|
||||
|
||||
def mysqldb(connect_string):
|
||||
"""Makes a connection to the MySQL server. The Argument should be of
|
||||
the form 'db@host user pass' or 'db@host user' or 'db@host' or 'db'
|
||||
or 'db user pass' or 'db user', where db is the database name, host
|
||||
is the server's host name, user is your user name, and pass is your
|
||||
password."""
|
||||
val = split(connect_string)
|
||||
if len(val) == 0: raise error, "no database specified"
|
||||
while len(val) < 3: val.append('')
|
||||
dh = split(val[0], '@')
|
||||
if len(dh) == 0: raise error, "no database specified"
|
||||
while len(dh) < 2: dh.append('')
|
||||
return Connection(dh[1], val[1], val[2], dh[0])
|
||||
|
9
MySQLdb/MANIFEST.in
Normal file
9
MySQLdb/MANIFEST.in
Normal file
@ -0,0 +1,9 @@
|
||||
prune CVS
|
||||
recursive-include doc *
|
||||
recursive-include examples *
|
||||
include _mysql_version.h
|
||||
include README.MySQLmodule
|
||||
include license.py
|
||||
include MANIFEST.in
|
||||
include MANIFEST
|
||||
include GPL
|
82
MySQLdb/MySQLdb/__init__.py
Normal file
82
MySQLdb/MySQLdb/__init__.py
Normal file
@ -0,0 +1,82 @@
|
||||
"""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.
|
||||
|
||||
"""
|
||||
|
||||
__author__ = "Andy Dustman <andy@dustman.net>"
|
||||
__revision__ = """$Revision$"""[11:-2]
|
||||
version_info = (
|
||||
0,
|
||||
9,
|
||||
0,
|
||||
"beta",
|
||||
1)
|
||||
if version_info[3] == "final": __version__ = "%d.%d.%d" % version_info[:3]
|
||||
else: __version__ = "%d.%d.%d%1.1s%d" % version_info[:5]
|
||||
|
||||
import _mysql
|
||||
|
||||
if __version__ != getattr(_mysql, '__version__', None):
|
||||
raise ImportError, "this is MySQLdb version %s, but _mysql is version %s" %\
|
||||
(__version__, _mysql.__version__)
|
||||
|
||||
|
||||
threadsafety = 2
|
||||
apilevel = "2.0"
|
||||
paramstyle = "format"
|
||||
|
||||
|
||||
class DBAPITypeObject:
|
||||
|
||||
"""Helper class for determining column types; required by DB API."""
|
||||
|
||||
def __init__(self,*values):
|
||||
self.values = values
|
||||
|
||||
def __cmp__(self,other):
|
||||
if other in self.values:
|
||||
return 0
|
||||
if other < self.values:
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
|
||||
|
||||
_Set = DBAPITypeObject
|
||||
from constants import FIELD_TYPE
|
||||
|
||||
STRING = _Set(FIELD_TYPE.CHAR, FIELD_TYPE.ENUM, FIELD_TYPE.INTERVAL,
|
||||
FIELD_TYPE.SET, FIELD_TYPE.STRING, FIELD_TYPE.VAR_STRING)
|
||||
BINARY = _Set(FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB, FIELD_TYPE.MEDIUM_BLOB,
|
||||
FIELD_TYPE.TINY_BLOB)
|
||||
NUMBER = _Set(FIELD_TYPE.DECIMAL, FIELD_TYPE.DOUBLE, FIELD_TYPE.FLOAT,
|
||||
FIELD_TYPE.INT24, FIELD_TYPE.LONG, FIELD_TYPE.LONGLONG,
|
||||
FIELD_TYPE.TINY, FIELD_TYPE.YEAR)
|
||||
DATE = _Set(FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE)
|
||||
TIME = _Set(FIELD_TYPE.TIME)
|
||||
TIMESTAMP = _Set(FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME)
|
||||
ROWID = _Set()
|
||||
|
||||
def Binary(x): return str(x)
|
||||
|
||||
from _mysql import *
|
||||
from connections import Connection
|
||||
|
||||
def Connect(*args, **kwargs):
|
||||
"""Factory function for connections.Connection."""
|
||||
return apply(Connection, args, kwargs)
|
||||
|
||||
connect = Connect
|
||||
|
||||
__all__ = ['BINARY', 'Binary', 'Connect', 'Connection', 'DATE', 'DataError', 'DatabaseError', 'Error', 'FIELD_TYPE', 'IntegrityError', 'InterfaceError', 'InternalError', 'MySQLError', 'NULL', 'NUMBER', 'NotSupportedError', 'OperationalError', 'ProgrammingError', 'ROWID', 'STRING', 'TIME', 'TIMESTAMP', 'Warning', 'apilevel', 'connect', 'connections', 'constants', 'cursors', 'debug', 'escape', 'escape_dict', 'escape_sequence', 'escape_string', 'get_client_info', 'paramstyle', 'string_literal', 'threadsafety', 'version_info']
|
||||
|
209
MySQLdb/MySQLdb/connections.py
Normal file
209
MySQLdb/MySQLdb/connections.py
Normal file
@ -0,0 +1,209 @@
|
||||
"""MySQLdb Connections Module
|
||||
|
||||
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 NotSupportedError, ProgrammingError
|
||||
|
||||
class Connection:
|
||||
|
||||
"""Create a connection to the database. It is strongly recommended
|
||||
that you only use keyword parameters. "NULL pointer" indicates that
|
||||
NULL will be passed to mysql_real_connect(); the value in parenthesis
|
||||
indicates how MySQL interprets the NULL. Consult the MySQL C API
|
||||
documentation for more information.
|
||||
|
||||
host -- string, host to connect to or NULL pointer (localhost)
|
||||
user -- string, user to connect as or NULL pointer (your username)
|
||||
passwd -- string, password to use or NULL pointer (no password)
|
||||
db -- string, database to use or NULL (no DB selected)
|
||||
port -- integer, TCP/IP port to connect to or default MySQL port
|
||||
unix_socket -- string, location of unix_socket to use or use TCP
|
||||
client_flags -- integer, flags to use or 0 (see MySQL docs)
|
||||
conv -- conversion dictionary, see MySQLdb.converters
|
||||
connect_time -- number of seconds to wait before the connection
|
||||
attempt fails.
|
||||
compress -- if set, compression is enabled
|
||||
init_command -- command which is run once the connection is created
|
||||
read_default_file -- see the MySQL documentation for mysql_options()
|
||||
read_default_group -- see the MySQL documentation for mysql_options()
|
||||
cursorclass -- class object, used to create cursors or cursors.Cursor.
|
||||
This parameter MUST be specified as a keyword parameter.
|
||||
threads -- boolean, if false threading is disabled, otherwise threads
|
||||
are enabled by default. (MUST be a keyword parameter.)
|
||||
|
||||
Returns a Connection object.
|
||||
|
||||
There are a number of undocumented, non-standard methods. See the
|
||||
documentation for the MySQL C API for some hints on what they do.
|
||||
"""
|
||||
|
||||
default_cursor = cursors.Cursor
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
from _mysql import connect
|
||||
from constants import CLIENT
|
||||
from converters import conversions
|
||||
import types
|
||||
kwargs2 = kwargs.copy()
|
||||
self.__threads = kwargs.get('threads',1)
|
||||
if kwargs.has_key('threads'):
|
||||
del kwargs2['threads']
|
||||
if not kwargs.has_key('conv'):
|
||||
kwargs2['conv'] = conversions.copy()
|
||||
if kwargs.has_key('cursorclass'):
|
||||
self.cursorclass = kwargs['cursorclass']
|
||||
del kwargs2['cursorclass']
|
||||
else:
|
||||
self.cursorclass = self.default_cursor
|
||||
self._db = apply(connect, args, kwargs2)
|
||||
self._db.converter[types.StringType] = self._db.string_literal
|
||||
self._transactional = self._db.server_capabilities & CLIENT.TRANSACTIONS
|
||||
self._autocommit = 1
|
||||
if self.__threads:
|
||||
# __c_lock: connection lock. Cursors must always obtain the
|
||||
# connection lock before doing any queries. A blocking
|
||||
# call is used. If the same thread tries to acquire the
|
||||
# lock, produce an error.
|
||||
#
|
||||
# _t_lock: transaction lock. If operating transactionally,
|
||||
# Cursors must acquire the transaction lock on the first
|
||||
# query. The same thread may acquire the lock more than
|
||||
# once. commit() or rollback() or an error releases this
|
||||
# lock.
|
||||
import threading
|
||||
self.__c_lock = threading.Lock()
|
||||
self.__c_locker = None
|
||||
self.__t_lock = threading.Lock()
|
||||
self.__t_locker = None
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def _begin(self):
|
||||
"""Obtain the transaction lock. A thread may try to obtain this
|
||||
lock multiple times."""
|
||||
if not self.__threads: return
|
||||
import threading
|
||||
me = threading.currentThread()
|
||||
if self.__t_locker == me: return
|
||||
self.__t_lock.acquire()
|
||||
self.__t_locker = me
|
||||
|
||||
def _end(self):
|
||||
"""Release the transaction lock. If a thread tries to release this
|
||||
lock when it is not currently locking it, it does nothing."""
|
||||
if not self.__threads: return
|
||||
import threading
|
||||
me = threading.currentThread()
|
||||
if self.__t_locker != me: return
|
||||
self.__t_locker = None
|
||||
self.__t_lock.release()
|
||||
|
||||
def _acquire(self):
|
||||
"""Acquire the connection. ProgrammingError is raised if the
|
||||
thread has already acquired the connection."""
|
||||
if not self.__threads: return
|
||||
import threading
|
||||
me = threading.currentThread()
|
||||
if self.__c_locker == me:
|
||||
raise ProgrammingError, "would produce deadlock"
|
||||
self.__c_lock.acquire()
|
||||
self.__c_locker = me
|
||||
|
||||
def _release(self):
|
||||
"""Release the connection. If a thread tries to release this
|
||||
lock when it is not currently locking it, ProgrammingError
|
||||
is raised (this shouldn't happen)."""
|
||||
if not self.__threads: return
|
||||
import threading
|
||||
me = threading.currentThread()
|
||||
if self.__c_locker != me:
|
||||
if not self.__c_locker: return
|
||||
raise ProgrammingError, "tried to release another %s's lock" % self.__c_locker
|
||||
self.__c_locker = None
|
||||
self.__c_lock.release()
|
||||
|
||||
def close(self):
|
||||
"""Close the connection. No further activity possible."""
|
||||
self._db.close()
|
||||
|
||||
def autocommit(self, v):
|
||||
"""Turn autocommit on or off."""
|
||||
self._db.query("SET AUTOCOMMIT=%d"%v)
|
||||
self._transactional = not v
|
||||
self._autocommit = v
|
||||
|
||||
def begin(self):
|
||||
"""Explicitly begin a transaction. Non-standard."""
|
||||
self._db.query("BEGIN")
|
||||
self._transactional = 1
|
||||
|
||||
def commit(self):
|
||||
"""Commit the current transaction."""
|
||||
try:
|
||||
if self._transactional:
|
||||
self._db.query("COMMIT")
|
||||
finally:
|
||||
self._end()
|
||||
self._transactional = not self._autocommit
|
||||
|
||||
def rollback(self):
|
||||
"""Rollback the current transaction."""
|
||||
try:
|
||||
if self._transactional:
|
||||
self._db.query("ROLLBACK")
|
||||
else:
|
||||
raise NotSupportedError, "Not supported by server"
|
||||
finally:
|
||||
self._end()
|
||||
self._transactional = not self._autocommit
|
||||
|
||||
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)
|
||||
|
||||
# Non-portable MySQL-specific stuff
|
||||
# Methods not included on purpose (use Cursors instead):
|
||||
# query, store_result, use_result
|
||||
|
||||
def affected_rows(self): return self._db.affected_rows()
|
||||
def dump_debug_info(self): return self._db.dump_debug_info()
|
||||
def escape_string(self, s): return self._db.escape_string(s)
|
||||
def get_host_info(self): return self._db.get_host_info()
|
||||
def get_proto_info(self): return self._db.get_proto_info()
|
||||
def get_server_info(self): return self._db.get_server_info()
|
||||
def info(self): return self._db.info()
|
||||
def kill(self, p): return self._db.kill(p)
|
||||
def list_dbs(self): return self._db.list_dbs().fetch_row(0)
|
||||
def list_fields(self, table): return self._db.list_fields(table).fetch_row(0)
|
||||
def list_processes(self): return self._db.list_processes().fetch_row(0)
|
||||
def list_tables(self, db): return self._db.list_tables(db).fetch_row(0)
|
||||
def field_count(self): return self._db.field_count()
|
||||
num_fields = field_count # used prior to MySQL-3.22.24
|
||||
def ping(self): return self._db.ping()
|
||||
def row_tell(self): return self._db.row_tell()
|
||||
def select_db(self, db): return self._db.select_db(db)
|
||||
def shutdown(self): return self._db.shutdown()
|
||||
def stat(self): return self._db.stat()
|
||||
def string_literal(self, s): return self._db.string_literal(s)
|
||||
def thread_id(self): return self._db.thread_id()
|
||||
|
||||
def _try_feature(self, feature, *args, **kwargs):
|
||||
try:
|
||||
return apply(getattr(self._db, feature), args, kwargs)
|
||||
except AttributeError:
|
||||
raise NotSupportedError, "not supported by MySQL library"
|
||||
def character_set_name(self):
|
||||
return self._try_feature('character_set_name')
|
||||
def change_user(self, *args, **kwargs):
|
||||
return apply(self._try_feature, ('change_user',)+args, kwargs)
|
23
MySQLdb/MySQLdb/constants/CLIENT.py
Normal file
23
MySQLdb/MySQLdb/constants/CLIENT.py
Normal file
@ -0,0 +1,23 @@
|
||||
"""MySQL CLIENT constants
|
||||
|
||||
These constants are used when creating the connection. Use bitwise-OR
|
||||
(|) to combine options together, and pass them as the client_flags
|
||||
parameter to MySQLdb.Connection. For more information on these flags,
|
||||
see the MySQL C API documentation for mysql_real_connect().
|
||||
|
||||
"""
|
||||
|
||||
LONG_PASSWORD = 1
|
||||
FOUND_ROWS = 2
|
||||
LONG_FLAG = 4
|
||||
CONNECT_WITH_DB = 8
|
||||
NO_SCHEMA = 16
|
||||
COMPRESS = 32
|
||||
ODBC = 64
|
||||
LOCAL_FILES = 128
|
||||
IGNORE_SPACE = 256
|
||||
CHANGE_USER = 512
|
||||
INTERACTIVE = 1024
|
||||
SSL = 2048
|
||||
IGNORE_SIGPIPE = 4096
|
||||
TRANSACTIONS = 8192 # mysql_com.h was WRONG prior to 3.23.35
|
30
MySQLdb/MySQLdb/constants/CR.py
Normal file
30
MySQLdb/MySQLdb/constants/CR.py
Normal file
@ -0,0 +1,30 @@
|
||||
"""MySQL Connection Errors
|
||||
|
||||
Nearly all of these raise OperationalError. COMMANDS_OUT_OF_SYNC
|
||||
raises ProgrammingError.
|
||||
|
||||
"""
|
||||
|
||||
MIN_ERROR = 2000
|
||||
MAX_ERROR = 2999
|
||||
UNKNOWN_ERROR = 2000
|
||||
SOCKET_CREATE_ERROR = 2001
|
||||
CONNECTION_ERROR = 2002
|
||||
CONN_HOST_ERROR = 2003
|
||||
IPSOCK_ERROR = 2004
|
||||
UNKNOWN_HOST = 2005
|
||||
SERVER_GONE_ERROR = 2006
|
||||
VERSION_ERROR = 2007
|
||||
OUT_OF_MEMORY = 2008
|
||||
WRONG_HOST_INFO = 2009
|
||||
LOCALHOST_CONNECTION = 2010
|
||||
TCP_CONNECTION = 2011
|
||||
SERVER_HANDSHAKE_ERR = 2012
|
||||
SERVER_LOST = 2013
|
||||
COMMANDS_OUT_OF_SYNC = 2014
|
||||
NAMEDPIPE_CONNECTION = 2015
|
||||
NAMEDPIPEWAIT_ERROR = 2016
|
||||
NAMEDPIPEOPEN_ERROR = 2017
|
||||
NAMEDPIPESETSTATE_ERROR = 2018
|
||||
CANT_READ_CHARSET = 2019
|
||||
NET_PACKET_TOO_LARGE = 2020
|
211
MySQLdb/MySQLdb/constants/ER.py
Normal file
211
MySQLdb/MySQLdb/constants/ER.py
Normal file
@ -0,0 +1,211 @@
|
||||
"""MySQL ER Constants
|
||||
|
||||
These constants are error codes for the bulk of the error conditions
|
||||
that may occur.
|
||||
|
||||
"""
|
||||
|
||||
HASHCHK = 1000
|
||||
NISAMCHK = 1001
|
||||
NO = 1002
|
||||
YES = 1003
|
||||
CANT_CREATE_FILE = 1004
|
||||
CANT_CREATE_TABLE = 1005
|
||||
CANT_CREATE_DB = 1006
|
||||
DB_CREATE_EXISTS = 1007
|
||||
DB_DROP_EXISTS = 1008
|
||||
DB_DROP_DELETE = 1009
|
||||
DB_DROP_RMDIR = 1010
|
||||
CANT_DELETE_FILE = 1011
|
||||
CANT_FIND_SYSTEM_REC = 1012
|
||||
CANT_GET_STAT = 1013
|
||||
CANT_GET_WD = 1014
|
||||
CANT_LOCK = 1015
|
||||
CANT_OPEN_FILE = 1016
|
||||
FILE_NOT_FOUND = 1017
|
||||
CANT_READ_DIR = 1018
|
||||
CANT_SET_WD = 1019
|
||||
CHECKREAD = 1020
|
||||
DISK_FULL = 1021
|
||||
DUP_KEY = 1022
|
||||
ERROR_ON_CLOSE = 1023
|
||||
ERROR_ON_READ = 1024
|
||||
ERROR_ON_RENAME = 1025
|
||||
ERROR_ON_WRITE = 1026
|
||||
FILE_USED = 1027
|
||||
FILSORT_ABORT = 1028
|
||||
FORM_NOT_FOUND = 1029
|
||||
GET_ERRNO = 1030
|
||||
ILLEGAL_HA = 1031
|
||||
KEY_NOT_FOUND = 1032
|
||||
NOT_FORM_FILE = 1033
|
||||
NOT_KEYFILE = 1034
|
||||
OLD_KEYFILE = 1035
|
||||
OPEN_AS_READONLY = 1036
|
||||
OUTOFMEMORY = 1037
|
||||
OUT_OF_SORTMEMORY = 1038
|
||||
UNEXPECTED_EOF = 1039
|
||||
CON_COUNT_ERROR = 1040
|
||||
OUT_OF_RESOURCES = 1041
|
||||
BAD_HOST_ERROR = 1042
|
||||
HANDSHAKE_ERROR = 1043
|
||||
DBACCESS_DENIED_ERROR = 1044
|
||||
ACCESS_DENIED_ERROR = 1045
|
||||
NO_DB_ERROR = 1046
|
||||
UNKNOWN_COM_ERROR = 1047
|
||||
BAD_NULL_ERROR = 1048
|
||||
BAD_DB_ERROR = 1049
|
||||
TABLE_EXISTS_ERROR = 1050
|
||||
BAD_TABLE_ERROR = 1051
|
||||
NON_UNIQ_ERROR = 1052
|
||||
SERVER_SHUTDOWN = 1053
|
||||
BAD_FIELD_ERROR = 1054
|
||||
WRONG_FIELD_WITH_GROUP = 1055
|
||||
WRONG_GROUP_FIELD = 1056
|
||||
WRONG_SUM_SELECT = 1057
|
||||
WRONG_VALUE_COUNT = 1058
|
||||
TOO_LONG_IDENT = 1059
|
||||
DUP_FIELDNAME = 1060
|
||||
DUP_KEYNAME = 1061
|
||||
DUP_ENTRY = 1062
|
||||
WRONG_FIELD_SPEC = 1063
|
||||
PARSE_ERROR = 1064
|
||||
EMPTY_QUERY = 1065
|
||||
NONUNIQ_TABLE = 1066
|
||||
INVALID_DEFAULT = 1067
|
||||
MULTIPLE_PRI_KEY = 1068
|
||||
TOO_MANY_KEYS = 1069
|
||||
TOO_MANY_KEY_PARTS = 1070
|
||||
TOO_LONG_KEY = 1071
|
||||
KEY_COLUMN_DOES_NOT_EXITS = 1072
|
||||
BLOB_USED_AS_KEY = 1073
|
||||
TOO_BIG_FIELDLENGTH = 1074
|
||||
WRONG_AUTO_KEY = 1075
|
||||
READY = 1076
|
||||
NORMAL_SHUTDOWN = 1077
|
||||
GOT_SIGNAL = 1078
|
||||
SHUTDOWN_COMPLETE = 1079
|
||||
FORCING_CLOSE = 1080
|
||||
IPSOCK_ERROR = 1081
|
||||
NO_SUCH_INDEX = 1082
|
||||
WRONG_FIELD_TERMINATORS = 1083
|
||||
BLOBS_AND_NO_TERMINATED = 1084
|
||||
TEXTFILE_NOT_READABLE = 1085
|
||||
FILE_EXISTS_ERROR = 1086
|
||||
LOAD_INFO = 1087
|
||||
ALTER_INFO = 1088
|
||||
WRONG_SUB_KEY = 1089
|
||||
CANT_REMOVE_ALL_FIELDS = 1090
|
||||
CANT_DROP_FIELD_OR_KEY = 1091
|
||||
INSERT_INFO = 1092
|
||||
INSERT_TABLE_USED = 1093
|
||||
NO_SUCH_THREAD = 1094
|
||||
KILL_DENIED_ERROR = 1095
|
||||
NO_TABLES_USED = 1096
|
||||
TOO_BIG_SET = 1097
|
||||
NO_UNIQUE_LOGFILE = 1098
|
||||
TABLE_NOT_LOCKED_FOR_WRITE = 1099
|
||||
TABLE_NOT_LOCKED = 1100
|
||||
BLOB_CANT_HAVE_DEFAULT = 1101
|
||||
WRONG_DB_NAME = 1102
|
||||
WRONG_TABLE_NAME = 1103
|
||||
TOO_BIG_SELECT = 1104
|
||||
UNKNOWN_ERROR = 1105
|
||||
UNKNOWN_PROCEDURE = 1106
|
||||
WRONG_PARAMCOUNT_TO_PROCEDURE = 1107
|
||||
WRONG_PARAMETERS_TO_PROCEDURE = 1108
|
||||
UNKNOWN_TABLE = 1109
|
||||
FIELD_SPECIFIED_TWICE = 1110
|
||||
INVALID_GROUP_FUNC_USE = 1111
|
||||
UNSUPPORTED_EXTENSION = 1112
|
||||
TABLE_MUST_HAVE_COLUMNS = 1113
|
||||
RECORD_FILE_FULL = 1114
|
||||
UNKNOWN_CHARACTER_SET = 1115
|
||||
TOO_MANY_TABLES = 1116
|
||||
TOO_MANY_FIELDS = 1117
|
||||
TOO_BIG_ROWSIZE = 1118
|
||||
STACK_OVERRUN = 1119
|
||||
WRONG_OUTER_JOIN = 1120
|
||||
NULL_COLUMN_IN_INDEX = 1121
|
||||
CANT_FIND_UDF = 1122
|
||||
CANT_INITIALIZE_UDF = 1123
|
||||
UDF_NO_PATHS = 1124
|
||||
UDF_EXISTS = 1125
|
||||
CANT_OPEN_LIBRARY = 1126
|
||||
CANT_FIND_DL_ENTRY = 1127
|
||||
FUNCTION_NOT_DEFINED = 1128
|
||||
HOST_IS_BLOCKED = 1129
|
||||
HOST_NOT_PRIVILEGED = 1130
|
||||
PASSWORD_ANONYMOUS_USER = 1131
|
||||
PASSWORD_NOT_ALLOWED = 1132
|
||||
PASSWORD_NO_MATCH = 1133
|
||||
UPDATE_INFO = 1134
|
||||
CANT_CREATE_THREAD = 1135
|
||||
WRONG_VALUE_COUNT_ON_ROW = 1136
|
||||
CANT_REOPEN_TABLE = 1137
|
||||
INVALID_USE_OF_NULL = 1138
|
||||
REGEXP_ERROR = 1139
|
||||
MIX_OF_GROUP_FUNC_AND_FIELDS = 1140
|
||||
NONEXISTING_GRANT = 1141
|
||||
TABLEACCESS_DENIED_ERROR = 1142
|
||||
COLUMNACCESS_DENIED_ERROR = 1143
|
||||
ILLEGAL_GRANT_FOR_TABLE = 1144
|
||||
GRANT_WRONG_HOST_OR_USER = 1145
|
||||
NO_SUCH_TABLE = 1146
|
||||
NONEXISTING_TABLE_GRANT = 1147
|
||||
NOT_ALLOWED_COMMAND = 1148
|
||||
SYNTAX_ERROR = 1149
|
||||
DELAYED_CANT_CHANGE_LOCK = 1150
|
||||
TOO_MANY_DELAYED_THREADS = 1151
|
||||
ABORTING_CONNECTION = 1152
|
||||
NET_PACKET_TOO_LARGE = 1153
|
||||
NET_READ_ERROR_FROM_PIPE = 1154
|
||||
NET_FCNTL_ERROR = 1155
|
||||
NET_PACKETS_OUT_OF_ORDER = 1156
|
||||
NET_UNCOMPRESS_ERROR = 1157
|
||||
NET_READ_ERROR = 1158
|
||||
NET_READ_INTERRUPTED = 1159
|
||||
NET_ERROR_ON_WRITE = 1160
|
||||
NET_WRITE_INTERRUPTED = 1161
|
||||
TOO_LONG_STRING = 1162
|
||||
TABLE_CANT_HANDLE_BLOB = 1163
|
||||
TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164
|
||||
DELAYED_INSERT_TABLE_LOCKED = 1165
|
||||
WRONG_COLUMN_NAME = 1166
|
||||
WRONG_KEY_COLUMN = 1167
|
||||
WRONG_MRG_TABLE = 1168
|
||||
DUP_UNIQUE = 1169
|
||||
BLOB_KEY_WITHOUT_LENGTH = 1170
|
||||
PRIMARY_CANT_HAVE_NULL = 1171
|
||||
TOO_MANY_ROWS = 1172
|
||||
REQUIRES_PRIMARY_KEY = 1173
|
||||
NO_RAID_COMPILED = 1174
|
||||
UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175
|
||||
KEY_DOES_NOT_EXITS = 1176
|
||||
CHECK_NO_SUCH_TABLE = 1177
|
||||
CHECK_NOT_IMPLEMENTED = 1178
|
||||
CANT_DO_THIS_DURING_AN_TRANSACTION = 1179
|
||||
ERROR_DURING_COMMIT = 1180
|
||||
ERROR_DURING_ROLLBACK = 1181
|
||||
ERROR_DURING_FLUSH_LOGS = 1182
|
||||
ERROR_DURING_CHECKPOINT = 1183
|
||||
NEW_ABORTING_CONNECTION = 1184
|
||||
DUMP_NOT_IMPLEMENTED = 1185
|
||||
FLUSH_MASTER_BINLOG_CLOSED = 1186
|
||||
INDEX_REBUILD = 1187
|
||||
MASTER = 1188
|
||||
MASTER_NET_READ = 1189
|
||||
MASTER_NET_WRITE = 1190
|
||||
FT_MATCHING_KEY_NOT_FOUND = 1191
|
||||
LOCK_OR_ACTIVE_TRANSACTION = 1192
|
||||
UNKNOWN_SYSTEM_VARIABLE = 1193
|
||||
CRASHED_ON_USAGE = 1194
|
||||
CRASHED_ON_REPAIR = 1195
|
||||
WARNING_NOT_COMPLETE_ROLLBACK = 1196
|
||||
TRANS_CACHE_FULL = 1197
|
||||
SLAVE_MUST_STOP = 1198
|
||||
SLAVE_NOT_RUNNING = 1199
|
||||
BAD_SLAVE = 1200
|
||||
MASTER_INFO = 1201
|
||||
SLAVE_THREAD = 1202
|
||||
ERROR_MESSAGES = 203
|
33
MySQLdb/MySQLdb/constants/FIELD_TYPE.py
Normal file
33
MySQLdb/MySQLdb/constants/FIELD_TYPE.py
Normal file
@ -0,0 +1,33 @@
|
||||
"""MySQL FIELD_TYPE Constants
|
||||
|
||||
These constants represent the various column (field) types that are
|
||||
supported by MySQL.
|
||||
|
||||
"""
|
||||
|
||||
DECIMAL = 0
|
||||
TINY = 1
|
||||
SHORT = 2
|
||||
LONG = 3
|
||||
FLOAT = 4
|
||||
DOUBLE = 5
|
||||
NULL = 6
|
||||
TIMESTAMP = 7
|
||||
LONGLONG = 8
|
||||
INT24 = 9
|
||||
DATE = 10
|
||||
TIME = 11
|
||||
DATETIME = 12
|
||||
YEAR = 13
|
||||
NEWDATE = 14
|
||||
ENUM = 247
|
||||
SET = 248
|
||||
TINY_BLOB = 249
|
||||
MEDIUM_BLOB = 250
|
||||
LONG_BLOB = 251
|
||||
BLOB = 252
|
||||
VAR_STRING = 253
|
||||
STRING = 254
|
||||
|
||||
CHAR = TINY
|
||||
INTERVAL = ENUM
|
23
MySQLdb/MySQLdb/constants/FLAG.py
Normal file
23
MySQLdb/MySQLdb/constants/FLAG.py
Normal file
@ -0,0 +1,23 @@
|
||||
"""MySQL FLAG Constants
|
||||
|
||||
These flags are used along with the FIELD_TYPE to indicate various
|
||||
properties of columns in a result set.
|
||||
|
||||
"""
|
||||
|
||||
NOT_NULL = 1
|
||||
PRI_KEY = 2
|
||||
UNIQUE_KEY = 4
|
||||
MULTIPLE_KEY = 8
|
||||
BLOB = 16
|
||||
UNSIGNED = 32
|
||||
ZEROFILL = 64
|
||||
BINARY = 128
|
||||
ENUM = 256
|
||||
AUTO_INCREMENT = 512
|
||||
TIMESTAMP = 1024
|
||||
SET = 2048
|
||||
NUM = 32768
|
||||
PART_KEY = 16384
|
||||
GROUP = 32768
|
||||
UNIQUE = 65536
|
17
MySQLdb/MySQLdb/constants/REFRESH.py
Normal file
17
MySQLdb/MySQLdb/constants/REFRESH.py
Normal file
@ -0,0 +1,17 @@
|
||||
"""MySQL REFRESH Constants
|
||||
|
||||
These constants seem to mostly deal with things internal to the
|
||||
MySQL server. Forget you saw this.
|
||||
|
||||
"""
|
||||
|
||||
GRANT = 1
|
||||
LOG = 2
|
||||
TABLES = 4
|
||||
HOSTS = 8
|
||||
STATUS = 16
|
||||
THREADS = 32
|
||||
SLAVE = 64
|
||||
MASTER = 128
|
||||
READ_LOCK = 16384
|
||||
FAST = 32768
|
1
MySQLdb/MySQLdb/constants/__init__.py
Normal file
1
MySQLdb/MySQLdb/constants/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__all__ = ['CR', 'FIELD_TYPE','CLIENT','REFRESH','ER','FLAG']
|
187
MySQLdb/MySQLdb/converters.py
Normal file
187
MySQLdb/MySQLdb/converters.py
Normal file
@ -0,0 +1,187 @@
|
||||
"""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
|
||||
from time import localtime, strftime
|
||||
import types
|
||||
|
||||
def Thing2Str(s, d):
|
||||
"""Convert something into a string via str()."""
|
||||
return str(s)
|
||||
|
||||
# Python 1.5.2 compatibility hack
|
||||
if str(0L)[-1]=='L':
|
||||
def Long2Int(l, d):
|
||||
"""Convert a long integer to a string, chopping the L."""
|
||||
return str(l)[:-1]
|
||||
else:
|
||||
Long2Int = Thing2Str
|
||||
|
||||
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)==types.ClassType and isinstance(o,x), d.keys())
|
||||
if not cl:
|
||||
return d[types.StringType](o,d)
|
||||
d[o.__class__] = d[cl[0]]
|
||||
return d[cl[0]](o, d)
|
||||
|
||||
conversions = {
|
||||
types.IntType: Thing2Str,
|
||||
types.LongType: Long2Int,
|
||||
types.FloatType: Thing2Str,
|
||||
types.NoneType: None2NULL,
|
||||
types.TupleType: escape_sequence,
|
||||
types.ListType: escape_sequence,
|
||||
types.DictType: escape_dict,
|
||||
types.InstanceType: Instance2Str,
|
||||
types.StringType: Thing2Literal, # default
|
||||
FIELD_TYPE.TINY: int,
|
||||
FIELD_TYPE.SHORT: int,
|
||||
FIELD_TYPE.LONG: long,
|
||||
FIELD_TYPE.FLOAT: float,
|
||||
FIELD_TYPE.DOUBLE: float,
|
||||
FIELD_TYPE.LONGLONG: long,
|
||||
FIELD_TYPE.INT24: int,
|
||||
FIELD_TYPE.YEAR: int
|
||||
}
|
||||
|
||||
try:
|
||||
try:
|
||||
# new packaging
|
||||
from mx.DateTime import Date, Time, Timestamp, ISO, \
|
||||
DateTimeType, DateTimeDeltaType
|
||||
except ImportError:
|
||||
# old packaging, deprecated
|
||||
from DateTime import Date, Time, Timestamp, ISO, \
|
||||
DateTimeType, DateTimeDeltaType
|
||||
|
||||
def DateFromTicks(ticks):
|
||||
"""Convert UNIX ticks into a mx.DateTime.Date."""
|
||||
return apply(Date, localtime(ticks)[:3])
|
||||
|
||||
def TimeFromTicks(ticks):
|
||||
"""Convert UNIX ticks into a mx.DateTime.Time."""
|
||||
return apply(Time, localtime(ticks)[3:6])
|
||||
|
||||
def TimestampFromTicks(ticks):
|
||||
"""Convert UNIX ticks into a mx.DateTime.Timestamp."""
|
||||
return apply(Timestamp, localtime(ticks)[:6])
|
||||
|
||||
def format_DATE(d):
|
||||
"""Format a DateTime object as an ISO date."""
|
||||
return d.strftime("%Y-%m-%d")
|
||||
|
||||
def format_TIME(d):
|
||||
"""Format a DateTime object as a time value."""
|
||||
return d.strftime("%H:%M:%S")
|
||||
|
||||
def format_TIMESTAMP(d):
|
||||
"""Format a DateTime object as an ISO timestamp."""
|
||||
return d.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
def mysql_timestamp_converter(s):
|
||||
"""Convert a MySQL TIMESTAMP to a mx.DateTime.Timestamp."""
|
||||
parts = map(int, filter(None, (s[:4],s[4:6],s[6:8],
|
||||
s[8:10],s[10:12],s[12:14])))
|
||||
try: return apply(Timestamp, tuple(parts))
|
||||
except: return None
|
||||
|
||||
def DateTime_or_None(s):
|
||||
try: return ISO.ParseDateTime(s)
|
||||
except: return None
|
||||
|
||||
def TimeDelta_or_None(s):
|
||||
try: return ISO.ParseTimeDelta(s)
|
||||
except: return None
|
||||
|
||||
def Date_or_None(s):
|
||||
try: return ISO.ParseDate(s)
|
||||
except: return None
|
||||
|
||||
conversions[FIELD_TYPE.TIMESTAMP] = mysql_timestamp_converter
|
||||
conversions[FIELD_TYPE.DATETIME] = DateTime_or_None
|
||||
conversions[FIELD_TYPE.TIME] = TimeDelta_or_None
|
||||
conversions[FIELD_TYPE.DATE] = Date_or_None
|
||||
|
||||
def DateTime2literal(d, c):
|
||||
"""Format a DateTime object as an ISO timestamp."""
|
||||
return escape(format_TIMESTAMP(d),c)
|
||||
|
||||
def DateTimeDelta2literal(d, c):
|
||||
"""Format a DateTimeDelta object as a time."""
|
||||
return escape(format_TIME(d),c)
|
||||
|
||||
conversions[DateTimeType] = DateTime2literal
|
||||
conversions[DateTimeDeltaType] = DateTimeDelta2literal
|
||||
|
||||
except ImportError:
|
||||
# no DateTime? We'll muddle through somehow.
|
||||
|
||||
def DateFromTicks(ticks):
|
||||
"""Convert UNIX ticks to ISO date format."""
|
||||
return strftime("%Y-%m-%d", localtime(ticks))
|
||||
|
||||
def TimeFromTicks(ticks):
|
||||
"""Convert UNIX ticks to time format."""
|
||||
return strftime("%H:%M:%S", localtime(ticks))
|
||||
|
||||
def TimestampFromTicks(ticks):
|
||||
"""Convert UNIX ticks to ISO timestamp format."""
|
||||
return strftime("%Y-%m-%d %H:%M:%S", localtime(ticks))
|
||||
|
||||
def format_DATE(d):
|
||||
"""Format a date as a date (does nothing, you don't have mx.DateTime)."""
|
||||
return d
|
||||
|
||||
format_TIME = format_TIMESTAMP = format_DATE
|
||||
|
||||
__all__ = [ 'conversions', 'DateFromTicks', 'TimeFromTicks',
|
||||
'TimestampFromTicks', 'format_DATE', 'format_TIME',
|
||||
'format_TIMESTAMP' ]
|
390
MySQLdb/MySQLdb/cursors.py
Normal file
390
MySQLdb/MySQLdb/cursors.py
Normal file
@ -0,0 +1,390 @@
|
||||
"""MySQLdb Cursors
|
||||
|
||||
This module implements Cursors of various types for MySQLdb. By
|
||||
default, MySQLdb uses the Cursor class.
|
||||
|
||||
"""
|
||||
|
||||
import re
|
||||
insert_values = re.compile(r'values\s(\(.+\))', re.IGNORECASE)
|
||||
from _mysql import escape, ProgrammingError, Warning
|
||||
|
||||
class BaseCursor:
|
||||
|
||||
"""A base for Cursor classes. Useful attributes:
|
||||
|
||||
description -- DB API 7-tuple describing columns in last query
|
||||
arraysize -- default number of rows fetchmany() will fetch
|
||||
|
||||
See the MySQL docs for more information."""
|
||||
|
||||
def __init__(self, connection):
|
||||
self.__conn = connection
|
||||
self.description = None
|
||||
self.rowcount = -1
|
||||
self.arraysize = 100
|
||||
self._executed = None
|
||||
self._transaction = 0
|
||||
self.__c_locked = 0
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def close(self):
|
||||
"""Close the cursor. No further queries will be possible."""
|
||||
if not self.__conn: return
|
||||
self._end()
|
||||
self.__conn = None
|
||||
self._executed = None
|
||||
self._transaction = None
|
||||
|
||||
def _check_executed(self):
|
||||
if not self._executed:
|
||||
raise ProgrammingError, "execute() first"
|
||||
|
||||
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.__conn:
|
||||
raise ProgrammingError, "cursor closed"
|
||||
return self.__conn._db
|
||||
|
||||
def execute(self, query, args=None):
|
||||
|
||||
"""Execute a query.
|
||||
|
||||
query -- string, query to execute on server
|
||||
args -- sequence or mapping, parameters to use with query.
|
||||
returns long integer rows affected, if any"""
|
||||
|
||||
from types import ListType, TupleType
|
||||
qc = self._get_db().converter
|
||||
if not args:
|
||||
r = self._query(query)
|
||||
elif type(args) is ListType and type(args[0]) is TupleType:
|
||||
r = self.executemany(query, args) # deprecated
|
||||
else:
|
||||
try:
|
||||
r = self._query(query % escape(args, qc))
|
||||
except TypeError, m:
|
||||
if m.args[0] in ("not enough arguments for format string",
|
||||
"not all arguments converted"):
|
||||
raise ProgrammingError, m.args[0]
|
||||
else:
|
||||
raise
|
||||
self._executed = query
|
||||
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. The query must contain the clause "values ( ... )".
|
||||
The parenthetical portion will be repeated once for each
|
||||
item in the sequence.
|
||||
returns long integer rows affected, if any
|
||||
|
||||
This method performs multiple-row inserts and similar queries."""
|
||||
|
||||
from string import join
|
||||
qc = self._get_db().converter
|
||||
m = insert_values.search(query)
|
||||
if not m: raise ProgrammingError, "can't find values"
|
||||
p = m.start(1)
|
||||
qv = query[p:]
|
||||
qargs = escape(args, qc)
|
||||
try:
|
||||
q = [ query % qargs[0] ]
|
||||
for a in qargs[1:]: q.append( qv % a )
|
||||
except TypeError, msg:
|
||||
if msg.args[0] in ("not enough arguments for format string",
|
||||
"not all arguments converted"):
|
||||
raise ProgrammingError, (0, msg.args[0])
|
||||
else:
|
||||
raise
|
||||
r = self._query(join(q,',\n'))
|
||||
self._executed = query
|
||||
return r
|
||||
|
||||
def __do_query(self, q):
|
||||
from string import split, atoi
|
||||
db = self._get_db()
|
||||
if self._transaction: self._begin()
|
||||
try:
|
||||
db.query(q)
|
||||
self._result = self._get_result()
|
||||
self.rowcount = db.affected_rows()
|
||||
self.description = self._result and self._result.describe() or None
|
||||
self._insert_id = db.insert_id()
|
||||
self._info = db.info()
|
||||
self._check_for_warnings()
|
||||
except:
|
||||
self._end()
|
||||
raise
|
||||
return self.rowcount
|
||||
|
||||
def _check_for_warnings(self): pass
|
||||
|
||||
_query = __do_query
|
||||
|
||||
def info(self):
|
||||
"""Return some information about the last query (db.info())"""
|
||||
self._check_executed()
|
||||
return self._info
|
||||
|
||||
def insert_id(self):
|
||||
"""Return the last inserted ID on an AUTO_INCREMENT columns."""
|
||||
self._check_executed()
|
||||
return self._insert_id
|
||||
|
||||
def nextset(self):
|
||||
"""Does nothing. Required by DB API."""
|
||||
self._check_executed()
|
||||
return None
|
||||
|
||||
def _fetch_row(self, size=1):
|
||||
return self._result.fetch_row(size, self._fetch_type)
|
||||
|
||||
def _begin(self):
|
||||
self.__conn._begin()
|
||||
self._transaction = 1
|
||||
|
||||
def _end(self):
|
||||
self._transaction = 0
|
||||
self.__conn._end()
|
||||
|
||||
def _acquire(self):
|
||||
if self.__c_locked: return
|
||||
self.__conn._acquire()
|
||||
self.__c_locked = 1
|
||||
|
||||
def _release(self):
|
||||
if not self.__conn: return
|
||||
self.__conn._release()
|
||||
self.__c_locked = 0
|
||||
|
||||
def _is_transactional(self):
|
||||
return self.__conn._transactional
|
||||
|
||||
|
||||
class CursorWarningMixIn:
|
||||
|
||||
"""This is a MixIn class that provides the capability of raising
|
||||
the Warning exception when something went slightly wrong with your
|
||||
query."""
|
||||
|
||||
def _check_for_warnings(self):
|
||||
from string import atoi, split
|
||||
if self._info:
|
||||
warnings = atoi(split(self._info)[-1])
|
||||
if warnings:
|
||||
raise Warning, self._info
|
||||
|
||||
|
||||
class CursorStoreResultMixIn:
|
||||
|
||||
"""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 __init__(self, connection):
|
||||
BaseCursor.__init__(self, connection)
|
||||
self._acquire()
|
||||
|
||||
def _get_result(self): return self._get_db().store_result()
|
||||
|
||||
def close(self):
|
||||
"""Close the cursor. Further queries will not be possible."""
|
||||
self._rows = ()
|
||||
BaseCursor.close(self)
|
||||
|
||||
def _query(self, q):
|
||||
self._acquire()
|
||||
try:
|
||||
rowcount = self._BaseCursor__do_query(q)
|
||||
self._rows = self._result and self._fetch_row(0) or ()
|
||||
self._pos = 0
|
||||
del self._result
|
||||
if not self._is_transactional: self._end()
|
||||
return rowcount
|
||||
finally:
|
||||
self._release()
|
||||
|
||||
def fetchone(self):
|
||||
"""Fetches a single row from the cursor."""
|
||||
self._check_executed()
|
||||
if self._pos >= len(self._rows): return None
|
||||
result = self._rows[self._pos]
|
||||
self._pos = self._pos+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._pos + size or self.arraysize
|
||||
result = self._rows[self._pos:end]
|
||||
self._pos = end
|
||||
return result
|
||||
|
||||
def fetchall(self):
|
||||
"""Fetchs all available rows from the cursor."""
|
||||
self._check_executed()
|
||||
result = self._pos and self._rows[self._pos:] or self._rows
|
||||
self._pos = len(self._rows)
|
||||
return result
|
||||
|
||||
def seek(self, row, whence=0):
|
||||
"""seek to a given row of the result set analogously to file.seek().
|
||||
This is non-standard extension."""
|
||||
self._check_executed()
|
||||
if whence == 0:
|
||||
self._pos = row
|
||||
elif whence == 1:
|
||||
self._pos = self._pos + row
|
||||
elif whence == 2:
|
||||
self._pos = len(self._rows) + row
|
||||
|
||||
def tell(self):
|
||||
"""Return the current position in the result set analogously to
|
||||
file.tell(). This is a non-standard extension."""
|
||||
self._check_executed()
|
||||
return self._pos
|
||||
|
||||
|
||||
class CursorUseResultMixIn:
|
||||
|
||||
"""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."""
|
||||
|
||||
def close(self):
|
||||
"""Close the cursor. No further queries can be executed."""
|
||||
self._release()
|
||||
self._result = None
|
||||
BaseCursor.close(self)
|
||||
|
||||
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)
|
||||
return r and r[0] or None
|
||||
|
||||
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()
|
||||
return self._fetch_row(size or self.arraysize)
|
||||
|
||||
def fetchall(self):
|
||||
"""Fetchs all available rows from the cursor."""
|
||||
self._check_open()
|
||||
return self._fetch_row(0)
|
||||
|
||||
|
||||
class CursorTupleRowsMixIn:
|
||||
|
||||
"""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:
|
||||
|
||||
"""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."""
|
||||
return self.fetchone()
|
||||
|
||||
def fetchmanyDict(self, size=None):
|
||||
"""Fetch several rows as a list of dictionaries. Deprecated:
|
||||
Use fetchmany() instead."""
|
||||
return self.fetchmany(size)
|
||||
|
||||
def fetchallDict(self):
|
||||
"""Fetch all available rows as a list of dictionaries. Deprecated:
|
||||
Use fetchall() instead."""
|
||||
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 CursorNW(CursorStoreResultMixIn, CursorTupleRowsMixIn,
|
||||
BaseCursor):
|
||||
|
||||
"""This is a basic Cursor class that returns rows as tuples and
|
||||
stores the result set in the client. Warnings are not raised."""
|
||||
|
||||
|
||||
class Cursor(CursorWarningMixIn, CursorNW):
|
||||
|
||||
"""This is the standard Cursor class that returns rows as tuples
|
||||
and stores the result set in the client. Warnings are raised as
|
||||
necessary."""
|
||||
|
||||
|
||||
class DictCursorNW(CursorStoreResultMixIn, CursorDictRowsMixIn,
|
||||
BaseCursor):
|
||||
|
||||
"""This is a Cursor class that returns rows as dictionaries and
|
||||
stores the result set in the client. Warnings are not raised."""
|
||||
|
||||
|
||||
class DictCursor(CursorWarningMixIn, DictCursorNW):
|
||||
|
||||
"""This is a Cursor class that returns rows as dictionaries and
|
||||
stores the result set in the client. Warnings are raised as
|
||||
necessary."""
|
||||
|
||||
|
||||
class SSCursorNW(CursorUseResultMixIn, CursorTupleRowsMixIn,
|
||||
BaseCursor):
|
||||
|
||||
"""This is a basic Cursor class that returns rows as tuples and
|
||||
stores the result set in the server. Warnings are not raised."""
|
||||
|
||||
|
||||
class SSCursor(CursorWarningMixIn, SSCursorNW):
|
||||
|
||||
"""This is a Cursor class that returns rows as tuples and stores
|
||||
the result set in the server. Warnings are raised as necessary."""
|
||||
|
||||
|
||||
class SSDictCursorNW(CursorUseResultMixIn, CursorDictRowsMixIn,
|
||||
BaseCursor):
|
||||
|
||||
"""This is a Cursor class that returns rows as dictionaries and
|
||||
stores the result set in the server. Warnings are not raised."""
|
||||
|
||||
|
||||
class SSDictCursor(CursorWarningMixIn, SSDictCursorNW):
|
||||
|
||||
"""This is a Cursor class that returns rows as dictionaries and
|
||||
stores the result set in the server. Warnings are raised as
|
||||
necessary."""
|
||||
|
||||
|
26
MySQLdb/PKG-INFO
Normal file
26
MySQLdb/PKG-INFO
Normal file
@ -0,0 +1,26 @@
|
||||
Metadata-Version: 1.0
|
||||
Name: MySQL-python
|
||||
Version: 0.9.0a3
|
||||
Summary: An interface to MySQL
|
||||
Home-page: http://dustman.net/andy/python/MySQLdb
|
||||
Author: Andy Dustman
|
||||
Author-email: andy@dustman.net
|
||||
License: UNKNOWN
|
||||
Description: Python interface to MySQL-3.23
|
||||
|
||||
MySQLdb is an interface to the popular MySQL database server for Python.
|
||||
The design goals are:
|
||||
|
||||
- Compliance with Python database API version 2.0
|
||||
- Thread-safety
|
||||
- Thread-friendliness (threads will not block each other)
|
||||
- Compatibility with MySQL-3.23 and later
|
||||
|
||||
This module should be mostly compatible with an older interface
|
||||
written by Joe Skinner and others. However, the older version is
|
||||
a) not thread-friendly, b) written for MySQL 3.21, c) apparently
|
||||
not actively maintained. No code from that version is used in
|
||||
MySQLdb. MySQLdb is free software.
|
||||
|
||||
|
||||
Platform: UNKNOWN
|
57
MySQLdb/README
Normal file
57
MySQLdb/README
Normal file
@ -0,0 +1,57 @@
|
||||
Prerequisites:
|
||||
|
||||
Python 1.5.2 or higher
|
||||
-- http://www.pythonlabs.com/products/python2.0/download_python2.0.html
|
||||
-- http://www.python.org/1.6/
|
||||
-- http://www.python.org/1.5/
|
||||
-- Versions lower than 1.5.2 WON'T WORK.
|
||||
-- If you have Red Hat Linux or a similar packaging system, make sure
|
||||
you have the Python development headers and libraries (python-devel).
|
||||
|
||||
Distutils 1.0 or higher
|
||||
-- comes with Python 1.6 and 2.0
|
||||
-- http://www.python.org/sigs/distutils-sig/download.html
|
||||
|
||||
MySQL 3.22.19 or higher
|
||||
-- http://www.mysql.com/downloads/
|
||||
-- Versions lower than 3.22 definitely WON'T WORK.
|
||||
-- Versions lower than 3.22.19 might not work.
|
||||
-- The current (recommended) 3.22 release is 3.22.32.
|
||||
-- MySQL-3.23 is beta at present but supported.
|
||||
-- If you have Red Hat Linux or a similar packaging system, make sure
|
||||
you have the MySQL development headers and libraries (MySQL-devel).
|
||||
|
||||
First thing to do is edit setup.py. There are some variables towards the
|
||||
beginning that tell it where your MySQL include files and libraries are.
|
||||
The values are right for MySQL's standard Red Hat Linux (6.2) RPMs. If
|
||||
you have another platform, you'll have to figure out the right values
|
||||
yourself.
|
||||
|
||||
Note that recent binary distributions include two sets of client
|
||||
libraries: mysqlclient and mysqlclient_r. The latter are the
|
||||
"thread-safe" libraries, so use those if you can, and if threading is
|
||||
important to you.
|
||||
|
||||
If you have the dynamic client libraries (on Linux, .so vs. .a), those
|
||||
will be used by default. If they are not on your standard loader path,
|
||||
you will have to set or adjust the LD_LIBRARY_PATH environment variable
|
||||
(on Linux) or whatever your platform requires. Otherwise, you can adjust
|
||||
setup.py to link against the static library.
|
||||
|
||||
Finally, putting it together:
|
||||
|
||||
$ python setup.py build
|
||||
# python setup.py install
|
||||
|
||||
TIP: If you are using a binary package of Zope, you need run setup.py
|
||||
with Zope's python executable. Otherwise, Zope (ZMySQLDA) will not
|
||||
be able to find _mysql.
|
||||
|
||||
If you prefer RPMs, you can use the bdist_rpm command with setup.py.
|
||||
|
||||
Thanks go to Brian Fordham for cooking up an early version of setup.py.
|
||||
|
||||
License: GPL or the original license based on Python 1.5.2's license.
|
||||
|
||||
Andy Dustman <andy@dustman.net>
|
||||
2000-11-30
|
1613
MySQLdb/_mysql.c
Normal file
1613
MySQLdb/_mysql.c
Normal file
File diff suppressed because it is too large
Load Diff
83
MySQLdb/_mysql_exceptions.py
Normal file
83
MySQLdb/_mysql_exceptions.py
Normal file
@ -0,0 +1,83 @@
|
||||
"""_mysql_exceptions: Exception classes for _mysql and MySQLdb.
|
||||
|
||||
These classes are dictated by the DB API v2.0:
|
||||
|
||||
http://www.python.org/topics/database/DatabaseAPI-2.0.html
|
||||
"""
|
||||
|
||||
from exceptions import Exception, StandardError
|
||||
|
||||
class MySQLError(StandardError):
|
||||
|
||||
"""Exception related to operation with MySQL."""
|
||||
|
||||
|
||||
class Warning(MySQLError):
|
||||
|
||||
"""Exception raised for important warnings like data truncations
|
||||
while inserting, etc."""
|
||||
|
||||
class Error(MySQLError):
|
||||
|
||||
"""Exception that is the base class of all other error exceptions
|
||||
(not Warning)."""
|
||||
|
||||
|
||||
class InterfaceError(Error):
|
||||
|
||||
"""Exception raised for errors that are related to the database
|
||||
interface rather than the database itself."""
|
||||
|
||||
|
||||
class DatabaseError(Error):
|
||||
|
||||
"""Exception raised for errors that are related to the
|
||||
database."""
|
||||
|
||||
|
||||
class DataError(DatabaseError):
|
||||
|
||||
"""Exception raised for errors that are due to problems with the
|
||||
processed data like division by zero, numeric value out of range,
|
||||
etc."""
|
||||
|
||||
|
||||
class OperationalError(DatabaseError):
|
||||
|
||||
"""Exception raised for errors that are related to the database's
|
||||
operation and not necessarily under the control of the programmer,
|
||||
e.g. an unexpected disconnect occurs, the data source name is not
|
||||
found, a transaction could not be processed, a memory allocation
|
||||
error occurred during processing, etc."""
|
||||
|
||||
|
||||
class IntegrityError(DatabaseError):
|
||||
|
||||
"""Exception raised when the relational integrity of the database
|
||||
is affected, e.g. a foreign key check fails, duplicate key,
|
||||
etc."""
|
||||
|
||||
|
||||
class InternalError(DatabaseError):
|
||||
|
||||
"""Exception raised when the database encounters an internal
|
||||
error, e.g. the cursor is not valid anymore, the transaction is
|
||||
out of sync, etc."""
|
||||
|
||||
|
||||
class ProgrammingError(DatabaseError):
|
||||
|
||||
"""Exception raised for programming errors, e.g. table not found
|
||||
or already exists, syntax error in the SQL statement, wrong number
|
||||
of parameters specified, etc."""
|
||||
|
||||
|
||||
class NotSupportedError(DatabaseError):
|
||||
|
||||
"""Exception raised in case a method or database API was used
|
||||
which is not supported by the database, e.g. requesting a
|
||||
.rollback() on a connection that does not support transaction or
|
||||
has transactions turned off."""
|
||||
|
||||
|
||||
del Exception, StandardError
|
1
MySQLdb/_mysql_version.h
Normal file
1
MySQLdb/_mysql_version.h
Normal file
@ -0,0 +1 @@
|
||||
static char _mysql__version__[] = "0.9.0b1";
|
109
MySQLdb/setup.py
Normal file
109
MySQLdb/setup.py
Normal file
@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""Setup script for the MySQLdb module distribution."""
|
||||
|
||||
import os, sys
|
||||
from distutils.core import setup
|
||||
from distutils.extension import Extension
|
||||
|
||||
YES = 1
|
||||
NO = 0
|
||||
|
||||
# set this to 1 if you have the thread-safe mysqlclient library
|
||||
thread_safe_library = NO
|
||||
|
||||
# You probably don't have to do anything past this point. If you
|
||||
# do, please mail me the configuration for your platform. Don't
|
||||
# forget to include the value of sys.platform and os.name.
|
||||
|
||||
mysqlclient = thread_safe_library and "mysqlclient_r" or "mysqlclient"
|
||||
|
||||
if sys.platform == "linux-i386": # Red Hat
|
||||
include_dirs = ['/usr/include/mysql']
|
||||
library_dirs = ['/usr/lib/mysql']
|
||||
libraries = [mysqlclient, "z"]
|
||||
runtime_library_dirs = []
|
||||
extra_objects = []
|
||||
elif sys.platform in ("freebsd4", "openbsd2"):
|
||||
include_dirs = ['/usr/local/include/mysql']
|
||||
library_dirs = ['/usr/local/lib/mysql']
|
||||
libraries = [mysqlclient, "z"]
|
||||
runtime_library_dirs = []
|
||||
extra_objects = []
|
||||
elif sys.platform == "win32":
|
||||
include_dirs = [r'c:\mysql\include']
|
||||
library_dirs = [r'c:\mysql\lib\opt']
|
||||
libraries = [mysqlclient, 'zlib', 'msvcrt', 'libcmt',
|
||||
'wsock32', 'advapi32']
|
||||
runtime_library_dirs = []
|
||||
extra_objects = [r'c:\mysql\lib\opt\mysqlclient.lib']
|
||||
elif os.name == "posix": # most Linux/UNIX platforms
|
||||
include_dirs = ['/usr/include/mysql']
|
||||
library_dirs = ['/usr/lib/mysql']
|
||||
# MySQL-3.23 seems to need libz
|
||||
libraries = [mysqlclient, "z"]
|
||||
# On some platorms, this can be used to find the shared libraries
|
||||
# at runtime, if they are in a non-standard location. Doesn't
|
||||
# work for Linux gcc.
|
||||
## runtime_library_dirs = library_dirs
|
||||
runtime_library_dirs = []
|
||||
# This can be used on Linux to force use of static mysqlclient lib
|
||||
## extra_objects = ['/usr/lib/mysql/libmysqlclient.a']
|
||||
extra_objects = []
|
||||
else:
|
||||
raise "UnknownPlatform", "sys.platform=%s, os.name=%s" % \
|
||||
(sys.platform, os.name)
|
||||
|
||||
long_description = \
|
||||
"""Python interface to MySQL-3.23
|
||||
|
||||
MySQLdb is an interface to the popular MySQL database server for Python.
|
||||
The design goals are:
|
||||
|
||||
- Compliance with Python database API version 2.0
|
||||
- Thread-safety
|
||||
- Thread-friendliness (threads will not block each other)
|
||||
- Compatibility with MySQL-3.23 and later
|
||||
|
||||
This module should be mostly compatible with an older interface
|
||||
written by Joe Skinner and others. However, the older version is
|
||||
a) not thread-friendly, b) written for MySQL 3.21, c) apparently
|
||||
not actively maintained. No code from that version is used in
|
||||
MySQLdb. MySQLdb is free software.
|
||||
|
||||
"""
|
||||
|
||||
setup (# Distribution meta-data
|
||||
name = "MySQL-python",
|
||||
version = "0.9.0b1",
|
||||
description = "An interface to MySQL",
|
||||
long_description=long_description,
|
||||
author = "Andy Dustman",
|
||||
author_email = "andy@dustman.net",
|
||||
url = "http://dustman.net/andy/python/MySQLdb",
|
||||
|
||||
# Description of the modules and packages in the distribution
|
||||
|
||||
py_modules = ["CompatMysqldb",
|
||||
"_mysql_exceptions",
|
||||
"MySQLdb.converters",
|
||||
"MySQLdb.connections",
|
||||
"MySQLdb.cursors",
|
||||
"MySQLdb.constants.CR",
|
||||
"MySQLdb.constants.FIELD_TYPE",
|
||||
"MySQLdb.constants.ER",
|
||||
"MySQLdb.constants.FLAG",
|
||||
"MySQLdb.constants.REFRESH",
|
||||
"MySQLdb.constants.CLIENT",
|
||||
],
|
||||
|
||||
ext_modules = [Extension(
|
||||
name='_mysql',
|
||||
sources=['_mysql.c'],
|
||||
include_dirs=include_dirs,
|
||||
library_dirs=library_dirs,
|
||||
runtime_library_dirs=runtime_library_dirs,
|
||||
libraries=libraries,
|
||||
extra_objects=extra_objects,
|
||||
)],
|
||||
)
|
Reference in New Issue
Block a user