@@ -103,7 +103,7 @@ def _read_column_data(self, cols_bitmap):
103
103
# See http://dev.mysql.com/doc/internals/en/rows-event.html
104
104
null_bitmap = self .packet .read ((BitCount (cols_bitmap ) + 7 ) / 8 )
105
105
106
- nullBitmapIndex = 0
106
+ null_bitmap_index = 0
107
107
nb_columns = len (self .columns )
108
108
for i in range (0 , nb_columns ):
109
109
column = self .columns [i ]
@@ -112,117 +112,127 @@ def _read_column_data(self, cols_bitmap):
112
112
zerofill = self .table_map [self .table_id ].columns [i ].zerofill
113
113
fixed_binary_length = self .table_map [self .table_id ].columns [i ].fixed_binary_length
114
114
115
- if BitGet (cols_bitmap , i ) == 0 :
116
- values [name ] = None
117
- continue
118
-
119
- if self ._is_null (null_bitmap , nullBitmapIndex ):
120
- values [name ] = None
121
- elif column .type == FIELD_TYPE .TINY :
122
- if unsigned :
123
- values [name ] = struct .unpack ("<B" , self .packet .read (1 ))[0 ]
124
- if zerofill :
125
- values [name ] = format (values [name ], '03d' )
126
- else :
127
- values [name ] = struct .unpack ("<b" , self .packet .read (1 ))[0 ]
128
- elif column .type == FIELD_TYPE .SHORT :
129
- if unsigned :
130
- values [name ] = struct .unpack ("<H" , self .packet .read (2 ))[0 ]
131
- if zerofill :
132
- values [name ] = format (values [name ], '05d' )
133
- else :
134
- values [name ] = struct .unpack ("<h" , self .packet .read (2 ))[0 ]
135
- elif column .type == FIELD_TYPE .LONG :
136
- if unsigned :
137
- values [name ] = struct .unpack ("<I" , self .packet .read (4 ))[0 ]
138
- if zerofill :
139
- values [name ] = format (values [name ], '010d' )
140
- else :
141
- values [name ] = struct .unpack ("<i" , self .packet .read (4 ))[0 ]
142
- elif column .type == FIELD_TYPE .INT24 :
143
- if unsigned :
144
- values [name ] = self .packet .read_uint24 ()
145
- if zerofill :
146
- values [name ] = format (values [name ], '08d' )
147
- else :
148
- values [name ] = self .packet .read_int24 ()
149
- elif column .type == FIELD_TYPE .FLOAT :
150
- values [name ] = struct .unpack ("<f" , self .packet .read (4 ))[0 ]
151
- elif column .type == FIELD_TYPE .DOUBLE :
152
- values [name ] = struct .unpack ("<d" , self .packet .read (8 ))[0 ]
153
- elif column .type == FIELD_TYPE .VARCHAR or \
154
- column .type == FIELD_TYPE .STRING :
155
- if column .max_length > 255 :
156
- values [name ] = self .__read_string (2 , column )
157
- else :
158
- values [name ] = self .__read_string (1 , column )
159
-
160
- if fixed_binary_length and len (values [name ]) < fixed_binary_length :
161
- # Fixed-length binary fields are stored in the binlog
162
- # without trailing zeros and must be padded with zeros up
163
- # to the specified length at read time.
164
- nr_pad = fixed_binary_length - len (values [name ])
165
- values [name ] += b'\x00 ' * nr_pad
166
-
167
- elif column .type == FIELD_TYPE .NEWDECIMAL :
168
- values [name ] = self .__read_new_decimal (column )
169
- elif column .type == FIELD_TYPE .BLOB :
170
- values [name ] = self .__read_string (column .length_size , column )
171
- elif column .type == FIELD_TYPE .DATETIME :
172
- values [name ] = self .__read_datetime ()
173
- elif column .type == FIELD_TYPE .TIME :
174
- values [name ] = self .__read_time ()
175
- elif column .type == FIELD_TYPE .DATE :
176
- values [name ] = self .__read_date ()
177
- elif column .type == FIELD_TYPE .TIMESTAMP :
178
- values [name ] = datetime .datetime .utcfromtimestamp (
179
- self .packet .read_uint32 ())
180
-
181
- # For new date format:
182
- elif column .type == FIELD_TYPE .DATETIME2 :
183
- values [name ] = self .__read_datetime2 (column )
184
- elif column .type == FIELD_TYPE .TIME2 :
185
- values [name ] = self .__read_time2 (column )
186
- elif column .type == FIELD_TYPE .TIMESTAMP2 :
187
- values [name ] = self .__add_fsp_to_time (
188
- datetime .datetime .utcfromtimestamp (
189
- self .packet .read_int_be_by_size (4 )), column )
190
- elif column .type == FIELD_TYPE .LONGLONG :
191
- if unsigned :
192
- values [name ] = self .packet .read_uint64 ()
193
- if zerofill :
194
- values [name ] = format (values [name ], '020d' )
195
- else :
196
- values [name ] = self .packet .read_int64 ()
197
- elif column .type == FIELD_TYPE .YEAR :
198
- values [name ] = self .packet .read_uint8 () + 1900
199
- elif column .type == FIELD_TYPE .ENUM :
200
- values [name ] = column .enum_values [
201
- self .packet .read_uint_by_size (column .size )]
202
- elif column .type == FIELD_TYPE .SET :
203
- # We read set columns as a bitmap telling us which options
204
- # are enabled
205
- bit_mask = self .packet .read_uint_by_size (column .size )
206
- values [name ] = set (
207
- val for idx , val in enumerate (column .set_values )
208
- if bit_mask & 2 ** idx
209
- ) or None
210
-
211
- elif column .type == FIELD_TYPE .BIT :
212
- values [name ] = self .__read_bit (column )
213
- elif column .type == FIELD_TYPE .GEOMETRY :
214
- values [name ] = self .packet .read_length_coded_pascal_string (
215
- column .length_size )
216
- elif column .type == FIELD_TYPE .JSON :
217
- values [name ] = self .packet .read_binary_json (column .length_size )
218
- else :
219
- raise NotImplementedError ("Unknown MySQL column type: %d" %
220
- (column .type ))
115
+ values [name ] = self .__read_values_name (column , null_bitmap , null_bitmap_index ,
116
+ cols_bitmap , unsigned , zerofill ,
117
+ fixed_binary_length , i )
221
118
222
- nullBitmapIndex += 1
119
+ if BitGet (cols_bitmap , i ) != 0 :
120
+ null_bitmap_index += 1
223
121
224
122
return values
225
123
124
+ def __read_values_name (self , column , null_bitmap , null_bitmap_index , cols_bitmap , unsigned , zerofill ,
125
+ fixed_binary_length , i ):
126
+
127
+ if BitGet (cols_bitmap , i ) == 0 :
128
+ return None
129
+
130
+ if self ._is_null (null_bitmap , null_bitmap_index ):
131
+ return None
132
+
133
+ if column .type == FIELD_TYPE .TINY :
134
+ if unsigned :
135
+ ret = struct .unpack ("<B" , self .packet .read (1 ))[0 ]
136
+ if zerofill :
137
+ ret = format (ret , '03d' )
138
+ return ret
139
+ else :
140
+ return struct .unpack ("<b" , self .packet .read (1 ))[0 ]
141
+ elif column .type == FIELD_TYPE .SHORT :
142
+ if unsigned :
143
+ ret = struct .unpack ("<H" , self .packet .read (2 ))[0 ]
144
+ if zerofill :
145
+ ret = format (ret , '05d' )
146
+ return ret
147
+ else :
148
+ return struct .unpack ("<h" , self .packet .read (2 ))[0 ]
149
+ elif column .type == FIELD_TYPE .LONG :
150
+ if unsigned :
151
+ ret = struct .unpack ("<I" , self .packet .read (4 ))[0 ]
152
+ if zerofill :
153
+ ret = format (ret , '010d' )
154
+ return ret
155
+ else :
156
+ return struct .unpack ("<i" , self .packet .read (4 ))[0 ]
157
+ elif column .type == FIELD_TYPE .INT24 :
158
+ if unsigned :
159
+ ret = self .packet .read_uint24 ()
160
+ if zerofill :
161
+ ret = format (ret , '08d' )
162
+ return ret
163
+ else :
164
+ return self .packet .read_int24 ()
165
+ elif column .type == FIELD_TYPE .FLOAT :
166
+ return struct .unpack ("<f" , self .packet .read (4 ))[0 ]
167
+ elif column .type == FIELD_TYPE .DOUBLE :
168
+ return struct .unpack ("<d" , self .packet .read (8 ))[0 ]
169
+ elif column .type == FIELD_TYPE .VARCHAR or \
170
+ column .type == FIELD_TYPE .STRING :
171
+ ret = self .__read_string (2 , column ) if column .max_length > 255 else self .__read_string (1 , column )
172
+
173
+ if fixed_binary_length and len (ret ) < fixed_binary_length :
174
+ # Fixed-length binary fields are stored in the binlog
175
+ # without trailing zeros and must be padded with zeros up
176
+ # to the specified length at read time.
177
+ nr_pad = fixed_binary_length - len (ret )
178
+ ret += b'\x00 ' * nr_pad
179
+ return ret
180
+ elif column .type == FIELD_TYPE .NEWDECIMAL :
181
+ return self .__read_new_decimal (column )
182
+ elif column .type == FIELD_TYPE .BLOB :
183
+ return self .__read_string (column .length_size , column )
184
+ elif column .type == FIELD_TYPE .DATETIME :
185
+ return self .__read_datetime ()
186
+ elif column .type == FIELD_TYPE .TIME :
187
+ return self .__read_time ()
188
+ elif column .type == FIELD_TYPE .DATE :
189
+ return self .__read_date ()
190
+ elif column .type == FIELD_TYPE .TIMESTAMP :
191
+ return datetime .datetime .fromtimestamp (
192
+ self .packet .read_uint32 ())
193
+
194
+ # For new date format:
195
+ elif column .type == FIELD_TYPE .DATETIME2 :
196
+ return self .__read_datetime2 (column )
197
+ elif column .type == FIELD_TYPE .TIME2 :
198
+ return self .__read_time2 (column )
199
+ elif column .type == FIELD_TYPE .TIMESTAMP2 :
200
+ return self .__add_fsp_to_time (
201
+ datetime .datetime .fromtimestamp (
202
+ self .packet .read_int_be_by_size (4 )), column )
203
+ elif column .type == FIELD_TYPE .LONGLONG :
204
+ if unsigned :
205
+ ret = self .packet .read_uint64 ()
206
+ if zerofill :
207
+ ret = format (ret , '020d' )
208
+ return ret
209
+ else :
210
+ return self .packet .read_int64 ()
211
+ elif column .type == FIELD_TYPE .YEAR :
212
+ return self .packet .read_uint8 () + 1900
213
+ elif column .type == FIELD_TYPE .ENUM :
214
+ return column .enum_values [
215
+ self .packet .read_uint_by_size (column .size )]
216
+ elif column .type == FIELD_TYPE .SET :
217
+ # We read set columns as a bitmap telling us which options
218
+ # are enabled
219
+ bit_mask = self .packet .read_uint_by_size (column .size )
220
+ return set (
221
+ val for idx , val in enumerate (column .set_values )
222
+ if bit_mask & 2 ** idx
223
+ ) or None
224
+
225
+ elif column .type == FIELD_TYPE .BIT :
226
+ return self .__read_bit (column )
227
+ elif column .type == FIELD_TYPE .GEOMETRY :
228
+ return self .packet .read_length_coded_pascal_string (
229
+ column .length_size )
230
+ elif column .type == FIELD_TYPE .JSON :
231
+ return self .packet .read_binary_json (column .length_size )
232
+ else :
233
+ raise NotImplementedError ("Unknown MySQL column type: %d" %
234
+ (column .type ))
235
+
226
236
def __add_fsp_to_time (self , time , column ):
227
237
"""Read and add the fractional part of time
228
238
For more details about new date format:
0 commit comments