flydata 0.2.20 → 0.2.21
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/flydata.gemspec +7 -4
- data/lib/flydata/command/base.rb +3 -0
- data/lib/flydata/command_logger.rb +1 -1
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +7 -1
- data/lib/flydata/fluent-plugins/mysql/binlog_record_handler.rb +1 -0
- data/lib/flydata/fluent-plugins/mysql/context.rb +1 -1
- data/lib/flydata/fluent-plugins/mysql/dml_record_handler.rb +12 -3
- data/lib/flydata/fluent-plugins/mysql/table_meta.rb +83 -0
- data/spec/fluent_plugins_spec_helper.rb +3 -1
- data/spec/flydata/cli_spec.rb +1 -1
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +1 -0
- data/spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb +5 -2
- data/spec/flydata/fluent-plugins/mysql/binlog_position_spec.rb +2 -1
- data/spec/flydata/fluent-plugins/mysql/binlog_query_dispatcher_spec.rb +1 -1
- data/spec/flydata/fluent-plugins/mysql/table_meta_spec.rb +61 -0
- data/spec/flydata/parser/mysql/alter_table_parser_spec.rb +1 -0
- data/spec/flydata/sync_file_manager_spec.rb +2 -0
- data/spec/spec_helper.rb +3 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2bb40962e8bd93a3daf20cee2de578c4abc1788
|
4
|
+
data.tar.gz: 266ca371867bd725c6721bae7d23fbea9fd4a0e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: daaa7f5468f4f334ef0b7d0cea6cfd672c0a816fd119ca4b54c4f6fa5619987ff37c5df587b11c734d4a29fd2518072277c98a810755d0f0db8008fc719a0ec1
|
7
|
+
data.tar.gz: 3140aea09a5fad9977f1a0bf9d60f317f71637129e0b7ac423198e43e84159534f1715d49d28db28ddc135e522bcbdc32f3ed1415904d2f6cffeffc1f46066c3
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.21
|
data/flydata.gemspec
CHANGED
@@ -2,14 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: flydata 0.2.21 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "flydata"
|
8
|
-
s.version = "0.2.
|
9
|
+
s.version = "0.2.21"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
|
12
|
-
s.date = "2014-12-
|
14
|
+
s.date = "2014-12-12"
|
13
15
|
s.description = "FlyData Agent"
|
14
16
|
s.email = "sysadmin@flydata.com"
|
15
17
|
s.executables = ["fdmysqldump", "flydata", "serverinfo"]
|
@@ -100,6 +102,7 @@ Gem::Specification.new do |s|
|
|
100
102
|
"lib/flydata/fluent-plugins/mysql/context.rb",
|
101
103
|
"lib/flydata/fluent-plugins/mysql/ddl_query_handler.rb",
|
102
104
|
"lib/flydata/fluent-plugins/mysql/dml_record_handler.rb",
|
105
|
+
"lib/flydata/fluent-plugins/mysql/table_meta.rb",
|
103
106
|
"lib/flydata/fluent-plugins/out_forward_ssl.rb",
|
104
107
|
"lib/flydata/fluent-plugins/preference.rb",
|
105
108
|
"lib/flydata/flydata_crontab.sh",
|
@@ -127,6 +130,7 @@ Gem::Specification.new do |s|
|
|
127
130
|
"spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb",
|
128
131
|
"spec/flydata/fluent-plugins/mysql/binlog_position_spec.rb",
|
129
132
|
"spec/flydata/fluent-plugins/mysql/binlog_query_dispatcher_spec.rb",
|
133
|
+
"spec/flydata/fluent-plugins/mysql/table_meta_spec.rb",
|
130
134
|
"spec/flydata/heroku_spec.rb",
|
131
135
|
"spec/flydata/output/forwarder_spec.rb",
|
132
136
|
"spec/flydata/parser/mysql/alter_table_parser_spec.rb",
|
@@ -139,8 +143,7 @@ Gem::Specification.new do |s|
|
|
139
143
|
]
|
140
144
|
s.homepage = "http://flydata.com/"
|
141
145
|
s.licenses = ["All right reserved."]
|
142
|
-
s.
|
143
|
-
s.rubygems_version = "2.0.14"
|
146
|
+
s.rubygems_version = "2.2.2"
|
144
147
|
s.summary = "FlyData Agent"
|
145
148
|
|
146
149
|
if s.respond_to? :specification_version then
|
data/lib/flydata/command/base.rb
CHANGED
@@ -14,6 +14,7 @@ require_relative 'preference'
|
|
14
14
|
require_relative 'mysql/binlog_position_file'
|
15
15
|
require_relative 'mysql/binlog_record_dispatcher'
|
16
16
|
require_relative 'mysql/context'
|
17
|
+
require_relative 'mysql/table_meta'
|
17
18
|
|
18
19
|
#Monkey-patch fluentd class (EngineClass) to support shutdown for input plugin.
|
19
20
|
#This will be called when USR1 signal is received
|
@@ -69,9 +70,14 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
|
|
69
70
|
end
|
70
71
|
sync_fm = Flydata::FileUtil::SyncFileManager.new(nil) # Passing nil for data_entry as this class does not use methods which require data_entry
|
71
72
|
|
73
|
+
table_meta = Mysql::TableMeta.new(
|
74
|
+
mysql_url: mysql_url, database: @database, tables: @tables)
|
75
|
+
table_meta.update
|
76
|
+
|
72
77
|
@context = Mysql::Context.new(
|
73
78
|
database: @database, tables: @tables,
|
74
|
-
tag: @tag, sync_fm: sync_fm, omit_events: @omit_events
|
79
|
+
tag: @tag, sync_fm: sync_fm, omit_events: @omit_events,
|
80
|
+
table_meta: table_meta,
|
75
81
|
)
|
76
82
|
@record_dispatcher = Mysql::FlydataBinlogRecordDispatcher.new(@context)
|
77
83
|
end
|
@@ -42,25 +42,34 @@ module Mysql
|
|
42
42
|
|
43
43
|
def emit_rows(type, record)
|
44
44
|
emit_record(type, record) do |opt|
|
45
|
+
table_name = record['table_name']
|
45
46
|
records = record["rows"].collect do |row|
|
46
47
|
row = yield(row) if block_given? # Give the caller a chance to generate the correct row
|
47
|
-
{ ROW => convert_to_flydata_row_format(row) }
|
48
|
+
{ ROW => convert_to_flydata_row_format(table_name, row) }
|
48
49
|
end
|
49
50
|
encode_signless_integer(records, record["columns"])
|
50
51
|
records
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
|
-
def convert_to_flydata_row_format(row)
|
55
|
+
def convert_to_flydata_row_format(table_name, row)
|
55
56
|
row.each.with_index(1).inject({}) do |h, (v, i)|
|
56
57
|
if v.kind_of?(String)
|
57
|
-
v =
|
58
|
+
v = encode_row_value(table_name, v)
|
58
59
|
end
|
59
60
|
h[i.to_s] = v
|
60
61
|
h
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
65
|
+
def encode_row_value(table_name, value)
|
66
|
+
if src_encoding = @table_meta[table_name][:encoding]
|
67
|
+
value.encode('utf-8', src_encoding, :undef => :replace, :invalid => :replace)
|
68
|
+
else
|
69
|
+
value.encode('utf-16', :undef => :replace, :invalid => :replace).encode('utf-8')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
64
73
|
def encode_signless_integer(records, column_types)
|
65
74
|
records.each do |record|
|
66
75
|
record[ROW].keys.each do |position|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'mysql2'
|
2
|
+
|
3
|
+
module Mysql
|
4
|
+
class TableMeta
|
5
|
+
MANDATORY_OPTS = [
|
6
|
+
:mysql_url, :database, :tables
|
7
|
+
]
|
8
|
+
OPTIONAL_OPTS = [
|
9
|
+
]
|
10
|
+
|
11
|
+
GET_TABLE_META_SQL = <<EOT
|
12
|
+
SELECT
|
13
|
+
T.table_name as table_name,
|
14
|
+
CCSA.character_set_name as character_set_name
|
15
|
+
FROM
|
16
|
+
information_schema.`TABLES` T,
|
17
|
+
information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
|
18
|
+
WHERE
|
19
|
+
CCSA.collation_name = T.table_collation
|
20
|
+
AND T.table_schema = '%{database}'
|
21
|
+
AND T.table_name in (%{tables});
|
22
|
+
EOT
|
23
|
+
|
24
|
+
def initialize(opts)
|
25
|
+
missing_opts = MANDATORY_OPTS - opts.keys
|
26
|
+
raise "Mandatory option(s) are missing: #{missing_opts.join(', ')}" unless (missing_opts.empty?)
|
27
|
+
@mysql_url = opts[:mysql_url]
|
28
|
+
@database = opts[:database]
|
29
|
+
@tables = opts[:tables]
|
30
|
+
@table_meta = Hash.new{|h, k| h[k] = {}}
|
31
|
+
end
|
32
|
+
|
33
|
+
def update
|
34
|
+
conn = Mysql2::Client.new(@mysql_url)
|
35
|
+
sql = GET_TABLE_META_SQL % {
|
36
|
+
database: @database, tables: @tables.collect{|t| "'#{t}'"}.join(',') }
|
37
|
+
columns = conn.query(sql)
|
38
|
+
columns.collect do |col|
|
39
|
+
@table_meta[col['table_name'].to_sym][:encoding] = get_ruby_charset_name(col['character_set_name'])
|
40
|
+
end
|
41
|
+
ensure
|
42
|
+
conn.close rescue nil if conn
|
43
|
+
end
|
44
|
+
|
45
|
+
# Charset naming conversion rule. mysql => ruby
|
46
|
+
#
|
47
|
+
# mysql
|
48
|
+
# http://dev.mysql.com/doc/refman/5.6/en/charset-charsets.html
|
49
|
+
# mysql(supported CJK character sets)
|
50
|
+
# http://dev.mysql.com/doc/refman/5.6/en/faqs-cjk.html#qandaitem-A-11-1-1
|
51
|
+
# For ruby, you can see encoding list with "Encoding.list"
|
52
|
+
CHARSET_ENCODE_RULE = {
|
53
|
+
'ascii' => nil, # 'ASCII-8BIT', (not need to be encoded)
|
54
|
+
'utf8' => nil, # 'UTF-8', (not need to be encoded)
|
55
|
+
'utf16' => 'UTF-16',
|
56
|
+
'utf32' => 'UTF-32',
|
57
|
+
'latin1' => 'ISO-8859-1',
|
58
|
+
'latin2' => 'ISO-8859-2',
|
59
|
+
'big5' => 'Big5',
|
60
|
+
'cp932' => 'CP932',
|
61
|
+
'eucjpms' => 'eucJP-ms',
|
62
|
+
'euckr' => 'EUC-KR',
|
63
|
+
'gb18030' => 'GB18030',
|
64
|
+
'gb2312' => 'GB2312',
|
65
|
+
'gbk' => 'GBK',
|
66
|
+
'sjis' => 'Shift_JIS',
|
67
|
+
'ujis' => 'EUC-JP',
|
68
|
+
}
|
69
|
+
|
70
|
+
def get_ruby_charset_name(mysql_charset)
|
71
|
+
return nil if mysql_charset.to_s.empty?
|
72
|
+
raise "Unsupported charset:#{mysql_charset}." unless CHARSET_ENCODE_RULE.has_key?(mysql_charset)
|
73
|
+
charset = CHARSET_ENCODE_RULE[mysql_charset]
|
74
|
+
return charset
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return table meta
|
78
|
+
# :character_set_name
|
79
|
+
def [](table_name)
|
80
|
+
@table_meta[table_name.to_sym]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/spec/flydata/cli_spec.rb
CHANGED
@@ -225,6 +225,7 @@ EOT
|
|
225
225
|
setup_initial_flydata_files
|
226
226
|
allow(MysqlBinlogInput::BinlogUtil).to receive(:to_hash) {|e| e}
|
227
227
|
allow(Mysql::BinLogPositionFile).to receive(:new).with(TEST_POSITION_FILE).and_return(binlog_position_file)
|
228
|
+
allow(Mysql::TableMeta).to receive(:update)
|
228
229
|
allow(plugin).to receive(:`).with("mysql -V").and_return("mysql Ver 14.14 Distrib 5.5.40")
|
229
230
|
allow(plugin).to receive(:`).with(/^echo 'select version\(\);'/).and_return("version()\n5.5.40-0ubuntu0.12.04.1-log")
|
230
231
|
Timecop.freeze(now)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'fluent_plugins_spec_helper'
|
2
2
|
require 'flydata/fluent-plugins/mysql/alter_table_query_handler'
|
3
3
|
|
4
4
|
module Mysql
|
@@ -10,11 +10,13 @@ module Mysql
|
|
10
10
|
end
|
11
11
|
let(:database) { "testdb" }
|
12
12
|
let(:table) { "foo" }
|
13
|
+
let(:table_meta) { double'table_meta' }
|
13
14
|
let(:context) do
|
14
15
|
r = double('context')
|
15
16
|
allow(r).to receive(:sync_fm).and_return(sync_fm)
|
16
17
|
allow(r).to receive(:database).and_return([database])
|
17
18
|
allow(r).to receive(:tables).and_return([table])
|
19
|
+
allow(r).to receive(:table_meta).and_return(table_meta)
|
18
20
|
r
|
19
21
|
end
|
20
22
|
subject { described_class.new(context) }
|
@@ -38,7 +40,8 @@ module Mysql
|
|
38
40
|
r
|
39
41
|
end
|
40
42
|
before do
|
41
|
-
|
43
|
+
parser_class = ParserProvider.parser(:mysql, :mysql_alter_table)
|
44
|
+
allow(parser_class).to receive(:new).and_return(parser)
|
42
45
|
allow(subject).to receive(:acceptable_table?).and_return(true)
|
43
46
|
allow(subject).to receive(:acceptable_db?).and_return(true)
|
44
47
|
allow(subject).to receive(:check_empty_binlog)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'fluent_plugins_spec_helper'
|
2
|
+
require 'flydata/fluent-plugins/mysql/table_meta'
|
3
|
+
|
4
|
+
module Mysql
|
5
|
+
describe TableMeta do
|
6
|
+
let(:mysql_url) { double('mysql_url') }
|
7
|
+
let(:database) { 'test-db' }
|
8
|
+
let(:tables) { %w(a_table b_table c_table) }
|
9
|
+
|
10
|
+
let(:conn) { double('conn') }
|
11
|
+
let(:table_meta) { TableMeta.new(
|
12
|
+
mysql_url: mysql_url, database: database, tables: tables) }
|
13
|
+
|
14
|
+
before do
|
15
|
+
allow(conn).to receive(:close)
|
16
|
+
allow(Mysql2::Client).to receive(:new).and_return(conn)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.update' do
|
20
|
+
let(:query_result) {[]}
|
21
|
+
before do
|
22
|
+
allow(conn).to receive(:query).and_return(query_result)
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when character_set_name is supported' do
|
26
|
+
context 'when encoding is not necessary' do
|
27
|
+
let(:query_result) {[
|
28
|
+
{'table_name' => 'a_table', 'character_set_name' => 'utf8' }
|
29
|
+
]}
|
30
|
+
it 'set nil for encoding' do
|
31
|
+
table_meta.update
|
32
|
+
expect(table_meta['a_table'][:encoding]).to be_nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when encoding is needed' do
|
37
|
+
let(:query_result) {[
|
38
|
+
{'table_name' => 'a_table', 'character_set_name' => 'latin1' },
|
39
|
+
{'table_name' => 'b_table', 'character_set_name' => 'cp932' }
|
40
|
+
]}
|
41
|
+
it 'set ruby encoding encoding' do
|
42
|
+
table_meta.update
|
43
|
+
expect(table_meta['a_table'][:encoding]).to eq('ISO-8859-1')
|
44
|
+
expect(table_meta['b_table'][:encoding]).to eq('CP932')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when character_set_name is not supported' do
|
50
|
+
let(:query_result) {[
|
51
|
+
{'table_name' => 'a_table', 'character_set_name' => 'xxxx' }
|
52
|
+
]}
|
53
|
+
it 'raise an error' do
|
54
|
+
expect{table_meta.update}.to raise_error('Unsupported charset:xxxx.')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flydata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koichi Fujikawa
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-12-
|
15
|
+
date: 2014-12-12 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rest-client
|
@@ -485,6 +485,7 @@ files:
|
|
485
485
|
- lib/flydata/fluent-plugins/mysql/context.rb
|
486
486
|
- lib/flydata/fluent-plugins/mysql/ddl_query_handler.rb
|
487
487
|
- lib/flydata/fluent-plugins/mysql/dml_record_handler.rb
|
488
|
+
- lib/flydata/fluent-plugins/mysql/table_meta.rb
|
488
489
|
- lib/flydata/fluent-plugins/out_forward_ssl.rb
|
489
490
|
- lib/flydata/fluent-plugins/preference.rb
|
490
491
|
- lib/flydata/flydata_crontab.sh
|
@@ -512,6 +513,7 @@ files:
|
|
512
513
|
- spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb
|
513
514
|
- spec/flydata/fluent-plugins/mysql/binlog_position_spec.rb
|
514
515
|
- spec/flydata/fluent-plugins/mysql/binlog_query_dispatcher_spec.rb
|
516
|
+
- spec/flydata/fluent-plugins/mysql/table_meta_spec.rb
|
515
517
|
- spec/flydata/heroku_spec.rb
|
516
518
|
- spec/flydata/output/forwarder_spec.rb
|
517
519
|
- spec/flydata/parser/mysql/alter_table_parser_spec.rb
|
@@ -541,7 +543,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
541
543
|
version: '0'
|
542
544
|
requirements: []
|
543
545
|
rubyforge_project:
|
544
|
-
rubygems_version: 2.
|
546
|
+
rubygems_version: 2.2.2
|
545
547
|
signing_key:
|
546
548
|
specification_version: 4
|
547
549
|
summary: FlyData Agent
|