activerecord-oracle_enhanced-adapter 6.0.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +112 -0
  3. data/README.md +12 -1
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +3 -4
  6. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +0 -1
  7. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +0 -9
  8. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +64 -47
  9. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +4 -5
  10. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +0 -1
  11. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +3 -4
  12. data/lib/active_record/connection_adapters/oracle_enhanced/lob.rb +1 -2
  13. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +12 -7
  14. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +0 -1
  15. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +38 -3
  16. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +3 -4
  17. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +1 -1
  18. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +16 -4
  19. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +65 -59
  20. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +35 -34
  21. data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +2 -1
  22. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +64 -21
  23. data/lib/active_record/type/oracle_enhanced/boolean.rb +0 -1
  24. data/lib/active_record/type/oracle_enhanced/integer.rb +0 -1
  25. data/lib/arel/visitors/oracle.rb +217 -0
  26. data/lib/arel/visitors/oracle12.rb +124 -0
  27. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +35 -3
  28. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +6 -1
  29. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +0 -1
  30. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +28 -1
  31. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +2 -1
  32. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +122 -0
  33. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +4 -2
  34. data/spec/spec_config.yaml.template +2 -2
  35. data/spec/spec_helper.rb +13 -4
  36. metadata +28 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c77f9b16cb8c699e6c8916d1cd5c3546f0bd03ed49d2e72106a66dfd9273d88
4
- data.tar.gz: bf3b674aebc3267df0668fd211b29b361ebe4c60b5832282ea39d281b6a5bf4a
3
+ metadata.gz: c5985d7537ecc79468e80b7ecddf9c8a52309719db665c0b904cb2d04994eb99
4
+ data.tar.gz: 0e01cd4d37d2cd9a3f1a48f33b9cdcc9b9adc340a186415cfccb13975693bd3a
5
5
  SHA512:
6
- metadata.gz: ac56991732d1cb09f4996c23d399909045ab89d67388e54636c37e94a4bb599f8d9676717ce0c04d07ba3f7d39bd4271942b1d96a9963663422685fe1c565358
7
- data.tar.gz: 740c29c91f5d4b2786493cc035786064bde94bd21d67c5ccee83e54654dd98e31d8ea147255f9f8297446655bafdb19450fbf0878c29add0232bd417e6e30e26
6
+ metadata.gz: 58000a64e1d069d9058848a5ecf33474c8ef09ebb7ecf660d9169b5cc4b4a1911e3f8b72f24011801885c333930c378252a8f2bba5ac4051806acde9093a1af3
7
+ data.tar.gz: 0c21d8db90ff52720800a717b47f776abf91eded32aec137141e1510453d1eea21e31f291a771df17d7a5957873f2d5479ada8a96aeb4eb24420598080157cfa
data/History.md CHANGED
@@ -1,3 +1,115 @@
1
+ ## 6.1.0.rc1 / 2020-11-03
2
+
3
+ * Changes and bug fixes
4
+ * Support Rails 6.1.0.rc1
5
+ * Add support to change the permissions granted when creating DB [#1885]
6
+ * Refactor `create_table`'s options separation [#1886]
7
+ * Move schema cache to pool [#1888]
8
+ * Clear schema cache when a table is created/dropped/renamed [#1891]
9
+ * Deduplicate various Active Record schema cache structures [#1897]
10
+ * Support SQLCounter change to ignore "SCHEMA" and "TRANSACTION" log [#1892]
11
+ * Share the column and table name quote cache between connections [#1901]
12
+ * Add database_exists? method to connection adapters [#1906]
13
+ * Accept columns passed with options in remove_index [#1930]
14
+ * Fix `NameError` for `SchemaCreation` [#1933]
15
+ * Add `supports_common_table_expressions?` for CTE testing [#1946]
16
+ * create_table_definition and add_column take keyword arguments [#1942]
17
+ * Address `uninitialized constant ActiveRecord::ConnectionAdapters::AbstractAdapter::Quoting (NameError) [#1950]
18
+ * Fix an error when writing lobs [#1962]
19
+ * Uninstall SimpleCov [#1968]
20
+ * fix: Auto retry only works for connection.exec() [#1976]
21
+ * Fix keyword arguments errors for Ruby 2.8.0-dev [#1977]
22
+ * Fix a build errors when using Ruby 2.8.0-dev [#1983]
23
+ * Include sync option when dumping a context index [#1988]
24
+ * Use `build_result` instead of `ActiveRecord::Result.new` [#1994]
25
+ * Use the new API for build_results [#1995]
26
+ * Merge Arel visitors [#2002]
27
+ * Enable `Rails/IndexBy` and `Rails/IndexWith` cops [#2006]
28
+ * Don't refer `allowed_index_name_length` directly [#2009]
29
+ * Should not rely on the global `Arel::Table.engine` in the framework [#2010]
30
+ * Suppress `warning: already initialized constant` [#2011]
31
+ * Deprecate passing a column to `type_cast` [#2012]
32
+ * Limit number of expressions in a list during a "homogenous in" operation [#2013]
33
+ * Allow column name with function (e.g. `length(title)`) as safe SQL string [#2017]
34
+ * Default engine `ENGINE=InnoDB` is no longer dumped to make schema more agnostic [#2019]
35
+ * Separate primary key column options from table options [#2019]
36
+ * Make index options to kwargs [#2022]
37
+ * Make remaining migration options to kwargs [#2024]
38
+ * Allow TruffleRuby RUBY_ENGINE [#2046]
39
+ * Restore Schema Dumper behavior changed by #2019 [#2047]
40
+ * Support JDBC service name syntax [#2035]
41
+ * Use Rake 13.0.0.pre.1 [#1924]
42
+ * Bump RuboCop version to 0.71 [#1887]
43
+ * Bump RuboCop to 0.74.0 [#1914]
44
+ * Bump RuboCop to 0.76.0 [#1947]
45
+ * Use RuboCop 0.77 [#1959]
46
+ * Bump RuboCop to 0.82.0 [#2005]
47
+ * Suppress RuboCop's offenses [#2020]
48
+ * Enable `Layout/EmptyLinesAroundAccessModifier` cop [#1890]
49
+ * Disable `Style/BracesAroundHashParameters` cop [#1923]
50
+ * Enable `Layout/ClosingHeredocIndentation` cop [#1958]
51
+ * Unlock RuboCop gem versions [#1926]
52
+ * Enable `Rails/IndexBy` and `Rails/IndexWith` cops [#2006]
53
+ * Enable `Performance/DeletePrefix` and `Performance/DeleteSuffix` cops [#2021]
54
+ * Enable `Layout/SpaceAroundOperators` cop [#2057]
55
+ * Fix links to rails-dev-box running on docker [#1883]
56
+ * Fix spec config template copy instructions [#1884]
57
+ * Update UPGRADE section for Rails 5.2 [#1993]
58
+
59
+ * CI
60
+ * Enable GitHub Actions and run RuboCop [#1925]
61
+ * Run CI with GitHub Actions [#2015]
62
+ * Enabled Dependabot by creating .dependabot/config.yml [#1931]
63
+ * Disable Code Climate #1938
64
+ * CI against JRuby 9.2.8.0 [#1911]
65
+ * CI against JRuby 9.2.9.0 #1948
66
+ * CI against Ruby 2.6.4 and Ruby 2.5.6 [#1921]
67
+ * CI against Ruby 2.5.7 and Ruby 2.6.5 [#1949]
68
+ * CI against Ruby 2.7.0 [#1975]
69
+ * CI against JRuby 9.2.10.0 [#1989]
70
+ * CI against JRuby 9.2.11.0 [#1992]
71
+ * CI against JRuby 9.2.11.1 [#1997]
72
+ * CI againt Ruby 2.7.1, 2.6.6 and 2.5.8 #1998
73
+ * CI against JRuby 9.2.12.0 [#2034]
74
+ * Use Oracle Instant Client 18.5 [#2036]
75
+ * Support `jruby-head` again [#2037]
76
+ * CI against JRuby 9.2.13.0 [#2041]
77
+ * CI against Ruby 2.7.2 [#2052]
78
+ * Remove unnecessary PATH and LD_LIBRARY_PATH environment variables [#1927]
79
+ * Use Ubuntu 18.04 (Bionic Beaver) at Travis CI [#1937]
80
+ * Run bug report template at CI [#1936]
81
+ * Skip known failures until #1943 is resolved [#1961]
82
+ * Migrate to `ruby/setup-ruby` to use Ruby 2.7 [#2026]
83
+
84
+ ## 6.0.4 / 2020-08-18
85
+
86
+ * Changes and bug fixes
87
+ * create_table_definition and add_column take keyword arguments [#1942, #2043]
88
+ * Fix keyword arguments errors for Ruby 2.8.0-dev [#1977,#2043]
89
+ * Fix a build errors when using Ruby 2.8.0-dev [#1983, #2043]
90
+
91
+ ## 6.0.3 / 2020-06-16
92
+
93
+ * Changes and bug fixes
94
+ * Auto retry works for other `exec_*` methods [#1976, #1981]
95
+ * Allow column name with function (e.g. `length(title)`) as safe SQL string [#2017, #2018]
96
+
97
+ * CI
98
+ * CI against latest Ruby versions [#1979]
99
+
100
+ ## 6.0.2 / 2019-12-25
101
+
102
+ * Changes and bug fixes
103
+ * Uninstall SimpleCov [#1968]
104
+
105
+ ## 6.0.1 / 2019-12-20
106
+
107
+ * Changes and bug fixes
108
+ * Address `undefined local variable or method `sql' [#1932 #1962 #1963]
109
+
110
+ * CI
111
+ * CI against Ruby 2.6.4 and Ruby 2.5.6 [#1922]
112
+
1
113
  ## 6.0.0 / 2019-08-17
2
114
 
3
115
  * Major changes, including changes since 6.0.0.beta1
data/README.md CHANGED
@@ -10,6 +10,17 @@ Oracle enhanced ActiveRecord adapter provides Oracle database access from Ruby o
10
10
 
11
11
  INSTALLATION
12
12
  ------------
13
+ ### Rails 6.1
14
+
15
+ Oracle enhanced adapter version 6.1 supports Rails 6.1.
16
+ When using Ruby on Rails version 6.1 then in Gemfile include
17
+
18
+ ```ruby
19
+ # Use oracle as the database for Active Record
20
+ gem 'activerecord-oracle_enhanced-adapter', '~> 6.1.0'
21
+ gem 'ruby-oci8' # only for CRuby users
22
+ ```
23
+
13
24
  ### Rails 6.0
14
25
 
15
26
  Oracle enhanced adapter version 6.0 supports Rails 6.0.
@@ -663,7 +674,7 @@ if any database structure changed by migrations, execute `rails db:schema:cache:
663
674
 
664
675
  UPGRADE
665
676
  ---------------
666
- ### Upgrade Rails 5.0 or older version to Rails 5.2
677
+ ### Upgrade Rails 5.1 or older version to Rails 5.2
667
678
 
668
679
  * `emulate_booleans_from_strings = true` change
669
680
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.0.0
1
+ 6.1.0
@@ -19,7 +19,6 @@ module ActiveRecord
19
19
  attr_reader :raw_connection
20
20
 
21
21
  private
22
-
23
22
  # Used always by JDBC connection as well by OCI connection when describing tables over database link
24
23
  def describe(name)
25
24
  name = name.to_s
@@ -35,7 +34,7 @@ module ActiveRecord
35
34
  table_owner, table_name = default_owner, real_name
36
35
  end
37
36
  sql = <<~SQL.squish
38
- SELECT owner, table_name, 'TABLE' name_type
37
+ SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, table_name, 'TABLE' name_type
39
38
  FROM all_tables
40
39
  WHERE owner = '#{table_owner}'
41
40
  AND table_name = '#{table_name}'
@@ -116,8 +115,8 @@ module ActiveRecord
116
115
  end
117
116
  end
118
117
 
119
- # if MRI or YARV
120
- if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
118
+ # if MRI or YARV or TruffleRuby
119
+ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby"
121
120
  ORACLE_ENHANCED_CONNECTION = :oci
122
121
  require "active_record/connection_adapters/oracle_enhanced/oci_connection"
123
122
  # if JRuby
@@ -142,7 +142,6 @@ module ActiveRecord
142
142
  end
143
143
 
144
144
  private
145
-
146
145
  def create_datastore_procedure(table_name, procedure_name, column_names, options)
147
146
  quoted_table_name = quote_table_name(table_name)
148
147
  select_queries, column_names = column_names.partition { |c| c.to_s =~ /^\s*SELECT\s+/i }
@@ -25,15 +25,6 @@ module ActiveRecord
25
25
  end
26
26
  deprecate :column_name_length
27
27
 
28
- # Returns the maximum allowed length for an index name. This
29
- # limit is enforced by rails and Is less than or equal to
30
- # <tt>index_name_length</tt>. The gap between
31
- # <tt>index_name_length</tt> is to allow internal rails
32
- # opreations to use prefixes in temporary opreations.
33
- def allowed_index_name_length
34
- index_name_length
35
- end
36
-
37
28
  # the maximum length of an index name
38
29
  # supported by this database
39
30
  def index_name_length
@@ -24,23 +24,25 @@ 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
- if (name == "EXPLAIN") && sql =~ /^EXPLAIN/
45
+ if (name == "EXPLAIN") && sql.start_with?("EXPLAIN")
44
46
  res = true
45
47
  else
46
48
  columns = cursor.get_col_names.map do |col_name|
@@ -51,7 +53,7 @@ module ActiveRecord
51
53
  while row = cursor.fetch(fetch_options)
52
54
  rows << row
53
55
  end
54
- res = ActiveRecord::Result.new(columns, rows)
56
+ res = build_result(columns: columns, rows: rows)
55
57
  end
56
58
 
57
59
  cursor.close unless cached
@@ -65,7 +67,7 @@ module ActiveRecord
65
67
 
66
68
  def explain(arel, binds = [])
67
69
  sql = "EXPLAIN PLAN FOR #{to_sql(arel, binds)}"
68
- return if sql =~ /FROM all_/
70
+ return if /FROM all_/.match?(sql)
69
71
  if ORACLE_ENHANCED_CONNECTION == :jdbc
70
72
  exec_query(sql, "EXPLAIN", binds)
71
73
  else
@@ -96,36 +98,39 @@ 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
125
130
  rows << [returning_id]
126
131
  end
127
132
  cursor.close unless cached
128
- ActiveRecord::Result.new(returning_id_col || [], rows)
133
+ build_result(columns: returning_id_col || [], rows: rows)
129
134
  end
130
135
  end
131
136
 
@@ -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
 
@@ -189,11 +196,11 @@ module ActiveRecord
189
196
  end
190
197
 
191
198
  def create_savepoint(name = current_savepoint_name) #:nodoc:
192
- execute("SAVEPOINT #{name}")
199
+ execute("SAVEPOINT #{name}", "TRANSACTION")
193
200
  end
194
201
 
195
202
  def exec_rollback_to_savepoint(name = current_savepoint_name) #:nodoc:
196
- execute("ROLLBACK TO #{name}")
203
+ execute("ROLLBACK TO #{name}", "TRANSACTION")
197
204
  end
198
205
 
199
206
  def release_savepoint(name = current_savepoint_name) #:nodoc:
@@ -252,7 +259,7 @@ module ActiveRecord
252
259
  value = klass.attribute_types[col.name].serialize(value)
253
260
  end
254
261
  uncached do
255
- unless lob_record = select_one(<<~SQL.squish, "Writable Large Object")
262
+ unless lob_record = select_one(sql = <<~SQL.squish, "Writable Large Object")
256
263
  SELECT #{quote_column_name(col.name)} FROM #{quote_table_name(table_name)}
257
264
  WHERE #{quote_column_name(klass.primary_key)} = #{id} FOR UPDATE
258
265
  SQL
@@ -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
@@ -27,11 +27,10 @@ module ActiveRecord
27
27
  raise e
28
28
  end
29
29
  end
30
- connection.execute "GRANT unlimited tablespace TO #{@config['username']}"
31
- connection.execute "GRANT create session TO #{@config['username']}"
32
- connection.execute "GRANT create table TO #{@config['username']}"
33
- connection.execute "GRANT create view TO #{@config['username']}"
34
- connection.execute "GRANT create sequence TO #{@config['username']}"
30
+
31
+ OracleEnhancedAdapter.permissions.each do |permission|
32
+ connection.execute "GRANT #{permission} TO #{@config['username']}"
33
+ end
35
34
  end
36
35
 
37
36
  def drop
@@ -31,7 +31,6 @@ module ActiveRecord
31
31
  end
32
32
 
33
33
  private
34
-
35
34
  def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil)
36
35
  super
37
36
  ensure
@@ -115,9 +115,9 @@ module ActiveRecord
115
115
  else
116
116
  unless database.match?(/^(\:|\/)/)
117
117
  # assume database is a SID if no colon or slash are supplied (backward-compatibility)
118
- database = ":#{database}"
118
+ database = "/#{database}"
119
119
  end
120
- url = config[:url] || "jdbc:oracle:thin:@#{host || 'localhost'}:#{port || 1521}#{database}"
120
+ url = config[:url] || "jdbc:oracle:thin:@//#{host || 'localhost'}:#{port || 1521}#{database}"
121
121
  end
122
122
 
123
123
  prefetch_rows = config[:prefetch_rows] || 100
@@ -238,7 +238,7 @@ module ActiveRecord
238
238
  begin
239
239
  yield if block_given?
240
240
  rescue Java::JavaSql::SQLException => e
241
- raise unless e.message =~ /^(Closed Connection|Io exception:|No more data to read from socket|IO Error:)/
241
+ raise unless /^(Closed Connection|Io exception:|No more data to read from socket|IO Error:)/.match?(e.message)
242
242
  @active = false
243
243
  raise unless should_retry
244
244
  should_retry = false
@@ -512,7 +512,6 @@ module ActiveRecord
512
512
  end
513
513
 
514
514
  private
515
-
516
515
  def lob_to_ruby_value(val)
517
516
  case val
518
517
  when ::Java::OracleSql::CLOB