activerecord-oracle_enhanced-adapter 5.2.8 → 6.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +79 -13
  3. data/README.md +1 -7
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +10 -13
  6. data/lib/active_record/connection_adapters/oracle_enhanced/context_index.rb +7 -7
  7. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +4 -0
  8. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +7 -18
  9. data/lib/active_record/connection_adapters/oracle_enhanced/database_tasks.rb +1 -1
  10. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +17 -4
  11. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +32 -32
  12. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +17 -27
  13. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +4 -4
  14. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +13 -3
  15. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +1 -13
  16. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +55 -71
  17. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +27 -17
  18. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +87 -61
  19. data/lib/active_record/type/oracle_enhanced/character_string.rb +36 -0
  20. data/spec/active_record/connection_adapters/emulation/oracle_adapter_spec.rb +0 -2
  21. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +25 -50
  22. data/spec/active_record/connection_adapters/oracle_enhanced/context_index_spec.rb +5 -13
  23. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +0 -2
  24. data/spec/active_record/connection_adapters/oracle_enhanced/quoting_spec.rb +0 -15
  25. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +1 -31
  26. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +71 -253
  27. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +2 -3
  28. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +81 -81
  29. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +0 -1
  30. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +0 -2
  31. data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +43 -0
  32. data/spec/active_record/oracle_enhanced/type/decimal_spec.rb +56 -0
  33. data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +1 -1
  34. data/spec/active_record/oracle_enhanced/type/json_spec.rb +0 -1
  35. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +1 -2
  36. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +0 -2
  37. data/spec/spec_helper.rb +2 -0
  38. metadata +27 -23
  39. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements_ext.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa24e2267bec0862bb898b8f03c11af04a34543d38f75e8b39a5b46000009437
4
- data.tar.gz: '0485525d25c1f4307c1e9b958cd2f1b286bc5d10542e2fd8615e499a00c989c2'
3
+ metadata.gz: 88d4ded25c413bd3ad25d89e39551c5709e070365d687c515bca47e8c8f327fa
4
+ data.tar.gz: 7e3c7a298c9e4fed4a66c08a8085883ecaf52698841fdf91bbd5fc98213dac41
5
5
  SHA512:
6
- metadata.gz: e70d58d735fec37fd8e19122f37b284397f152c911e3baf8127d8828cefd7b9f139d1acf2f3e147def7c82be26decd7e4f4eb10e85e63489ef6933ab089f83b7
7
- data.tar.gz: 5651ab5ab00219a433b7281959d51068ea47dcd33648761cd4dc4f22c69f285dd79a8c73e262fdabe81042e9751dcb02021392c472649f7662b593daf1187d60
6
+ metadata.gz: 7c90e048c399283b8125ae3aa6929140ead8db07cab427894993445ceb09d0c0665080444a28be6e8609fb26387b5d6bca50f1de2623c090626e2b4275c01d74
7
+ data.tar.gz: db3ff9ab3f530b13074bd7dc9cf2146c0da1756e9a8c57429567f1122716dc0bc03e5724e35cb7e0349830e686146379f404b554f265a3292850608043797b66
data/History.md CHANGED
@@ -1,21 +1,87 @@
1
- ## 5.2.8 / 2019-12-25
1
+ ## 6.0.0.beta1 / 2018-03-18
2
+
3
+ * Major changes
4
+
5
+ * Rails 6 requires Ruby 2.5 [#1801]
6
+ * Support longer identifier for Oracle database 12.2 or higher [#1703 #1705]
7
+ * Introduce `use_shorter_identifier` [#1707]
8
+ * Change `default_sequence_start_value` from 10000 to 1 [#1636]
9
+ * Supports `supports_optimizer_hints?` [#1850 #1852]
10
+ * `OracleEnhanced::SchemaStatements#tables` excludes materialized views [#1708]
11
+ * rake db:structure:dump extracts views by default [#1625 #1641]
12
+ * Drop db link support [#1668 #1681 #1696 #1706]
13
+ * Drop trigger based primary key support for Rails 6 [#1669]
14
+ * Don't allow unsupported NLS parameters [#1685]
15
+ * fix Handling with char-column problem [#1760]
16
+ * Make `t.timestamps` with precision by default [#1818]
17
+ * fix mapping of decimal type to map to `NUMBER` instead of `DECIMAL` [#1840]
2
18
 
3
19
  * Changes and bug fixes
4
- * Uninstall SimpleCov [#1968 #1970]
5
20
 
6
- ## 5.2.7 / 2019-12-20
21
+ * Handle ORA-02292 as `InvalidForeignKey` [#1771]
22
+ * Suppress deprecated warning for `table_name_length` [#1772]
23
+ * `update_attributes!` will be deprecated in Rails 6 [#1665]
24
+ * `update_attributes` will be deprecated in Rails 6 [#1667]
25
+ * Remove `OCI8#describe` to use `OracleEnhanced::Connection#describe` [#1639]
26
+ * Remove `strip_heredoc` [#1652]
27
+ * Remove `rails/arel` from Gemfile [#1711]
28
+ * Remove `rails/arel` from bug report templates [skip ci] [#1715]
29
+ * Remove NativeException [#1666 #1762]
30
+ * Do not set nil value to java.util.Properties [#1763]
31
+ * Deprecated `table_name_length` and `column_name_length` [#1770]
32
+ * Add a check to supported Oracle database version [#1773]
33
+ * Update bug report templates [#1777]
34
+ * Use `supports_foreign_keys?` instead of removed `supports_foreign_keys_in_create?` [#1825]
35
+ * Ensure `clear_cache!` clears the prepared statements cache [#1845]
7
36
 
8
- * Changes and bug fixes
9
- * Address undefined local variable or method sql' [#1932 #1962 #1964]
10
- * CI against Ruby 2.6.4 and Ruby 2.5.6 [#1922]
11
- * Lock simplecov version for Ruby 2.2 and 2.3 [#1902]
12
-
13
- ## 5.2.6 / 2019-05-17
37
+ * Refactoring
14
38
 
15
- * Changes and bug fixes
16
- * Add TCP keepalive and TCP keepalive time configurations [#1874 #1878]
17
- * CI against Ruby 2.6.2 and 2.5.5 #1849
18
- * CI against Ruby 2.4.6 #1858
39
+ * Extract `structure_dump_views` and `structure_dump_synonyms` [#1640]
40
+ * Remove unnecessary `respond_to?(:report_on_exception)` [#1664]
41
+ * Remove deprecated `#insert_fixtures` method for Rails 6.0 [#1815]
42
+ * Use `SYS_CONTEXT('userenv', 'current_schema')` to find schema objects [#1671]
43
+ * Use `SYS_CONTEXT('userenv', 'current_schema')` for owner [#1672]
44
+ * Suppress warning `BigDecimal.new` is deprecated [#1742]
45
+ * Refactor to initialize `TableDefinition` by kwargs [#1785]
46
+ * Redact SQL in errors [#1791]
47
+ * Arity change at `sql_for_insert` [#1814]
48
+
49
+ * CI
50
+ * Use Ubuntu Xenial at Travis CI [#1790]
51
+ * Bump Ruby versions to 2.6.2 and 2.5.4 [#1847]
52
+ * CI against Ruby 2.5.5 [#1848]
53
+ * Do not run CI against Ruby 2.2, which will not be supported with Rails 6 [#1653]
54
+ * CI against JRuby 9.2.6.0 [#1824]
55
+ * Show ruby version at CI [#1829]
56
+ * Remove unused blocklist from .travis.yml [#1830]
57
+ * Add spec for custom sequence name [#1846]
58
+ * Restore old Code Climate behavior [#1716]
59
+ * Do not install bundler explicitly [#1725]
60
+
61
+ * RuboCop
62
+
63
+ * Add RuboCop to Gemfile [#1841]
64
+ * Bump RuboCop to 0.63.0 [#1816]
65
+ * No need to exclude `jdbc_connection.rb` for `Style/ColonMethodCall` cop [#1698]
66
+ * Enable `Style/ColonMethodCall` cop [#1658]
67
+ * Enable `Lint/StringConversionInInterpolation` cop [#1724]
68
+ * Add `Style/RedundantFreeze` to remove redudant `.freeze` [#1662]
69
+ * Use `Layout/EndAlignment` cop to support RuboCop 0.54 [#1709]
70
+ * Introduced StartWith, EndWith and RegexpMatch cops [#1738]
71
+ * Enable `Layout/EmptyLinesAroundBlockBody` cop [#1732]
72
+ * Turn on performance based cops [#1734]
73
+ * Enable performance unfreeze string cop [#1729]
74
+ * Enable `Lint/UriEscapeUnescape` cop [#1758]
75
+ * Enable Style/ParenthesesAroundCondition cop [#1759]
76
+ * Enable performance unfreeze string cop [#1729]
77
+ * Enable `Layout/SpaceAfterSemicolon` cop [#1800]
78
+ * Enable `Style/RedundantBegin` cop [#1802]
79
+ * Enable `Lint/ShadowingOuterLocalVariable` cop [#1810]
80
+ * Enable `Lint/UselessAssignment` cop [#1812]
81
+ * Enable `Lint/DeprecatedClassMethods` cop [#1813]
82
+ * Enable `Lint/ErbNewArguments` cop [#1823]
83
+ * Enable `Lint/AmbiguousOperator` and `Lint/AmbiguousRegexpLiteral` cops [#1842]
84
+ * Enable `Performance/ReverseEach` cop [#1843]
19
85
 
20
86
  ## 5.2.5 / 2019-03-05
21
87
 
data/README.md CHANGED
@@ -6,7 +6,7 @@ Oracle enhanced adapter for ActiveRecord
6
6
  DESCRIPTION
7
7
  -----------
8
8
 
9
- Oracle enhanced ActiveRecord adapter provides Oracle database access from Ruby on Rails applications. Oracle enhanced adapter can be used from Ruby on Rails versions between 2.3.x and 5.1 and it is working with Oracle database versions from 10g to 12c.
9
+ Oracle enhanced ActiveRecord adapter provides Oracle database access from Ruby on Rails applications. Oracle enhanced adapter can be used from Ruby on Rails versions between 2.3.x and 5.2 and it is working with Oracle database versions from 10g to 12c.
10
10
 
11
11
  INSTALLATION
12
12
  ------------
@@ -666,12 +666,6 @@ class Post < ActiveRecord::Base
666
666
  end
667
667
  ```
668
668
 
669
- * Respect database instance `cursor_sharing` value exact by default
670
-
671
- Oracle enhanced adapter changed `cursor_sharing` parameter value to `force` in Rails 5.1 or lower. However, Oracle enhanced adapter 5.2 supports prepared statements for dictionary queries There is no need to change `cursor_sharing` value to `exact` anymore.
672
-
673
- If you want to keep the old behavior in Rails 5.2, set `cursor_sharing: :force` explicitly in the database.yml.
674
-
675
669
  * Remove `OracleEnhancedAdapter.cache_columns` to use Rails `db:schema:cache:dump`
676
670
 
677
671
  Refer https://github.com/rsim/oracle-enhanced#schema-cache
data/VERSION CHANGED
@@ -1 +1 @@
1
- 5.2.8
1
+ 6.0.0.beta1
@@ -24,11 +24,8 @@ module ActiveRecord
24
24
  def describe(name)
25
25
  name = name.to_s
26
26
  if name.include?("@")
27
- name, db_link = name.split("@")
28
- default_owner = _select_value("SELECT username FROM all_db_links WHERE db_link = '#{db_link.upcase}'")
29
- db_link = "@#{db_link}"
27
+ raise ArgumentError "db link is not supported"
30
28
  else
31
- db_link = nil
32
29
  default_owner = @owner
33
30
  end
34
31
  real_name = OracleEnhanced::Quoting.valid_table_name?(name) ? name.upcase : name
@@ -39,31 +36,31 @@ module ActiveRecord
39
36
  end
40
37
  sql = <<-SQL.strip.gsub(/\s+/, " ")
41
38
  SELECT owner, table_name, 'TABLE' name_type
42
- FROM all_tables#{db_link}
39
+ FROM all_tables
43
40
  WHERE owner = '#{table_owner}'
44
41
  AND table_name = '#{table_name}'
45
42
  UNION ALL
46
43
  SELECT owner, view_name table_name, 'VIEW' name_type
47
- FROM all_views#{db_link}
44
+ FROM all_views
48
45
  WHERE owner = '#{table_owner}'
49
46
  AND view_name = '#{table_name}'
50
47
  UNION ALL
51
- SELECT table_owner, DECODE(db_link, NULL, table_name, table_name||'@'||db_link), 'SYNONYM' name_type
52
- FROM all_synonyms#{db_link}
48
+ SELECT table_owner, table_name, 'SYNONYM' name_type
49
+ FROM all_synonyms
53
50
  WHERE owner = '#{table_owner}'
54
51
  AND synonym_name = '#{table_name}'
55
52
  UNION ALL
56
- SELECT table_owner, DECODE(db_link, NULL, table_name, table_name||'@'||db_link), 'SYNONYM' name_type
57
- FROM all_synonyms#{db_link}
53
+ SELECT table_owner, table_name, 'SYNONYM' name_type
54
+ FROM all_synonyms
58
55
  WHERE owner = 'PUBLIC'
59
56
  AND synonym_name = '#{real_name}'
60
57
  SQL
61
58
  if result = _select_one(sql)
62
59
  case result["name_type"]
63
60
  when "SYNONYM"
64
- describe("#{result['owner'] && "#{result['owner']}."}#{result['table_name']}#{db_link}")
61
+ describe("#{result['owner'] && "#{result['owner']}."}#{result['table_name']}")
65
62
  else
66
- db_link ? [result["owner"], result["table_name"], db_link] : [result["owner"], result["table_name"]]
63
+ [result["owner"], result["table_name"]]
67
64
  end
68
65
  else
69
66
  raise OracleEnhanced::ConnectionException, %Q{"DESC #{name}" failed; does it exist?}
@@ -85,7 +82,7 @@ module ActiveRecord
85
82
  # To avoid it is called from anywhere else, added _ at the beginning of the method name.
86
83
  def _oracle_downcase(column_name)
87
84
  return nil if column_name.nil?
88
- column_name =~ /[a-z]/ ? column_name : column_name.downcase
85
+ /[a-z]/.match?(column_name) ? column_name : column_name.downcase
89
86
  end
90
87
 
91
88
  # _select_one and _select_value methods are expected to be called
@@ -86,7 +86,7 @@ module ActiveRecord
86
86
  create_index_column_trigger(table_name, index_name, options[:index_column], options[:index_column_trigger_on])
87
87
  end
88
88
 
89
- sql = "CREATE INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}".dup
89
+ sql = +"CREATE INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
90
90
  sql << " (#{quoted_column_name})"
91
91
  sql << " INDEXTYPE IS CTXSYS.CONTEXT"
92
92
  parameters = []
@@ -153,7 +153,7 @@ module ActiveRecord
153
153
  CREATE OR REPLACE PROCEDURE #{quote_table_name(procedure_name)}
154
154
  (p_rowid IN ROWID,
155
155
  p_clob IN OUT NOCOPY CLOB) IS
156
- -- add_context_index_parameters #{(column_names + select_queries).inspect}#{!options.empty? ? ', '.dup << options.inspect[1..-2] : ''}
156
+ -- add_context_index_parameters #{(column_names + select_queries).inspect}#{!options.empty? ? +', ' << options.inspect[1..-2] : ''}
157
157
  #{
158
158
  selected_columns.map do |cols|
159
159
  cols.map do |col|
@@ -170,7 +170,7 @@ module ActiveRecord
170
170
  #{
171
171
  (column_names.map do |col|
172
172
  col = col.to_s
173
- "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length + 2}, '<#{col}>');\n".dup <<
173
+ +"DBMS_LOB.WRITEAPPEND(p_clob, #{col.length + 2}, '<#{col}>');\n" <<
174
174
  "IF LENGTH(r1.#{col}) > 0 THEN\n" <<
175
175
  "DBMS_LOB.WRITEAPPEND(p_clob, LENGTH(r1.#{col}), r1.#{col});\n" <<
176
176
  "END IF;\n" <<
@@ -188,7 +188,7 @@ module ActiveRecord
188
188
  "END LOOP;\n" <<
189
189
  (cols.map do |col|
190
190
  col = col.to_s
191
- "DBMS_LOB.WRITEAPPEND(p_clob, #{col.length + 2}, '<#{col}>');\n".dup <<
191
+ +"DBMS_LOB.WRITEAPPEND(p_clob, #{col.length + 2}, '<#{col}>');\n" <<
192
192
  "IF LENGTH(l_#{col}) > 0 THEN\n" <<
193
193
  "DBMS_LOB.WRITEAPPEND(p_clob, LENGTH(l_#{col}), l_#{col});\n" <<
194
194
  "END IF;\n" <<
@@ -225,7 +225,7 @@ module ActiveRecord
225
225
 
226
226
  def create_storage_preference(storage_name, tablespace)
227
227
  drop_ctx_preference(storage_name)
228
- sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{storage_name}', 'BASIC_STORAGE');\n".dup
228
+ sql = +"BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{storage_name}', 'BASIC_STORAGE');\n"
229
229
  ["I_TABLE_CLAUSE", "K_TABLE_CLAUSE", "R_TABLE_CLAUSE",
230
230
  "N_TABLE_CLAUSE", "I_INDEX_CLAUSE", "P_TABLE_CLAUSE"].each do |clause|
231
231
  default_clause = case clause
@@ -241,7 +241,7 @@ module ActiveRecord
241
241
 
242
242
  def create_lexer_preference(lexer_name, lexer_type, options)
243
243
  drop_ctx_preference(lexer_name)
244
- sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{lexer_name}', '#{lexer_type}');\n".dup
244
+ sql = +"BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{lexer_name}', '#{lexer_type}');\n"
245
245
  options.each do |key, value|
246
246
  plsql_value = case value
247
247
  when String; "'#{value}'"
@@ -258,7 +258,7 @@ module ActiveRecord
258
258
 
259
259
  def create_wordlist_preference(wordlist_name, wordlist_type, options)
260
260
  drop_ctx_preference(wordlist_name)
261
- sql = "BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{wordlist_name}', '#{wordlist_type}');\n".dup
261
+ sql = +"BEGIN\nCTX_DDL.CREATE_PREFERENCE('#{wordlist_name}', '#{wordlist_type}');\n"
262
262
  options.each do |key, value|
263
263
  plsql_value = case value
264
264
  when String; "'#{value}'"
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/deprecation"
4
+
3
5
  module ActiveRecord
4
6
  module ConnectionAdapters
5
7
  module OracleEnhanced
@@ -15,11 +17,13 @@ module ActiveRecord
15
17
  def table_name_length
16
18
  IDENTIFIER_MAX_LENGTH
17
19
  end
20
+ deprecate :table_name_length
18
21
 
19
22
  # the maximum length of a column name
20
23
  def column_name_length
21
24
  IDENTIFIER_MAX_LENGTH
22
25
  end
26
+ deprecate :column_name_length
23
27
 
24
28
  # Returns the maximum allowed length for an index name. This
25
29
  # limit is enforced by rails and Is less than or equal to
@@ -13,9 +13,9 @@ module ActiveRecord
13
13
  log(sql, name) { @connection.exec(sql) }
14
14
  end
15
15
 
16
- def clear_cache!
17
- @statements.clear
16
+ def clear_cache! # :nodoc:
18
17
  reload_type_map
18
+ super
19
19
  end
20
20
 
21
21
  def exec_query(sql, name = "SQL", binds = [], prepare: false)
@@ -76,8 +76,8 @@ module ActiveRecord
76
76
 
77
77
  # New method in ActiveRecord 3.1
78
78
  # Will add RETURNING clause in case of trigger generated primary keys
79
- def sql_for_insert(sql, pk, id_value, sequence_name, binds)
80
- unless id_value || pk == false || pk.nil? || pk.is_a?(Array)
79
+ def sql_for_insert(sql, pk, sequence_name, binds)
80
+ unless pk == false || pk.nil? || pk.is_a?(Array)
81
81
  sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO :returning_id"
82
82
  (binds = binds.dup) << ActiveRecord::Relation::QueryAttribute.new("returning_id", nil, Type::OracleEnhanced::Integer.new)
83
83
  end
@@ -91,7 +91,7 @@ module ActiveRecord
91
91
 
92
92
  # New method in ActiveRecord 3.1
93
93
  def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
94
- sql, binds = sql_for_insert(sql, pk, nil, sequence_name, binds)
94
+ sql, binds = sql_for_insert(sql, pk, sequence_name, binds)
95
95
  type_casted_binds = type_casted_binds(binds)
96
96
 
97
97
  log(sql, name, binds, type_casted_binds) do
@@ -108,7 +108,7 @@ module ActiveRecord
108
108
 
109
109
  cursor.bind_params(type_casted_binds)
110
110
 
111
- if sql =~ /:returning_id/
111
+ if /:returning_id/.match?(sql)
112
112
  # it currently expects that returning_id comes last part of binds
113
113
  returning_id_index = binds.size
114
114
  cursor.bind_returning_param(returning_id_index, Integer)
@@ -222,17 +222,6 @@ module ActiveRecord
222
222
  end
223
223
  end
224
224
 
225
- # fallback to non bulk fixture insert
226
- def insert_fixtures(fixtures, table_name)
227
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
228
- `insert_fixtures` is deprecated and will be removed in the next version of Rails.
229
- Consider using `insert_fixtures_set` for performance improvement.
230
- MSG
231
- fixtures.each do |fixture|
232
- insert_fixture(fixture, table_name)
233
- end
234
- end
235
-
236
225
  def insert_fixtures_set(fixture_set, tables_to_delete = [])
237
226
  disable_referential_integrity do
238
227
  transaction(requires_new: true) do
@@ -263,7 +252,7 @@ module ActiveRecord
263
252
  value = klass.attribute_types[col.name].serialize(value)
264
253
  end
265
254
  uncached do
266
- unless lob_record = select_one(sql = <<-SQL.strip.gsub(/\s+/, " "), "Writable Large Object")
255
+ unless lob_record = select_one(<<-SQL.strip.gsub(/\s+/, " "), "Writable Large Object")
267
256
  SELECT #{quote_column_name(col.name)} FROM #{quote_table_name(table_name)}
268
257
  WHERE #{quote_column_name(klass.primary_key)} = #{id} FOR UPDATE
269
258
  SQL
@@ -21,7 +21,7 @@ module ActiveRecord
21
21
  begin
22
22
  connection.execute "CREATE USER #{@config['username']} IDENTIFIED BY #{@config['password']}"
23
23
  rescue => e
24
- if e.message =~ /ORA-01920/ # user name conflicts with another user or role name
24
+ if /ORA-01920/.match?(e.message) # user name conflicts with another user or role name
25
25
  connection.execute "ALTER USER #{@config['username']} IDENTIFIED BY #{@config['password']}"
26
26
  else
27
27
  raise e
@@ -18,7 +18,7 @@ begin
18
18
  # Oracle 12c Release 2 client provides ojdbc8.jar
19
19
  ojdbc_jars = %w(ojdbc8.jar ojdbc7.jar ojdbc6.jar)
20
20
 
21
- if ENV_JAVA["java.class.path"] !~ Regexp.new(ojdbc_jars.join("|"))
21
+ if !ENV_JAVA["java.class.path"]&.match?(Regexp.new(ojdbc_jars.join("|")))
22
22
  # On Unix environment variable should be PATH, on Windows it is sometimes Path
23
23
  env_path = (ENV["PATH"] || ENV["Path"] || "").split(File::PATH_SEPARATOR)
24
24
  # Look for JDBC driver at first in lib subdirectory (application specific JDBC file version)
@@ -26,7 +26,7 @@ begin
26
26
  ["./lib"].concat($LOAD_PATH).concat(env_path).detect do |dir|
27
27
  # check any compatible JDBC driver in the priority order
28
28
  ojdbc_jars.any? do |ojdbc_jar|
29
- if File.exists?(file_path = File.join(dir, ojdbc_jar))
29
+ if File.exist?(file_path = File.join(dir, ojdbc_jar))
30
30
  require file_path
31
31
  true
32
32
  end
@@ -113,7 +113,7 @@ module ActiveRecord
113
113
  if database && (using_tns_alias || host == "connection-string")
114
114
  url = "jdbc:oracle:thin:@#{database}"
115
115
  else
116
- unless database.match(/^(\:|\/)/)
116
+ unless database.match?(/^(\:|\/)/)
117
117
  # assume database is a SID if no colon or slash are supplied (backward-compatibility)
118
118
  database = ":#{database}"
119
119
  end
@@ -125,6 +125,8 @@ module ActiveRecord
125
125
  time_zone = config[:time_zone] || ENV["TZ"] || java.util.TimeZone.default.getID
126
126
 
127
127
  properties = java.util.Properties.new
128
+ raise "username not set" unless username
129
+ raise "password not set" unless password
128
130
  properties.put("user", username)
129
131
  properties.put("password", password)
130
132
  properties.put("defaultRowPrefetch", "#{prefetch_rows}") if prefetch_rows
@@ -161,6 +163,10 @@ module ActiveRecord
161
163
  end
162
164
  end
163
165
 
166
+ OracleEnhancedAdapter::FIXED_NLS_PARAMETERS.each do |key, value|
167
+ exec "alter session set #{key} = '#{value}'"
168
+ end
169
+
164
170
  self.autocommit = true
165
171
 
166
172
  schema = config[:schema] && config[:schema].to_s
@@ -312,6 +318,8 @@ module ActiveRecord
312
318
  @raw_statement.setClob(position, value)
313
319
  when Type::OracleEnhanced::Raw
314
320
  @raw_statement.setString(position, OracleEnhanced::Quoting.encode_raw(value))
321
+ when Type::OracleEnhanced::CharacterString::Data
322
+ @raw_statement.setFixedCHAR(position, value.to_s)
315
323
  when String
316
324
  @raw_statement.setString(position, value)
317
325
  when Java::OracleSql::DATE
@@ -470,8 +478,13 @@ module ActiveRecord
470
478
  end
471
479
  when :BINARY_FLOAT
472
480
  rset.getFloat(i)
473
- when :VARCHAR2, :CHAR, :LONG, :NVARCHAR2, :NCHAR
481
+ when :VARCHAR2, :LONG, :NVARCHAR2
474
482
  rset.getString(i)
483
+ when :CHAR, :NCHAR
484
+ char_str = rset.getString(i)
485
+ if !char_str.nil?
486
+ char_str.rstrip
487
+ end
475
488
  when :DATE
476
489
  if dt = rset.getDATE(i)
477
490
  d = dt.dateValue
@@ -15,7 +15,7 @@ end
15
15
  required_oci8_version = [2, 2, 4]
16
16
  oci8_version_ints = OCI8::VERSION.scan(/\d+/).map { |s| s.to_i }
17
17
  if (oci8_version_ints <=> required_oci8_version) < 0
18
- $stderr.puts <<-EOS.strip_heredoc
18
+ $stderr.puts <<~EOS
19
19
  "ERROR: ruby-oci8 version #{OCI8::VERSION} is too old. Please install ruby-oci8 version #{required_oci8_version.join('.')} or later."
20
20
  EOS
21
21
 
@@ -125,6 +125,8 @@ module ActiveRecord
125
125
  @raw_cursor.bind_param(position, OracleEnhanced::Quoting.encode_raw(value))
126
126
  when ActiveModel::Type::Decimal
127
127
  @raw_cursor.bind_param(position, BigDecimal(value.to_s))
128
+ when Type::OracleEnhanced::CharacterString::Data
129
+ @raw_cursor.bind_param(position, value.to_character_str)
128
130
  when NilClass
129
131
  @raw_cursor.bind_param(position, nil, String)
130
132
  else
@@ -151,8 +153,19 @@ module ActiveRecord
151
153
  def fetch(options = {})
152
154
  if row = @raw_cursor.fetch
153
155
  get_lob_value = options[:get_lob_value]
156
+ col_index = 0
154
157
  row.map do |col|
155
- @connection.typecast_result_value(col, get_lob_value)
158
+ col_value = @connection.typecast_result_value(col, get_lob_value)
159
+ col_metadata = @raw_cursor.column_metadata.fetch(col_index)
160
+ if !col_metadata.nil?
161
+ key = col_metadata.data_type
162
+ case key.to_s.downcase
163
+ when "char"
164
+ col_value = col.to_s.rstrip
165
+ end
166
+ end
167
+ col_index = col_index + 1
168
+ col_value
156
169
  end
157
170
  end
158
171
  end
@@ -184,7 +197,16 @@ module ActiveRecord
184
197
  hash = column_hash.dup
185
198
 
186
199
  cols.each_with_index do |col, i|
187
- hash[col] = typecast_result_value(row[i], get_lob_value)
200
+ col_value = typecast_result_value(row[i], get_lob_value)
201
+ col_metadata = cursor.column_metadata.fetch(i)
202
+ if !col_metadata.nil?
203
+ key = col_metadata.data_type
204
+ case key.to_s.downcase
205
+ when "char"
206
+ col_value = col_value.to_s.rstrip
207
+ end
208
+ end
209
+ hash[col] = col_value
188
210
  end
189
211
 
190
212
  rows << hash
@@ -200,17 +222,7 @@ module ActiveRecord
200
222
  end
201
223
 
202
224
  def describe(name)
203
- # fall back to SELECT based describe if using database link
204
- return super if name.to_s.include?("@")
205
- quoted_name = OracleEnhanced::Quoting.valid_table_name?(name) ? name : "\"#{name}\""
206
- @raw_connection.describe(quoted_name)
207
- rescue OCIException => e
208
- if e.code == 4043
209
- raise OracleEnhanced::ConnectionException, %Q{"DESC #{name}" failed; does it exist?}
210
- else
211
- # fall back to SELECT which can handle synonyms to database links
212
- super
213
- end
225
+ super
214
226
  end
215
227
 
216
228
  # Return OCIError error code
@@ -285,8 +297,6 @@ module ActiveRecord
285
297
  # The OracleEnhancedOCIFactory factors out the code necessary to connect and
286
298
  # configure an Oracle/OCI connection.
287
299
  class OracleEnhancedOCIFactory #:nodoc:
288
- DEFAULT_TCP_KEEPALIVE_TIME = 600
289
-
290
300
  def self.new_connection(config)
291
301
  # to_s needed if username, password or database is specified as number in database.yml file
292
302
  username = config[:username] && config[:username].to_s
@@ -316,13 +326,11 @@ module ActiveRecord
316
326
  else
317
327
  database
318
328
  end
319
-
320
- OCI8.properties[:tcp_keepalive] = config[:tcp_keepalive] == false ? false : true
329
+ OCI8.properties[:tcp_keepalive] = true
321
330
  begin
322
- OCI8.properties[:tcp_keepalive_time] = config[:tcp_keepalive_time] || DEFAULT_TCP_KEEPALIVE_TIME
331
+ OCI8.properties[:tcp_keepalive_time] = 600
323
332
  rescue NotImplementedError
324
333
  end
325
-
326
334
  conn = OCI8.new username, password, connection_string, privilege
327
335
  conn.autocommit = true
328
336
  conn.non_blocking = true if async
@@ -342,6 +350,10 @@ module ActiveRecord
342
350
  conn.exec "alter session set #{key} = '#{value}'"
343
351
  end
344
352
  end
353
+
354
+ OracleEnhancedAdapter::FIXED_NLS_PARAMETERS.each do |key, value|
355
+ conn.exec "alter session set #{key} = '#{value}'"
356
+ end
345
357
  conn
346
358
  end
347
359
  end
@@ -349,18 +361,6 @@ module ActiveRecord
349
361
  end
350
362
  end
351
363
 
352
- class OCI8 #:nodoc:
353
- def describe(name)
354
- info = describe_table(name.to_s)
355
- raise %Q{"DESC #{name}" failed} if info.nil?
356
- if info.respond_to?(:obj_link) && info.obj_link
357
- [info.obj_schema, info.obj_name, "@" + info.obj_link]
358
- else
359
- [info.obj_schema, info.obj_name]
360
- end
361
- end
362
- end
363
-
364
364
  # The OCI8AutoRecover class enhances the OCI8 driver with auto-recover and
365
365
  # reset functionality. If a call to #exec fails, and autocommit is turned on
366
366
  # (ie., we're not in the middle of a longer transaction), it will