3
3
import re
4
4
import struct
5
5
import binascii
6
+ from io import BytesIO
6
7
7
8
8
9
class Gtid (object ):
@@ -16,17 +17,18 @@ def parse_interval(interval):
16
17
else :
17
18
return (int (m .group (1 )), int (m .group (2 )))
18
19
19
-
20
20
@staticmethod
21
21
def parse (gtid ):
22
- m = re .search ('^([0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})((?::[0-9-]+)+)$' , gtid )
22
+ m = re .search ('^([0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})'
23
+ '((?::[0-9-]+)+)$' , gtid )
23
24
if not m :
24
25
raise ValueError ('GTID format is incorrect: %r' % (gtid , ))
25
26
26
27
sid = m .group (1 )
27
28
intervals = m .group (2 )
28
29
29
- intervals_parsed = [Gtid .parse_interval (x ) for x in intervals .split (':' )[1 :]]
30
+ intervals_parsed = [Gtid .parse_interval (x )
31
+ for x in intervals .split (':' )[1 :]]
30
32
31
33
return (sid , intervals_parsed )
32
34
@@ -39,18 +41,18 @@ def __init__(self, gtid):
39
41
def __str__ (self ):
40
42
return '%s:%s' % (self .sid ,
41
43
':' .join (('%d-%s' % x ) if isinstance (x , tuple )
42
- else str (x )
43
- for x in self .intervals ))
44
+ else str (x )
45
+ for x in self .intervals ))
44
46
45
47
def __repr__ (self ):
46
48
return '<Gtid "%s">' % self
47
49
48
50
@property
49
51
def encoded_length (self ):
50
- return (16 + # sid
51
- 8 + # n_intervals
52
- 2 * # stop/start
53
- 8 * # stop/start mark encoded as int64
52
+ return (16 + # sid
53
+ 8 + # n_intervals
54
+ 2 * # stop/start
55
+ 8 * # stop/start mark encoded as int64
54
56
len (self .intervals ))
55
57
56
58
def encode (self ):
@@ -79,25 +81,72 @@ def encode(self):
79
81
80
82
return buffer
81
83
84
+ @classmethod
85
+ def decode (cls , payload ):
86
+ assert isinstance (payload , BytesIO ), \
87
+ 'payload is expected to be a BytesIO'
88
+ sid = b''
89
+ sid = sid + binascii .hexlify (payload .read (4 ))
90
+ sid = sid + b'-'
91
+ sid = sid + binascii .hexlify (payload .read (2 ))
92
+ sid = sid + b'-'
93
+ sid = sid + binascii .hexlify (payload .read (2 ))
94
+ sid = sid + b'-'
95
+ sid = sid + binascii .hexlify (payload .read (2 ))
96
+ sid = sid + b'-'
97
+ sid = sid + binascii .hexlify (payload .read (6 ))
98
+
99
+ (n_intervals ,) = struct .unpack ('<Q' , payload .read (8 ))
100
+ intervals = []
101
+ for i in range (0 , n_intervals ):
102
+ start , end = struct .unpack ('<QQ' , payload .read (16 ))
103
+ if end == start + 1 :
104
+ intervals .append (start )
105
+ else :
106
+ intervals .append ((start , end ))
107
+
108
+ return cls ('%s:%s' % (sid .decode ('ascii' ), ':' .join ([
109
+ '%d-%d' % x
110
+ if isinstance (x , tuple )
111
+ else '%d' % x
112
+ for x in intervals ])))
113
+
82
114
83
115
class GtidSet (object ):
84
116
def __init__ (self , gtid_set ):
117
+ def _to_gtid (element ):
118
+ if isinstance (element , Gtid ):
119
+ return element
120
+ return Gtid (element .strip (' \n ' ))
121
+
85
122
if not gtid_set :
86
123
self .gtids = []
124
+ elif isinstance (gtid_set , (list , set )):
125
+ self .gtids = [_to_gtid (x ) for x in gtid_set ]
87
126
else :
88
127
self .gtids = [Gtid (x .strip (' \n ' )) for x in gtid_set .split (',' )]
89
128
90
129
def __str__ (self ):
91
130
return ',' .join (str (x ) for x in self .gtids )
92
131
93
132
def __repr__ (self ):
94
- return '<GtidSet "%s" ' % ',' . join ( repr ( x ) for x in self .gtids )
133
+ return '<GtidSet %r> ' % self .gtids
95
134
96
135
@property
97
136
def encoded_length (self ):
98
- return (8 + # n_sids
137
+ return (8 + # n_sids
99
138
sum (x .encoded_length for x in self .gtids ))
100
139
101
140
def encoded (self ):
102
141
return b'' + (struct .pack ('<Q' , len (self .gtids )) +
103
- b'' .join (x .encode () for x in self .gtids ))
142
+ b'' .join (x .encode () for x in self .gtids ))
143
+
144
+ encode = encoded
145
+
146
+ @classmethod
147
+ def decode (cls , payload ):
148
+ assert isinstance (payload , BytesIO ), \
149
+ 'payload is expected to be a BytesIO'
150
+ (n_sid ,) = struct .unpack ('<Q' , payload .read (8 ))
151
+
152
+ return cls ([Gtid .decode (payload ) for _ in range (0 , n_sid )])
0 commit comments