9
9
10
10
from .packet import BinLogPacketWrapper
11
11
from .constants .BINLOG import TABLE_MAP_EVENT , ROTATE_EVENT
12
- from .event import NotImplementedEvent
13
12
from .gtid import GtidSet
13
+ from .event import QueryEvent , RotateEvent , FormatDescriptionEvent , XidEvent , GtidEvent , NotImplementedEvent
14
+ from .row_event import UpdateRowsEvent , WriteRowsEvent , DeleteRowsEvent , TableMapEvent
14
15
15
16
try :
16
17
from pymysql .constants .COMMAND import COM_BINLOG_DUMP_GTID
@@ -48,9 +49,12 @@ def __init__(self, connection_settings, server_id, resume_stream=False,
48
49
self .__connected_ctl = False
49
50
self .__resume_stream = resume_stream
50
51
self .__blocking = blocking
51
- self .__only_events = only_events
52
- self .__ignored_events = ignored_events
53
- self .__filter_non_implemented_events = filter_non_implemented_events
52
+ self .__allowed_events = self ._allowed_event_list (only_events , ignored_events , filter_non_implemented_events )
53
+
54
+ # We can't filter on packet level TABLE_MAP and rotate event because we need
55
+ # them for handling other operations
56
+ self .__allowed_events_in_packet = frozenset ([TableMapEvent , RotateEvent ]).union (self .__allowed_events )
57
+
54
58
self .__server_id = server_id
55
59
self .__use_checksum = False
56
60
@@ -156,7 +160,7 @@ def __connect_to_stream(self):
156
160
# A gtid set looks like:
157
161
# 19d69c1e-ae97-4b8c-a1ef-9e12ba966457:1-3:8-10,
158
162
# 1c2aad49-ae92-409a-b4df-d05a03e4702e:42-47:80-100:130-140
159
- #
163
+ #
160
164
# In this particular gtid set, 19d69c1e-ae97-4b8c-a1ef-9e12ba966457:1-3:8-10
161
165
# is the first member of the set, it is called a gtid.
162
166
# In this gtid, 19d69c1e-ae97-4b8c-a1ef-9e12ba966457 is the sid
@@ -228,7 +232,8 @@ def fetchone(self):
228
232
229
233
binlog_event = BinLogPacketWrapper (pkt , self .table_map ,
230
234
self ._ctl_connection ,
231
- self .__use_checksum )
235
+ self .__use_checksum ,
236
+ self .__allowed_events_in_packet )
232
237
if binlog_event .event_type == TABLE_MAP_EVENT :
233
238
self .table_map [binlog_event .event .table_id ] = \
234
239
binlog_event .event .get_table ()
@@ -242,35 +247,44 @@ def fetchone(self):
242
247
# wrong table schema.
243
248
# The fix is to rely on the fact that MySQL will also rotate to a new binlog file every time it
244
249
# restarts. That means every rotation we see *could* be a sign of restart and so potentially
245
- # invalidates all our cached table id to schema mappings. This means we have to load them all
250
+ # invalidates all our cached table id to schema mappings. This means we have to load them all
246
251
# again for each logfile which is potentially wasted effort but we can't really do much better
247
252
# without being broken in restart case
248
253
self .table_map = {}
249
254
elif binlog_event .log_pos :
250
255
self .log_pos = binlog_event .log_pos
251
256
252
- if self .__filter_event (binlog_event .event ):
257
+ # event is none if we have filter it on packet level
258
+ # we filter also not allowed events
259
+ if binlog_event .event is None or (binlog_event .event .__class__ not in self .__allowed_events ):
253
260
continue
254
261
255
262
return binlog_event .event
256
263
257
- def __filter_event (self , event ):
258
- if self .__filter_non_implemented_events and isinstance (event , NotImplementedEvent ):
259
- return True
260
-
261
- if self .__ignored_events is not None :
262
- for ignored_event in self .__ignored_events :
263
- if isinstance (event , ignored_event ):
264
- return True
265
-
266
- if self .__only_events is not None :
267
- for allowed_event in self .__only_events :
268
- if isinstance (event , allowed_event ):
269
- return False
270
- else :
271
- return True
272
-
273
- return False
264
+ def _allowed_event_list (self , only_events , ignored_events , filter_non_implemented_events ):
265
+ if only_events is not None :
266
+ events = set (only_events )
267
+ else :
268
+ events = set ((
269
+ QueryEvent ,
270
+ RotateEvent ,
271
+ FormatDescriptionEvent ,
272
+ XidEvent ,
273
+ GtidEvent ,
274
+ UpdateRowsEvent ,
275
+ WriteRowsEvent ,
276
+ DeleteRowsEvent ,
277
+ TableMapEvent ,
278
+ NotImplementedEvent ))
279
+ if ignored_events is not None :
280
+ for e in ignored_events :
281
+ events .remove (e )
282
+ if filter_non_implemented_events :
283
+ try :
284
+ events .remove (NotImplementedEvent )
285
+ except KeyError :
286
+ pass
287
+ return frozenset (events )
274
288
275
289
def __get_table_information (self , schema , table ):
276
290
for i in range (1 , 3 ):
0 commit comments