|
| 1 | +import copy |
1 | 2 | import io
|
2 | 3 | import time
|
3 | 4 | import unittest
|
| 5 | +from unittest.mock import patch |
| 6 | + |
| 7 | +from pymysql.protocol import MysqlPacket |
4 | 8 |
|
5 |
| -from pymysqlreplication.json_binary import JsonDiff, JsonDiffOperation |
6 |
| -from pymysqlreplication.tests import base |
7 | 9 | from pymysqlreplication import BinLogStreamReader
|
8 |
| -from pymysqlreplication.gtid import GtidSet, Gtid |
9 |
| -from pymysqlreplication.event import * |
10 | 10 | from pymysqlreplication.constants.BINLOG import *
|
11 | 11 | from pymysqlreplication.constants.NONE_SOURCE import *
|
12 |
| -from pymysqlreplication.row_event import * |
| 12 | +from pymysqlreplication.event import * |
| 13 | +from pymysqlreplication.gtid import Gtid, GtidSet |
| 14 | +from pymysqlreplication.json_binary import JsonDiff, JsonDiffOperation |
13 | 15 | from pymysqlreplication.packet import BinLogPacketWrapper
|
14 |
| -from pymysql.protocol import MysqlPacket |
15 |
| -from unittest.mock import patch |
16 |
| - |
| 16 | +from pymysqlreplication.row_event import * |
| 17 | +from pymysqlreplication.tests import base |
17 | 18 |
|
18 | 19 | __all__ = [
|
19 | 20 | "TestBasicBinLogStreamReader",
|
@@ -284,43 +285,11 @@ def test_delete_row_event(self):
|
284 | 285 | self.execute("COMMIT")
|
285 | 286 |
|
286 | 287 | self.assertIsInstance(self.stream.fetchone(), RotateEvent)
|
287 |
| - self.assertIsInstance(self.stream.fetchone(), FormatDescriptionEvent) |
288 |
| - |
289 |
| - # QueryEvent for the BEGIN |
290 |
| - if not self.isMariaDB(): |
291 |
| - self.assertIsInstance(self.stream.fetchone(), QueryEvent) |
292 |
| - |
293 |
| - self.assertIsInstance(self.stream.fetchone(), TableMapEvent) |
294 |
| - |
295 |
| - event = self.stream.fetchone() |
296 |
| - if self.isMySQL56AndMore(): |
297 |
| - self.assertEqual(event.event_type, DELETE_ROWS_EVENT_V2) |
298 |
| - else: |
299 |
| - self.assertEqual(event.event_type, DELETE_ROWS_EVENT_V1) |
300 |
| - self.assertIsInstance(event, DeleteRowsEvent) |
301 |
| - if event.table_map[event.table_id].column_name_flag: |
302 |
| - self.assertEqual(event.rows[0]["values"]["id"], 1) |
303 |
| - self.assertEqual(event.rows[0]["values"]["data"], "Hello World") |
304 |
| - |
305 |
| - def test_update_row_event(self): |
306 |
| - query = "CREATE TABLE test (id INT NOT NULL AUTO_INCREMENT, data VARCHAR (50) NOT NULL, PRIMARY KEY (id))" |
307 |
| - self.execute(query) |
308 |
| - query = "INSERT INTO test (data) VALUES('Hello')" |
309 |
| - self.execute(query) |
310 |
| - |
311 |
| - self.resetBinLog() |
312 |
| - |
313 |
| - query = "UPDATE test SET data = 'World' WHERE id = 1" |
314 |
| - self.execute(query) |
| 288 | + self.execute( |
| 289 | + "INSERT INTO test (data) VALUES ('ó')".encode("latin-1") |
| 290 | + ) |
315 | 291 | self.execute("COMMIT")
|
316 | 292 |
|
317 |
| - self.assertIsInstance(self.stream.fetchone(), RotateEvent) |
318 |
| - self.assertIsInstance(self.stream.fetchone(), FormatDescriptionEvent) |
319 |
| - |
320 |
| - # QueryEvent for the BEGIN |
321 |
| - if not self.isMariaDB(): |
322 |
| - self.assertIsInstance(self.stream.fetchone(), QueryEvent) |
323 |
| - |
324 | 293 | self.assertIsInstance(self.stream.fetchone(), TableMapEvent)
|
325 | 294 |
|
326 | 295 | event = self.stream.fetchone()
|
@@ -617,6 +586,7 @@ def create_binlog_packet_wrapper(pkt):
|
617 | 586 | self.stream._BinLogStreamReader__ignored_schemas,
|
618 | 587 | self.stream._BinLogStreamReader__freeze_schema,
|
619 | 588 | self.stream._BinLogStreamReader__ignore_decode_errors,
|
| 589 | + self.stream._BinLogStreamReader__force_encoding, |
620 | 590 | self.stream._BinLogStreamReader__verify_checksum,
|
621 | 591 | self.stream._BinLogStreamReader__optional_meta_data,
|
622 | 592 | )
|
@@ -837,42 +807,83 @@ def test_delete_multiple_row_event(self):
|
837 | 807 | self.assertEqual(event.rows[1]["values"]["id"], 2)
|
838 | 808 | self.assertEqual(event.rows[1]["values"]["data"], "World")
|
839 | 809 |
|
| 810 | + def test_force_encoding(self): |
| 811 | + if self.isMySQL80AndMore(): |
| 812 | + self.skipTest("MYSQL 8 Version don't need force encoding") |
| 813 | + self.stream.close() |
| 814 | + |
| 815 | + db = copy.copy(self.database) |
| 816 | + db["charset"] = "latin1" |
| 817 | + self.connect_conn_control(db) |
| 818 | + |
| 819 | + string = "\u00e9" |
| 820 | + |
| 821 | + create_query = ( |
| 822 | + "CREATE TABLE test (test CHAR(12)) CHARACTER SET latin1 COLLATE latin1_bin;" |
| 823 | + ) |
| 824 | + insert_query = b"INSERT INTO test VALUES('" + string.encode("latin-1") + b"');" |
| 825 | + self.execute(create_query) |
| 826 | + self.execute(insert_query) |
| 827 | + self.execute("COMMIT") |
| 828 | + |
| 829 | + self.stream = BinLogStreamReader( |
| 830 | + self.database, |
| 831 | + server_id=1024, |
| 832 | + only_events=(WriteRowsEvent,), |
| 833 | + force_encoding="utf-8", |
| 834 | + ) |
| 835 | + with self.assertRaises(UnicodeError): |
| 836 | + event = self.stream.fetchone() |
| 837 | + data = event.rows[0]["values"]["data"] |
| 838 | + |
| 839 | + self.stream = BinLogStreamReader( |
| 840 | + self.database, |
| 841 | + server_id=1024, |
| 842 | + only_events=(WriteRowsEvent,), |
| 843 | + force_encoding="latin-1", |
| 844 | + ) |
| 845 | + event = self.stream.fetchone() |
| 846 | + if event.table_map[event.table_id].column_name_flag: |
| 847 | + data = event.rows[0]["values"]["data"] |
| 848 | + self.assertEqual(data, '[{"text":" Some string"}]') |
| 849 | + |
| 850 | + |
840 | 851 | def test_ignore_decode_errors(self):
|
841 | 852 | if self.isMySQL80AndMore():
|
842 | 853 | self.skipTest("MYSQL 8 Version Pymysql Data Error Incorrect string value")
|
| 854 | + problematic_unicode_string = "ó".encode("latin-1") |
| 855 | + self.stream.close() |
843 | 856 | problematic_unicode_string = (
|
844 | 857 | b'[{"text":"\xed\xa0\xbd \xed\xb1\x8d Some string"}]'
|
845 | 858 | )
|
846 |
| - self.stream.close() |
847 | 859 | self.execute("CREATE TABLE test (data VARCHAR(50) CHARACTER SET utf8mb4)")
|
848 | 860 | self.execute_with_args(
|
849 | 861 | "INSERT INTO test (data) VALUES (%s)", (problematic_unicode_string)
|
850 | 862 | )
|
851 | 863 | self.execute("COMMIT")
|
852 | 864 |
|
853 |
| - # Initialize with ignore_decode_errors=False |
854 | 865 | self.stream = BinLogStreamReader(
|
855 | 866 | self.database,
|
856 | 867 | server_id=1024,
|
857 | 868 | only_events=(WriteRowsEvent,),
|
858 |
| - ignore_decode_errors=False, |
| 869 | + force_encoding=None, |
859 | 870 | )
|
860 | 871 | with self.assertRaises(UnicodeError):
|
861 | 872 | event = self.stream.fetchone()
|
862 | 873 | data = event.rows[0]["values"]["data"]
|
863 | 874 |
|
864 |
| - # Initialize with ignore_decode_errors=True |
865 | 875 | self.stream = BinLogStreamReader(
|
866 | 876 | self.database,
|
867 | 877 | server_id=1024,
|
868 | 878 | only_events=(WriteRowsEvent,),
|
869 |
| - ignore_decode_errors=True, |
| 879 | + force_encoding="latin-1", |
870 | 880 | )
|
871 | 881 | event = self.stream.fetchone()
|
872 | 882 | if event.table_map[event.table_id].column_name_flag:
|
873 | 883 | data = event.rows[0]["values"]["data"]
|
874 | 884 | self.assertEqual(data, '[{"text":" Some string"}]')
|
875 | 885 |
|
| 886 | + |
876 | 887 | def test_drop_column(self):
|
877 | 888 | self.stream.close()
|
878 | 889 | self.execute("CREATE TABLE test_drop_column (id INTEGER(11), data VARCHAR(50))")
|
|
0 commit comments