diff --git a/pymysqlreplication/gtid.py b/pymysqlreplication/gtid.py index e8f20c0e..226b2931 100644 --- a/pymysqlreplication/gtid.py +++ b/pymysqlreplication/gtid.py @@ -3,6 +3,7 @@ import re import struct import binascii +from io import BytesIO class Gtid(object): @@ -16,17 +17,18 @@ def parse_interval(interval): else: return (int(m.group(1)), int(m.group(2))) - @staticmethod def parse(gtid): - m = re.search('^([0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})((?::[0-9-]+)+)$', gtid) + m = re.search('^([0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})' + '((?::[0-9-]+)+)$', gtid) if not m: raise ValueError('GTID format is incorrect: %r' % (gtid, )) sid = m.group(1) intervals = m.group(2) - intervals_parsed = [Gtid.parse_interval(x) for x in intervals.split(':')[1:]] + intervals_parsed = [Gtid.parse_interval(x) + for x in intervals.split(':')[1:]] return (sid, intervals_parsed) @@ -39,18 +41,18 @@ def __init__(self, gtid): def __str__(self): return '%s:%s' % (self.sid, ':'.join(('%d-%s' % x) if isinstance(x, tuple) - else str(x) - for x in self.intervals)) + else str(x) + for x in self.intervals)) def __repr__(self): return '' % self @property def encoded_length(self): - return (16 + # sid - 8 + # n_intervals - 2 * # stop/start - 8 * # stop/start mark encoded as int64 + return (16 + # sid + 8 + # n_intervals + 2 * # stop/start + 8 * # stop/start mark encoded as int64 len(self.intervals)) def encode(self): @@ -79,11 +81,48 @@ def encode(self): return buffer + @classmethod + def decode(cls, payload): + assert isinstance(payload, BytesIO), \ + 'payload is expected to be a BytesIO' + sid = b'' + sid = sid + binascii.hexlify(payload.read(4)) + sid = sid + b'-' + sid = sid + binascii.hexlify(payload.read(2)) + sid = sid + b'-' + sid = sid + binascii.hexlify(payload.read(2)) + sid = sid + b'-' + sid = sid + binascii.hexlify(payload.read(2)) + sid = sid + b'-' + sid = sid + binascii.hexlify(payload.read(6)) + + (n_intervals,) = struct.unpack('' % self.gtids @property def encoded_length(self): - return (8 + # n_sids + return (8 + # n_sids sum(x.encoded_length for x in self.gtids)) def encoded(self): return b'' + (struct.pack('