bricolage 5.17.2 → 5.18.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 +4 -4
- data/jobclass/my-import.rb +7 -2
- data/jobclass/my-migrate.rb +7 -2
- data/lib/bricolage/exception.rb +11 -14
- data/lib/bricolage/logger.rb +9 -0
- data/lib/bricolage/postgresconnection.rb +52 -3
- data/lib/bricolage/psqldatasource.rb +7 -5
- data/lib/bricolage/version.rb +1 -1
- data/test/home/Gemfile.lock +8 -8
- data/test/home/config/development/database.yml +10 -0
- data/test/home/sqltest.rb +16 -0
- data/test/home/subsys/migrate.job +1 -0
- data/test/home/subsys/my-import.job +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 12e309ad5b258e1f273a35fb9b71e8f556501555
|
|
4
|
+
data.tar.gz: 861d23ff01a1b07c4c97c8f4f8cce26ac50a8a0f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f70ce6284e2e5c0e5b8d5b101dd6b1ea79545aeee2cb97970aa499107a75dd86326526f4ad3c6adcf9ceea29926e1ba8b3d84733f6055a3fe6430c19725ef36c
|
|
7
|
+
data.tar.gz: e4d2b5141b3afabe8d5e93b559876c637382f2d4b53b614bb2476f5e7c62329db18c3e90e21e60d2b60ae158aeb7b9a3cc06e244bf86b01bbd0aa1c13aa7a45c
|
data/jobclass/my-import.rb
CHANGED
|
@@ -18,6 +18,7 @@ JobClass.define('my-import') {
|
|
|
18
18
|
optional: true, default: PSQLLoadOptions.new,
|
|
19
19
|
value_handler: lambda {|value, ctx, vars| PSQLLoadOptions.parse(value) })
|
|
20
20
|
params.add SQLFileParam.new('table-def', 'PATH', 'Create table file.')
|
|
21
|
+
params.add OptionalBoolParam.new('no-backup', 'Do not backup current table with suffix "_old".', default: false)
|
|
21
22
|
|
|
22
23
|
# Misc
|
|
23
24
|
params.add OptionalBoolParam.new('analyze', 'ANALYZE table after SQL is executed.', default: true)
|
|
@@ -73,8 +74,12 @@ JobClass.define('my-import') {
|
|
|
73
74
|
|
|
74
75
|
# RENAME
|
|
75
76
|
task.transaction {
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
if params['no-backup']
|
|
78
|
+
task.drop_force params['dest-table'].to_s
|
|
79
|
+
else
|
|
80
|
+
task.create_dummy_table '${dest_table}'
|
|
81
|
+
task.rename_table params['dest-table'].to_s, "#{params['dest-table'].name}_old"
|
|
82
|
+
end
|
|
78
83
|
task.rename_table work_table, params['dest-table'].name
|
|
79
84
|
}
|
|
80
85
|
}
|
data/jobclass/my-migrate.rb
CHANGED
|
@@ -22,6 +22,7 @@ JobClass.define('my-migrate') {
|
|
|
22
22
|
optional: true, default: PSQLLoadOptions.new,
|
|
23
23
|
value_handler: lambda {|value, ctx, vars| PSQLLoadOptions.parse(value) })
|
|
24
24
|
params.add SQLFileParam.new('table-def', 'PATH', 'Create table file.')
|
|
25
|
+
params.add OptionalBoolParam.new('no-backup', 'Do not backup current table with suffix "_old".', default: false)
|
|
25
26
|
|
|
26
27
|
# Misc
|
|
27
28
|
params.add OptionalBoolParam.new('analyze', 'ANALYZE table after SQL is executed.', default: true)
|
|
@@ -95,8 +96,12 @@ JobClass.define('my-migrate') {
|
|
|
95
96
|
|
|
96
97
|
# RENAME
|
|
97
98
|
task.transaction {
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
if params['no-backup']
|
|
100
|
+
task.drop_force params['dest-table'].to_s
|
|
101
|
+
else
|
|
102
|
+
task.create_dummy_table '${dest_table}'
|
|
103
|
+
task.rename_table params['dest-table'].to_s, "#{params['dest-table'].name}_old"
|
|
104
|
+
end
|
|
100
105
|
task.rename_table work_table, params['dest-table'].name
|
|
101
106
|
}
|
|
102
107
|
}
|
data/lib/bricolage/exception.rb
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
module Bricolage
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
# Common super-class of handlable bricolage exceptions
|
|
3
|
+
# Common super class of handleable Bricolage exceptions
|
|
5
4
|
class ApplicationError < StandardError; end
|
|
6
5
|
|
|
7
|
-
##
|
|
8
6
|
# Job failure.
|
|
9
7
|
# This exception may occur in production environment and is temporary.
|
|
10
8
|
# e.g. Source data error, SQL error
|
|
11
9
|
class JobFailure < ApplicationError; end
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class SQLException < JobFailure
|
|
16
|
-
def SQLException.wrap(ex)
|
|
11
|
+
class JobFailureByException < JobFailure
|
|
12
|
+
def JobFailureByException.wrap(ex)
|
|
17
13
|
new(ex.message, ex)
|
|
18
14
|
end
|
|
19
15
|
|
|
@@ -25,26 +21,27 @@ module Bricolage
|
|
|
25
21
|
attr_reader :original
|
|
26
22
|
end
|
|
27
23
|
|
|
28
|
-
|
|
24
|
+
# Various SQL exception, except connection problem.
|
|
25
|
+
class SQLException < JobFailureByException; end
|
|
26
|
+
|
|
27
|
+
# Database connection problems (not established, closed unexpectedly, invalid state)
|
|
28
|
+
class ConnectionError < JobFailureByException; end
|
|
29
|
+
|
|
29
30
|
# Aquiring lock takes too long (e.g. VACUUM lock)
|
|
30
31
|
class LockTimeout < JobFailure; end
|
|
31
32
|
|
|
32
|
-
##
|
|
33
33
|
# Job error.
|
|
34
34
|
# This exception should NOT be thrown in production environment.
|
|
35
|
-
#
|
|
35
|
+
# You must fix source code or configuration not to be get this exception.
|
|
36
36
|
class JobError < ApplicationError; end
|
|
37
37
|
|
|
38
|
-
##
|
|
39
38
|
# Command-line option errors (should NOT be thrown in production environment)
|
|
40
39
|
class OptionError < JobError; end
|
|
41
40
|
|
|
42
|
-
##
|
|
43
41
|
# User parameter errors (should NOT be thrown in production environment)
|
|
44
42
|
class ParameterError < JobError; end
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
# Bad code in bricolage core or job classes.
|
|
44
|
+
# Bad code in Bricolage core or job classes.
|
|
48
45
|
# This exception should NOT be thrown in ANY user environment.
|
|
49
46
|
class FatalError < Exception; end
|
|
50
47
|
|
data/lib/bricolage/logger.rb
CHANGED
|
@@ -3,6 +3,15 @@ require 'logger'
|
|
|
3
3
|
|
|
4
4
|
module Bricolage
|
|
5
5
|
class Logger < ::Logger
|
|
6
|
+
def Logger.intern_severity(sev)
|
|
7
|
+
if sev.kind_of?(Integer)
|
|
8
|
+
sev
|
|
9
|
+
else
|
|
10
|
+
SEV_LABEL.index(sev.to_s.upcase) or
|
|
11
|
+
raise ParameterError, "no such log level: #{sev}"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
6
15
|
def Logger.default
|
|
7
16
|
@default ||= new
|
|
8
17
|
end
|
|
@@ -6,16 +6,54 @@ module Bricolage
|
|
|
6
6
|
class PostgreSQLException < SQLException; end
|
|
7
7
|
|
|
8
8
|
class PostgresConnection
|
|
9
|
+
|
|
10
|
+
def PostgresConnection.open_data_source(ds)
|
|
11
|
+
conn = _open_ds(ds)
|
|
12
|
+
if block_given?
|
|
13
|
+
begin
|
|
14
|
+
yield conn
|
|
15
|
+
ensure
|
|
16
|
+
conn.close_force
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
return conn
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def PostgresConnection._open_ds(ds)
|
|
24
|
+
conn = PG::Connection.open(host: ds.host, port: ds.port, dbname: ds.database, user: ds.user, password: ds.password)
|
|
25
|
+
new(conn, ds, ds.logger)
|
|
26
|
+
rescue PG::ConnectionBad, PG::UnableToSend => ex
|
|
27
|
+
raise ConnectionError.wrap(ex)
|
|
28
|
+
end
|
|
29
|
+
private_class_method :_open_ds
|
|
30
|
+
|
|
9
31
|
def initialize(connection, ds, logger)
|
|
10
32
|
@connection = connection
|
|
11
33
|
@ds = ds
|
|
12
34
|
@logger = logger
|
|
35
|
+
@closed = false
|
|
36
|
+
@connection_failed = false
|
|
13
37
|
end
|
|
14
38
|
|
|
15
39
|
def source
|
|
16
40
|
@connection
|
|
17
41
|
end
|
|
18
42
|
|
|
43
|
+
def close
|
|
44
|
+
@connection.close
|
|
45
|
+
@closed = true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def close_force
|
|
49
|
+
close
|
|
50
|
+
rescue
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def closed?
|
|
54
|
+
@closed
|
|
55
|
+
end
|
|
56
|
+
|
|
19
57
|
def execute_update(query)
|
|
20
58
|
log_query query
|
|
21
59
|
rs = log_elapsed_time {
|
|
@@ -24,6 +62,9 @@ module Bricolage
|
|
|
24
62
|
result = rs.to_a
|
|
25
63
|
rs.clear
|
|
26
64
|
result
|
|
65
|
+
rescue PG::ConnectionBad, PG::UnableToSend => ex
|
|
66
|
+
@connection_failed = true
|
|
67
|
+
raise ConnectionError.wrap(ex)
|
|
27
68
|
rescue PG::Error => ex
|
|
28
69
|
raise PostgreSQLException.wrap(ex)
|
|
29
70
|
end
|
|
@@ -56,6 +97,9 @@ module Bricolage
|
|
|
56
97
|
result = yield rs
|
|
57
98
|
rs.clear
|
|
58
99
|
result
|
|
100
|
+
rescue PG::ConnectionBad, PG::UnableToSend => ex
|
|
101
|
+
@connection_failed = true
|
|
102
|
+
raise ConnectionError.wrap(ex)
|
|
59
103
|
rescue PG::Error => ex
|
|
60
104
|
raise PostgreSQLException.wrap(ex)
|
|
61
105
|
end
|
|
@@ -82,6 +126,9 @@ module Bricolage
|
|
|
82
126
|
rs.clear
|
|
83
127
|
end
|
|
84
128
|
end
|
|
129
|
+
rescue PG::ConnectionBad, PG::UnableToSend => ex
|
|
130
|
+
@connection_failed = true
|
|
131
|
+
raise ConnectionError.wrap(ex)
|
|
85
132
|
rescue PG::Error => ex
|
|
86
133
|
raise PostgreSQLException.wrap(ex)
|
|
87
134
|
end
|
|
@@ -97,7 +144,9 @@ module Bricolage
|
|
|
97
144
|
yield txn
|
|
98
145
|
rescue
|
|
99
146
|
begin
|
|
100
|
-
|
|
147
|
+
if not txn.committed? and not @connection_failed
|
|
148
|
+
txn.abort
|
|
149
|
+
end
|
|
101
150
|
rescue => ex
|
|
102
151
|
@logger.error "SQL error on transaction abort: #{ex.message} (ignored)"
|
|
103
152
|
end
|
|
@@ -195,7 +244,7 @@ module Bricolage
|
|
|
195
244
|
end
|
|
196
245
|
|
|
197
246
|
def log_query(query)
|
|
198
|
-
@logger.
|
|
247
|
+
@logger.log(@ds.sql_log_level) { "[#{@ds.name}] #{mask_secrets query}" }
|
|
199
248
|
end
|
|
200
249
|
|
|
201
250
|
def mask_secrets(msg)
|
|
@@ -209,7 +258,7 @@ module Bricolage
|
|
|
209
258
|
ensure
|
|
210
259
|
e = Time.now
|
|
211
260
|
t = e - b
|
|
212
|
-
@logger.
|
|
261
|
+
@logger.log(@ds.sql_log_level) { "#{'%.1f' % t} secs" }
|
|
213
262
|
end
|
|
214
263
|
|
|
215
264
|
end
|
|
@@ -5,6 +5,7 @@ require 'bricolage/commandutils'
|
|
|
5
5
|
require 'bricolage/postgresconnection'
|
|
6
6
|
require 'bricolage/vacuumlock'
|
|
7
7
|
require 'bricolage/exception'
|
|
8
|
+
require 'bricolage/logger'
|
|
8
9
|
require 'pathname'
|
|
9
10
|
|
|
10
11
|
module Bricolage
|
|
@@ -23,6 +24,7 @@ module Bricolage
|
|
|
23
24
|
pgpass: nil,
|
|
24
25
|
encoding: nil,
|
|
25
26
|
psql: 'psql',
|
|
27
|
+
sql_log_level: Logger::INFO,
|
|
26
28
|
tmpdir: Dir.tmpdir)
|
|
27
29
|
@host = host
|
|
28
30
|
@port = port
|
|
@@ -32,6 +34,7 @@ module Bricolage
|
|
|
32
34
|
@pgpass = pgpass
|
|
33
35
|
@encoding = encoding
|
|
34
36
|
@psql = psql
|
|
37
|
+
@sql_log_level = Logger.intern_severity(sql_log_level)
|
|
35
38
|
@tmpdir = tmpdir
|
|
36
39
|
raise ParameterError, "missing psql host" unless @host
|
|
37
40
|
raise ParameterError, "missing psql port" unless @port
|
|
@@ -47,6 +50,8 @@ module Bricolage
|
|
|
47
50
|
attr_reader :database
|
|
48
51
|
attr_reader :user
|
|
49
52
|
|
|
53
|
+
attr_reader :sql_log_level
|
|
54
|
+
|
|
50
55
|
def new_task
|
|
51
56
|
PSQLTask.new(self)
|
|
52
57
|
end
|
|
@@ -96,10 +101,7 @@ module Bricolage
|
|
|
96
101
|
end
|
|
97
102
|
|
|
98
103
|
def open(&block)
|
|
99
|
-
|
|
100
|
-
yield PostgresConnection.new(conn, self, logger)
|
|
101
|
-
ensure
|
|
102
|
-
conn.close if conn
|
|
104
|
+
PostgresConnection.open_data_source(self, &block)
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
def query_batch(query, batch_size = 5000, &block)
|
|
@@ -178,7 +180,7 @@ module Bricolage
|
|
|
178
180
|
buf.puts '\timing on'
|
|
179
181
|
each_statement do |stmt|
|
|
180
182
|
buf.puts
|
|
181
|
-
buf.puts "
|
|
183
|
+
buf.puts "/* #{stmt.location} */" if stmt.location
|
|
182
184
|
buf.puts stmt.stripped_source
|
|
183
185
|
end
|
|
184
186
|
buf.string
|
data/lib/bricolage/version.rb
CHANGED
data/test/home/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ../..
|
|
3
3
|
specs:
|
|
4
|
-
bricolage (5.
|
|
4
|
+
bricolage (5.18.0)
|
|
5
5
|
aws-sdk (~> 2)
|
|
6
6
|
mysql2
|
|
7
7
|
pg (~> 0.18.0)
|
|
@@ -11,12 +11,12 @@ PATH
|
|
|
11
11
|
GEM
|
|
12
12
|
remote: https://rubygems.org/
|
|
13
13
|
specs:
|
|
14
|
-
aws-sdk (2.6.
|
|
15
|
-
aws-sdk-resources (= 2.6.
|
|
16
|
-
aws-sdk-core (2.6.
|
|
14
|
+
aws-sdk (2.6.4)
|
|
15
|
+
aws-sdk-resources (= 2.6.4)
|
|
16
|
+
aws-sdk-core (2.6.4)
|
|
17
17
|
jmespath (~> 1.0)
|
|
18
|
-
aws-sdk-resources (2.6.
|
|
19
|
-
aws-sdk-core (= 2.6.
|
|
18
|
+
aws-sdk-resources (2.6.4)
|
|
19
|
+
aws-sdk-core (= 2.6.4)
|
|
20
20
|
coderay (1.1.0)
|
|
21
21
|
fluent-logger (0.5.1)
|
|
22
22
|
msgpack (>= 0.4.4, < 0.6.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
|
|
@@ -47,7 +47,7 @@ GEM
|
|
|
47
47
|
td-logger (~> 0.3.21)
|
|
48
48
|
yajl-ruby (~> 1.1)
|
|
49
49
|
zip-zip (~> 0.3)
|
|
50
|
-
td-client (0.8.
|
|
50
|
+
td-client (0.8.83)
|
|
51
51
|
httpclient (~> 2.7)
|
|
52
52
|
json (>= 1.7.6)
|
|
53
53
|
msgpack (>= 0.4.4, < 0.8.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
|
|
@@ -67,4 +67,4 @@ DEPENDENCIES
|
|
|
67
67
|
pry
|
|
68
68
|
|
|
69
69
|
BUNDLED WITH
|
|
70
|
-
1.
|
|
70
|
+
1.13.2
|
|
@@ -32,6 +32,16 @@ sql_app2:
|
|
|
32
32
|
pgpass: <%= user_home_relative_path '.pgpass' %>
|
|
33
33
|
encoding: utf8
|
|
34
34
|
|
|
35
|
+
postgres:
|
|
36
|
+
type: psql
|
|
37
|
+
host: localhost
|
|
38
|
+
port: 5432
|
|
39
|
+
database: bricolage
|
|
40
|
+
username: bricolage
|
|
41
|
+
password: bricolage
|
|
42
|
+
encoding: utf8
|
|
43
|
+
sql_log_level: DEBUG
|
|
44
|
+
|
|
35
45
|
td:
|
|
36
46
|
type: td
|
|
37
47
|
database: logs
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'bricolage/commandlineapplication'
|
|
2
|
+
require 'pp'
|
|
3
|
+
|
|
4
|
+
app = Bricolage::CommandLineApplication.define {|opts|
|
|
5
|
+
opts.data_source_option('--ds', 'Target data source', short: '-D', kind: 'sql')
|
|
6
|
+
}
|
|
7
|
+
ds = app.data_source('--ds')
|
|
8
|
+
ds.open {|conn|
|
|
9
|
+
#task_ids = conn.query_values('select task_id from strload_tasks')
|
|
10
|
+
#p [task_ids.class, task_ids.size]
|
|
11
|
+
|
|
12
|
+
conn.update('create table t (x int)')
|
|
13
|
+
pp conn.query_value('select count(*) from t')
|
|
14
|
+
conn.update('drop table t')
|
|
15
|
+
pp conn.query_value('select count(*) from t')
|
|
16
|
+
}
|
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.
|
|
4
|
+
version: 5.18.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-
|
|
11
|
+
date: 2016-10-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: pg
|
|
@@ -206,6 +206,7 @@ files:
|
|
|
206
206
|
- test/home/data/20141002-1355_02.txt
|
|
207
207
|
- test/home/data/test.txt
|
|
208
208
|
- test/home/jobnet-test.rb
|
|
209
|
+
- test/home/sqltest.rb
|
|
209
210
|
- test/home/subsys/d.ct
|
|
210
211
|
- test/home/subsys/insert.sql.job
|
|
211
212
|
- test/home/subsys/job1.job
|