33import binascii
44import struct
55import datetime
6+ from pymysqlreplication .constants .STATUS_VAR_KEY import *
67
78
89class BinLogEvent (object ):
@@ -167,7 +168,13 @@ def __init__(self, from_packet, event_size, table_map, ctl_connection, **kwargs)
167168 self .status_vars_length = self .packet .read_uint16 ()
168169
169170 # 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+
171178 self .schema = self .packet .read (self .schema_length )
172179 self .packet .advance (1 )
173180
@@ -181,6 +188,80 @@ def _dump(self):
181188 print ("Execution time: %d" % (self .execution_time ))
182189 print ("Query: %s" % (self .query ))
183190
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 ()
184265
185266class BeginLoadQueryEvent (BinLogEvent ):
186267 """
0 commit comments