mysql_binlog 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/mysql_binlog_dump
CHANGED
@@ -5,8 +5,10 @@ require 'mysql_binlog'
|
|
5
5
|
|
6
6
|
include MysqlBinlog
|
7
7
|
|
8
|
-
|
8
|
+
reader = BinlogFileReader.new(ARGV.first)
|
9
|
+
#reader = DebuggingReader.new(reader, :data => true, :calls => true)
|
10
|
+
binlog = Binlog.new(reader)
|
9
11
|
|
10
|
-
|
12
|
+
binlog.each_event do |event|
|
11
13
|
pp event
|
12
14
|
end
|
@@ -107,7 +107,8 @@ module MysqlBinlog
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
# Parse column metadata within a table map event.
|
111
|
+
def _table_map_event_column_metadata(columns_type)
|
111
112
|
length = parser.read_varint
|
112
113
|
columns_type.map do |c|
|
113
114
|
parser.read_mysql_type_metadata(c)
|
@@ -123,7 +124,7 @@ module MysqlBinlog
|
|
123
124
|
map_entry[:table] = parser.read_lpstringz
|
124
125
|
columns = parser.read_varint
|
125
126
|
columns_type = parser.read_uint8_array(columns).map { |c| MYSQL_TYPES[c] }
|
126
|
-
columns_metadata =
|
127
|
+
columns_metadata = _table_map_event_column_metadata(columns_type)
|
127
128
|
columns_nullable = parser.read_bit_array(columns)
|
128
129
|
|
129
130
|
map_entry[:columns] = columns.times.map do |c|
|
@@ -137,29 +138,44 @@ module MysqlBinlog
|
|
137
138
|
fields[:map_entry] = map_entry
|
138
139
|
end
|
139
140
|
|
141
|
+
# Parse a single row image, which is comprised of a series of columns. Not
|
142
|
+
# all columns are present in the row image, the columns_used array of true
|
143
|
+
# and false values identifies which columns are present.
|
144
|
+
def _generic_rows_event_row_image(header, fields, columns_used)
|
145
|
+
row_image = []
|
146
|
+
columns_null = parser.read_bit_array(fields[:table][:columns].size)
|
147
|
+
fields[:table][:columns].each_with_index do |column, column_index|
|
148
|
+
if !columns_used[column_index]
|
149
|
+
row_image << nil
|
150
|
+
elsif columns_null[column_index]
|
151
|
+
row_image << { column => nil }
|
152
|
+
else
|
153
|
+
row_image << {
|
154
|
+
column => parser.read_mysql_type(column[:type], column[:metadata])
|
155
|
+
}
|
156
|
+
end
|
157
|
+
end
|
158
|
+
row_image
|
159
|
+
end
|
160
|
+
|
140
161
|
# Parse the row images present in a row-based replication row event. This
|
141
162
|
# is rather incomplete right now due missing support for many MySQL types,
|
142
163
|
# but can parse some basic events.
|
143
164
|
def _generic_rows_event_row_images(header, fields, columns_used)
|
144
|
-
row_image_index = 0
|
145
165
|
row_images = []
|
146
166
|
end_position = reader.position + reader.remaining(header)
|
147
167
|
while reader.position < end_position
|
148
|
-
row_image =
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
column => parser.read_mysql_type(column[:type], column[:metadata])
|
158
|
-
}
|
159
|
-
end
|
168
|
+
row_image = {}
|
169
|
+
case EVENT_TYPES[header[:event_type]]
|
170
|
+
when :write_rows_event
|
171
|
+
row_image[:after] = _generic_rows_event_row_image(header, fields, columns_used[:after])
|
172
|
+
when :delete_rows_event
|
173
|
+
row_image[:before] = _generic_rows_event_row_image(header, fields, columns_used[:before])
|
174
|
+
when :update_rows_event
|
175
|
+
row_image[:before] = _generic_rows_event_row_image(header, fields, columns_used[:before])
|
176
|
+
row_image[:after] = _generic_rows_event_row_image(header, fields, columns_used[:after])
|
160
177
|
end
|
161
178
|
row_images << row_image
|
162
|
-
row_image_index += 1
|
163
179
|
end
|
164
180
|
row_images
|
165
181
|
end
|
@@ -173,10 +189,15 @@ module MysqlBinlog
|
|
173
189
|
fields[:table] = @table_map[table_id]
|
174
190
|
fields[:flags] = parser.read_uint16
|
175
191
|
columns = parser.read_varint
|
176
|
-
columns_used =
|
177
|
-
|
178
|
-
|
179
|
-
columns_used[
|
192
|
+
columns_used = {}
|
193
|
+
case EVENT_TYPES[header[:event_type]]
|
194
|
+
when :write_rows_event
|
195
|
+
columns_used[:after] = parser.read_bit_array(columns)
|
196
|
+
when :delete_rows_event
|
197
|
+
columns_used[:before] = parser.read_bit_array(columns)
|
198
|
+
when :update_rows_event
|
199
|
+
columns_used[:before] = parser.read_bit_array(columns)
|
200
|
+
columns_used[:after] = parser.read_bit_array(columns)
|
180
201
|
end
|
181
202
|
fields[:row_image] = _generic_rows_event_row_images(header, fields, columns_used)
|
182
203
|
end
|
@@ -218,10 +218,10 @@ module MysqlBinlog
|
|
218
218
|
}
|
219
219
|
when :blob
|
220
220
|
{ :length_size => read_uint8 }
|
221
|
-
when :
|
221
|
+
when :string, :var_string
|
222
222
|
{
|
223
223
|
:real_type => read_uint8,
|
224
|
-
:
|
224
|
+
:max_length => read_uint8,
|
225
225
|
}
|
226
226
|
when :geometry
|
227
227
|
{ :length_size => read_uint8 }
|
@@ -248,7 +248,9 @@ module MysqlBinlog
|
|
248
248
|
read_double
|
249
249
|
when :string, :var_string
|
250
250
|
read_varstring
|
251
|
-
when :varchar
|
251
|
+
when :varchar
|
252
|
+
read_lpstring(2)
|
253
|
+
when :blob
|
252
254
|
read_lpstring(metadata[:length_size])
|
253
255
|
when :timestamp
|
254
256
|
read_uint32
|
@@ -1,15 +1,4 @@
|
|
1
1
|
module MysqlBinlog
|
2
|
-
# A simple method to print a string as in hex representation per byte,
|
3
|
-
# with no more than 24 bytes per line, and spaces between each byte.
|
4
|
-
# There is probably a better way to do this, but I don't know it.
|
5
|
-
def puts_hex(data)
|
6
|
-
hex = data.bytes.each_slice(24).inject("") do |string, slice|
|
7
|
-
string << slice.map { |b| "%02x" % b }.join(" ") + "\n"
|
8
|
-
string
|
9
|
-
end
|
10
|
-
puts hex
|
11
|
-
end
|
12
|
-
|
13
2
|
# An array to quickly map an integer event type to its symbol.
|
14
3
|
EVENT_TYPES = [
|
15
4
|
:unknown_event, # 0
|
@@ -109,8 +98,8 @@ module MysqlBinlog
|
|
109
98
|
attr_accessor :filter_flags
|
110
99
|
attr_accessor :max_query_length
|
111
100
|
|
112
|
-
def initialize(
|
113
|
-
@reader =
|
101
|
+
def initialize(reader)
|
102
|
+
@reader = reader
|
114
103
|
@parser = BinlogParser.new(self)
|
115
104
|
@event_field_parser = BinlogEventFieldParser.new(self)
|
116
105
|
@fde = nil
|
data/lib/mysql_binlog.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'mysql_binlog/mysql_binlog'
|
2
2
|
require 'mysql_binlog/binlog_parser'
|
3
3
|
require 'mysql_binlog/binlog_event_field_parser'
|
4
|
+
require 'mysql_binlog/reader/debugging_reader'
|
4
5
|
require 'mysql_binlog/reader/binlog_file_reader'
|
5
6
|
require 'mysql_binlog/reader/binlog_stream_reader'
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysql_binlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 4
|
10
|
+
version: 0.1.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jeremy Cole
|