Skip to content

Commit 986bf5c

Browse files
heehehestarcat37mjs1995sean-k1mikaniz
authored
Developed RandEvent and add statement-based logging test (#414)
* Feat: implement rand_event * fix: change number of testcases * Add property for rand event * fix: rename seed to _seed * test: add test_rand_event * test: move statement setting to setUp * Chore: Delete unnecessary comment * Chore: delete unnecessary venv/* in .gitignore * comment: add rand_event warning description * refactor: change RandEvent import position * revert: remove resume_stream=True in example * test: add rand event seed type * test: add test_rand_event * test: move statement setting to setUp * Chore: Delete unnecessary comment * Chore: delete unnecessary venv/* in .gitignore * comment: add rand_event warning description * refactor: change RandEvent import position * revert: remove resume_stream=True in example * test: add rand event seed type * comment: add description for attributes * docs: Update docstring style --------- Co-authored-by: starcat37 <[email protected]> Co-authored-by: mjs <[email protected]> Co-authored-by: sean <[email protected]> Co-authored-by: mikaniz <[email protected]> Co-authored-by: 김진아 <[email protected]>
1 parent 558444e commit 986bf5c

File tree

4 files changed

+72
-6
lines changed

4 files changed

+72
-6
lines changed

Diff for: pymysqlreplication/binlogstream.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
XidEvent, GtidEvent, StopEvent, XAPrepareEvent,
1616
BeginLoadQueryEvent, ExecuteLoadQueryEvent,
1717
HeartbeatLogEvent, NotImplementedEvent, MariadbGtidEvent,
18-
MariadbAnnotateRowsEvent)
18+
MariadbAnnotateRowsEvent, RandEvent)
1919
from .exceptions import BinLogNotEnabled
2020
from .row_event import (
2121
UpdateRowsEvent, WriteRowsEvent, DeleteRowsEvent, TableMapEvent)
@@ -621,7 +621,8 @@ def _allowed_event_list(self, only_events, ignored_events,
621621
HeartbeatLogEvent,
622622
NotImplementedEvent,
623623
MariadbGtidEvent,
624-
MariadbAnnotateRowsEvent
624+
MariadbAnnotateRowsEvent,
625+
RandEvent
625626
))
626627
if ignored_events is not None:
627628
for e in ignored_events:

Diff for: pymysqlreplication/event.py

+33
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,39 @@ def _dump(self):
454454
print("type: %d" % (self.type))
455455
print("Value: %d" % (self.value))
456456

457+
class RandEvent(BinLogEvent):
458+
"""
459+
RandEvent is generated every time a statement uses the RAND() function.
460+
Indicates the seed values to use for generating a random number with RAND() in the next statement.
461+
462+
RandEvent only works in statement-based logging (need to set binlog_format as 'STATEMENT')
463+
and only works when the seed number is not specified.
464+
465+
:ivar seed1: int - value for the first seed
466+
:ivar seed2: int - value for the second seed
467+
"""
468+
469+
def __init__(self, from_packet, event_size, table_map, ctl_connection, **kwargs):
470+
super(RandEvent, self).__init__(from_packet, event_size, table_map,
471+
ctl_connection, **kwargs)
472+
# Payload
473+
self._seed1 = self.packet.read_uint64()
474+
self._seed2 = self.packet.read_uint64()
475+
476+
@property
477+
def seed1(self):
478+
"""Get the first seed value"""
479+
return self._seed1
480+
481+
@property
482+
def seed2(self):
483+
"""Get the second seed value"""
484+
return self._seed2
485+
486+
def _dump(self):
487+
super(RandEvent, self)._dump()
488+
print("seed1: %d" % (self.seed1))
489+
print("seed2: %d" % (self.seed2))
457490

458491
class NotImplementedEvent(BinLogEvent):
459492
def __init__(self, from_packet, event_size, table_map, ctl_connection, **kwargs):

Diff for: pymysqlreplication/packet.py

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class BinLogPacketWrapper(object):
7070
constants.EXECUTE_LOAD_QUERY_EVENT: event.ExecuteLoadQueryEvent,
7171
constants.HEARTBEAT_LOG_EVENT: event.HeartbeatLogEvent,
7272
constants.XA_PREPARE_EVENT: event.XAPrepareEvent,
73+
constants.RAND_EVENT: event.RandEvent,
7374
# row_event
7475
constants.UPDATE_ROWS_EVENT_V1: row_event.UpdateRowsEvent,
7576
constants.WRITE_ROWS_EVENT_V1: row_event.WriteRowsEvent,

Diff for: pymysqlreplication/tests/test_basic.py

+35-4
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@
1919
from pymysqlreplication.constants.BINLOG import *
2020
from pymysqlreplication.row_event import *
2121

22-
__all__ = ["TestBasicBinLogStreamReader", "TestMultipleRowBinLogStreamReader", "TestCTLConnectionSettings", "TestGtidBinLogStreamReader","TestMariadbBinlogStreamReader"]
22+
__all__ = ["TestBasicBinLogStreamReader", "TestMultipleRowBinLogStreamReader", "TestCTLConnectionSettings", "TestGtidBinLogStreamReader", "TestMariadbBinlogStreamReader", "TestStatementConnectionSetting"]
2323

2424

2525
class TestBasicBinLogStreamReader(base.PyMySQLReplicationTestCase):
2626
def ignoredEvents(self):
2727
return [GtidEvent]
2828

2929
def test_allowed_event_list(self):
30-
self.assertEqual(len(self.stream._allowed_event_list(None, None, False)), 17)
31-
self.assertEqual(len(self.stream._allowed_event_list(None, None, True)), 16)
32-
self.assertEqual(len(self.stream._allowed_event_list(None, [RotateEvent], False)), 16)
30+
self.assertEqual(len(self.stream._allowed_event_list(None, None, False)), 18)
31+
self.assertEqual(len(self.stream._allowed_event_list(None, None, True)), 17)
32+
self.assertEqual(len(self.stream._allowed_event_list(None, [RotateEvent], False)), 17)
3333
self.assertEqual(len(self.stream._allowed_event_list([RotateEvent], None, False)), 1)
3434

3535
def test_read_query_event(self):
@@ -1036,6 +1036,37 @@ def test_annotate_rows_event(self):
10361036
self.assertEqual(event.sql_statement,insert_query)
10371037
self.assertIsInstance(event,MariadbAnnotateRowsEvent)
10381038

1039+
class TestStatementConnectionSetting(base.PyMySQLReplicationTestCase):
1040+
def setUp(self):
1041+
super(TestStatementConnectionSetting, self).setUp()
1042+
self.stream.close()
1043+
self.stream = BinLogStreamReader(
1044+
self.database,
1045+
server_id=1024,
1046+
only_events=(RandEvent, QueryEvent),
1047+
fail_on_table_metadata_unavailable=True
1048+
)
1049+
self.execute("SET @@binlog_format='STATEMENT'")
1050+
1051+
def test_rand_event(self):
1052+
self.execute("CREATE TABLE test (id INT NOT NULL AUTO_INCREMENT, data INT NOT NULL, PRIMARY KEY (id))")
1053+
self.execute("INSERT INTO test (data) VALUES(RAND())")
1054+
self.execute("COMMIT")
1055+
1056+
self.assertEqual(self.bin_log_format(), "STATEMENT")
1057+
self.assertIsInstance(self.stream.fetchone(), QueryEvent)
1058+
self.assertIsInstance(self.stream.fetchone(), QueryEvent)
1059+
1060+
expect_rand_event = self.stream.fetchone()
1061+
self.assertIsInstance(expect_rand_event, RandEvent)
1062+
self.assertEqual(type(expect_rand_event.seed1), int)
1063+
self.assertEqual(type(expect_rand_event.seed2), int)
1064+
1065+
def tearDown(self):
1066+
self.execute("SET @@binlog_format='ROW'")
1067+
self.assertEqual(self.bin_log_format(), "ROW")
1068+
super(TestStatementConnectionSetting, self).tearDown()
1069+
10391070

10401071
if __name__ == "__main__":
10411072
import unittest

0 commit comments

Comments
 (0)