Drizzled Public API Documentation

column.py
00001 #!/usr/bin/env python
00002 #
00003 # Drizzle Client & Protocol Library
00004 # 
00005 # Copyright (C) 2008 Eric Day (eday@oddments.org)
00006 # All rights reserved.
00007 #
00008 # Redistribution and use in source and binary forms, with or without
00009 # modification, are permitted provided that the following conditions are
00010 # met:
00011 #
00012 #     * Redistributions of source code must retain the above copyright
00013 # notice, this list of conditions and the following disclaimer.
00014 #
00015 #     * Redistributions in binary form must reproduce the above
00016 # copyright notice, this list of conditions and the following disclaimer
00017 # in the documentation and/or other materials provided with the
00018 # distribution.
00019 #
00020 #     * The names of its contributors may not be used to endorse or
00021 # promote products derived from this software without specific prior
00022 # written permission.
00023 #
00024 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035 #
00036 
00037 '''
00038 MySQL Protocol Column Objects
00039 '''
00040 
00041 import struct
00042 import unittest
00043 import bitfield
00044 import packet
00045 
00046 class ColumnType(object):
00047   DECIMAL = 0
00048   TINY = 1
00049   SHORT = 2
00050   LONG = 3
00051   FLOAT = 4
00052   DOUBLE = 5
00053   NULL = 6
00054   TIMESTAMP = 7
00055   LONGLONG = 8
00056   INT24 = 9
00057   DATE = 10
00058   TIME = 11
00059   DATETIME = 12
00060   YEAR = 13
00061   NEWDATE = 14
00062   VARCHAR = 15
00063   BIT = 16
00064   NEWDECIMAL = 246
00065   ENUM = 247
00066   SET = 248
00067   TINY_BLOB = 249
00068   MEDIUM_BLOB = 250
00069   LONG_BLOB = 251
00070   BLOB = 252
00071   VAR_STRING = 253
00072   STRING = 254
00073   GEOMETRY = 255
00074 
00075 class ColumnFlags(bitfield.BitField):
00076   _fields = [
00077     'NOT_NULL',
00078     'PRI_KEY',
00079     'UNIQUE_KEY',
00080     'MULTIPLE_KEY',
00081     'BLOB',
00082     'UNSIGNED',
00083     'ZEROFILL',
00084     'BINARY',
00085     'ENUM',
00086     'AUTO_INCREMENT',
00087     'TIMESTAMP',
00088     'SET',
00089     'NO_DEFAULT_VALUE',
00090     'ON_UPDATE_NOW',
00091     'PART_KEY',
00092     'NUM',
00093     'UNIQUE',
00094     'BINCMP',
00095     'GET_FIXED_FIELDS',
00096     'IN_PART_FUNC',
00097     'IN_ADD_INDEX',
00098     'RENAMED'
00099   ]
00100 
00101 
00102 class Column(object):
00103   '''This class represents a column packet sent from the client.'''
00104 
00105   def __init__(self, packed=None, catalog='', db='', table='', orig_table='',
00106                name='', orig_name='', unused1=0, charset=0, size=0, type=0,
00107                flags=0, decimal=0, unused2=tuple([0] * 2), default_value=''):
00108     if packed is None:
00109       self.catalog = catalog
00110       self.db = db
00111       self.table = table
00112       self.orig_table = orig_table
00113       self.name = name
00114       self.orig_name = orig_name
00115       self.unused1 = unused1
00116       self.charset = charset
00117       self.size = size
00118       self.type = type
00119       self.flags = ColumnFlags(flags)
00120       self.decimal = decimal
00121       self.unused2 = unused2
00122       self.default_value = default_value
00123     else:
00124       self._packed = packed
00125       self.catalog = self.parseString()
00126       self.db = self.parseString()
00127       self.table = self.parseString()
00128       self.orig_table = self.parseString()
00129       self.name = self.parseString()
00130       self.orig_name = self.parseString()
00131       data = struct.unpack('B2B4BB2BB', self._packed[:11])
00132       self.unused1 = data[0]
00133       self.charset = data[1] | (data[2] << 8)
00134       self.size = data[3] | (data[4] << 8) | (data[5] << 16) | (data[6] << 24)
00135       self.type = data[7]
00136       self.flags = ColumnFlags(data[8] | (data[9] << 8))
00137       self.decimal = data[10]
00138       self.unused2 = tuple(data[11:13])
00139       self.default_value = self._packed[13:]
00140 
00141   def parseString(self):
00142     (size, packed_size) = packet.parse_encoded_size(self._packed)
00143     string = self._packed[packed_size:size+packed_size]
00144     self._packed = self._packed[size+packed_size:]
00145     return string
00146 
00147   def pack(self):
00148     return chr(self.command) + self.payload
00149 
00150   def __str__(self):
00151     return '''Column
00152   catalog = %s
00153   db = %s
00154   table = %s
00155   orig_table = %s
00156   name = %s
00157   orig_name = %s
00158   unused1 = %s
00159   charset = %s
00160   size = %s
00161   type = %s
00162   flags = %s
00163   decimal = %s
00164   unused2 = %s
00165   default_value = %s
00166 ''' % (self.catalog, self.db, self.table, self.orig_table, self.name,
00167        self.orig_name, self.unused1, self.charset, self.size, self.type,
00168        self.flags, self.decimal, self.unused2, self.default_value)
00169 
00170 if __name__ == '__main__':
00171   unittest.main()