3
3
import binascii
4
4
import struct
5
5
import datetime
6
+ from pymysqlreplication .constants .STATUS_VAR_KEY import *
6
7
7
8
8
9
class BinLogEvent (object ):
@@ -167,7 +168,13 @@ def __init__(self, from_packet, event_size, table_map, ctl_connection, **kwargs)
167
168
self .status_vars_length = self .packet .read_uint16 ()
168
169
169
170
# Payload
170
- self .status_vars = self .packet .read (self .status_vars_length )
171
+ status_vars_end_pos = self .packet .read_bytes + self .status_vars_length
172
+ while self .packet .read_bytes < status_vars_end_pos : # while 남은 data length가 얼마만큼? OR read_bytes
173
+ # read KEY for status variable
174
+ status_vars_key = self .packet .read_uint8 ()
175
+ # read VALUE for status variable
176
+ self ._read_status_vars_value_for_key (status_vars_key )
177
+
171
178
self .schema = self .packet .read (self .schema_length )
172
179
self .packet .advance (1 )
173
180
@@ -181,6 +188,80 @@ def _dump(self):
181
188
print ("Execution time: %d" % (self .execution_time ))
182
189
print ("Query: %s" % (self .query ))
183
190
191
+
192
+ # TODO: check if instance attribute with the same name already exists
193
+ # TODO: put all the instace attribute in separate class? called status_vars
194
+ # TODO: does length need to be remembered?
195
+ # TODO: ref(mysql doc. and mysql-server) for each hunk
196
+ def _read_status_vars_value_for_key (self , key ):
197
+ """parse status variable VALUE for given KEY
198
+
199
+ A status variable in query events is a sequence of status KEY-VALUE pairs.
200
+ Parsing logic from mysql-server source code edited by dongwook-chan
201
+ https://github.com/mysql/mysql-server/blob/beb865a960b9a8a16cf999c323e46c5b0c67f21f/libbinlogevents/src/statement_events.cpp#L181-L336
202
+
203
+ Args:
204
+ key: key for status variable
205
+ """
206
+ if key == Q_FLAGS2_CODE : # 0x00
207
+ self .flags2 = self .packet .read_uint32 ()
208
+ elif key == Q_SQL_MODE_CODE : # 0x01
209
+ self .sql_mode = self .packet .read_uint64 ()
210
+ elif key == Q_CATALOG_CODE : # 0x02 for MySQL 5.0.x
211
+ pass
212
+ elif key == Q_AUTO_INCREMENT : # 0x03
213
+ self .auto_increment_increment = self .packet .read_uint16 ()
214
+ self .auto_increment_offset = self .packet .read_uint16 ()
215
+ elif key == Q_CHARSET_CODE : # 0x04
216
+ self .character_set_client = self .packet .read_uint16 ()
217
+ self .collation_connection = self .packet .read_uint16 ()
218
+ self .collation_server = self .packet .read_uint16 ()
219
+ elif key == Q_TIME_ZONE_CODE : # 0x05
220
+ time_zone_len = self .packet .read_uint8 ()
221
+ if time_zone_len :
222
+ self .time_zone = self .packet .read (time_zone_len )
223
+ elif key == Q_CATALOG_NZ_CODE : # 0x06
224
+ catalog_len = self .packet .read_uint8 ()
225
+ if catalog_len :
226
+ self .catalog_nz_code = self .packet .read (catalog_len )
227
+ elif key == Q_LC_TIME_NAMES_CODE : # 0x07
228
+ self .lc_time_names_number = self .packet .read_uint16 ()
229
+ elif key == Q_CHARSET_DATABASE_CODE : # 0x08
230
+ self .charset_database_number = self .packet .read_uint16 ()
231
+ elif key == Q_TABLE_MAP_FOR_UPDATE_CODE : # 0x09
232
+ self .table_map_for_update = self .packet .read_uint64 ()
233
+ elif key == Q_MASTER_DATA_WRITTEN_CODE : # 0x0A
234
+ pass
235
+ elif key == Q_INVOKER : # 0x0B
236
+ user_len = self .packet .read_uint8 ()
237
+ if user_len :
238
+ self .user = self .packet .read (user_len )
239
+ host_len = self .packet .read_uint8 ()
240
+ if host_len :
241
+ self .host = self .packet .read (host_len )
242
+ elif key == Q_UPDATED_DB_NAMES : # 0x0C
243
+ mts_accessed_dbs = self .packet .read_uint8 ()
244
+ dbs = []
245
+ for i in range (mts_accessed_dbs ):
246
+ db = self .packet .read_string ()
247
+ dbs .append (db )
248
+ self .mts_accessed_db_names = dbs
249
+ elif key == Q_MICROSECONDS : # 0x0D
250
+ self .microseconds = self .packet .read_uint24 ()
251
+ elif key == Q_COMMIT_TS : # 0x0E
252
+ pass
253
+ elif key == Q_COMMIT_TS2 : # 0x0F
254
+ pass
255
+ elif key == Q_EXPLICIT_DEFAULTS_FOR_TIMESTAMP :# 0x10
256
+ self .explicit_defaults_ts = self .packet .read_uint8 ()
257
+ elif key == Q_DDL_LOGGED_WITH_XID : # 0x11
258
+ self .ddl_xid = self .packet .read_uint64 ()
259
+ elif key == Q_DEFAULT_COLLATION_FOR_UTF8MB4 : # 0x12
260
+ self .default_collation_for_utf8mb4_number = self .packet .read_uint16 ()
261
+ elif key == Q_SQL_REQUIRE_PRIMARY_KEY : # 0x13
262
+ self .sql_require_primary_key = self .packet .read_uint8 ()
263
+ elif key == Q_DEFAULT_TABLE_ENCRYPTION : # 0x14
264
+ self .default_table_encryption = self .packet .read_uint8 ()
184
265
185
266
class BeginLoadQueryEvent (BinLogEvent ):
186
267
"""
0 commit comments