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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a9370caedc8884fd3923af7d5c4c970fbe3e2b5
4
- data.tar.gz: 38084d6817ed52e925ff100bc651caf0ca990004
3
+ metadata.gz: 12e309ad5b258e1f273a35fb9b71e8f556501555
4
+ data.tar.gz: 861d23ff01a1b07c4c97c8f4f8cce26ac50a8a0f
5
5
  SHA512:
6
- metadata.gz: 3fe83ffc1f604fa2b7a1bd704bd0652893412b52999abdd0af84716a76e691e333122b4de0d9e5ad2861331e7cdd3f73f62b1e9547ea0fc4b1768aacf9f2a247
7
- data.tar.gz: 99f10efff0298ad6a4f3e48c2b54de3b93faa4fb79e6e6f393379ae5724e0b799cfb28996d6b41cb67f2ca6c96224ff814e27fa2930f411793afb5dfe864f3e3
6
+ metadata.gz: f70ce6284e2e5c0e5b8d5b101dd6b1ea79545aeee2cb97970aa499107a75dd86326526f4ad3c6adcf9ceea29926e1ba8b3d84733f6055a3fe6430c19725ef36c
7
+ data.tar.gz: e4d2b5141b3afabe8d5e93b559876c637382f2d4b53b614bb2476f5e7c62329db18c3e90e21e60d2b60ae158aeb7b9a3cc06e244bf86b01bbd0aa1c13aa7a45c
@@ -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
- task.create_dummy_table '${dest_table}'
77
- task.rename_table params['dest-table'].to_s, "#{params['dest-table'].name}_old"
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
  }
@@ -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
- task.create_dummy_table '${dest_table}'
99
- task.rename_table params['dest-table'].to_s, "#{params['dest-table'].name}_old"
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
  }
@@ -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
- # various SQL exception
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
- # Developer must fix source code or configuration, not to be get this exception.
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
 
@@ -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
- txn.abort unless txn.committed?
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.info "[#{@ds.name}] #{mask_secrets query}"
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.info "#{'%.1f' % t} secs"
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
- conn = PG::Connection.open(host: @host, port: @port, dbname: @database, user: @user, password: password)
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 "-- #{stmt.location}" if stmt.location
183
+ buf.puts "/* #{stmt.location} */" if stmt.location
182
184
  buf.puts stmt.stripped_source
183
185
  end
184
186
  buf.string
@@ -1,4 +1,4 @@
1
1
  module Bricolage
2
2
  APPLICATION_NAME = 'Bricolage'
3
- VERSION = '5.17.2'
3
+ VERSION = '5.18.0'
4
4
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- bricolage (5.17.2)
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.2)
15
- aws-sdk-resources (= 2.6.2)
16
- aws-sdk-core (2.6.2)
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.2)
19
- aws-sdk-core (= 2.6.2)
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.82)
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.12.5
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
+ }
@@ -12,6 +12,7 @@ remove-tmp: true
12
12
  dest-ds: sql
13
13
  dest-table: $test_schema.search_backends
14
14
  table-def: search_backends.ct
15
+ no-backup: true
15
16
  options:
16
17
  statupdate: false
17
18
  compupdate: false
@@ -14,6 +14,7 @@ dump-options:
14
14
  dest-ds: sql
15
15
  dest-table: $test_schema.users
16
16
  table-def: users.ct
17
+ #no-backup: true
17
18
  options:
18
19
  statupdate: false
19
20
  compupdate: false
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.17.2
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-09-29 00:00:00.000000000 Z
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