# Perforce Defect Tracking Integration Project # # # MYSQLDB_SUPPORT.PY -- CHECK RELEASE OF MYSQLDB MODULE # # Nick Barnes, Ravenbrook Limited, 2001-10-24 # # # 1. INTRODUCTION # # This module provides a function check_supported to the P4DTI. # That function attempts to determine the release of the MySQLdb # library, checks whether the release is supported by the P4DTI, and # takes action accordingly: # # - If the MySQLdb release is supported by the P4DTI, it generates an # informative message. # # - If the MySQLdb release is known to be incompatible with the P4DTI, # it raises a fatal exception. # # - If the MySQLdb release is unsupported, but not known to be # incompatible, it generates a warning message. # # See job000317, job000413, job000411 for problems addressed by # identifying the MySQLdb release. # # When support for other MySQLdb releases is added, the table # 'MySQLdb_release_support' in section 3 must be modified. # # Functions in this module take a MySQLdb module as argument M. This # is to allow us to test this module without having multiple actual # MySQLdb modules installed. # # The intended readership of this document is project developers. # # This document is not confidential. import types import MySQLdb import catalog error = "MySQLdb module support error" # 2. IDENTIFYING MYSQLDB RELEASE # # This section provides a function what_release (q.v.) which attempts # to identify a MySQLdb release. # 2.1. Distinguish between release 0.3.0 and release 0.3.1 # Also distinguish those releases from unknown other releases which # resemble those releases. # # Release 0.3.0 has MySQLdb.type_conv[MySQLdb.FIELD_TYPE.LONG] == int. # Release 0.3.1 has MySQLdb.type_conv[MySQLdb.FIELD_TYPE.LONG] == long. def distinguish_030_031(M): if M.__dict__.has_key('type_conv'): converter = M.type_conv[M.FIELD_TYPE.LONG] if converter == int: return '0.3.0' elif converter == long: return '0.3.1' else: return None else: return None # 2.2. Map __version__ strings to release names # # This table maps the MySQLdb __version__ string to either a string # (in which case it's the MySQLdb release name) or a function, which # should be called with the MySQLdb module as an argument and which # returns the MySQLdb release name, or None if it can't tell. MySQLdb_versions = { '1.21': '0.2.0', '1.24': '0.2.1', '1.29': '0.2.2', '1.32': distinguish_030_031, '1.33': '0.3.2', '1.34': '0.3.3', '1.39': '0.3.4', '1.40': '0.3.5', '0.9.0': '0.9.0', '0.9.1g2': '0.9.1c1', '0.9.1': '0.9.1', } # 2.3. Determine the MySQLdb release # Returns a pair (version, release), where version is the MySQLdb # module's version string and release is the identified MySQLdb # release. def what_release(M): version = M.__dict__.get('__version__', 'No __version__') release = MySQLdb_versions.get(M.__version__, None) if isinstance(release, types.FunctionType): release = release(M) if release is None: release = 'Unknown' return (version, release) # 3. SUPPORT FOR MYSQLDB RELEASES # # This section provides a function check_supported (q.v.) which checks # the MySQLdb release against supported releases and takes appropriate # action. # 3.1. Action functions. # # These three functions take the appropriate action. # For supported releases. def supported(version, release, logger): # "MySQLdb version '%s' (release '%s') detected. # This release is supported by the P4DTI." msg = catalog.msg(1007, (version, release)) logger(msg) # For unsupported releases which are not known not to work. def unsupported(version, release, logger): # "MySQLdb version '%s' (release '%s') detected. # This release is not supported by the P4DTI." msg = catalog.msg(1006, (version, release)) logger(msg) # For releases known not to work. def broken(version, release, logger): # "MySQLdb version '%s' (release '%s') detected. # This release is incompatible with the P4DTI." raise error, catalog.msg(1005, (version, release)) # 3.2. Map MySQLdb release names to actions. # # This table maps the MySQLdb release name (as determined by the # what_release, q.v.) to a function that we call when we identify that # release. The function takes three arguments: the actual MySQLdb # __version__ string, the MySQLdb release name (or None if # undetermined), and a logger function. # # Old versions lack an escape_string method (see job000317). New # versions lack a type_conv map (see job000413). We've tested against # 0.2.2 and 0.3.0. # # This table will be updated as we test against and support more # MySQLdb releases. MySQLdb_release_support = { '0.2.0': broken, '0.2.1': broken, '0.2.2': supported, '0.3.0': supported, '0.9.0': broken, '0.9.1c1': broken, '0.9.1': broken, } # 3.3. Find the release and take the necessary action # # Providing this function is the purpose of this module. def check_supported(M, logger): (version, release) = what_release(M) MySQLdb_release_support.get(release, unsupported)(version, release, logger) # A. REFERENCES # # # B. DOCUMENT HISTORY # # 2001-10-25 NB Created. # # # C. COPYRIGHT AND LICENCE # # This file is copyright (c) 2001 Perforce Software, Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # # $Id: //info.ravenbrook.com/project/p4dti/branch/2001-11-05/nt-service/code/replicator/mysqldb_support.py#1 $