bricolage 5.15.2 → 5.16.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: 5acaeef75f7cfc4d74814c7f036d7e7a187f728f
4
- data.tar.gz: 4ef05fb1c2b2e292a51f2c6331ceaa9a12d445e9
3
+ metadata.gz: 2660120a7623731fb14dac13b2efa0582e535265
4
+ data.tar.gz: 859704e487ea718d76bc4567d4e46451acad39db
5
5
  SHA512:
6
- metadata.gz: 4569b393900821b004f84b341e9e5ce87298c6e83d8fb49719960448bac8ad6d8d59cb29ce49acc7e5e5047a0a05324170e76957928ed7ea102944835a733c09
7
- data.tar.gz: c17dddd3e8a46e246250e746a02e9f8eaa8f335a3cbfe245ab709aa35c8e59caf1629f0636b0928bfc285f60a84968456ae7556132386a71854634e546b09054
6
+ metadata.gz: a68f420cbfbc54ad9596200c3dc00204e4c0105b68051e06eeb256c7096bc2334cd9dceb678c3b997efe09dca22103ea6545845b76a8824c6eea69fb4779d9cc
7
+ data.tar.gz: a39835ca04114f75c778c9c129b8ab7e08ea8d9601dcd45504c2fbac84bb5ac286914cc55db308ad49cef94d55de61d58682e23537a0d595a8916e003ded9891
@@ -0,0 +1,79 @@
1
+ require 'bricolage/psqldatasource'
2
+ require 'bricolage/mysqldatasource'
3
+
4
+ JobClass.define('my-import') {
5
+ parameters {|params|
6
+ # S3Export
7
+ params.add SrcTableParam.new(optional: false)
8
+ params.add DataSourceParam.new('mysql', 'src-ds', 'Source data source.')
9
+ params.add SQLFileParam.new(optional: true)
10
+ params.add DataSourceParam.new('s3', 's3-ds', 'Temporary file storage.')
11
+ params.add DestFileParam.new('s3-prefix', 'PREFIX', 'Temporary S3 prefix.')
12
+ params.add KeyValuePairsParam.new('dump-options', 'KEY:VALUE', 'dump options.', optional: true)
13
+
14
+ # Load
15
+ params.add DestTableParam.new(optional: false)
16
+ params.add DataSourceParam.new('sql', 'dest-ds', 'Destination data source.')
17
+ params.add KeyValuePairsParam.new('options', 'OPTIONS', 'Loader options.',
18
+ optional: true, default: PSQLLoadOptions.new,
19
+ value_handler: lambda {|value, ctx, vars| PSQLLoadOptions.parse(value) })
20
+ params.add SQLFileParam.new('table-def', 'PATH', 'Create table file.')
21
+
22
+ # Misc
23
+ params.add OptionalBoolParam.new('analyze', 'ANALYZE table after SQL is executed.', default: true)
24
+ params.add OptionalBoolParam.new('vacuum', 'VACUUM table after SQL is executed.')
25
+ params.add OptionalBoolParam.new('vacuum-sort', 'VACUUM SORT table after SQL is executed.')
26
+ params.add KeyValuePairsParam.new('grant', 'KEY:VALUE', 'GRANT table after SQL is executed. (required keys: privilege, to)')
27
+
28
+ # All
29
+ params.add OptionalBoolParam.new('export', 'Runs EXPORT task.')
30
+ params.add OptionalBoolParam.new('put', 'Runs PUT task.')
31
+ params.add OptionalBoolParam.new('load', 'Runs LOAD task.')
32
+ params.add OptionalBoolParam.new('gzip', 'Compress Temporary files.')
33
+ }
34
+
35
+ script {|params, script|
36
+ run_all = !params['export'] && !params['put'] && !params['load']
37
+
38
+ # S3Export
39
+ if params['export'] || run_all
40
+ script.task(params['src-ds']) {|task|
41
+ task.s3export params['src-tables'].keys.first,
42
+ params['sql-file'],
43
+ params['s3-ds'],
44
+ params['s3-prefix'],
45
+ params['gzip'],
46
+ dump_options: params['dump-options']
47
+ }
48
+ end
49
+
50
+ # Load
51
+ if params['load'] || run_all
52
+ script.task(params['dest-ds']) {|task|
53
+ prev_table = '${dest_table}_old'
54
+ work_table = '${dest_table}_wk'
55
+
56
+ # CREATE
57
+ task.drop_force prev_table
58
+ task.drop_force work_table
59
+ task.exec params['table-def'].replace(/\$\{?dest_table\}?\b/, work_table)
60
+
61
+ # COPY
62
+ task.load params['s3-ds'], params['s3-prefix'], work_table,
63
+ 'json', nil, params['options'].merge('gzip' => params['gzip'])
64
+
65
+ # VACUUM, ANALYZE, GRANT
66
+ task.vacuum_if params['vacuum'], params['vacuum-sort'], work_table
67
+ task.analyze_if params['analyze'], work_table
68
+ task.grant_if params['grant'], work_table
69
+
70
+ # RENAME
71
+ task.create_dummy_table '${dest_table}'
72
+ task.transaction {
73
+ task.rename_table params['dest-table'].to_s, "#{params['dest-table'].name}_old"
74
+ task.rename_table work_table, params['dest-table'].name
75
+ }
76
+ }
77
+ end
78
+ }
79
+ }
@@ -261,21 +261,13 @@ class StreamingLoadJobClass < RubyJobClass
261
261
 
262
262
  def create_tmp_log_table(conn, log_url)
263
263
  target_table = log_table_wk
264
- execute_update conn, "create table #{target_table} (like #{@log_table});"
264
+ execute_update conn, "truncate #{target_table};"
265
265
  execute_update conn, load_log_copy_stmt(target_table, log_url, @src.credential_string)
266
- begin
267
- yield target_table
268
- ensure
269
- begin
270
- execute_update conn, "drop table #{target_table}"
271
- rescue PostgreSQLException => ex
272
- @logger.error ex.message + " (ignored)"
273
- end
274
- end
266
+ yield target_table
275
267
  end
276
268
 
277
269
  def log_table_wk
278
- "#{@log_table}_tmp#{Process.pid}"
270
+ "#{@log_table}_wk"
279
271
  end
280
272
 
281
273
  def load_log_copy_stmt(target_table, log_url, credential_string)
@@ -15,6 +15,8 @@ module Bricolage
15
15
  @client = nil
16
16
  end
17
17
 
18
+ attr_reader :mysql_options
19
+
18
20
  def host
19
21
  @mysql_options[:host]
20
22
  end
@@ -172,6 +174,104 @@ module Bricolage
172
174
  end
173
175
  end
174
176
 
177
+ def s3export(table, stmt, s3ds, prefix, gzip, dump_options)
178
+ options = dump_options.nil? ? {} : dump_options[:dump_options]
179
+ add S3Export.new(table, stmt, s3ds, prefix, gzip: gzip,
180
+ format: options['format'],
181
+ partition_column: options['partition_column'],
182
+ partition_number: options['partition_number'],
183
+ write_concurrency: options['write_concurrency'],
184
+ rotation_size: options['rotation_size'],
185
+ delete_objects: options['delete_objects'],
186
+ object_key_delimiter: options['object_key_delimiter'])
187
+ end
188
+
189
+ class S3Export < Action
190
+
191
+ def initialize(table, stmt, s3ds, prefix, gzip: true,
192
+ format: "json",
193
+ partition_column: nil,
194
+ partition_number: 4,
195
+ write_concurrency: 4,
196
+ rotation_size: nil,
197
+ delete_objects: false,
198
+ object_key_delimiter: nil)
199
+ @table = table
200
+ @statement = stmt
201
+ @s3ds = s3ds
202
+ @prefix = build_prefix @s3ds.prefix, prefix
203
+ @format = format
204
+ @gzip = gzip
205
+ @partition_column = partition_column
206
+ @partition_number = partition_number
207
+ @write_concurrency = write_concurrency
208
+ @rotation_size = rotation_size
209
+ @delete_objects = delete_objects
210
+ @object_key_delimiter = object_key_delimiter
211
+ end
212
+
213
+ def run
214
+ s3export
215
+ JobResult.success
216
+ end
217
+
218
+ def bind(*args)
219
+ @statement.bind(*args) if @statement
220
+ end
221
+
222
+ def s3export
223
+ cmd = build_cmd(command_parameters)
224
+ ds.logger.info '[CMD] ' + cmd.join(' ')
225
+ Open3.popen2e(*cmd) do |input, output, thread|
226
+ input.close
227
+ output.each do |line|
228
+ puts line
229
+ end
230
+ unless thread.value.success?
231
+ raise JobFailure, "#{cmd.join(' ')} failed (status #{thread.value.to_i})"
232
+ end
233
+ end
234
+ end
235
+
236
+ def command_parameters
237
+ params = {jar: mys3dump_path.to_s, h: ds.host, P: ds.port.to_s, D: ds.database, u: ds.username, p: ds.password, o: connection_property, t: @table,
238
+ 'Daws.accessKeyId': @s3ds.access_key, 'Daws.secretKey': @s3ds.secret_key, b: @s3ds.bucket.name, x: @prefix}
239
+ params[:q] = @statement.stripped_source.chop if @statement
240
+ params[:f] = @format if @format
241
+ params[:C] = nil if @gzip
242
+ params[:c] = @partition_column if @partition_column
243
+ params[:n] = @partition_number if @partition_number
244
+ params[:w] = @write_concurrency if @write_concurrency
245
+ params[:r] = @rotation_size if @rotation_size
246
+ params[:d] = nil if @delete_objects
247
+ params[:k] = @object_key_delimiter if @object_key_delimiter
248
+ params
249
+ end
250
+
251
+ OPTION_MAP = {
252
+ encoding: 'useUnicode=true&characterEncoding',
253
+ read_timeout: 'netTimeoutForStreamingResults',
254
+ connect_timeout: 'connectTimeout',
255
+ reconnect: 'autoReconnect'
256
+ }
257
+
258
+ def connection_property
259
+ ds.mysql_options.map {|k, v| opt = OPTION_MAP[k] ; opt ? "#{opt}=#{v}" : nil }.compact.join('&')
260
+ end
261
+
262
+ def build_prefix(ds_prefix, pm_prefix)
263
+ ((ds_prefix || "") + "//" + (pm_prefix.to_s || "")).gsub(%r<\A/>, '').gsub(%r<//>, '/')
264
+ end
265
+
266
+ def mys3dump_path
267
+ Pathname(__dir__).parent.parent + "libexec/mys3dump.jar"
268
+ end
269
+
270
+ def build_cmd(options)
271
+ ['java'] + options.flat_map {|k, v| v ? ["-#{k}", v.to_s] : ["-#{k}"] }
272
+ end
273
+ end
274
+
175
275
  WRITER_CLASSES = {}
176
276
 
177
277
  class JSONWriter
@@ -1,5 +1,4 @@
1
1
  require 'bricolage/exception'
2
- require 'securerandom'
3
2
  require 'pg'
4
3
 
5
4
  module Bricolage
@@ -11,14 +10,13 @@ module Bricolage
11
10
  @connection = connection
12
11
  @ds = ds
13
12
  @logger = logger
14
- @cursor = nil
15
13
  end
16
14
 
17
15
  def source
18
16
  @connection
19
17
  end
20
18
 
21
- def execute(query)
19
+ def execute_update(query)
22
20
  @logger.info "[#{@ds.name}] #{query}"
23
21
  log_elapsed_time {
24
22
  rs = @connection.exec(query)
@@ -30,42 +28,97 @@ module Bricolage
30
28
  raise PostgreSQLException.wrap(ex)
31
29
  end
32
30
 
31
+ alias execute execute_update
32
+ alias update execute_update
33
+
34
+ def select(table, &block)
35
+ execute_query("select * from #{table}", &block)
36
+ end
37
+
33
38
  def execute_query(query, &block)
34
39
  @logger.info "[#{@ds.name}] #{query}"
35
- exec(query, &block)
36
- end
37
-
38
- def execute_query_with_cursor(query, fetch_size, cursor, &block)
39
- raise "Begin transaction before invoking this method" unless in_transaction?
40
- if @cursor.nil?
41
- @cursor = cursor || (0...32).map { alphabets[rand(alphabets.length)] }.join
42
- declare_cursor = "declare #{@cursor} cursor for #{query}"
43
- @logger.info "[#{@ds.name}] #{declare_cursor}"
44
- @connection.exec(declare_cursor)
45
- elsif !@cursor.nil? && cursor.nil?
46
- raise "Cannot declare new cursor. Cursor in use: #{@cursor}"
47
- elsif @cursor != cursor
48
- raise "Specified cursor not exists. Specified: #{cursor}, Current: #{@cursor}"
49
- end
50
- fetch = "fetch #{fetch_size} in #{@cursor}"
51
- @logger.info "[#{@ds.name}] #{fetch}" if cursor.nil?
52
- yield @connection.exec(fetch)
53
- return @cursor
40
+ rs = log_elapsed_time {
41
+ @connection.exec(query)
42
+ }
43
+ result = yield rs
44
+ rs.clear
45
+ result
46
+ rescue PG::Error => ex
47
+ raise PostgreSQLException.wrap(ex)
54
48
  end
55
49
 
56
- def clear_cursor
57
- @cursor = nil
50
+ alias query execute_query
51
+
52
+ def query_batch(query, batch_size = 5000, &block)
53
+ open_cursor(query) {|cur|
54
+ cur.each_result_set(batch_size, &block)
55
+ }
58
56
  end
59
57
 
60
- def alphabets
61
- @alphabets = @alphabets || [('a'...'z'), ('A'...'Z')].map { |i| i.to_a }.flatten
58
+ def streaming_execute_query(query, &block)
59
+ @logger.info "[#{@ds.name}] #{query}"
60
+ log_elapsed_time {
61
+ @connection.send_query(query)
62
+ }
63
+ @connection.set_single_row_mode
64
+ while rs = @connection.get_result
65
+ begin
66
+ rs.check
67
+ yield rs
68
+ ensure
69
+ rs.clear
70
+ end
71
+ end
72
+ rescue PG::Error => ex
73
+ raise PostgreSQLException.wrap(ex)
62
74
  end
63
75
 
64
76
  def in_transaction?
65
77
  @connection.transaction_status == PG::Constants::PQTRANS_INTRANS
66
78
  end
67
79
 
68
- alias update execute
80
+ def transaction
81
+ execute 'begin transaction'
82
+ yield
83
+ execute 'commit'
84
+ end
85
+
86
+ def open_cursor(query, name = nil, &block)
87
+ unless in_transaction?
88
+ transaction {
89
+ return open_cursor(query, &block)
90
+ }
91
+ end
92
+ name ||= make_unique_cursor_name
93
+ execute "declare #{name} cursor for #{query}"
94
+ yield Cursor.new(name, self, @logger)
95
+ end
96
+
97
+ Thread.current['bricolage_cursor_seq'] = 0
98
+
99
+ def make_unique_cursor_name
100
+ seq = (Thread.current['bricolage_cursor_seq'] += 1)
101
+ "cur_bric_#{$$}_#{'%X' % Thread.current.object_id}_#{seq}"
102
+ end
103
+
104
+ class Cursor
105
+ def initialize(name, conn, logger)
106
+ @name = name
107
+ @conn = conn
108
+ @logger = logger
109
+ end
110
+
111
+ attr_reader :name
112
+
113
+ def each_result_set(fetch_size = 5000)
114
+ while true
115
+ @conn.execute_query("fetch #{fetch_size} in #{@name}") {|rs|
116
+ return if rs.values.empty?
117
+ yield rs
118
+ }
119
+ end
120
+ end
121
+ end
69
122
 
70
123
  def drop_table(name)
71
124
  execute "drop table #{name} cascade;"
@@ -77,12 +130,6 @@ module Bricolage
77
130
  @logger.error err.message
78
131
  end
79
132
 
80
- def select(table, &block)
81
- query = "select * from #{table}"
82
- @logger.info "[#{@ds.name}] #{query}"
83
- exec(query, &block)
84
- end
85
-
86
133
  def vacuum(table)
87
134
  execute "vacuum #{table};"
88
135
  end
@@ -105,19 +152,6 @@ module Bricolage
105
152
  t = e - b
106
153
  @logger.info "#{'%.1f' % t} secs"
107
154
  end
108
-
109
- def exec(query, &block)
110
- @connection.send_query(query)
111
- @connection.set_single_row_mode
112
- loop do
113
- rs = @connection.get_result or break
114
- begin
115
- rs.check
116
- yield rs
117
- ensure
118
- rs.clear
119
- end
120
- end
121
- end
122
155
  end
156
+
123
157
  end
@@ -102,34 +102,8 @@ module Bricolage
102
102
  conn.close if conn
103
103
  end
104
104
 
105
- def 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) }
111
- end
112
-
113
- def cursor_transaction(&block)
114
- raise "Cursor in use" if cursor_in_transaction?
115
- conn = PG::Connection.open(host: @host, port: @port, dbname: @database, user: @user, password: password)
116
- @cur_conn = PostgresConnection.new(conn, self, logger)
117
- @cur_conn.execute("begin transaction")
118
- yield
119
- ensure
120
- @cur_conn.execute("commit") if cursor_in_transaction?
121
- @cur_conn.clear_cursor if @cur_conn
122
- @cur_conn = nil
123
- conn.close if conn
124
- end
125
-
126
- def cursor_execute_query(query, fetch_size: 10000, cursor: nil, &block)
127
- raise "Begin transaction before invoking this method" unless cursor_in_transaction?
128
- @cur_conn.execute_query_with_cursor(query, fetch_size, cursor, &block)
129
- end
130
-
131
- def cursor_in_transaction?
132
- @cur_conn && @cur_conn.in_transaction?
105
+ def query_batch(query, batch_size = 5000, &block)
106
+ open {|conn| conn.query_batch(query, batch_size, &block) }
133
107
  end
134
108
 
135
109
  def drop_table(name)
@@ -22,8 +22,9 @@ module Bricolage
22
22
  RedisTask.new(self)
23
23
  end
24
24
 
25
- def client
26
- @client = @client || Redis.new(:host => @host, :port => @port, **@options)
25
+ def open
26
+ client = Redis.new(host: @host, port: @port, **@options)
27
+ yield client
27
28
  end
28
29
  end
29
30
 
@@ -38,11 +39,9 @@ module Bricolage
38
39
  @table = table
39
40
  @query = query
40
41
  @key_columns = key_column.split(',').map(&:strip)
41
- @prefix = prefix
42
+ @prefix = prefix || "#{@table.last.schema}_#{@table.last.name}_"
42
43
  @encode = encode
43
44
  @expire = expire
44
- @read_count = 0
45
- @write_count = 0
46
45
  end
47
46
 
48
47
  def bind(*args)
@@ -53,84 +52,102 @@ module Bricolage
53
52
  @query.stripped_source
54
53
  end
55
54
 
56
- def prefix
57
- @prefix = @prefix || "#{@table.last.schema}_#{@table.last.name}_"
55
+ def run
56
+ logger = ds.logger
57
+ begin
58
+ logger.info "Key Pattern: #{@prefix}<#{@key_columns.join('_')}>"
59
+ logger.info "Encode: #{@encode}"
60
+ logger.info "Expire: #{@expire}"
61
+ ds.open {|client|
62
+ writer = RedisRowWriter.for_encode(@encode).new(client, @prefix, @key_columns)
63
+ import writer
64
+ }
65
+ rescue => ex
66
+ logger.exception ex
67
+ raise JobFailure, ex.message
68
+ end
69
+ JobResult.success
58
70
  end
59
71
 
60
- def import
61
- @src.cursor_transaction {
62
- read_count = 0
63
- loop do
64
- ds.client.pipelined do
65
- read_count = read_row do |row|
66
- write_row row
67
- end
68
- end
69
- break if read_count == 0
70
- end
71
- }
72
- @cursor = nil
73
- end
72
+ BATCH_SIZE = 5000
74
73
 
75
- def read_row
76
- rs_size = 0
77
- @cursor = @src.cursor_execute_query(source, cursor: @cursor) do |rs|
78
- rs_size = rs.values.size
79
- break if rs_size == 0
80
- rs.each do |row|
81
- yield row
82
- @read_count += 1
83
- ds.logger.info "Rows read: #{@read_count}" if @read_count % 100000 == 0
84
- end
74
+ def import(writer)
75
+ count = 0
76
+ @src.query_batch(source, BATCH_SIZE) do |rs|
77
+ writer.pipelined {
78
+ rs.each do |row|
79
+ writer.write(row)
80
+ count += 1
81
+ ds.logger.info "transfered: #{count} rows" if count % 100_0000 == 0
82
+ end
83
+ }
85
84
  end
86
- rs_size
85
+ ds.logger.info "all rows written: #{count} rows"
87
86
  end
87
+ end
88
+ end
88
89
 
89
- def write_row(row)
90
- key = key(row)
91
- data = delete_key_columns(row)
92
- f = []
93
- case @encode
94
- when 'hash'
95
- # set a value for each key:field pair
96
- data.each do |field,value|
97
- f.push ds.client.hset(key, field, value)
98
- end
99
- when 'json'
100
- f.push ds.client.set(key, JSON.generate(data))
101
- else
102
- raise %Q("encode: #{type}" is not supported)
103
- end
104
- f.push ds.client.expire(key, @expire) if @expire
105
- @write_count += 1
106
- return f
90
+ class RedisRowWriter
91
+ def RedisRowWriter.for_encode(encode)
92
+ case encode
93
+ when 'hash' then RedisHashRowWriter
94
+ when 'json' then RedisJSONRowWriter
95
+ else
96
+ raise ParameterError, "unsupported Redis encode: #{encode.inspect}"
107
97
  end
98
+ end
108
99
 
109
- def delete_key_columns(row)
110
- r = row.dup
111
- @key_columns.each do |key|
112
- r.delete(key)
113
- end
114
- r.empty? ? {1 => 1} : r
115
- end
100
+ def initialize(client, prefix, key_columns)
101
+ @client = client
102
+ @prefix = prefix
103
+ @key_columns = key_columns
104
+ end
116
105
 
117
- def key(row)
118
- prefix + @key_columns.map {|k| row[k]}.join('_')
119
- end
106
+ attr_reader :prefix
107
+ attr_reader :write_count
120
108
 
121
- def run
122
- begin
123
- ds.logger.info "Key Pattern: #{prefix}<#{@key_columns.join('_')}>"
124
- ds.logger.info "Encode: #{@encode}"
125
- ds.logger.info "Expire: #{@expire}"
126
- import
127
- rescue => ex
128
- ds.logger.error ex.backtrace.join("\n")
129
- raise JobFailure, ex.message
130
- end
131
- ds.logger.info "Rows written: #{@write_count}"
132
- JobResult.success
109
+ def key(row)
110
+ @prefix + @key_columns.map {|k| row[k] }.join('_')
111
+ end
112
+
113
+ def value_columns(row)
114
+ r = row.dup
115
+ @key_columns.each do |key|
116
+ r.delete(key)
133
117
  end
118
+ r.empty? ? {1 => 1} : r
119
+ end
120
+
121
+ def pipelined(&block)
122
+ @client.pipelined(&block)
123
+ end
124
+
125
+ def write(row)
126
+ key = key(row)
127
+ futures = do_write(key, value_columns(row))
128
+ futures.push @client.expire(key, @expire) if @expire
129
+ futures
130
+ end
131
+
132
+ def expire
133
+ @client.expire(key, @expire)
134
+ end
135
+ end
136
+
137
+ class RedisHashRowWriter < RedisRowWriter
138
+ def do_write(key, values)
139
+ # set a value for each key:field pair
140
+ values.map {|field, value|
141
+ @client.hset(key, field, value)
142
+ }
134
143
  end
135
144
  end
145
+
146
+ class RedisJSONRowWriter < RedisRowWriter
147
+ def do_write(key, values)
148
+ future = @client.set(key, JSON.generate(values))
149
+ [future]
150
+ end
151
+ end
152
+
136
153
  end
@@ -1,4 +1,4 @@
1
1
  module Bricolage
2
2
  APPLICATION_NAME = 'Bricolage'
3
- VERSION = '5.15.2'
3
+ VERSION = '5.16.0'
4
4
  end
Binary file
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- bricolage (5.15.2)
4
+ bricolage (5.16.0)
5
5
  aws-sdk (~> 2)
6
6
  mysql2
7
7
  pg
@@ -1,7 +1,7 @@
1
1
  sql: &redshift_parameters
2
2
  type: psql
3
- host: <%= ENV['RSPROXYHOST'] ? 'localhost' : (ENV['RSHOST'] || 'cookpad-dwh-401.cbzwjkf60uat.ap-northeast-1.redshift.amazonaws.com') %>
4
- port: <%= ENV['RSPROXYPORT'] || ENV['RSPORT'] || 5439 %>
3
+ host: <%= ENV['RSHOST'] || 'dwh.ckpd.co' %>
4
+ port: <%= ENV['RSPORT'] || 5439 %>
5
5
  database: production
6
6
  username: <%= ENV['RSUSER'] || 'tabemirudev' %>
7
7
  pgpass: <%= user_home_relative_path '.pgpass' %>
@@ -0,0 +1,13 @@
1
+ event_queue:
2
+ sqs_url: "https://sqs.ap-northeast-1.amazonaws.com/789035092620/log-stream-dev"
3
+ visibility_timeout: 60
4
+
5
+ load_queue:
6
+ sqs_url: "https://sqs.ap-northeast-1.amazonaws.com/789035092620/XXXXXXXXXXXXXX"
7
+ visibility_timeout: 60
8
+
9
+ url_patterns:
10
+ -
11
+ url: "s3://redshift-copy-buffer/development/log_stream/\\d{8}_\\d{4}_\\d+.*\\.gz"
12
+ schema: "aamine"
13
+ table: "pv_log"
@@ -0,0 +1,32 @@
1
+ class: my-import
2
+ src-ds: mysql
3
+ src-tables:
4
+ users: main.users
5
+ s3-ds: s3
6
+ s3-prefix: shimpeko/test-abc-
7
+ gzip: true
8
+ dump-options:
9
+ partition_column: id
10
+ partition_number: 8
11
+ write_concurrency: 16
12
+ rotation_size: 16000000
13
+ delete_objects: true
14
+ dest-ds: sql
15
+ dest-table: $test_schema.users
16
+ table-def: users.ct
17
+ options:
18
+ statupdate: false
19
+ compupdate: false
20
+ maxerror: 3
21
+ acceptinvchars: " "
22
+ #trimblanks: true
23
+ #truncatecolumns: true
24
+ ## datetime
25
+ #acceptanydate: true
26
+ #dateformat: "auto"
27
+ #timeformat: "auto"
28
+ vacuum-sort: true
29
+ analyze: true
30
+ grant:
31
+ privilege: select
32
+ to: "$test_group"
@@ -0,0 +1,13 @@
1
+ --dest-table: users
2
+
3
+ create table $dest_table
4
+ ( id int encode delta
5
+ , user_name varchar(1000) encode lzo
6
+ , birthday date encode lzo
7
+ , zip varchar(255) encode lzo
8
+ , created_at timestamp encode lzo
9
+ , updated_at timestamp encode lzo
10
+ )
11
+ distkey (id)
12
+ sortkey (id)
13
+ ;
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.15.2
4
+ version: 5.16.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-03-17 00:00:00.000000000 Z
11
+ date: 2016-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -126,6 +126,7 @@ files:
126
126
  - jobclass/insert.rb
127
127
  - jobclass/load.rb
128
128
  - jobclass/my-export.rb
129
+ - jobclass/my-import.rb
129
130
  - jobclass/my-migrate.rb
130
131
  - jobclass/noop.rb
131
132
  - jobclass/rebuild-drop.rb
@@ -173,12 +174,14 @@ files:
173
174
  - lib/bricolage/variables.rb
174
175
  - lib/bricolage/version.rb
175
176
  - libexec/create-lockfile
177
+ - libexec/mys3dump.jar
176
178
  - libexec/sqldump
177
179
  - libexec/sqldump.Darwin
178
180
  - libexec/sqldump.Linux
179
181
  - test/all.rb
180
182
  - test/home/Gemfile
181
183
  - test/home/Gemfile.lock
184
+ - test/home/config.yml
182
185
  - test/home/config/development/database.yml
183
186
  - test/home/config/development/password.yml
184
187
  - test/home/config/development/variable.yml
@@ -202,6 +205,7 @@ files:
202
205
  - test/home/subsys/load_test.ct
203
206
  - test/home/subsys/load_test.job
204
207
  - test/home/subsys/migrate.job
208
+ - test/home/subsys/my-import.job
205
209
  - test/home/subsys/net1.jobnet
206
210
  - test/home/subsys/net2.jobnet
207
211
  - test/home/subsys/put.job
@@ -216,6 +220,7 @@ files:
216
220
  - test/home/subsys/some_view-cv.sql.job
217
221
  - test/home/subsys/unified.jobnet
218
222
  - test/home/subsys/unified.sql.job
223
+ - test/home/subsys/users.ct
219
224
  - test/home/subsys/variable.yml
220
225
  - test/test_c_streaming_load.rb
221
226
  - test/test_filesystem.rb