embulk-output-bigobject 0.2.8 → 0.3.0

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: 03d0eda74a099f6b37f90a96d23cfa4eea9da2b4
4
- data.tar.gz: c54cab398511de5290c0a36cf46709cfe76967ee
3
+ metadata.gz: 43abe5dc1730fe8a446ddeed77a4de07f514c89c
4
+ data.tar.gz: df2bee768096c9abdfe944e6137e934aa2b66e96
5
5
  SHA512:
6
- metadata.gz: 29126af1038a32a65246b50679fe005d2c1dde141d5de96b5a7bffad1a12b3e36692fc38849e5499b8f0bbeec44f9c53e234b2d680ca104dad0d42bf55153d0e
7
- data.tar.gz: eaf4267a3554f840ca863ba3fc4c9aae13ea573cc727b02e096b6fe875ce58c9207f8d72894b7d6d8701083cc7ff532be00af214f41fb36bf0b93760e4d492d5
6
+ metadata.gz: 4cfa4216e75df1bb68990700e529a3477d6a5f0c1eecdfbb91df1b70e9e4681c73525999019031269776b3c94679321ef0079952b879d27b2b0625d7dceefa5f
7
+ data.tar.gz: 8aa257ce70a52b46b3cf3f4cb6e2cda9d734678cf7636e03582a84ad918e2bbe08f17438c4504f89983669aab47d794b87b2808a47430fd0e59a288f721edef3
data/Gemfile CHANGED
File without changes
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
@@ -17,8 +17,9 @@ embulk gem install embulk-output-bigobject
17
17
 
18
18
  ## Configuration
19
19
 
20
- - **host**: database host name (string, required)
21
- - **port**: database port number (integer, default: 9090)
20
+ - **host**: database host name (string, default: localhost)
21
+ - **restport**: database port number (integer, default: 9090)
22
+ - **ncport**: database port number (integer, default: 9090)
22
23
  - **table**: database table name (string, required)
23
24
 
24
25
  ## Example
@@ -28,6 +29,11 @@ out:
28
29
  type: bigobject
29
30
  host: localhost
30
31
  table: mytest
32
+ column_options:
33
+ - {name: "col1", type: 'INT64', is_key: true}
34
+ - {name: "col2", type: 'BYTE', is_key: true}
35
+ - {name: "col3", type: 'DATE32'}
36
+ - {name: "col4", type: 'STRING(16)'}
31
37
  ```
32
38
 
33
39
 
data/Rakefile CHANGED
File without changes
@@ -1,11 +1,11 @@
1
1
 
2
2
  Gem::Specification.new do |spec|
3
3
  spec.name = "embulk-output-bigobject"
4
- spec.version = "0.2.8"
5
- spec.authors = ["randyviola"]
4
+ spec.version = "0.3.0"
5
+ spec.authors = ["cchuang"]
6
6
  spec.summary = "Bigobject output plugin for Embulk"
7
7
  spec.description = "Dumps records to Bigobject."
8
- spec.email = ["randyh0329@gmail.com"]
8
+ spec.email = ["cchuang.tw@gmail.com"]
9
9
  spec.licenses = ["MIT"]
10
10
  spec.homepage = "https://github.com/bigobject-inc/embulk-output-bigobject"
11
11
 
@@ -13,9 +13,9 @@ Gem::Specification.new do |spec|
13
13
  spec.test_files = spec.files.grep(%r{^(test|spec)/})
14
14
  spec.require_paths = ["lib"]
15
15
 
16
- spec.add_dependency 'rest-client', ['~> 1.8.0']
17
- spec.add_development_dependency 'rest-client', ['~> 1.8.0']
18
- spec.add_development_dependency 'embulk', ['~> 0.7.10']
19
- spec.add_development_dependency 'bundler', ['~> 1.0']
20
- spec.add_development_dependency 'rake', ['>= 10.0']
16
+ spec.add_dependency 'rest-client', ['>= 1.8.0']
17
+ #spec.add_development_dependency 'rest-client', ['>= 1.8.0']
18
+ spec.add_development_dependency 'embulk', ['>= 0.8.9']
19
+ spec.add_development_dependency 'bundler', ['>= 1.10.6']
20
+ spec.add_development_dependency 'rake', ['>= 10.5.0']
21
21
  end
@@ -1,37 +1,55 @@
1
1
  module Embulk
2
+
2
3
  module Output
3
4
 
4
5
  class Bigobject < OutputPlugin
5
6
 
6
7
  require 'rest-client'
7
8
  require 'json'
9
+ require 'socket'
8
10
 
9
11
  Plugin.register_output("bigobject", self)
10
12
 
11
- def self.transaction(config, schema, count, &control)
13
+ def self.configure(config, schema, count)
12
14
  # configuration code:
13
15
  task = {
14
- "host" => config.param("host", :string), # string, required
15
- "port" => config.param("port", :integer, default: 9090), # integer, optional
16
- "table" => config.param("table", :string), # string, required
16
+ "host" => config.param("host", :string, :default => "localhost"), # string, optional
17
+ "restport" => config.param("restport", :integer, :default => 9090), # integer, optional
18
+ "ncport" => config.param("ncport", :integer, :default => 9091), # integer, optional
19
+ "table" => config.param("table", :string), # string, required
20
+ "column_options" => config.param("column_options", :array, :default => []),
17
21
  }
18
22
 
19
- @@bo_url = "http://#{task['host']}:#{task['port']}/cmd".freeze
20
- @@ttlcounter = 0
23
+ task
24
+ end
25
+
26
+ def self.column_options_map(column_options)
27
+ (column_options || {}).map do |column_option|
28
+ [column_option['name'], column_option]
29
+ end.to_h
30
+ end
31
+
32
+ def self.transaction(config, schema, count, &control)
33
+ task = self.configure(config, schema, count)
34
+ task['co_map'] = self.column_options_map task["column_options"]
35
+ task['rest_uri'] = "http://#{task['host']}:#{task['restport']}/cmd".freeze
36
+ task['ttl_counter'] = 0
21
37
 
38
+ Embulk.logger.debug { "Transaction #{count}" }
22
39
  # resumable output:
23
40
  # resume(task, schema, count, &control)
24
41
 
25
- # Create Table if not exists
26
- response = send_stmt2borest("desc #{task['table']}") # check table
27
- if response["Status"] == 0 then # table exist
28
- Embulk.logger.debug { "#{response}" }
29
- elsif response["Status"] == -11 then # table not exist
30
- response = send_stmt2borest("#{create_botable_stmt("#{task['table']}",schema)}")
31
- if response["Status"] != 0 then
32
- Embulk.logger.error { "#{response}" }
33
- raise "Create table #{task['table']} in BigObject Failed"
34
- end
42
+ # Create-Table if it does not exist
43
+ response = rest_exec(task['rest_uri'], "desc #{task['table']}") # check table
44
+ if response["Status"] == 0 then # the table exists
45
+ Embulk.logger.debug { "#{response}" }
46
+ elsif response["Status"] == -11 then # the table does not exist
47
+ response = rest_exec(task['rest_uri'], "#{create_botable_stmt("#{task['table']}",schema, task['co_map'])}")
48
+ if response["Status"] != 0 then
49
+ Embulk.logger.error { "#{response}" }
50
+ raise "Create table #{task['table']} in BigObject Failed"
51
+ end
52
+ Embulk.logger.info { "embulk-output-bigobject: Create table #{task['table']}" }
35
53
  else # should not be here
36
54
  Embulk.logger.error { "#{response}" }
37
55
  raise "Please check table #{task['table']} in BigObject First"
@@ -43,6 +61,22 @@ module Embulk
43
61
  return next_config_diff
44
62
  end
45
63
 
64
+ def safe_io_puts(buff)
65
+ @@io ||= create_shared_io
66
+ @@mutext ||= Mutex.new
67
+ @@mutext.synchronize do
68
+ @@io.puts buff
69
+ end
70
+ end
71
+
72
+ def create_shared_io
73
+ io = TCPSocket.new @task['host'], @task['ncport']
74
+ #@@io = File.new "embulkout.dump", "w"
75
+ io.write "csv\x01"
76
+ io.puts @task['table']
77
+ io
78
+ end
79
+
46
80
  #def self.resume(task, schema, count, &control)
47
81
  # task_reports = yield(task)
48
82
  #
@@ -50,7 +84,10 @@ module Embulk
50
84
  # return next_config_diff
51
85
  #end
52
86
 
53
- def init
87
+ def initialize(task, schema, index)
88
+ super
89
+
90
+ # Embulk.logger.debug { "Initialize #{index}" }
54
91
  # initialization code:
55
92
  @table = task["table"]
56
93
  @counter = 0
@@ -62,26 +99,20 @@ module Embulk
62
99
  def add(page)
63
100
  # output code:
64
101
 
65
- data = Array.new
102
+ #data = Array.new
66
103
  values = Array.new
104
+ count = 0
67
105
 
68
106
  page.each do |records|
69
107
  values = []
70
108
  records.each do |row| values << "#{row}".to_json end
71
- data.push("(#{values.join(",")})")
109
+ #data.push("(#{values.join(",")})")
110
+ safe_io_puts "#{values.join(",")}"
111
+ count += 1
72
112
  end
73
113
 
74
- @counter += data.length
75
- @@ttlcounter += data.length
76
-
77
- Embulk.logger.trace { "INSERT INTO #@table VALUES #{data.join(",")}" }
78
- rsp = self.class.send_stmt2borest("INSERT INTO #@table VALUES #{data.join(",")}")
79
- if rsp["Status"] == 0 then
80
- Embulk.logger.debug { "add #{data.length} to BigObject - #@counter | #@@ttlcounter" }
81
- else
82
- Embulk.logger.error { "add #{data.length} to BigObject failed!!" }
83
- abort
84
- end
114
+ @counter += count
115
+ @task['ttl_counter'] += count
85
116
 
86
117
  end
87
118
 
@@ -99,21 +130,43 @@ module Embulk
99
130
  return task_report
100
131
  end
101
132
 
102
- def self.send_stmt2borest(stmt)
133
+ def self.rest_exec(uri, stmt)
103
134
  begin
104
- response = RestClient.post @@bo_url, { "Stmt" => "#{stmt}" }.to_json, :content_type => :json, :accept => :json
135
+ response = RestClient.post uri, { "Stmt" => "#{stmt}" }.to_json, :content_type => :json, :accept => :json, :timeout => 2
105
136
  JSON.parse(response.body)
106
- rescue Exception => e
107
- Embulk.logger.error { e }
137
+ rescue RestClient::Exception => e
138
+ #Embulk.logger.error { "RestClient: #{e.http_code}, #{e.message}, response: #{e.response}" }
139
+ Embulk.logger.warn { "Timeout: statement: #{stmt}" }
140
+ begin
141
+ response = RestClient.post uri, { "Stmt" => "#{stmt}" }.to_json, :content_type => :json, :accept => :json, :timeout => 4
142
+ JSON.parse(response.body)
143
+ rescue RestClient::Exception => e2
144
+ Embulk.logger.error { "RestClient: #{e2.http_code}, #{e2.message}, response: #{e2.response}" }
145
+ end
146
+ rescue JSON::Exception => e
147
+ Embulk.logger.error { "JSON: #{e.message}" }
108
148
  end
109
149
  end
110
150
 
111
- def self.create_botable_stmt(tbl,schema)
112
- bo_table_schema = schema.map {|column| "#{column.name} #{to_bigobject_column_type(column.type.to_s, column.format.to_s)}" }.join(',')
113
- "CREATE TABLE #{tbl} (#{bo_table_schema})"
151
+ def self.create_botable_stmt(tbl,schema, cos)
152
+ Embulk.logger.debug {"schema: #{schema}"}
153
+ bo_table_schema = schema.map {|column| "#{column.name} #{to_bigobject_column_type(column.type.to_s, column.format.to_s, cos[column.name])}" }.join(',')
154
+ keys = Array.new
155
+ cos.each do |k, co|
156
+ keys.push co["name"] if co["is_key"]
157
+ end
158
+ if keys.length == 0
159
+ "CREATE TABLE #{tbl} (#{bo_table_schema})"
160
+ else
161
+ "CREATE TABLE #{tbl} (#{bo_table_schema} KEY(#{keys.join(',')}))"
162
+ end
114
163
  end
115
164
 
116
- def self.to_bigobject_column_type(type, format)
165
+ def self.to_bigobject_column_type(type, format, co)
166
+ co = co || {}
167
+ Embulk.logger.debug {"type: #{type}, format #{format}, option #{co}"}
168
+ return co["type"] if co["type"]
169
+
117
170
  case type
118
171
  when 'long'
119
172
  botype = :INT64
metadata CHANGED
@@ -1,88 +1,74 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-output-bigobject
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - randyviola
7
+ - cchuang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-18 00:00:00.000000000 Z
11
+ date: 2016-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.8.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: 1.8.0
27
- - !ruby/object:Gem::Dependency
28
- name: rest-client
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ~>
32
- - !ruby/object:Gem::Version
33
- version: 1.8.0
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ~>
24
+ - - ">="
39
25
  - !ruby/object:Gem::Version
40
26
  version: 1.8.0
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: embulk
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
- - - ~>
31
+ - - ">="
46
32
  - !ruby/object:Gem::Version
47
- version: 0.7.10
33
+ version: 0.8.9
48
34
  type: :development
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
- - - ~>
38
+ - - ">="
53
39
  - !ruby/object:Gem::Version
54
- version: 0.7.10
40
+ version: 0.8.9
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: bundler
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
- - - ~>
45
+ - - ">="
60
46
  - !ruby/object:Gem::Version
61
- version: '1.0'
47
+ version: 1.10.6
62
48
  type: :development
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
- - - ~>
52
+ - - ">="
67
53
  - !ruby/object:Gem::Version
68
- version: '1.0'
54
+ version: 1.10.6
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rake
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
- - - '>='
59
+ - - ">="
74
60
  - !ruby/object:Gem::Version
75
- version: '10.0'
61
+ version: 10.5.0
76
62
  type: :development
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
- - - '>='
66
+ - - ">="
81
67
  - !ruby/object:Gem::Version
82
- version: '10.0'
68
+ version: 10.5.0
83
69
  description: Dumps records to Bigobject.
84
70
  email:
85
- - randyh0329@gmail.com
71
+ - cchuang.tw@gmail.com
86
72
  executables: []
87
73
  extensions: []
88
74
  extra_rdoc_files: []
@@ -103,17 +89,17 @@ require_paths:
103
89
  - lib
104
90
  required_ruby_version: !ruby/object:Gem::Requirement
105
91
  requirements:
106
- - - '>='
92
+ - - ">="
107
93
  - !ruby/object:Gem::Version
108
94
  version: '0'
109
95
  required_rubygems_version: !ruby/object:Gem::Requirement
110
96
  requirements:
111
- - - '>='
97
+ - - ">="
112
98
  - !ruby/object:Gem::Version
113
99
  version: '0'
114
100
  requirements: []
115
101
  rubyforge_project:
116
- rubygems_version: 2.0.14
102
+ rubygems_version: 2.5.1
117
103
  signing_key:
118
104
  specification_version: 4
119
105
  summary: Bigobject output plugin for Embulk