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 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