00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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()