Bump metadata version.

Clean up setup.cfg so it doesn't break RPM builds on files which
are no longer included.

Add a test case for warnings for column truncation.

Clean up warnings; was working around the introduced bug that
returned (var)char columns with binary collations as array.

Exposed the column flags (values from constants.FLAG) as
description_flags on the cursor.
This commit is contained in:
adustman
2006-03-05 04:59:14 +00:00
parent 9e4c5ec971
commit 21a3d3397b
6 changed files with 78 additions and 19 deletions

View File

@ -253,7 +253,7 @@ class Connection(_mysql.connection):
self.query("SHOW WARNINGS") self.query("SHOW WARNINGS")
r = self.store_result() r = self.store_result()
warnings = r.fetch_row(0) warnings = r.fetch_row(0)
return [ (level.tostring(), int(code), message.tostring()) return [ (level, code, message)
for level, code, message in warnings ] for level, code, message in warnings ]
Warning = Warning Warning = Warning

View File

@ -16,10 +16,20 @@ class BaseCursor(object):
"""A base for Cursor classes. Useful attributes: """A base for Cursor classes. Useful attributes:
description -- DB API 7-tuple describing columns in last query description
arraysize -- default number of rows fetchmany() will fetch A tuple of DB API 7-tuples describing the columns in
the last executed query; see PEP-249 for details.
See the MySQL docs for more information.""" description_flags
Tuple of column flags for last query, one entry per column
in the result set. Values correspond to those in
MySQLdb.constants.FLAG. See MySQL documentation (C API)
for more information. Non-standard extension.
arraysize
default number of rows fetchmany() will fetch
"""
from _mysql_exceptions import MySQLError, Warning, Error, InterfaceError, \ from _mysql_exceptions import MySQLError, Warning, Error, InterfaceError, \
DatabaseError, DataError, OperationalError, IntegrityError, \ DatabaseError, DataError, OperationalError, IntegrityError, \
@ -28,6 +38,7 @@ class BaseCursor(object):
def __init__(self, connection): def __init__(self, connection):
self.connection = connection self.connection = connection
self.description = None self.description = None
self.description_flags = None
self.rowcount = -1 self.rowcount = -1
self.arraysize = 1 self.arraysize = 1
self._executed = None self._executed = None
@ -95,6 +106,7 @@ class BaseCursor(object):
self.rowcount = db.affected_rows() self.rowcount = db.affected_rows()
self.rownumber = 0 self.rownumber = 0
self.description = self._result and self._result.describe() or None self.description = self._result and self._result.describe() or None
self.description_flags = self._result and self._result.field_flags() or None
self.lastrowid = db.insert_id() self.lastrowid = db.insert_id()
self._warnings = db.warning_count() self._warnings = db.warning_count()
self._info = db.info() self._info = db.info()

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
version: 1.2.1c6 version: 1.2.1c7
version_info: (1,2,1,'gamma',6) version_info: (1,2,1,'gamma',7)
description: Python interface to MySQL description: Python interface to MySQL
long_description: long_description:
========================= =========================

View File

@ -1,7 +1,7 @@
[bdist_rpm] [bdist_rpm]
doc_files = README doc/*.html doc/*.txt doc/*.css doc/private doc/public ChangeLog doc_files = README doc/*.txt ChangeLog
vendor = MySQL-python SourceForge Project vendor = MySQL-python SourceForge Project
packager = Andy Dustman <andy@dustman.net> packager = Andy Dustman <andy@dustman.net>
distribution-name = Red Hat Linux distribution-name = Red Hat Linux
requires = python requires = python
build-requires = python-devel mysql-devel zlib-devel build-requires = python-devel mysql-devel zlib-devel openssl-devel

View File

@ -31,7 +31,7 @@ def mysql_config(what):
# of mysql_config # of mysql_config
def dequote(s): def dequote(s):
if (s[0] == "'" or s[0] == '"') and (s[0] == s[-1]): if s[0] in "\"'" and s[0] == s[-1]:
s = s[1:-1] s = s[1:-1]
return s return s
@ -45,10 +45,6 @@ def enabled(option):
else: else:
raise Abort, "Unknown value %s for option %s" % (value, option) raise Abort, "Unknown value %s for option %s" % (value, option)
include_dirs = [ dequote(i[2:])
for i in mysql_config('include')
if i.startswith('-i') ]
extra_objects = [] extra_objects = []
static = enabled('static') static = enabled('static')
if enabled('embedded'): if enabled('embedded'):
@ -69,7 +65,16 @@ metadata['name'] = name
library_dirs = [ dequote(i[2:]) for i in libs if i.startswith("-L") ] library_dirs = [ dequote(i[2:]) for i in libs if i.startswith("-L") ]
libraries = [ dequote(i[2:]) for i in libs if i.startswith("-l") ] libraries = [ dequote(i[2:]) for i in libs if i.startswith("-l") ]
extra_compile_args = mysql_config("cflags") removable_compile_args = '-I -L -l'.split()
extra_compile_args = [ i for i in mysql_config("cflags")
if i[:2] not in removable_compile_args ]
include_dirs = [ dequote(i[2:])
for i in mysql_config('include')
if i.startswith('-I') ]
if not include_dirs: # fix for MySQL-3.23
include_dirs = [ dequote(i[2:])
for i in mysql_config('cflags')
if i.startswith('-I') ]
if static: if static:
extra_objects.append(os.path.join( extra_objects.append(os.path.join(

View File

@ -97,11 +97,9 @@ class DatabaseTest(unittest.TestCase):
insert_statement = ('INSERT INTO %s VALUES (%s)' % insert_statement = ('INSERT INTO %s VALUES (%s)' %
(self.table, (self.table,
','.join(['%s'] * len(columndefs)))) ','.join(['%s'] * len(columndefs))))
for i in range(self.rows): data = [ [ generator(i,j) for j in range(len(columndefs)) ]
data = [] for i in range(self.rows) ]
for j in range(len(columndefs)): self.cursor.executemany(insert_statement, data)
data.append(generator(i,j))
self.cursor.execute(insert_statement,tuple(data))
# verify # verify
self.connection.commit() self.connection.commit()
self.cursor.execute('select * from %s' % self.table) self.cursor.execute('select * from %s' % self.table)
@ -123,6 +121,50 @@ class DatabaseTest(unittest.TestCase):
self.failUnless(len(l) == 1, "ROLLBACK didn't work") self.failUnless(len(l) == 1, "ROLLBACK didn't work")
self.cursor.execute('drop table %s' % (self.table)) self.cursor.execute('drop table %s' % (self.table))
def test_truncation(self):
columndefs = ( 'col1 INT', 'col2 VARCHAR(255)')
def generator(row, col):
if col == 0: return row
else: return ('%i' % (row%10))*((255-self.rows/2)+row)
self.create_table(columndefs)
insert_statement = ('INSERT INTO %s VALUES (%s)' %
(self.table,
','.join(['%s'] * len(columndefs))))
try:
self.cursor.execute(insert_statement, (0, '0'*256))
except Warning:
if self.debug: print self.cursor.messages
else:
self.fail("Over-long column did not generate warnings with single insert")
self.connection.rollback()
try:
for i in range(self.rows):
data = []
for j in range(len(columndefs)):
data.append(generator(i,j))
self.cursor.execute(insert_statement,tuple(data))
except Warning:
if self.debug: print self.cursor.messages
else:
self.fail("Over-long columns did not generate warnings with execute()")
self.connection.rollback()
try:
data = [ [ generator(i,j) for j in range(len(columndefs)) ]
for i in range(self.rows) ]
self.cursor.executemany(insert_statement, data)
except Warning:
if self.debug: print self.cursor.messages
else:
self.fail("Over-long columns did not generate warnings with executemany()")
self.connection.rollback()
self.cursor.execute('drop table %s' % (self.table))
def test_CHAR(self): def test_CHAR(self):
# Character data # Character data
def generator(row,col): def generator(row,col):