bricolage 5.14.0 → 5.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5bb93d5d2f2b8100f394fefef4df4a0312e612a4
4
- data.tar.gz: a961533ace5a56216757ab3c99666780922511ac
3
+ metadata.gz: f55cd961f8a67911b9ceb8383202dbf5a4bc5eac
4
+ data.tar.gz: 5ea072313fd1a0a7455a57e02ae8a38579c1d8ef
5
5
  SHA512:
6
- metadata.gz: 7d5e13b4683b83f850ebca170c0ba4f00917874f386d95d16b5764d63625be388de3940a3f8be6b07a19bb000b9da3c024aa05c4795d48067efc81b672ada610
7
- data.tar.gz: 68d542616e8a6826c0e9bddc33afd9744b449c7ee218610d65750186915ec51913f8144c8155bb083feb80b17ee086eafdc5c7dec07f16db012912d8546c5fba
6
+ metadata.gz: 43b49955f3739925b6c92e84f72fde9457d2f72a10034316f2fec0a44cbde62cdfd9072ae29048023092a3662bcae16733339a72429061159898740db2f3e15f
7
+ data.tar.gz: 397a51bc3f114ca552ee3441992ef7311e38c5cb081cde01acece6d2e0daa2db7cb8c35f7a3d7ab374c40dd6ab9123f05ffe389efc0b5d7a6cec281dc4188642
@@ -0,0 +1,40 @@
1
+ require 'bricolage/psqldatasource'
2
+ require 'bricolage/redisdatasource'
3
+ require 'redis'
4
+
5
+ JobClass.define('redis-export') {
6
+ parameters {|params|
7
+ # Export
8
+ params.add DataSourceParam.new('psql', 'src-ds', 'Source data source.')
9
+ params.add SrcTableParam.new(optional: false)
10
+ params.add SQLFileParam.new(optional: true)
11
+
12
+ # Redis import
13
+ params.add DataSourceParam.new('redis', 'dest-ds', 'Redis cluster')
14
+ params.add StringParam.new('key-column', 'REDIS_KEY', 'Redis object key. default: id', optional: true)
15
+ params.add StringParam.new('prefix', 'REDIS_PREFIX', 'Redis object key prefix', optional: true)
16
+ params.add StringParam.new('encode', 'REDIS_ENCODE', 'Redis object encoding. default: hash', optional: true)
17
+ }
18
+
19
+ script {|params, script|
20
+ # Export
21
+ script.task(params['dest-ds']) {|task|
22
+ task.import params['src-ds'],
23
+ params['src-tables'].first,
24
+ sql_statement(params),
25
+ params['key-column'] || "id",
26
+ params['prefix'],
27
+ params['encode'] || "hash"
28
+ }
29
+ }
30
+
31
+ def sql_statement(params)
32
+ return params['sql-file'] if params['sql-file']
33
+ srcs = params['src-tables']
34
+ raise ParameterError, "src-tables must be singleton when no sql-file is given" unless srcs.size == 1
35
+ src_table_var = srcs.keys.first
36
+ stmt = SQLStatement.for_string("select * from $#{src_table_var};")
37
+ stmt.declarations = Declarations.new({src_table_var => src_table_var})
38
+ stmt
39
+ end
40
+ }
@@ -134,10 +134,12 @@ class StreamingLoadJobClass < RubyJobClass
134
134
  end
135
135
  create_load_log_file(objects) {|log_url|
136
136
  @ds.open {|conn|
137
- execute_update conn, copy_load_log_stmt(log_url, @src.credential_string)
138
- foreach_loaded_object(objects) do |obj|
139
- obj.dequeue(@noop)
140
- end
137
+ create_tmp_log_table(conn, log_url) {|tmp_log_table|
138
+ loaded, not_loaded = partition_loaded_objects(conn, objects, tmp_log_table)
139
+ loaded.each do |obj|
140
+ obj.dequeue(force: true, noop: @noop)
141
+ end
142
+ }
141
143
  }
142
144
  }
143
145
  end
@@ -28,6 +28,11 @@ module Bricolage
28
28
  raise PostgreSQLException.wrap(ex)
29
29
  end
30
30
 
31
+ def execute_query(query, &block)
32
+ @logger.info "[#{@ds.name}] #{query}"
33
+ exec(query, &block)
34
+ end
35
+
31
36
  alias update execute
32
37
 
33
38
  def drop_table(name)
@@ -43,12 +48,7 @@ module Bricolage
43
48
  def select(table, &block)
44
49
  query = "select * from #{table}"
45
50
  @logger.info "[#{@ds.name}] #{query}"
46
- rs = @connection.exec(query)
47
- begin
48
- yield rs
49
- ensure
50
- rs.clear
51
- end
51
+ exec(query, &block)
52
52
  end
53
53
 
54
54
  def vacuum(table)
@@ -73,6 +73,20 @@ module Bricolage
73
73
  t = e - b
74
74
  @logger.info "#{'%.1f' % t} secs"
75
75
  end
76
+
77
+ def exec(query, &block)
78
+ @connection.send_query(query)
79
+ @connection.set_single_row_mode
80
+ loop do
81
+ rs = @connection.get_result or break
82
+ begin
83
+ rs.check
84
+ yield rs
85
+ ensure
86
+ rs.clear
87
+ end
88
+ end
89
+ end
76
90
  end
77
91
 
78
92
  end
@@ -103,7 +103,11 @@ module Bricolage
103
103
  end
104
104
 
105
105
  def query(query)
106
- open {|conn| conn.query(query) }
106
+ open {|conn| conn.execute(query) }
107
+ end
108
+
109
+ def execute_query(query, &block)
110
+ open {|conn| conn.execute_query(query, &block) }
107
111
  end
108
112
 
109
113
  def drop_table(name)
@@ -0,0 +1,112 @@
1
+ require 'bricolage/datasource'
2
+ require 'bricolage/commandutils'
3
+ require 'redis'
4
+ require 'json'
5
+
6
+ module Bricolage
7
+
8
+ class RedisDataSource < DataSource
9
+ declare_type 'redis'
10
+
11
+ def initialize(host: 'localhost', port: 6380, **opts)
12
+ @host = host
13
+ @port = port
14
+ @options = opts
15
+ end
16
+
17
+ attr_reader :host
18
+ attr_reader :port
19
+ attr_reader :opts
20
+
21
+ def new_task
22
+ RedisTask.new(self)
23
+ end
24
+
25
+ def client
26
+ @client = @client || Redis.new(:host => @host, :port => @port, **@options)
27
+ end
28
+ end
29
+
30
+ class RedisTask < DataSourceTask
31
+ def import(src, table, query, key_column, prefix, encode)
32
+ add Import.new(src, table, query, key_column, prefix, encode)
33
+ end
34
+
35
+ class Import < Action
36
+ def initialize(src, table, query, key_column, prefix, encode)
37
+ @src = src
38
+ @table = table
39
+ @query = query
40
+ @key_column = key_column
41
+ puts key_column
42
+ @prefix = prefix
43
+ @encode = encode
44
+ @read_count = 0
45
+ @write_count = 0
46
+ end
47
+
48
+ def bind(*args)
49
+ @query.bind(*args)
50
+ end
51
+
52
+ def source
53
+ @query.stripped_source
54
+ end
55
+
56
+ def prefix
57
+ @prefix = @prefix || "#{@table.last.schema}_#{@table.last.name}_"
58
+ end
59
+
60
+ def import
61
+ read_row do |row|
62
+ write_row(row)
63
+ end
64
+ end
65
+
66
+ def read_row
67
+ @src.execute_query(source) do |rs|
68
+ rs.each do |row|
69
+ yield row
70
+ @read_count += 1
71
+ ds.logger.info "Rows read: #{@read_count}" if @read_count % 100000 == 0
72
+ end
73
+ end
74
+ end
75
+
76
+ def write_row(row, &block)
77
+ key = key(row)
78
+ case @encode
79
+ when 'hash'
80
+ # set a value for each key:field pair
81
+ r = []
82
+ row.each do |field,value|
83
+ r.push ds.client.hset(key, field, value)
84
+ end
85
+ when 'json'
86
+ r = ds.client.set(key, JSON.generate(row))
87
+ else
88
+ raise %Q("encode: #{type}" is not supported)
89
+ end
90
+ yield r if block
91
+ ds.logger.info "Key sample: #{key}" if @write_count == 0
92
+ @write_count += 1
93
+ end
94
+
95
+ def key(row)
96
+ key_columns = @key_column.split(',').map(&:strip).map {|k| row[k]}
97
+ prefix + key_columns.join('_')
98
+ end
99
+
100
+ def run
101
+ begin
102
+ import
103
+ rescue => ex
104
+ ds.logger.error ex.backtrace.join("\n")
105
+ raise JobFailure, ex.message
106
+ end
107
+ ds.logger.info "Rows written: #{@write_count}"
108
+ JobResult.success
109
+ end
110
+ end
111
+ end
112
+ end
@@ -1,4 +1,4 @@
1
1
  module Bricolage
2
2
  APPLICATION_NAME = 'Bricolage'
3
- VERSION = '5.14.0'
3
+ VERSION = '5.15.0'
4
4
  end
@@ -1,54 +1,56 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- bricolage (5.14.0)
4
+ bricolage (5.15.0)
5
5
  aws-sdk (~> 2)
6
6
  mysql2
7
7
  pg
8
+ redis (>= 3.0.0)
8
9
  td
9
10
 
10
11
  GEM
11
12
  remote: https://rubygems.org/
12
13
  specs:
13
- aws-sdk (2.2.13)
14
- aws-sdk-resources (= 2.2.13)
15
- aws-sdk-core (2.2.13)
14
+ aws-sdk (2.2.26)
15
+ aws-sdk-resources (= 2.2.26)
16
+ aws-sdk-core (2.2.26)
16
17
  jmespath (~> 1.0)
17
- aws-sdk-resources (2.2.13)
18
- aws-sdk-core (= 2.2.13)
18
+ aws-sdk-resources (2.2.26)
19
+ aws-sdk-core (= 2.2.26)
19
20
  coderay (1.1.0)
20
21
  fluent-logger (0.5.1)
21
22
  msgpack (>= 0.4.4, < 0.6.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
22
23
  hirb (0.7.3)
23
- httpclient (2.5.3.3)
24
+ httpclient (2.7.1)
24
25
  jmespath (1.1.3)
25
26
  json (1.8.3)
26
27
  method_source (0.8.2)
27
- msgpack (0.5.11)
28
- mysql2 (0.4.2)
28
+ msgpack (0.5.12)
29
+ mysql2 (0.4.3)
29
30
  parallel (0.6.5)
30
31
  pg (0.18.4)
31
32
  pry (0.10.3)
32
33
  coderay (~> 1.1.0)
33
34
  method_source (~> 0.8.1)
34
35
  slop (~> 3.4)
36
+ redis (3.2.2)
35
37
  ruby-progressbar (1.7.5)
36
38
  rubyzip (1.1.7)
37
39
  slop (3.6.0)
38
- td (0.13.1)
40
+ td (0.13.2)
39
41
  hirb (>= 0.4.5)
40
- msgpack (>= 0.4.4, < 0.5.12, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
42
+ msgpack (>= 0.4.4, < 0.8.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
41
43
  parallel (~> 0.6.1)
42
44
  ruby-progressbar (~> 1.7.5)
43
45
  rubyzip (~> 1.1.7)
44
- td-client (~> 0.8.77)
46
+ td-client (~> 0.8.78)
45
47
  td-logger (~> 0.3.21)
46
48
  yajl-ruby (~> 1.1)
47
49
  zip-zip (~> 0.3)
48
- td-client (0.8.77)
49
- httpclient (>= 2.5.2, < 2.6.0)
50
+ td-client (0.8.78)
51
+ httpclient (~> 2.7)
50
52
  json (>= 1.7.6)
51
- msgpack (>= 0.4.4, < 0.6.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
53
+ msgpack (>= 0.4.4, < 0.8.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
52
54
  td-logger (0.3.25)
53
55
  fluent-logger (~> 0.5.0)
54
56
  msgpack (>= 0.4.4, < 0.8.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
@@ -0,0 +1,6 @@
1
+ class: redis-export
2
+ src-ds: sql
3
+ src-tables:
4
+ users: $test_schema.users
5
+ dest-ds: redis
6
+ key-column: id, user_name
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bricolage
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.14.0
4
+ version: 5.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Minero Aoki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-25 00:00:00.000000000 Z
11
+ date: 2016-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: redis
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: test-unit
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -116,6 +130,7 @@ files:
116
130
  - jobclass/noop.rb
117
131
  - jobclass/rebuild-drop.rb
118
132
  - jobclass/rebuild-rename.rb
133
+ - jobclass/redis-export.rb
119
134
  - jobclass/s3-put.rb
120
135
  - jobclass/sql.rb
121
136
  - jobclass/streaming_load.rb
@@ -146,6 +161,7 @@ files:
146
161
  - lib/bricolage/parameters.rb
147
162
  - lib/bricolage/postgresconnection.rb
148
163
  - lib/bricolage/psqldatasource.rb
164
+ - lib/bricolage/redisdatasource.rb
149
165
  - lib/bricolage/resource.rb
150
166
  - lib/bricolage/rubyjobclass.rb
151
167
  - lib/bricolage/s3datasource.rb
@@ -192,6 +208,7 @@ files:
192
208
  - test/home/subsys/raw-vacuum.jobnet
193
209
  - test/home/subsys/raw-vacuum.sql.job
194
210
  - test/home/subsys/rebuild.sql.job
211
+ - test/home/subsys/redis_export.job
195
212
  - test/home/subsys/search_backends.ct
196
213
  - test/home/subsys/separated.job
197
214
  - test/home/subsys/separated.sql
@@ -224,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
241
  version: '0'
225
242
  requirements: []
226
243
  rubyforge_project:
227
- rubygems_version: 2.4.5.1
244
+ rubygems_version: 2.5.1
228
245
  signing_key:
229
246
  specification_version: 4
230
247
  summary: SQL batch framework