fluent-plugin-mysql-bulk 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e1f4635f23f11af148bbb46bffb0191992a1dd44
4
- data.tar.gz: cce2ab34d60e853b727c53f51d5bb1c48b2d56ff
3
+ metadata.gz: 86de300a43868df18918561c887617eecf22354c
4
+ data.tar.gz: 2fef1cc8fe51e087a5f6a71a561fda00dc8b438f
5
5
  SHA512:
6
- metadata.gz: 3666e01d6c87578447e656dec0cd9937cb7e50de564e63e20e2046a940b761d37a4ca14a7d481715a9e6ec5d555e4b4ec7ad0c2decb3519fa4787ad8194cd4d9
7
- data.tar.gz: 96cafee91c3690fd8a86db4d64e4a0ea6b819a27b582354f27abdbf5c6e1bd4ed44f193a0905c79b1d345ddb1ff6d990ababc6de9390937b2b920aaa9c4c3af7
6
+ metadata.gz: d37c300044121019994ce5fb752fad6f12c5a6f14268faf60f5b4d1994e1bd7aabb79b913d5841c0bfe7c84623cb617a23dc52016e39ed294b7695d972198c49
7
+ data.tar.gz: cf4c3176eb6420c7b324927bd971cc44fa1c79038664bc60a7c6239d6540ed4f138b08a4eeadd3c63710ef5021efd415342720f408f7c9b3101a88cb62fc62bb
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ test.conf
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - 2.0.0
5
+ gemfile:
6
+ - Gemfile
7
+ script: "rake test"
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Hiroshi Toyama
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,179 @@
1
+
2
+ # fluent-plugin-mysql-bulk [![Build Status](https://secure.travis-ci.org/toyama0919/fluent-plugin-mysql-bulk.png?branch=master)](http://travis-ci.org/toyama0919/fluent-plugin-mysql-bulk)
3
+
4
+ fluent plugin mysql bulk insert is high performance and on duplicate key update respond.
5
+
6
+ ## Installation
7
+
8
+ ### td-agent(Linux)
9
+
10
+ /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-mysql-bulk
11
+
12
+ ### td-agent(Mac)
13
+
14
+ sudo /usr/local/Cellar/td-agent/1.1.XX/bin/fluent-gem install fluent-plugin-mysql-bulk
15
+
16
+ ### fluentd only
17
+
18
+ gem install fluent-plugin-mysql-bulk
19
+
20
+
21
+ ## Parameters
22
+
23
+ param|value
24
+ --------|------
25
+ host|database host(default: 127.0.0.1)
26
+ database|database name(require)
27
+ username|user(require)
28
+ password|password(default: blank)
29
+ column_names|bulk insert column (require)
30
+ key_names|value key names (default : column_names)
31
+ table|bulk insert table (require)
32
+ on_duplicate_key_update|on duplicate key update enable (true:false)
33
+ on_duplicate_update_keys|on duplicate key update column, comma separator
34
+
35
+ ## Configuration Example(bulk insert)
36
+
37
+ ```
38
+ <match mysql.input>
39
+ type mysql_bulk
40
+ host localhost
41
+ database test_app_development
42
+ username root
43
+ password hogehoge
44
+ column_names id,user_name,created_at,updated_at
45
+ table users
46
+ flush_interval 10s
47
+ </match>
48
+ ```
49
+
50
+ Assume following input is coming:
51
+
52
+ ```js
53
+ mysql.input: {"user_name":"toyama","created_at":"2014/01/03 21:35:15","updated_at":"2014/01/03 21:35:15","dummy":"hogehoge"}
54
+ mysql.input: {"user_name":"toyama2","created_at":"2014/01/03 21:35:21","updated_at":"2014/01/03 21:35:21","dummy":"hogehoge"}
55
+ mysql.input: {"user_name":"toyama3","created_at":"2014/01/03 21:35:27","updated_at":"2014/01/03 21:35:27","dummy":"hogehoge"}
56
+ ```
57
+
58
+ then result becomes as below (indented):
59
+
60
+ ```sql
61
+ +-----+-----------+---------------------+---------------------+
62
+ | id | user_name | created_at | updated_at |
63
+ +-----+-----------+---------------------+---------------------+
64
+ | 1 | toyama | 2014-01-03 21:35:15 | 2014-01-03 21:35:15 |
65
+ | 2 | toyama2 | 2014-01-03 21:35:21 | 2014-01-03 21:35:21 |
66
+ | 3 | toyama3 | 2014-01-03 21:35:27 | 2014-01-03 21:35:27 |
67
+ +-----+-----------+---------------------+---------------------+
68
+ ```
69
+
70
+ running query
71
+
72
+ ```sql
73
+ INSERT INTO users (id,user_name,created_at,updated_at) VALUES (NULL,'toyama','2014/01/03 21:35:15','2014/01/03 21:35:15'),(NULL,'toyama2','2014/01/03 21:35:21','2014/01/03 21:35:21')
74
+ ```
75
+
76
+ ## Configuration Example(bulk insert , if duplicate error record update)
77
+
78
+ ```
79
+ <match mysql.input>
80
+ type mysql_bulk
81
+ host localhost
82
+ database test_app_development
83
+ username root
84
+ password hogehoge
85
+ column_names id,user_name,created_at,updated_at
86
+ table users
87
+ on_duplicate_key_update true
88
+ on_duplicate_update_keys user_name,updated_at
89
+ flush_interval 60s
90
+ </match>
91
+ ```
92
+
93
+ Assume following input is coming:
94
+
95
+ ```js
96
+ mysql.input: {"id":"1" ,"user_name":"toyama7","created_at":"2014/01/03 21:58:03","updated_at":"2014/01/03 21:58:03"}
97
+ mysql.input: {"id":"2" ,"user_name":"toyama7","created_at":"2014/01/03 21:58:06","updated_at":"2014/01/03 21:58:06"}
98
+ mysql.input: {"id":"3" ,"user_name":"toyama7","created_at":"2014/01/03 21:58:08","updated_at":"2014/01/03 21:58:08"}
99
+ mysql.input: {"id":"10","user_name":"toyama7","created_at":"2014/01/03 21:58:18","updated_at":"2014/01/03 21:58:18"}
100
+ ```
101
+
102
+ then result becomes as below (indented):
103
+
104
+ ```sql
105
+ +-----+-----------+---------------------+---------------------+
106
+ | id | user_name | created_at | updated_at |
107
+ +-----+-----------+---------------------+---------------------+
108
+ | 1 | toyama7 | 2014-01-03 21:35:15 | 2014-01-03 21:58:03 |
109
+ | 2 | toyama7 | 2014-01-03 21:35:21 | 2014-01-03 21:58:06 |
110
+ | 3 | toyama7 | 2014-01-03 21:35:27 | 2014-01-03 21:58:08 |
111
+ | 10 | toyama7 | 2014-01-03 21:58:18 | 2014-01-03 21:58:18 |
112
+ +-----+-----------+---------------------+---------------------+
113
+ ```
114
+
115
+ if duplicate id , update username and updated_at
116
+
117
+
118
+ ## Configuration Example(bulk insert,fluentd key different column name)
119
+
120
+ ```
121
+ <match mysql.input>
122
+ type mysql_bulk
123
+ host localhost
124
+ database test_app_development
125
+ username root
126
+ password hogehoge
127
+ column_names id,user_name,created_at,updated_at
128
+ key_names id,user,created_date,updated_date
129
+ table users
130
+ flush_interval 10s
131
+ </match>
132
+ ```
133
+
134
+ Assume following input is coming:
135
+
136
+ ```js
137
+ mysql.input: {"user":"toyama","created_date":"2014/01/03 21:35:15","updated_date":"2014/01/03 21:35:15","dummy":"hogehoge"}
138
+ mysql.input: {"user":"toyama2","created_date":"2014/01/03 21:35:21","updated_date":"2014/01/03 21:35:21","dummy":"hogehoge"}
139
+ mysql.input: {"user":"toyama3","created_date":"2014/01/03 21:35:27","updated_date":"2014/01/03 21:35:27","dummy":"hogehoge"}
140
+ ```
141
+
142
+ then result becomes as below (indented):
143
+
144
+ ```sql
145
+ +-----+-----------+---------------------+---------------------+
146
+ | id | user_name | created_at | updated_at |
147
+ +-----+-----------+---------------------+---------------------+
148
+ | 1 | toyama | 2014-01-03 21:35:15 | 2014-01-03 21:35:15 |
149
+ | 2 | toyama2 | 2014-01-03 21:35:21 | 2014-01-03 21:35:21 |
150
+ | 3 | toyama3 | 2014-01-03 21:35:27 | 2014-01-03 21:35:27 |
151
+ +-----+-----------+---------------------+---------------------+
152
+ ```
153
+
154
+
155
+
156
+
157
+ ## spec
158
+
159
+ ```
160
+ bundle install
161
+ rake test
162
+ ```
163
+
164
+ ## todo
165
+
166
+ divide bulk insert(exsample 1000 per)
167
+
168
+
169
+ ## Contributing
170
+
171
+ 1. Fork it
172
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
173
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
174
+ 4. Push to the branch (`git push origin my-new-feature`)
175
+ 5. Create new [Pull Request](../../pull/new/master)
176
+
177
+ ## Copyright
178
+
179
+ Copyright (c) 2013 Hiroshi Toyama. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/test_*.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ Gem::Specification.new do |gem|
3
+ gem.name = "fluent-plugin-mysql-bulk"
4
+ gem.version = "0.0.2"
5
+ gem.authors = ["Toyama Hiroshi"]
6
+ gem.email = ["toyama0919@gmail.com"]
7
+ gem.description = %q{fluent plugin mysql bulk insert is high performance and on duplicate key update respond.}
8
+ gem.summary = %q{fluent plugin mysql bulk insert is high performance and on duplicate key update respond.}
9
+ gem.homepage = "https://github.com/toyama0919/fluent-plugin-mysql-bulk"
10
+ gem.licenses = ["MIT"]
11
+ gem.has_rdoc = false
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_runtime_dependency "fluentd"
19
+ gem.add_runtime_dependency "mysql2-cs-bind"
20
+ gem.add_development_dependency "bundler", "~> 1.3"
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "rspec"
23
+ gem.add_development_dependency "spork"
24
+ gem.add_development_dependency "pry"
25
+
26
+ end
@@ -0,0 +1,94 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Fluent
3
+ class Fluent::MysqlBulkOutput < Fluent::BufferedOutput
4
+ Fluent::Plugin.register_output('mysql_bulk', self)
5
+
6
+ config_param :host, :string, :default => "127.0.0.1"
7
+ config_param :port, :integer, :default => 3306
8
+ config_param :database, :string
9
+ config_param :username, :string
10
+ config_param :password, :string, :default => ''
11
+
12
+ config_param :column_names, :string
13
+ config_param :key_names, :string, :default => nil
14
+ config_param :table, :string
15
+
16
+ config_param :on_duplicate_key_update, :bool, :default => false
17
+ config_param :on_duplicate_update_keys, :string, :default => nil
18
+
19
+ attr_accessor :handler
20
+
21
+ def initialize
22
+ super
23
+ require 'mysql2-cs-bind'
24
+ end
25
+
26
+ def configure(conf)
27
+ super
28
+
29
+ if @column_names.nil?
30
+ raise Fluent::ConfigError, "column_names MUST be specified, but missing"
31
+ end
32
+
33
+ if @on_duplicate_key_update
34
+ if @on_duplicate_update_keys.nil?
35
+ raise Fluent::ConfigError, "on_duplicate_key_update = true , on_duplicate_update_keys nil!"
36
+ end
37
+ @on_duplicate_update_keys = @on_duplicate_update_keys.split(',')
38
+
39
+ @on_duplicate_key_update_sql = " ON DUPLICATE KEY UPDATE "
40
+ updates = []
41
+ @on_duplicate_update_keys.each{|update_column|
42
+ updates.push(" #{update_column} = VALUES(#{update_column})")
43
+ }
44
+ @on_duplicate_key_update_sql += updates.join(',')
45
+ end
46
+
47
+ @column_names = @column_names.split(',')
48
+ @key_names = @key_names.nil? ? @column_names : @key_names.split(',')
49
+ @format_proc = Proc.new{|tag, time, record| @key_names.map{|k| record[k]}}
50
+
51
+ end
52
+
53
+ def start
54
+ @handler = client
55
+ super
56
+ end
57
+
58
+ def shutdown
59
+ super
60
+ end
61
+
62
+ def format(tag, time, record)
63
+ [tag, time, @format_proc.call(tag, time, record)].to_msgpack
64
+ end
65
+
66
+ def client
67
+ Mysql2::Client.new({
68
+ :host => @host,
69
+ :port => @port,
70
+ :username => @username,
71
+ :password => @password,
72
+ :database => @database,
73
+ :flags => Mysql2::Client::MULTI_STATEMENTS
74
+ })
75
+ end
76
+
77
+ def write(chunk)
78
+ values_templates = []
79
+ values = Array.new
80
+ chunk.msgpack_each { |tag, time, data|
81
+ values_templates.push "(#{@column_names.map{|key| '?'}.join(',')})"
82
+ values.concat(data)
83
+ }
84
+ sql = "INSERT INTO #{@table} (#{@column_names.join(',')}) VALUES #{values_templates.join(',')}"
85
+ if @on_duplicate_key_update
86
+ sql += @on_duplicate_key_update_sql
87
+ end
88
+
89
+ $log.info "bulk insert sql => [#{Mysql2::Client.pseudo_bind(sql, values)}]"
90
+ @handler.xquery(sql, values)
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ end
20
+ }
21
+ $log = nulllogger
22
+ end
23
+
24
+ require 'fluent/plugin/out_mysql_bulk'
25
+
26
+ class Test::Unit::TestCase
27
+ end
@@ -0,0 +1,107 @@
1
+ require 'helper'
2
+ require 'mysql2-cs-bind'
3
+
4
+ class MysqlBulkOutputTest < Test::Unit::TestCase
5
+ def setup
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ def create_driver(conf = CONFIG, tag='test')
10
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::MysqlBulkOutput, tag).configure(conf)
11
+ end
12
+
13
+ def test_configure_error
14
+
15
+ assert_raise(Fluent::ConfigError) {
16
+ d = create_driver %[
17
+ host localhost
18
+ database test_app_development
19
+ username root
20
+ password hogehoge
21
+ table users
22
+ on_duplicate_key_update true
23
+ on_duplicate_update_keys user_name,updated_at
24
+ flush_interval 10s
25
+ ]
26
+ }
27
+
28
+ assert_raise(Fluent::ConfigError) {
29
+ d = create_driver %[
30
+ host localhost
31
+ database test_app_development
32
+ username root
33
+ password hogehoge
34
+ column_names id,user_name,created_at,updated_at
35
+ table users
36
+ on_duplicate_key_update true
37
+ flush_interval 10s
38
+ ]
39
+ }
40
+
41
+ assert_raise(Fluent::ConfigError) {
42
+ d = create_driver %[
43
+ host localhost
44
+ username root
45
+ password hogehoge
46
+ column_names id,user_name,created_at,updated_at
47
+ table users
48
+ on_duplicate_key_update true
49
+ on_duplicate_update_keys user_name,updated_at
50
+ flush_interval 10s
51
+ ]
52
+ }
53
+ end
54
+
55
+ def test_configure
56
+ # not define format(default csv)
57
+ assert_nothing_raised(Fluent::ConfigError) {
58
+ d = create_driver %[
59
+ host localhost
60
+ database test_app_development
61
+ username root
62
+ password hogehoge
63
+ column_names id,user_name,created_at,updated_at
64
+ table users
65
+ on_duplicate_key_update true
66
+ on_duplicate_update_keys user_name,updated_at
67
+ flush_interval 10s
68
+ ]
69
+ }
70
+
71
+ assert_nothing_raised(Fluent::ConfigError) {
72
+ d = create_driver %[
73
+ database test_app_development
74
+ username root
75
+ password hogehoge
76
+ column_names id,user_name,created_at,updated_at
77
+ table users
78
+ ]
79
+ }
80
+
81
+ assert_nothing_raised(Fluent::ConfigError) {
82
+ d = create_driver %[
83
+ database test_app_development
84
+ username root
85
+ password hogehoge
86
+ column_names id,user_name,created_at,updated_at
87
+ table users
88
+ on_duplicate_key_update true
89
+ on_duplicate_update_keys user_name,updated_at
90
+ ]
91
+ }
92
+
93
+ assert_nothing_raised(Fluent::ConfigError) {
94
+ d = create_driver %[
95
+ database test_app_development
96
+ username root
97
+ password hogehoge
98
+ column_names id,user_name,created_at,updated_at
99
+ key_names id,user,created_date,updated_date
100
+ table users
101
+ on_duplicate_key_update true
102
+ on_duplicate_update_keys user_name,updated_at
103
+ ]
104
+ }
105
+ end
106
+
107
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-mysql-bulk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toyama Hiroshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-03 00:00:00.000000000 Z
11
+ date: 2014-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -115,7 +115,17 @@ email:
115
115
  executables: []
116
116
  extensions: []
117
117
  extra_rdoc_files: []
118
- files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".travis.yml"
121
+ - Gemfile
122
+ - LICENSE
123
+ - README.md
124
+ - Rakefile
125
+ - fluent-plugin-mysql-bulk.gemspec
126
+ - lib/fluent/plugin/out_mysql_bulk.rb
127
+ - test/helper.rb
128
+ - test/plugin/test_out_mysql_bulk.rb
119
129
  homepage: https://github.com/toyama0919/fluent-plugin-mysql-bulk
120
130
  licenses:
121
131
  - MIT
@@ -141,4 +151,6 @@ signing_key:
141
151
  specification_version: 4
142
152
  summary: fluent plugin mysql bulk insert is high performance and on duplicate key
143
153
  update respond.
144
- test_files: []
154
+ test_files:
155
+ - test/helper.rb
156
+ - test/plugin/test_out_mysql_bulk.rb