bricolage 5.17.2 → 5.18.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|