mirror of
https://github.com/PyMySQL/mysqlclient.git
synced 2025-08-15 19:31:54 +08:00
Lots of new __doc__ strings and other odds and ends
for new pydoc module in Python 2.1. Exceptions have been moved into _mysql_const/exc.py. Mostly this is for documentation purposes. Mostly.
This commit is contained in:
226
mysql/MySQLdb.py
226
mysql/MySQLdb.py
@ -4,22 +4,38 @@ This module is a thin wrapper around _mysql, which mostly implements the
|
||||
MySQL C API. All symbols from that module are imported.
|
||||
|
||||
connect() -- connects to server
|
||||
type_conv -- dictionary mapping SQL types to Python functions, which
|
||||
convert a string into an appropriate data type. Reasonable
|
||||
defaults are set for most items, and you can add your own.
|
||||
|
||||
type_conv -- dictionary mapping SQL types (FIELD_TYPE) to Python functions,
|
||||
which convert a string into an appropriate data type. Reasonable
|
||||
defaults are set for most items, and you can add your own.
|
||||
|
||||
quote_conv -- dictionary mapping Python types to functions. Function takes
|
||||
one argument of the indicated type and a mapping argument, and returns
|
||||
an SQL-quoted string. The mapping argument is only used for recursive
|
||||
quoting (i.e. when quoting sequences). Most simple converters
|
||||
will not need this and can ignore it.
|
||||
|
||||
See the API specification and the MySQL documentation for more info
|
||||
on other items.
|
||||
|
||||
This module uses the mxDateTime package for handling date/time types.
|
||||
This module uses the mx.DateTime package for handling date/time types,
|
||||
if it is available. Otherwise, date types are returned as strings.
|
||||
"""
|
||||
|
||||
__version__ = """$Revision$"""[11:-2]
|
||||
__author__ = "Andy Dustman <andy@dustman.net>"
|
||||
__version__ = "0.3.6"
|
||||
__revision__ = """$Revision$"""[11:-2]
|
||||
|
||||
import _mysql
|
||||
from _mysql import *
|
||||
from time import localtime
|
||||
import re, types
|
||||
from types import ListType, TupleType
|
||||
from string import rfind, join, split, atoi
|
||||
|
||||
if __version__ != _mysql.__version__:
|
||||
raise ImportError, "this is MySQLdb version %s, but _mysql is version %s" %\
|
||||
(__version__, _mysql.__version__)
|
||||
|
||||
threadsafety = 2
|
||||
apilevel = "2.0"
|
||||
@ -32,15 +48,28 @@ try:
|
||||
except ImportError:
|
||||
_threading = None
|
||||
|
||||
def Thing2Str(s, d={}): return str(s)
|
||||
def Long2Int(l, d={}): s = str(l); return s[-1] == 'L' and s[:-1] or s
|
||||
def None2NULL(o, d={}): return "NULL"
|
||||
def Thing2Literal(o, d={}): return string_literal(str(o))
|
||||
def Thing2Str(s, d):
|
||||
"""Convert something into a string via str()."""
|
||||
return str(s)
|
||||
|
||||
# MySQL-3.23.xx now has a new escape_string function that uses
|
||||
# the connection to determine what character set is in use and
|
||||
# quote accordingly. So this will be overridden by the connect()
|
||||
# method.
|
||||
# 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(str(o))
|
||||
|
||||
quote_conv = { types.IntType: Thing2Str,
|
||||
types.LongType: Long2Int,
|
||||
@ -62,28 +91,40 @@ type_conv = { FIELD_TYPE.TINY: int,
|
||||
|
||||
try:
|
||||
try:
|
||||
from mx import DateTime # new packaging
|
||||
# new packaging
|
||||
from mx.DateTime import Date, Time, Timestamp, ISO, \
|
||||
DateTimeType, DateTimeDeltaType
|
||||
except ImportError:
|
||||
import DateTime # old packaging
|
||||
# old packaging
|
||||
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): return d.strftime("%Y-%m-%d")
|
||||
def format_TIME(d): return d.strftime("%H:%M:%S")
|
||||
def format_TIMESTAMP(d): return d.strftime("%Y-%m-%d %H:%M:%S")
|
||||
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])))
|
||||
return apply(Timestamp, tuple(parts))
|
||||
@ -93,8 +134,13 @@ try:
|
||||
type_conv[FIELD_TYPE.TIME] = ISO.ParseTimeDelta
|
||||
type_conv[FIELD_TYPE.DATE] = ISO.ParseDate
|
||||
|
||||
def DateTime2literal(d, c={}): return "'%s'" % format_TIMESTAMP(d)
|
||||
def DateTimeDelta2literal(d, c={}): return "'%s'" % format_TIME(d)
|
||||
def DateTime2literal(d, c):
|
||||
"""Format a DateTime object as an ISO timestamp."""
|
||||
return "'%s'" % format_TIMESTAMP(d)
|
||||
|
||||
def DateTimeDelta2literal(d, c):
|
||||
"""Format a DateTimeDelta object as a time."""
|
||||
return "'%s'" % format_TIME(d)
|
||||
|
||||
quote_conv[DateTimeType] = DateTime2literal
|
||||
quote_conv[DateTimeDeltaType] = DateTimeDelta2literal
|
||||
@ -104,19 +150,27 @@ except ImportError:
|
||||
from time import strftime
|
||||
|
||||
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): return d
|
||||
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
|
||||
|
||||
|
||||
class DBAPITypeObject:
|
||||
|
||||
"""Helper class for determining column types; required by DB API."""
|
||||
|
||||
def __init__(self,*values):
|
||||
self.values = values
|
||||
@ -165,26 +219,27 @@ class BaseCursor:
|
||||
self._thequery = ''
|
||||
|
||||
def close(self):
|
||||
"""Close the cursor. No further queries will be possible."""
|
||||
self.connection = None
|
||||
|
||||
def _check_open(self):
|
||||
if not self.connection:
|
||||
raise ProgrammingError, "cursor closed"
|
||||
|
||||
def setinputsizes(self, *args): pass
|
||||
def setinputsizes(self, *args):
|
||||
"""Does nothing, required by DB API."""
|
||||
|
||||
def setoutputsizes(self, *args): pass
|
||||
def setoutputsizes(self, *args):
|
||||
"""Does nothing, required by DB API."""
|
||||
|
||||
def execute(self, query, args=None):
|
||||
"""rows=cursor.execute(query, args=None)
|
||||
"""Execute a query.
|
||||
|
||||
query -- string, query to execute on server
|
||||
args -- sequence or mapping, parameters to use with query.
|
||||
rows -- rows affected, if any"""
|
||||
returns long integer rows affected, if any"""
|
||||
self._check_open()
|
||||
self._thequery = query
|
||||
from types import ListType, TupleType
|
||||
from string import rfind, join, split, atoi
|
||||
qc = self.connection.quote_conv
|
||||
if not args:
|
||||
return self._query(query)
|
||||
@ -201,13 +256,14 @@ class BaseCursor:
|
||||
raise
|
||||
|
||||
def executemany(self, query, args):
|
||||
"""cursor.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."""
|
||||
self._check_open()
|
||||
@ -246,14 +302,18 @@ class BaseCursor:
|
||||
_query = __do_query
|
||||
|
||||
def info(self):
|
||||
"""Return some information about the last query (db.info())"""
|
||||
try: return self._info
|
||||
except AttributeError: raise ProgrammingError, "execute() first"
|
||||
|
||||
def insert_id(self):
|
||||
"""Return the last inserted ID on an AUTO_INCREMENT columns."""
|
||||
try: return self._insert_id
|
||||
except AttributeError: raise ProgrammingError, "execute() first"
|
||||
|
||||
def nextset(self): return None
|
||||
def nextset(self):
|
||||
"""Does nothing. Required by DB API."""
|
||||
return None
|
||||
|
||||
def _fetch_row(self):
|
||||
r = self._result.fetch_row(1, self._fetch_type)
|
||||
@ -268,6 +328,10 @@ class BaseCursor:
|
||||
|
||||
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:
|
||||
@ -278,9 +342,15 @@ class CursorWarningMixIn:
|
||||
|
||||
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 _get_result(self): return self.connection.db.store_result()
|
||||
|
||||
def close(self):
|
||||
"""Close the cursor. Further queries will not be possible."""
|
||||
self.connection = None
|
||||
self._rows = ()
|
||||
|
||||
@ -304,9 +374,8 @@ class CursorStoreResultMixIn:
|
||||
return result
|
||||
|
||||
def fetchmany(self, size=None):
|
||||
"""cursor.fetchmany(size=cursor.arraysize)
|
||||
|
||||
size -- integer, maximum number of rows to fetch."""
|
||||
"""Fetch up to size rows from the cursor. Result set may be smaller
|
||||
than size. If size is not defined, cursor.arraysize is used."""
|
||||
if not self._thequery: raise ProgrammingError, "execute() first"
|
||||
end = self._pos + size or self.arraysize
|
||||
result = self._rows[self._pos:end]
|
||||
@ -321,6 +390,8 @@ class CursorStoreResultMixIn:
|
||||
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."""
|
||||
if whence == 0:
|
||||
self._pos = row
|
||||
elif whence == 1:
|
||||
@ -328,17 +399,26 @@ class CursorStoreResultMixIn:
|
||||
elif whence == 2:
|
||||
self._pos = len(self._rows) + row
|
||||
|
||||
def tell(self): return self._pos
|
||||
def tell(self):
|
||||
"""Return the current position in the result set analogously to
|
||||
file.tell(). This is a non-standard extension."""
|
||||
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 __init__(self, connection):
|
||||
BaseCursor.__init__(self, connection)
|
||||
if not self.connection._acquire(0):
|
||||
raise ProgrammingError, "would deadlock"
|
||||
|
||||
def close(self):
|
||||
"""Close the cursor. No further queries can be executed."""
|
||||
if self.connection: self.connection._release()
|
||||
self.connection = None
|
||||
|
||||
@ -357,9 +437,8 @@ class CursorUseResultMixIn:
|
||||
return self._fetch_row()
|
||||
|
||||
def fetchmany(self, size=None):
|
||||
"""cursor.fetchmany(size=cursor.arraysize)
|
||||
|
||||
size -- integer, maximum number of rows to fetch."""
|
||||
"""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_open()
|
||||
if not self._thequery: raise ProgrammingError, "execute() first"
|
||||
return self._fetch_rows(size or self.arraysize)
|
||||
@ -373,57 +452,85 @@ class CursorUseResultMixIn:
|
||||
|
||||
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
|
||||
|
||||
## XXX Deprecated
|
||||
|
||||
def fetchoneDict(self, *args, **kwargs):
|
||||
"""Fetch a single row as a dictionary. Deprecated:
|
||||
Use fetchone() instead."""
|
||||
return apply(self.fetchone, args, kwargs)
|
||||
|
||||
def fetchmanyDict(self, *args, **kwargs):
|
||||
"""Fetch several rows as a list of dictionaries. Deprecated:
|
||||
Use fetchmany() instead."""
|
||||
return apply(self.fetchmany, args, kwargs)
|
||||
|
||||
def fetchallDict(self, *args, **kwargs):
|
||||
"""Fetch all available rows as a list of dictionaries. Deprecated:
|
||||
Use fetchall() instead."""
|
||||
return apply(self.fetchall, args, kwargs)
|
||||
|
||||
|
||||
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): pass
|
||||
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): pass
|
||||
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): pass
|
||||
|
||||
class DictCursor(CursorWarningMixIn, DictCursorNW): pass
|
||||
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): pass
|
||||
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): pass
|
||||
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): pass
|
||||
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): pass
|
||||
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."""
|
||||
|
||||
|
||||
class Connection:
|
||||
|
||||
"""Connection(host=NULL, user=NULL, passwd=NULL, db=NULL,
|
||||
port=<MYSQL_PORT>, unix_socket=NULL, client_flag=0)
|
||||
|
||||
Note: This interface uses keyword arguments exclusively.
|
||||
"""Create a connection to the database. Note that this interface
|
||||
uses keyword arguments exclusively.
|
||||
|
||||
host -- string, host to connect to or NULL pointer (localhost)
|
||||
user -- string, user to connect as or NULL (your username)
|
||||
@ -434,12 +541,18 @@ class Connection:
|
||||
client_flags -- integer, flags to use or 0 (see MySQL docs)
|
||||
conv -- dictionary, maps MySQL FIELD_TYPE.* to Python functions which
|
||||
convert a string to the appropriate Python type
|
||||
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()
|
||||
|
||||
Returns a Connection object.
|
||||
|
||||
Useful attributes and methods:
|
||||
|
||||
db -- connection object from _mysql. Good for accessing some of the
|
||||
db -- _mysql.MYSQL connection object. Good for accessing some of the
|
||||
MySQL-specific calls.
|
||||
close -- close the connection.
|
||||
cursor -- create a cursor (emulated) for executing queries.
|
||||
@ -467,7 +580,10 @@ class Connection:
|
||||
def _acquire(self, blocking=1): return 1
|
||||
def _release(self): return 1
|
||||
|
||||
def Thing2Literal(self, o, d={}): return self.db.string_literal(str(o))
|
||||
def Thing2Literal(self, o, d={}):
|
||||
"""Convert a thing to a string literal using the current
|
||||
character set."""
|
||||
return self.db.string_literal(str(o))
|
||||
|
||||
def close(self):
|
||||
"""Close the connection. No further activity possible."""
|
||||
@ -485,7 +601,9 @@ class Connection:
|
||||
else: raise NotSupportedError, "Not supported by server"
|
||||
|
||||
def cursor(self, cursorclass=None):
|
||||
"""Create a cursor on which queries may be performed."""
|
||||
"""Create a cursor on which queries may be performed.
|
||||
The optional cursorclass parameter is used to create
|
||||
the Cursor. By default, self.cursorclass=Cursor is used."""
|
||||
return (cursorclass or self.cursorclass)(self)
|
||||
|
||||
# Non-portable MySQL-specific stuff
|
||||
|
@ -1 +1 @@
|
||||
__all__ = ['CR', 'FIELD_TYPE','CLIENT','REFRESH','ER','FLAG']
|
||||
__all__ = ['exc','CR', 'FIELD_TYPE','CLIENT','REFRESH','ER','FLAG']
|
||||
|
59
mysql/_mysql_const/exc.py
Normal file
59
mysql/_mysql_const/exc.py
Normal file
@ -0,0 +1,59 @@
|
||||
"""_mysql_const.exc: 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,3 +1,4 @@
|
||||
static char _mysql__version__[] = "0.3.6";
|
||||
/*
|
||||
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
|
||||
@ -40,6 +41,7 @@ PERFORMANCE OF THIS SOFTWARE.
|
||||
#include "mysqld_error.h"
|
||||
#include "errmsg.h"
|
||||
|
||||
static PyObject *_mysql_MySQLError;
|
||||
static PyObject *_mysql_Warning;
|
||||
static PyObject *_mysql_Error;
|
||||
static PyObject *_mysql_DatabaseError;
|
||||
@ -156,6 +158,27 @@ _mysql_ResultObject_New(
|
||||
return r;
|
||||
}
|
||||
|
||||
static char _mysql_connect__doc__[] =
|
||||
"connect() -- takes a number of keyword arguments and\n\
|
||||
returns a MYSQL connection object.\n\
|
||||
\n\
|
||||
host -- string, host to connect to or NULL pointer (localhost)\n\
|
||||
user -- string, user to connect as or NULL (your username)\n\
|
||||
passwd -- string, password to use or NULL (no password)\n\
|
||||
db -- string, database to use or NULL (no DB selected)\n\
|
||||
port -- integer, TCP/IP port to connect to or default MySQL port\n\
|
||||
unix_socket -- string, location of unix_socket to use or use TCP\n\
|
||||
client_flags -- integer, flags to use or 0 (see MySQL docs)\n\
|
||||
conv -- dictionary, maps MySQL FIELD_TYPE.* to Python functions which\n\
|
||||
convert a string to the appropriate Python type\n\
|
||||
connect_time -- number of seconds to wait before the connection\n\
|
||||
attempt fails.\n\
|
||||
compress -- if set, compression is enabled\n\
|
||||
init_command -- command which is run once the connection is created\n\
|
||||
read_default_file -- see the MySQL documentation for mysql_options()\n\
|
||||
read_default_group -- see the MySQL documentation for mysql_options()\n\
|
||||
";
|
||||
|
||||
static PyObject *
|
||||
_mysql_connect(
|
||||
PyObject *self,
|
||||
@ -255,6 +278,12 @@ _mysql_ConnectionObject_affected_rows(
|
||||
return PyLong_FromUnsignedLongLong(mysql_affected_rows(&(self->connection)));
|
||||
}
|
||||
|
||||
static char _mysql_debug__doc__[] =
|
||||
"debug(s) -- 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,
|
||||
@ -300,6 +329,15 @@ _mysql_ConnectionObject_error(
|
||||
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\
|
||||
This function is somewhat deprecated. mysql_real_escape_string() was\n\
|
||||
introduced in MySQL-3.23. The new version handles character sets\n\
|
||||
correctly, but requires a connection object to work. Therefore,\n\
|
||||
escape_string() has become a method of the connection object. It is\n\
|
||||
retained as a module function for compatibility reasons. Use the\n\
|
||||
method version of this function if at all possible.";
|
||||
static PyObject *
|
||||
_mysql_escape_string(
|
||||
_mysql_ConnectionObject *self,
|
||||
@ -324,13 +362,19 @@ _mysql_escape_string(
|
||||
return (str);
|
||||
}
|
||||
|
||||
/* In 3.23.x, mysql_escape_string() is deprecated for
|
||||
* mysql_real_escape_string, which takes a connection
|
||||
* as the first arg, so this needs to be a connection
|
||||
* method. For backwards compatibility, it also needs
|
||||
* to be a module function.
|
||||
*/
|
||||
|
||||
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\
|
||||
This function is somewhat deprecated. mysql_real_escape_string() was\n\
|
||||
introduced in MySQL-3.23. The new version handles character sets\n\
|
||||
correctly, but requires a connection object to work. Therefore,\n\
|
||||
string_literal() has become a method of the connection object. It is\n\
|
||||
retained as a module function for compatibility reasons. Use the\n\
|
||||
method version of this function if at all possible.";
|
||||
static PyObject *
|
||||
_mysql_string_literal(
|
||||
_mysql_ConnectionObject *self,
|
||||
@ -388,6 +432,10 @@ 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,
|
||||
@ -404,6 +452,10 @@ _mysql_escape(
|
||||
return _escape_item(o, d);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -434,6 +486,10 @@ _mysql_escape_sequence(
|
||||
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,
|
||||
@ -775,6 +831,9 @@ _mysql_ConnectionObject_character_set_name(
|
||||
}
|
||||
#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,
|
||||
@ -784,16 +843,6 @@ _mysql_get_client_info(
|
||||
return PyString_FromString(mysql_get_client_info());
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_mysql_ConnectionObject_commit(
|
||||
_mysql_ConnectionObject *self,
|
||||
PyObject *args)
|
||||
{
|
||||
if (!PyArg_NoArgs(args)) return NULL;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_mysql_ConnectionObject_get_host_info(
|
||||
_mysql_ConnectionObject *self,
|
||||
@ -1113,6 +1162,8 @@ _mysql_ConnectionObject_repr(
|
||||
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,
|
||||
@ -1125,6 +1176,8 @@ _mysql_ResultObject_data_seek(
|
||||
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,
|
||||
@ -1139,6 +1192,8 @@ _mysql_ResultObject_row_seek(
|
||||
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,
|
||||
@ -1179,7 +1234,6 @@ static PyMethodDef _mysql_ConnectionObject_methods[] = {
|
||||
{"character_set_name", (PyCFunction)_mysql_ConnectionObject_character_set_name, 0},
|
||||
#endif
|
||||
{"close", (PyCFunction)_mysql_ConnectionObject_close, 0},
|
||||
{"commit", (PyCFunction)_mysql_ConnectionObject_commit, 0},
|
||||
{"dump_debug_info", (PyCFunction)_mysql_ConnectionObject_dump_debug_info, 0},
|
||||
{"escape_string", (PyCFunction)_mysql_escape_string, 1},
|
||||
{"error", (PyCFunction)_mysql_ConnectionObject_error, 0},
|
||||
@ -1215,9 +1269,12 @@ static struct memberlist _mysql_ConnectionObject_memberlist[] = {
|
||||
};
|
||||
|
||||
static PyMethodDef _mysql_ResultObject_methods[] = {
|
||||
{"data_seek", (PyCFunction)_mysql_ResultObject_data_seek, 1},
|
||||
{"row_seek", (PyCFunction)_mysql_ResultObject_row_seek, 1},
|
||||
{"row_tell", (PyCFunction)_mysql_ResultObject_row_tell, 0},
|
||||
{"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, 0},
|
||||
{"fetch_row", (PyCFunction)_mysql_ResultObject_fetch_row, METH_VARARGS | METH_KEYWORDS},
|
||||
{"field_flags", (PyCFunction)_mysql_ResultObject_field_flags, 0},
|
||||
@ -1331,31 +1388,61 @@ PyTypeObject _mysql_ResultObject_Type = {
|
||||
|
||||
static PyMethodDef
|
||||
_mysql_methods[] = {
|
||||
{ "connect", (PyCFunction)_mysql_connect, METH_VARARGS | METH_KEYWORDS },
|
||||
{ "debug", (PyCFunction)_mysql_debug, METH_VARARGS },
|
||||
{ "escape", (PyCFunction)_mysql_escape, METH_VARARGS },
|
||||
{ "escape_sequence", (PyCFunction)_mysql_escape_sequence, METH_VARARGS },
|
||||
{ "escape_dict", (PyCFunction)_mysql_escape_dict, METH_VARARGS },
|
||||
{ "escape_string", (PyCFunction)_mysql_escape_string, METH_VARARGS },
|
||||
{ "string_literal", (PyCFunction)_mysql_string_literal, METH_VARARGS },
|
||||
{ "get_client_info", (PyCFunction)_mysql_get_client_info },
|
||||
{ "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,
|
||||
0,
|
||||
_mysql_get_client_info__doc__
|
||||
},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
_mysql_NewException(
|
||||
PyObject *dict,
|
||||
char *name,
|
||||
PyObject *base)
|
||||
PyObject *edict,
|
||||
char *name)
|
||||
{
|
||||
PyObject *v;
|
||||
char longname[256];
|
||||
PyObject *e;
|
||||
|
||||
sprintf(longname, "_mysql.%s", name);
|
||||
if ((v = PyErr_NewException(longname, base, NULL)) == NULL)
|
||||
if (!(e = PyDict_GetItemString(edict, name)))
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(dict, name, v)) return NULL;
|
||||
return v;
|
||||
if (PyDict_SetItemString(dict, name, e)) return NULL;
|
||||
return e;
|
||||
}
|
||||
|
||||
int
|
||||
@ -1387,76 +1474,60 @@ return result objects (MYSQL_RES). Functions which expect MYSQL_RES * as\n\
|
||||
an argument are now methods of the result object. The mysql_real_*\n\
|
||||
functions are the ones used in place of not-real ones. The various\n\
|
||||
FLAG_*, CLIENT_*, FIELD_TYPE_*, etc. constants are renamed to FLAG.*,\n\
|
||||
CLIENT.*, FIELD_TYPE.*, etc. Deprecated functions are NOT implemented.\n\
|
||||
\n\
|
||||
type_conv is a dictionary which maps FIELD_TYPE.* to Python functions\n\
|
||||
which convert a string to some value. This is used by the fetch_row method.\n\
|
||||
Types not mapped are returned as strings. Numbers are all converted\n\
|
||||
reasonably, except DECIMAL.\n\
|
||||
\n\
|
||||
result.describe() produces a DB API description of the rows.\n\
|
||||
\n\
|
||||
escape_sequence() accepts a sequence of items and a type conversion dictionary.\n\
|
||||
Using the type of the item, it gets a converter function from the dictionary\n\
|
||||
(uses the string type if the item type is not found) and applies this to the\n\
|
||||
item. the result should be converted to strings with all the necessary\n\
|
||||
quoting.\n\
|
||||
\n\
|
||||
mysql_escape_string() on them, and returns them as a tuple.\n\
|
||||
\n\
|
||||
result.field_flags() returns the field flags for the result.\n\
|
||||
\n\
|
||||
result.fetch_row([n=0[, how=1]]) fetches up to n rows (default: n=1)\n\
|
||||
as a tuple of tuples (default: how=0) or dictionaries (how=1).\n\
|
||||
MySQL returns strings, but fetch_row() does data conversion\n\
|
||||
according to type_conv.\n\
|
||||
\n\
|
||||
For everything else, check the MySQL docs." ;
|
||||
CLIENT.*, FIELD_TYPE.*, etc. Deprecated functions (as of 3.22) are NOT\n\
|
||||
implemented.\n\
|
||||
";
|
||||
|
||||
DL_EXPORT(void)
|
||||
init_mysql(void)
|
||||
{
|
||||
PyObject *dict, *module;
|
||||
PyObject *dict, *module, *emod, *edict;
|
||||
module = Py_InitModule3("_mysql", _mysql_methods, _mysql___doc__);
|
||||
#ifdef MS_WIN32
|
||||
_mysql_ConnectionObject_Type.ob_type = &PyType_Type;
|
||||
_mysql_ResultObject_Type.ob_type = &PyType_Type;
|
||||
#endif
|
||||
dict = PyModule_GetDict(module);
|
||||
if (!(dict = PyModule_GetDict(module))) goto error;
|
||||
if (PyDict_SetItemString(dict, "__version__",
|
||||
PyString_FromString(_mysql__version__)))
|
||||
goto error;
|
||||
if (!(emod = PyImport_ImportModule("_mysql_const.exc")))
|
||||
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, "Warning", PyExc_StandardError)))
|
||||
_mysql_NewException(dict, edict, "Warning")))
|
||||
goto error;
|
||||
if (!(_mysql_Error =
|
||||
_mysql_NewException(dict, "Error", PyExc_StandardError)))
|
||||
_mysql_NewException(dict, edict, "Error")))
|
||||
goto error;
|
||||
if (!(_mysql_InterfaceError =
|
||||
_mysql_NewException(dict, "InterfaceError", _mysql_Error)))
|
||||
_mysql_NewException(dict, edict, "InterfaceError")))
|
||||
goto error;
|
||||
if (!(_mysql_DatabaseError =
|
||||
_mysql_NewException(dict, "DatabaseError", _mysql_Error)))
|
||||
_mysql_NewException(dict, edict, "DatabaseError")))
|
||||
goto error;
|
||||
if (!(_mysql_DataError =
|
||||
_mysql_NewException(dict, "DataError", _mysql_DatabaseError)))
|
||||
_mysql_NewException(dict, edict, "DataError")))
|
||||
goto error;
|
||||
if (!(_mysql_OperationalError =
|
||||
_mysql_NewException(dict, "OperationalError",
|
||||
_mysql_DatabaseError)))
|
||||
_mysql_NewException(dict, edict, "OperationalError")))
|
||||
goto error;
|
||||
if (!(_mysql_IntegrityError =
|
||||
_mysql_NewException(dict, "IntegrityError",
|
||||
_mysql_DatabaseError)))
|
||||
_mysql_NewException(dict, edict, "IntegrityError")))
|
||||
goto error;
|
||||
if (!(_mysql_InternalError =
|
||||
_mysql_NewException(dict, "InternalError",
|
||||
_mysql_DatabaseError)))
|
||||
goto error;
|
||||
_mysql_NewException(dict, edict, "InternalError")))
|
||||
if (!(_mysql_ProgrammingError =
|
||||
_mysql_NewException(dict, "ProgrammingError",
|
||||
_mysql_DatabaseError)))
|
||||
_mysql_NewException(dict, edict, "ProgrammingError")))
|
||||
goto error;
|
||||
if (!(_mysql_NotSupportedError =
|
||||
_mysql_NewException(dict, "NotSupportedError",
|
||||
_mysql_DatabaseError)))
|
||||
_mysql_NewException(dict, edict, "NotSupportedError")))
|
||||
goto error;
|
||||
Py_DECREF(emod);
|
||||
if (_mysql_Constant_class(dict, "_mysql_const.exc", "exc"))
|
||||
goto error;
|
||||
if (_mysql_Constant_class(dict, "_mysql_const.FLAG", "FLAG"))
|
||||
goto error;
|
||||
|
@ -24,7 +24,7 @@ if sys.platform == "linux-i386": # Red Hat
|
||||
libraries = [mysqlclient, "z"]
|
||||
runtime_library_dirs = []
|
||||
extra_objects = []
|
||||
elif sys.platform == "freebsd4":
|
||||
elif sys.platform in ("freebsd4", "openbsd2"):
|
||||
include_dirs = ['/usr/local/include/mysql']
|
||||
library_dirs = ['/usr/local/lib/mysql']
|
||||
libraries = [mysqlclient, "z"]
|
||||
@ -85,6 +85,7 @@ setup (# Distribution meta-data
|
||||
# Description of the modules and packages in the distribution
|
||||
|
||||
py_modules = ["MySQLdb", "CompatMysqldb",
|
||||
"_mysql_const.exc",
|
||||
"_mysql_const.CR",
|
||||
"_mysql_const.FIELD_TYPE",
|
||||
"_mysql_const.ER",
|
||||
|
Reference in New Issue
Block a user