activerecord-oracle_enhanced-adapter 6.0.2 → 6.0.3

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
  SHA256:
3
- metadata.gz: 286bf797dd7620f403978bac9b64706d1d9b7b802e1c9126548d1a8107047a38
4
- data.tar.gz: 5b0522c53cff924336c66a97ce53f8c901fe65bdc76c8a4b6cb86919a10d7abd
3
+ metadata.gz: 052b872f1a9b0e25deb107b79b568226bd0083f3747323b566cc61af3316004d
4
+ data.tar.gz: ba283f9be0de33aceb818753656a4887da42f6fd317036c9d34fa930aa8e9723
5
5
  SHA512:
6
- metadata.gz: b85ac030f6c23463f469e3c861d7b221ab642e33cc9878fb1a4fcaeeefd8eaeb5c33ddbb4756600c39ee262057a9648b443e1dc9f92aac51d7374c8328379ea3
7
- data.tar.gz: e476724d5b578459aa34211e2c80256027131123820c741065cbec1f8f0c49f7447fd136d86545b59660dabb0e3edd184b50c88eb96ee8419a199345db1cd226
6
+ metadata.gz: 9b4a606efdf65e2cc08a5e78f07a6d5d8750710f9c7660dfa116b885a151873f995472c01890e22716eaa1e74d9ee5527282c579d41c02978b525b2ea676b6b5
7
+ data.tar.gz: a937ae9b1fe755be2bfb2d100b0564bf25d1e6e23730947a09d06450e50431ee3c0d864f8cf472cbacc99e2a32b6b99d8cf8e959b86d04aabc75352798123c9c
data/History.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 6.0.3 / 2020-06-16
2
+
3
+ * Changes and bug fixes
4
+ * Auto retry works for other `exec_*` methods [#1976, #1981]
5
+ * Allow column name with function (e.g. `length(title)`) as safe SQL string [#2017, #2018]
6
+
7
+ * CI
8
+ * CI against latest Ruby versions [#1979]
9
+
1
10
  ## 6.0.2 / 2019-12-25
2
11
 
3
12
  * Changes and bug fixes
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.0.2
1
+ 6.0.3
@@ -24,21 +24,23 @@ module ActiveRecord
24
24
  log(sql, name, binds, type_casted_binds) do
25
25
  cursor = nil
26
26
  cached = false
27
- if without_prepared_statement?(binds)
28
- cursor = @connection.prepare(sql)
29
- else
30
- unless @statements.key? sql
31
- @statements[sql] = @connection.prepare(sql)
32
- end
27
+ with_retry do
28
+ if without_prepared_statement?(binds)
29
+ cursor = @connection.prepare(sql)
30
+ else
31
+ unless @statements.key? sql
32
+ @statements[sql] = @connection.prepare(sql)
33
+ end
33
34
 
34
- cursor = @statements[sql]
35
+ cursor = @statements[sql]
35
36
 
36
- cursor.bind_params(type_casted_binds)
37
+ cursor.bind_params(type_casted_binds)
37
38
 
38
- cached = true
39
- end
39
+ cached = true
40
+ end
40
41
 
41
- cursor.exec
42
+ cursor.exec
43
+ end
42
44
 
43
45
  if (name == "EXPLAIN") && sql =~ /^EXPLAIN/
44
46
  res = true
@@ -96,29 +98,32 @@ module ActiveRecord
96
98
 
97
99
  log(sql, name, binds, type_casted_binds) do
98
100
  cached = false
101
+ cursor = nil
99
102
  returning_id_col = returning_id_index = nil
100
- if without_prepared_statement?(binds)
101
- cursor = @connection.prepare(sql)
102
- else
103
- unless @statements.key?(sql)
104
- @statements[sql] = @connection.prepare(sql)
105
- end
103
+ with_retry do
104
+ if without_prepared_statement?(binds)
105
+ cursor = @connection.prepare(sql)
106
+ else
107
+ unless @statements.key?(sql)
108
+ @statements[sql] = @connection.prepare(sql)
109
+ end
110
+
111
+ cursor = @statements[sql]
106
112
 
107
- cursor = @statements[sql]
113
+ cursor.bind_params(type_casted_binds)
108
114
 
109
- cursor.bind_params(type_casted_binds)
115
+ if /:returning_id/.match?(sql)
116
+ # it currently expects that returning_id comes last part of binds
117
+ returning_id_index = binds.size
118
+ cursor.bind_returning_param(returning_id_index, Integer)
119
+ end
110
120
 
111
- if /:returning_id/.match?(sql)
112
- # it currently expects that returning_id comes last part of binds
113
- returning_id_index = binds.size
114
- cursor.bind_returning_param(returning_id_index, Integer)
121
+ cached = true
115
122
  end
116
123
 
117
- cached = true
124
+ cursor.exec_update
118
125
  end
119
126
 
120
- cursor.exec_update
121
-
122
127
  rows = []
123
128
  if returning_id_index
124
129
  returning_id = cursor.get_returning_param(returning_id_index, Integer).to_i
@@ -134,24 +139,26 @@ module ActiveRecord
134
139
  type_casted_binds = type_casted_binds(binds)
135
140
 
136
141
  log(sql, name, binds, type_casted_binds) do
137
- cached = false
138
- if without_prepared_statement?(binds)
139
- cursor = @connection.prepare(sql)
140
- else
141
- if @statements.key?(sql)
142
- cursor = @statements[sql]
142
+ with_retry do
143
+ cached = false
144
+ if without_prepared_statement?(binds)
145
+ cursor = @connection.prepare(sql)
143
146
  else
144
- cursor = @statements[sql] = @connection.prepare(sql)
145
- end
147
+ if @statements.key?(sql)
148
+ cursor = @statements[sql]
149
+ else
150
+ cursor = @statements[sql] = @connection.prepare(sql)
151
+ end
146
152
 
147
- cursor.bind_params(type_casted_binds)
153
+ cursor.bind_params(type_casted_binds)
148
154
 
149
- cached = true
150
- end
155
+ cached = true
156
+ end
151
157
 
152
- res = cursor.exec_update
153
- cursor.close unless cached
154
- res
158
+ res = cursor.exec_update
159
+ cursor.close unless cached
160
+ res
161
+ end
155
162
  end
156
163
  end
157
164
 
@@ -263,6 +270,16 @@ module ActiveRecord
263
270
  end
264
271
  end
265
272
  end
273
+
274
+ private
275
+ def with_retry
276
+ @connection.with_retry do
277
+ yield
278
+ rescue
279
+ @statements.clear
280
+ raise
281
+ end
282
+ end
266
283
  end
267
284
  end
268
285
  end
@@ -97,6 +97,10 @@ module ActiveRecord
97
97
  @raw_connection.exec(sql, *bindvars, &block)
98
98
  end
99
99
 
100
+ def with_retry(&block)
101
+ @raw_connection.with_retry(&block)
102
+ end
103
+
100
104
  def prepare(sql)
101
105
  Cursor.new(self, @raw_connection.parse(sql))
102
106
  end
@@ -423,13 +427,11 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
423
427
  LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114, 3135 ] #:nodoc:
424
428
 
425
429
  # Adds auto-recovery functionality.
426
- #
427
- # See: http://www.jiubao.org/ruby-oci8/api.en.html#label-11
428
- def exec(sql, *bindvars, &block) #:nodoc:
430
+ def with_retry #:nodoc:
429
431
  should_retry = self.class.auto_retry? && autocommit?
430
432
 
431
433
  begin
432
- @connection.exec(sql, *bindvars, &block)
434
+ yield
433
435
  rescue OCIException => e
434
436
  raise unless e.is_a?(OCIError) && LOST_CONNECTION_ERROR_CODES.include?(e.code)
435
437
  @active = false
@@ -439,5 +441,9 @@ class OCI8EnhancedAutoRecover < DelegateClass(OCI8) #:nodoc:
439
441
  retry
440
442
  end
441
443
  end
444
+
445
+ def exec(sql, *bindvars, &block) #:nodoc:
446
+ with_retry { @connection.exec(sql, *bindvars, &block) }
447
+ end
442
448
  end
443
449
  #:startdoc:
@@ -132,6 +132,42 @@ module ActiveRecord
132
132
  end
133
133
  end
134
134
 
135
+ def column_name_matcher
136
+ COLUMN_NAME
137
+ end
138
+
139
+ def column_name_with_order_matcher
140
+ COLUMN_NAME_WITH_ORDER
141
+ end
142
+
143
+ COLUMN_NAME = /
144
+ \A
145
+ (
146
+ (?:
147
+ # "table_name"."column_name" | function(one or no argument)
148
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
149
+ )
150
+ (?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
151
+ )
152
+ (?:\s*,\s*\g<1>)*
153
+ \z
154
+ /ix
155
+
156
+ COLUMN_NAME_WITH_ORDER = /
157
+ \A
158
+ (
159
+ (?:
160
+ # "table_name"."column_name" | function(one or no argument)
161
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
162
+ )
163
+ (?:\s+ASC|\s+DESC)?
164
+ (?:\s+NULLS\s+(?:FIRST|LAST))?
165
+ )
166
+ (?:\s*,\s*\g<1>)*
167
+ \z
168
+ /ix
169
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
170
+
135
171
  private
136
172
 
137
173
  def oracle_downcase(column_name)
Binary file
@@ -387,10 +387,22 @@ describe "OracleEnhancedConnection" do
387
387
  end
388
388
 
389
389
  describe "auto reconnection" do
390
+ include SchemaSpecHelper
391
+
390
392
  before(:all) do
391
393
  ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
392
394
  @conn = ActiveRecord::Base.connection.instance_variable_get("@connection")
393
395
  @sys_conn = ActiveRecord::ConnectionAdapters::OracleEnhanced::Connection.create(SYS_CONNECTION_PARAMS)
396
+ schema_define do
397
+ create_table :posts, force: true
398
+ end
399
+ class ::Post < ActiveRecord::Base
400
+ end
401
+ end
402
+
403
+ after(:all) do
404
+ Object.send(:remove_const, "Post")
405
+ ActiveRecord::Base.clear_cache!
394
406
  end
395
407
 
396
408
  before(:each) do
@@ -440,6 +452,20 @@ describe "OracleEnhancedConnection" do
440
452
  expect { @conn.select("SELECT * FROM dual") }.to raise_error(OCIError)
441
453
  end
442
454
  end
455
+
456
+ it "should reconnect and execute query if connection is lost and auto retry is enabled" do
457
+ Post.create!
458
+ ActiveRecord::Base.connection.auto_retry = true
459
+ kill_current_session
460
+ expect(Post.take).not_to be_nil
461
+ end
462
+
463
+ it "should not reconnect and execute query if connection is lost and auto retry is disabled" do
464
+ Post.create!
465
+ ActiveRecord::Base.connection.auto_retry = false
466
+ kill_current_session
467
+ expect { Post.take }.to raise_error(ActiveRecord::StatementInvalid)
468
+ end
443
469
  end
444
470
 
445
471
  describe "describe table" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-oracle_enhanced-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.2
4
+ version: 6.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raimonds Simanovskis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-25 00:00:00.000000000 Z
11
+ date: 2020-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -86,6 +86,7 @@ files:
86
86
  - lib/active_record/type/oracle_enhanced/timestampltz.rb
87
87
  - lib/active_record/type/oracle_enhanced/timestamptz.rb
88
88
  - lib/activerecord-oracle_enhanced-adapter.rb
89
+ - lib/ojdbc8.jar
89
90
  - spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb
90
91
  - spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb
91
92
  - spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb
@@ -140,33 +141,33 @@ signing_key:
140
141
  specification_version: 4
141
142
  summary: Oracle enhanced adapter for ActiveRecord
142
143
  test_files:
143
- - spec/spec_helper.rb
144
- - spec/active_record/oracle_enhanced/type/integer_spec.rb
145
- - spec/active_record/oracle_enhanced/type/raw_spec.rb
146
- - spec/active_record/oracle_enhanced/type/float_spec.rb
144
+ - spec/support/alter_system_user_password.sql
145
+ - spec/support/create_oracle_enhanced_users.sql
146
+ - spec/support/alter_system_set_open_cursors.sql
147
147
  - spec/active_record/oracle_enhanced/type/boolean_spec.rb
148
- - spec/active_record/oracle_enhanced/type/dirty_spec.rb
148
+ - spec/active_record/oracle_enhanced/type/float_spec.rb
149
+ - spec/active_record/oracle_enhanced/type/raw_spec.rb
150
+ - spec/active_record/oracle_enhanced/type/national_character_string_spec.rb
149
151
  - spec/active_record/oracle_enhanced/type/binary_spec.rb
150
- - spec/active_record/oracle_enhanced/type/timestamp_spec.rb
151
- - spec/active_record/oracle_enhanced/type/national_character_text_spec.rb
152
152
  - spec/active_record/oracle_enhanced/type/character_string_spec.rb
153
+ - spec/active_record/oracle_enhanced/type/decimal_spec.rb
153
154
  - spec/active_record/oracle_enhanced/type/json_spec.rb
155
+ - spec/active_record/oracle_enhanced/type/national_character_text_spec.rb
156
+ - spec/active_record/oracle_enhanced/type/timestamp_spec.rb
157
+ - spec/active_record/oracle_enhanced/type/dirty_spec.rb
158
+ - spec/active_record/oracle_enhanced/type/integer_spec.rb
154
159
  - spec/active_record/oracle_enhanced/type/text_spec.rb
155
- - spec/active_record/oracle_enhanced/type/decimal_spec.rb
156
- - spec/active_record/oracle_enhanced/type/national_character_string_spec.rb
157
- - spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb
158
- - spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb
159
- - spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb
160
- - spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb
161
- - spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb
162
- - spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb
163
160
  - spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb
161
+ - spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb
164
162
  - spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb
163
+ - spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb
164
+ - spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb
165
+ - spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb
165
166
  - spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb
167
+ - spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb
168
+ - spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb
166
169
  - spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb
167
170
  - spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb
168
171
  - spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb
169
- - spec/support/alter_system_user_password.sql
170
- - spec/support/create_oracle_enhanced_users.sql
171
- - spec/support/alter_system_set_open_cursors.sql
172
+ - spec/spec_helper.rb
172
173
  - spec/spec_config.yaml.template