Skip to content

Allow to force the encoding for old MySQL release #629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 24 additions & 19 deletions pymysqlreplication/binlogstream.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
import struct
import logging
from packaging.version import Version
import struct

import pymysql
from packaging.version import Version
from pymysql.constants.COMMAND import COM_BINLOG_DUMP, COM_REGISTER_SLAVE
from pymysql.cursors import DictCursor

from .constants.BINLOG import TABLE_MAP_EVENT, ROTATE_EVENT, FORMAT_DESCRIPTION_EVENT
from .constants.BINLOG import FORMAT_DESCRIPTION_EVENT, ROTATE_EVENT, TABLE_MAP_EVENT
from .event import (
QueryEvent,
RotateEvent,
FormatDescriptionEvent,
XidEvent,
GtidEvent,
StopEvent,
XAPrepareEvent,
BeginLoadQueryEvent,
ExecuteLoadQueryEvent,
FormatDescriptionEvent,
GtidEvent,
HeartbeatLogEvent,
NotImplementedEvent,
MariadbGtidEvent,
MariadbAnnotateRowsEvent,
RandEvent,
MariadbBinLogCheckPointEvent,
MariadbGtidEvent,
MariadbGtidListEvent,
MariadbStartEncryptionEvent,
NotImplementedEvent,
PreviousGtidsEvent,
QueryEvent,
RandEvent,
RotateEvent,
RowsQueryLogEvent,
MariadbGtidListEvent,
MariadbBinLogCheckPointEvent,
StopEvent,
UserVarEvent,
PreviousGtidsEvent,
XAPrepareEvent,
XidEvent,
)
from .exceptions import BinLogNotEnabled
from .gtid import GtidSet
from .packet import BinLogPacketWrapper
from .row_event import (
UpdateRowsEvent,
WriteRowsEvent,
DeleteRowsEvent,
TableMapEvent,
PartialUpdateRowsEvent,
TableMapEvent,
UpdateRowsEvent,
WriteRowsEvent,
)

try:
Expand Down Expand Up @@ -185,6 +185,7 @@ def __init__(
slave_heartbeat=None,
is_mariadb=False,
annotate_rows_event=False,
force_encoding=None,
ignore_decode_errors=False,
verify_checksum=False,
enable_logging=True,
Expand Down Expand Up @@ -225,6 +226,8 @@ def __init__(
to point to Mariadb specific GTID.
annotate_rows_event: Parameter value to enable annotate rows event in mariadb,
used with 'is_mariadb'
force_encoding: Force the encoding to decode a string this for MySQL 5.XXX This is the charset
to use example latin-1
ignore_decode_errors: If true, any decode errors encountered
when reading column data will be ignored.
verify_checksum: If true, verify events read from the binary log by examining checksums.
Expand Down Expand Up @@ -252,6 +255,7 @@ def __init__(
only_events, ignored_events, filter_non_implemented_events
)
self.__ignore_decode_errors = ignore_decode_errors
self.__force_encoding = force_encoding
self.__verify_checksum = verify_checksum
self.__optional_meta_data = False

Expand Down Expand Up @@ -628,6 +632,7 @@ def fetchone(self):
self.__ignored_schemas,
self.__freeze_schema,
self.__ignore_decode_errors,
self.__force_encoding,
self.__verify_checksum,
self.__optional_meta_data,
)
Expand Down
10 changes: 6 additions & 4 deletions pymysqlreplication/event.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import binascii
import struct
import datetime
import decimal
import zlib
import json
import logging
import struct
import zlib
from typing import Optional, Union

from pymysqlreplication.constants.STATUS_VAR_KEY import *
from pymysqlreplication.exceptions import StatusVariableMismatch
from pymysqlreplication.util.bytes import parse_decimal_from_bytes
from typing import Union, Optional
import json


class BinLogEvent(object):
Expand All @@ -26,6 +26,7 @@ def __init__(
ignored_schemas=None,
freeze_schema=False,
ignore_decode_errors=False,
force_encoding=None,
verify_checksum=False,
optional_meta_data=False,
):
Expand All @@ -37,6 +38,7 @@ def __init__(
self._ctl_connection = ctl_connection
self.mysql_version = mysql_version
self._ignore_decode_errors = ignore_decode_errors
self._force_encoding = force_encoding
self._verify_checksum = verify_checksum
self._is_event_valid = None
# The event have been fully processed, if processed is false
Expand Down
6 changes: 4 additions & 2 deletions pymysqlreplication/packet.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pymysqlreplication import constants, event, row_event
from pymysqlreplication.json_binary import parse_json, JsonDiff, JsonDiffOperation
from pymysqlreplication.util.bytes import *
from pymysqlreplication.constants import BINLOG
from pymysqlreplication.json_binary import JsonDiff, JsonDiffOperation, parse_json
from pymysqlreplication.util.bytes import *

# Constants from PyMYSQL source code
NULL_COLUMN = 251
Expand Down Expand Up @@ -72,6 +72,7 @@ def __init__(
ignored_schemas,
freeze_schema,
ignore_decode_errors,
force_encoding,
verify_checksum,
optional_meta_data,
):
Expand Down Expand Up @@ -125,6 +126,7 @@ def __init__(
ignored_schemas=ignored_schemas,
freeze_schema=freeze_schema,
ignore_decode_errors=ignore_decode_errors,
force_encoding=force_encoding,
verify_checksum=verify_checksum,
optional_meta_data=optional_meta_data,
)
Expand Down
20 changes: 10 additions & 10 deletions pymysqlreplication/row_event.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import struct
import decimal
import datetime
import decimal
import struct
from enum import Enum

from pymysql.charset import charset_by_name
from enum import Enum

from .event import BinLogEvent
from .constants import FIELD_TYPE
from .constants import BINLOG
from .constants import CHARSET
from .constants import NONE_SOURCE
from .bitmap import BitCount, BitGet
from .column import Column
from .constants import BINLOG, CHARSET, FIELD_TYPE, NONE_SOURCE
from .event import BinLogEvent
from .table import Table
from .bitmap import BitCount, BitGet


class RowsEvent(BinLogEvent):
Expand Down Expand Up @@ -332,7 +329,10 @@ def __read_string(self, size, column):
else:
# MYSQL 5.xx Version Goes Here
# We don't know encoding type So apply Default Utf-8
string = string.decode(errors=decode_errors)
if self._force_encoding:
string = string.decode(encoding=self._force_encoding, errors=decode_errors)
else:
string = string.decode(errors=decode_errors)
return string

def __read_bit(self, column):
Expand Down
18 changes: 9 additions & 9 deletions pymysqlreplication/tests/test_basic.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import io
import time
import unittest
from unittest.mock import patch

from pymysql.protocol import MysqlPacket

from pymysqlreplication.json_binary import JsonDiff, JsonDiffOperation
from pymysqlreplication.tests import base
from pymysqlreplication import BinLogStreamReader
from pymysqlreplication.gtid import GtidSet, Gtid
from pymysqlreplication.event import *
from pymysqlreplication.constants.BINLOG import *
from pymysqlreplication.constants.NONE_SOURCE import *
from pymysqlreplication.row_event import *
from pymysqlreplication.event import *
from pymysqlreplication.gtid import Gtid, GtidSet
from pymysqlreplication.json_binary import JsonDiff, JsonDiffOperation
from pymysqlreplication.packet import BinLogPacketWrapper
from pymysql.protocol import MysqlPacket
from unittest.mock import patch

from pymysqlreplication.row_event import *
from pymysqlreplication.tests import base

__all__ = [
"TestBasicBinLogStreamReader",
Expand Down Expand Up @@ -2198,4 +2198,4 @@ def test_json_partial_update_two_column(self):
if __name__ == "__main__":
import unittest

unittest.main()
unittest.main()
Loading