activerecord-oracle_enhanced-adapter 6.0.6 → 6.1.0.rc1

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 +80 -4
  3. data/README.md +1 -1
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +2 -3
  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 +7 -9
  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 +2 -3
  14. data/lib/active_record/connection_adapters/oracle_enhanced/procedures.rb +0 -1
  15. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +2 -3
  16. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +2 -3
  17. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +16 -4
  18. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +55 -55
  19. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +35 -39
  20. data/lib/active_record/connection_adapters/oracle_enhanced/type_metadata.rb +2 -1
  21. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +58 -40
  22. data/lib/active_record/type/oracle_enhanced/boolean.rb +0 -1
  23. data/lib/active_record/type/oracle_enhanced/integer.rb +0 -1
  24. data/lib/arel/visitors/oracle.rb +253 -0
  25. data/lib/arel/visitors/oracle12.rb +160 -0
  26. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +9 -3
  27. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +6 -1
  28. data/spec/active_record/connection_adapters/oracle_enhanced/procedures_spec.rb +0 -1
  29. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +27 -0
  30. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +2 -2
  31. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +30 -60
  32. data/spec/active_record/oracle_enhanced/type/national_character_string_spec.rb +4 -2
  33. data/spec/spec_config.yaml.template +2 -2
  34. data/spec/spec_helper.rb +13 -2
  35. data/spec/support/stats.sql +3 -0
  36. metadata +31 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1410c7eb8f55a7b4c96b8016f31c573512699978498ee6effae6d4875b1e3f31
4
- data.tar.gz: 36cbc570c5c5a1c6d074353f1de0d8d6ce07c90fd5b906727d7ee2e78a473a1e
3
+ metadata.gz: 47264bf6ac81ec4786fb1c3021c29661b8a02df12ac7a2ffc2e4ad02353794dd
4
+ data.tar.gz: eaceb8f2950700b0cc5eba5c1b0f7dae657bf26aa529444e83d901c7a4cb46ac
5
5
  SHA512:
6
- metadata.gz: 1f1ba2aed7eef1fa08e31c4fe7f43762eb077b10e412f9db61228589d1387f440b64b17db05fd3fd796e0eb4ebc8ca00f91f767f0ea6402e079783265cb583a6
7
- data.tar.gz: 700df5182daf9a04a67dcc478aa378d9deb8d09fba726ccf2ce9878b8c1dc70f56a5a135048e00438e5078b9916467f8b356e6a3a4bc5bc8897fb874a8a686c3
6
+ metadata.gz: 0c96bb5cdf7508d310484f6a6f25bec23c9eee8029df4e9cd4075f6acd1671c02d90837db4a88ca054745d218664049b55ec238cb5313d47dbbf868b85d829ea
7
+ data.tar.gz: 2ef70ebd9e11f9c6a5739b7644c4ac770b4fb2c3ebc2b56b46479625b3de0f89d78f77618ac7fe077416a373859662d5c4dd11ee7ff0eca4651198aca181d973
data/History.md CHANGED
@@ -1,9 +1,85 @@
1
- ## 6.0.5 / 2020-12-17
1
+ ## 6.1.0.rc1 / 2020-11-03
2
2
 
3
3
  * Changes and bug fixes
4
- * Address `next_sequence_value` ArgumentError syntax [#2048 #2050]
5
- * Add /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ hint to address slow SCHEMA queries [#2055, #2069]
6
- * `build_subselect` does not have ordering [#2023, #2070, #2073]
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]
7
83
 
8
84
  ## 6.0.4 / 2020-08-18
9
85
 
data/README.md CHANGED
@@ -663,7 +663,7 @@ if any database structure changed by migrations, execute `rails db:schema:cache:
663
663
 
664
664
  UPGRADE
665
665
  ---------------
666
- ### Upgrade Rails 5.0 or older version to Rails 5.2
666
+ ### Upgrade Rails 5.1 or older version to Rails 5.2
667
667
 
668
668
  * `emulate_booleans_from_strings = true` change
669
669
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.0.6
1
+ 6.1.0.rc1
@@ -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
@@ -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
@@ -42,7 +42,7 @@ module ActiveRecord
42
42
  cursor.exec
43
43
  end
44
44
 
45
- if (name == "EXPLAIN") && sql =~ /^EXPLAIN/
45
+ if (name == "EXPLAIN") && sql.start_with?("EXPLAIN")
46
46
  res = true
47
47
  else
48
48
  columns = cursor.get_col_names.map do |col_name|
@@ -53,7 +53,7 @@ module ActiveRecord
53
53
  while row = cursor.fetch(fetch_options)
54
54
  rows << row
55
55
  end
56
- res = ActiveRecord::Result.new(columns, rows)
56
+ res = build_result(columns: columns, rows: rows)
57
57
  end
58
58
 
59
59
  cursor.close unless cached
@@ -67,7 +67,7 @@ module ActiveRecord
67
67
 
68
68
  def explain(arel, binds = [])
69
69
  sql = "EXPLAIN PLAN FOR #{to_sql(arel, binds)}"
70
- return if sql =~ /FROM all_/
70
+ return if /FROM all_/.match?(sql)
71
71
  if ORACLE_ENHANCED_CONNECTION == :jdbc
72
72
  exec_query(sql, "EXPLAIN", binds)
73
73
  else
@@ -130,7 +130,7 @@ module ActiveRecord
130
130
  rows << [returning_id]
131
131
  end
132
132
  cursor.close unless cached
133
- ActiveRecord::Result.new(returning_id_col || [], rows)
133
+ build_result(columns: returning_id_col || [], rows: rows)
134
134
  end
135
135
  end
136
136
 
@@ -196,11 +196,11 @@ module ActiveRecord
196
196
  end
197
197
 
198
198
  def create_savepoint(name = current_savepoint_name) #:nodoc:
199
- execute("SAVEPOINT #{name}")
199
+ execute("SAVEPOINT #{name}", "TRANSACTION")
200
200
  end
201
201
 
202
202
  def exec_rollback_to_savepoint(name = current_savepoint_name) #:nodoc:
203
- execute("ROLLBACK TO #{name}")
203
+ execute("ROLLBACK TO #{name}", "TRANSACTION")
204
204
  end
205
205
 
206
206
  def release_savepoint(name = current_savepoint_name) #:nodoc:
@@ -254,11 +254,9 @@ module ActiveRecord
254
254
  columns.each do |col|
255
255
  value = attributes[col.name]
256
256
  # changed sequence of next two lines - should check if value is nil before converting to yaml
257
- next unless value
257
+ next if value.blank?
258
258
  if klass.attribute_types[col.name].is_a? Type::Serialized
259
259
  value = klass.attribute_types[col.name].serialize(value)
260
- # value can be nil after serialization because ActiveRecord serializes [] and {} as nil
261
- next unless value
262
260
  end
263
261
  uncached do
264
262
  unless lob_record = select_one(sql = <<~SQL.squish, "Writable Large Object")
@@ -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
@@ -18,13 +18,12 @@ module ActiveRecord #:nodoc:
18
18
  module ClassMethods
19
19
  def lob_columns
20
20
  columns.select do |column|
21
- column.sql_type_metadata.sql_type =~ /LOB$/
21
+ column.sql_type_metadata.sql_type.end_with?("LOB")
22
22
  end
23
23
  end
24
24
  end
25
25
 
26
26
  private
27
-
28
27
  def enhanced_write_lobs
29
28
  if self.class.connection.is_a?(ConnectionAdapters::OracleEnhancedAdapter) &&
30
29
  !(self.class.custom_create_method || self.class.custom_update_method)
@@ -269,7 +269,6 @@ module ActiveRecord
269
269
  end
270
270
 
271
271
  private
272
-
273
272
  def date_without_time?(value)
274
273
  case value
275
274
  when OraDate
@@ -323,9 +322,9 @@ module ActiveRecord
323
322
  # connection using host, port and database name
324
323
  elsif host || port
325
324
  host ||= "localhost"
326
- host = "[#{host}]" if host =~ /^[^\[].*:/ # IPv6
325
+ host = "[#{host}]" if /^[^\[].*:/.match?(host) # IPv6
327
326
  port ||= 1521
328
- database = "/#{database}" unless database.match(/^\//)
327
+ database = "/#{database}" unless database.start_with?("/")
329
328
  "//#{host}:#{port}#{database}"
330
329
  # if no host is specified then assume that
331
330
  # database parameter is TNS alias or TNS connection string
@@ -97,7 +97,6 @@ module ActiveRecord #:nodoc:
97
97
  end
98
98
 
99
99
  private
100
-
101
100
  # Creates a record with custom create method
102
101
  # and returns its id.
103
102
  def _create_record
@@ -169,7 +169,6 @@ module ActiveRecord
169
169
  private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
170
170
 
171
171
  private
172
-
173
172
  def oracle_downcase(column_name)
174
173
  return nil if column_name.nil?
175
174
  /[a-z]/.match?(column_name) ? column_name : column_name.downcase
@@ -179,8 +178,8 @@ module ActiveRecord
179
178
  end
180
179
  end
181
180
 
182
- # if MRI or YARV
183
- if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
181
+ # if MRI or YARV or TruffleRuby
182
+ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" || RUBY_ENGINE == "truffleruby"
184
183
  require "active_record/connection_adapters/oracle_enhanced/oci_quoting"
185
184
  # if JRuby
186
185
  elsif RUBY_ENGINE == "jruby"
@@ -3,9 +3,8 @@
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module OracleEnhanced
6
- class SchemaCreation < AbstractAdapter::SchemaCreation
6
+ class SchemaCreation < SchemaCreation
7
7
  private
8
-
9
8
  def visit_ColumnDefinition(o)
10
9
  if [:blob, :clob, :nclob].include?(sql_type = type_to_sql(o.type, **o.options).downcase.to_sym)
11
10
  if (tablespace = default_tablespace_for(sql_type))
@@ -36,7 +35,7 @@ module ActiveRecord
36
35
  create_sql << " TABLESPACE #{tablespace}"
37
36
  end
38
37
  end
39
- add_table_options!(create_sql, table_options(o))
38
+ add_table_options!(create_sql, o)
40
39
  create_sql << " AS #{to_sql(o.as)}" if o.as
41
40
  create_sql
42
41
  end
@@ -4,7 +4,15 @@ module ActiveRecord #:nodoc:
4
4
  module ConnectionAdapters #:nodoc:
5
5
  module OracleEnhanced #:nodoc:
6
6
  class SchemaDumper < ConnectionAdapters::SchemaDumper #:nodoc:
7
+ DEFAULT_PRIMARY_KEY_COLUMN_SPEC = { precision: "38", null: "false" }.freeze
8
+ private_constant :DEFAULT_PRIMARY_KEY_COLUMN_SPEC
9
+
7
10
  private
11
+ def column_spec_for_primary_key(column)
12
+ spec = super
13
+ spec.except!(:precision) if prepare_column_options(column) == DEFAULT_PRIMARY_KEY_COLUMN_SPEC
14
+ spec
15
+ end
8
16
 
9
17
  def tables(stream)
10
18
  # do not include materialized views in schema dump - they should be created separately after schema creation
@@ -51,6 +59,7 @@ module ActiveRecord #:nodoc:
51
59
  else
52
60
  statement_parts = [ ("add_context_index " + remove_prefix_and_suffix(table).inspect) ]
53
61
  statement_parts << index.columns.inspect
62
+ statement_parts << ("sync: " + $1.inspect) if index.parameters =~ /SYNC\((.*?)\)/
54
63
  statement_parts << ("name: " + index.name.inspect)
55
64
  end
56
65
  else
@@ -72,7 +81,7 @@ module ActiveRecord #:nodoc:
72
81
  index_statements = indexes.map do |index|
73
82
  " t.index #{index_parts(index).join(', ')}" unless index.type == "CTXSYS.CONTEXT"
74
83
  end
75
- stream.puts index_statements.sort.join("\n")
84
+ stream.puts index_statements.compact.sort.join("\n")
76
85
  end
77
86
  end
78
87
 
@@ -107,7 +116,10 @@ module ActiveRecord #:nodoc:
107
116
  tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
108
117
  pkcol = columns.detect { |c| c.name == pk }
109
118
  pkcolspec = column_spec_for_primary_key(pkcol)
110
- if pkcolspec.present?
119
+ unless pkcolspec.empty?
120
+ if pkcolspec != pkcolspec.slice(:id, :default)
121
+ pkcolspec = { id: { type: pkcolspec.delete(:id), **pkcolspec }.compact }
122
+ end
111
123
  tbl.print ", #{format_colspec(pkcolspec)}"
112
124
  end
113
125
  when Array
@@ -168,8 +180,8 @@ module ActiveRecord #:nodoc:
168
180
 
169
181
  def extract_expression_for_virtual_column(column)
170
182
  column_name = column.name
171
- @connection.select_value(<<~SQL.squish, "Table comment", [bind_string("table_name", table_name.upcase), bind_string("column_name", column_name.upcase)]).inspect
172
- select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ data_default from all_tab_columns
183
+ @connection.select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name.upcase), bind_string("column_name", column_name.upcase)]).inspect
184
+ select data_default from all_tab_columns
173
185
  where owner = SYS_CONTEXT('userenv', 'current_schema')
174
186
  and table_name = :table_name
175
187
  and column_name = :column_name
@@ -11,9 +11,8 @@ module ActiveRecord
11
11
  # see: abstract/schema_statements.rb
12
12
 
13
13
  def tables #:nodoc:
14
- select_values(<<~SQL.squish, "tables")
15
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
16
- DECODE(table_name, UPPER(table_name), LOWER(table_name), table_name)
14
+ select_values(<<~SQL.squish, "SCHEMA")
15
+ SELECT DECODE(table_name, UPPER(table_name), LOWER(table_name), table_name)
17
16
  FROM all_tables
18
17
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
19
18
  AND secondary = 'N'
@@ -44,8 +43,8 @@ module ActiveRecord
44
43
  table_owner, table_name = default_owner, real_name
45
44
  end
46
45
 
47
- select_values(<<~SQL.squish, "table exists", [bind_string("owner", table_owner), bind_string("table_name", table_name)]).any?
48
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, table_name
46
+ select_values(<<~SQL.squish, "SCHEMA", [bind_string("owner", table_owner), bind_string("table_name", table_name)]).any?
47
+ SELECT owner, table_name
49
48
  FROM all_tables
50
49
  WHERE owner = :owner
51
50
  AND table_name = :table_name
@@ -60,22 +59,20 @@ module ActiveRecord
60
59
  end
61
60
 
62
61
  def views # :nodoc:
63
- select_values(<<~SQL.squish, "views")
64
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
65
- LOWER(view_name) FROM all_views WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
62
+ select_values(<<~SQL.squish, "SCHEMA")
63
+ SELECT LOWER(view_name) FROM all_views WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
66
64
  SQL
67
65
  end
68
66
 
69
67
  def materialized_views #:nodoc:
70
- select_values(<<~SQL.squish, "materialized views")
71
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */
72
- LOWER(mview_name) FROM all_mviews WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
68
+ select_values(<<~SQL.squish, "SCHEMA")
69
+ SELECT LOWER(mview_name) FROM all_mviews WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
73
70
  SQL
74
71
  end
75
72
 
76
73
  # get synonyms for schema dump
77
74
  def synonyms
78
- result = select_all(<<~SQL.squish, "synonyms")
75
+ result = select_all(<<~SQL.squish, "SCHEMA")
79
76
  SELECT synonym_name, table_owner, table_name
80
77
  FROM all_synonyms where owner = SYS_CONTEXT('userenv', 'current_schema')
81
78
  SQL
@@ -90,8 +87,8 @@ module ActiveRecord
90
87
  (_owner, table_name) = @connection.describe(table_name)
91
88
  default_tablespace_name = default_tablespace
92
89
 
93
- result = select_all(<<~SQL.squish, "indexes", [bind_string("table_name", table_name)])
94
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
90
+ result = select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
91
+ SELECT LOWER(i.table_name) AS table_name, LOWER(i.index_name) AS index_name, i.uniqueness,
95
92
  i.index_type, i.ityp_owner, i.ityp_name, i.parameters,
96
93
  LOWER(i.tablespace_name) AS tablespace_name,
97
94
  LOWER(c.column_name) AS column_name, e.column_expression,
@@ -120,8 +117,8 @@ module ActiveRecord
120
117
  statement_parameters = nil
121
118
  if row["index_type"] == "DOMAIN" && row["ityp_owner"] == "CTXSYS" && row["ityp_name"] == "CONTEXT"
122
119
  procedure_name = default_datastore_procedure(row["index_name"])
123
- source = select_values(<<~SQL.squish, "procedure", [bind_string("procedure_name", procedure_name.upcase)]).join
124
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ text
120
+ source = select_values(<<~SQL.squish, "SCHEMA", [bind_string("procedure_name", procedure_name.upcase)]).join
121
+ SELECT text
125
122
  FROM all_source
126
123
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
127
124
  AND name = :procedure_name
@@ -199,19 +196,19 @@ module ActiveRecord
199
196
  # t.string :last_name, :comment => “Surname”
200
197
  # end
201
198
 
202
- def create_table(table_name, **options)
203
- create_sequence = options[:id] != false
204
- td = create_table_definition table_name, **options
199
+ def create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options)
200
+ create_sequence = id != false
201
+ td = create_table_definition(
202
+ table_name, **options.extract!(:temporary, :options, :as, :comment, :tablespace, :organization)
203
+ )
205
204
 
206
- if options[:id] != false && !options[:as]
207
- pk = options.fetch(:primary_key) do
208
- Base.get_primary_key table_name.to_s.singularize
209
- end
205
+ if id && !td.as
206
+ pk = primary_key || Base.get_primary_key(table_name.to_s.singularize)
210
207
 
211
208
  if pk.is_a?(Array)
212
209
  td.primary_keys pk
213
210
  else
214
- td.primary_key pk, options.fetch(:id, :primary_key), **options
211
+ td.primary_key pk, id, **options
215
212
  end
216
213
  end
217
214
 
@@ -229,8 +226,10 @@ module ActiveRecord
229
226
  yield td if block_given?
230
227
  create_sequence = create_sequence || td.create_sequence
231
228
 
232
- if options[:force] && data_source_exists?(table_name)
233
- drop_table(table_name, options)
229
+ if force && data_source_exists?(table_name)
230
+ drop_table(table_name, force: force, if_exists: true)
231
+ else
232
+ schema_cache.clear_data_source_cache!(table_name.to_s)
234
233
  end
235
234
 
236
235
  execute schema_creation.accept td
@@ -238,14 +237,14 @@ module ActiveRecord
238
237
  create_sequence_and_trigger(table_name, options) if create_sequence
239
238
 
240
239
  if supports_comments? && !supports_comments_in_create?
241
- if table_comment = options[:comment].presence
240
+ if table_comment = td.comment.presence
242
241
  change_table_comment(table_name, table_comment)
243
242
  end
244
243
  td.columns.each do |column|
245
244
  change_column_comment(table_name, column.name, column.comment) if column.comment.present?
246
245
  end
247
246
  end
248
- td.indexes.each { |c, o| add_index table_name, c, o }
247
+ td.indexes.each { |c, o| add_index table_name, c, **o }
249
248
 
250
249
  rebuild_primary_key_index_to_default_tablespace(table_name, options)
251
250
  end
@@ -254,13 +253,16 @@ module ActiveRecord
254
253
  if new_name.to_s.length > DatabaseLimits::IDENTIFIER_MAX_LENGTH
255
254
  raise ArgumentError, "New table name '#{new_name}' is too long; the limit is #{DatabaseLimits::IDENTIFIER_MAX_LENGTH} characters"
256
255
  end
256
+ schema_cache.clear_data_source_cache!(table_name.to_s)
257
+ schema_cache.clear_data_source_cache!(new_name.to_s)
257
258
  execute "RENAME #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
258
259
  execute "RENAME #{quote_table_name("#{table_name}_seq")} TO #{default_sequence_name(new_name)}" rescue nil
259
260
 
260
261
  rename_table_indexes(table_name, new_name)
261
262
  end
262
263
 
263
- def drop_table(table_name, options = {}) #:nodoc:
264
+ def drop_table(table_name, **options) #:nodoc:
265
+ schema_cache.clear_data_source_cache!(table_name.to_s)
264
266
  execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE CONSTRAINTS' if options[:force] == :cascade}"
265
267
  seq_name = options[:sequence_name] || default_sequence_name(table_name)
266
268
  execute "DROP SEQUENCE #{quote_table_name(seq_name)}" rescue nil
@@ -290,7 +292,7 @@ module ActiveRecord
290
292
  end
291
293
  end
292
294
 
293
- def add_index(table_name, column_name, options = {}) #:nodoc:
295
+ def add_index(table_name, column_name, **options) #:nodoc:
294
296
  index_name, index_type, quoted_column_names, tablespace, index_options = add_index_options(table_name, column_name, **options)
295
297
  execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})#{tablespace} #{index_options}"
296
298
  if index_type == "UNIQUE"
@@ -309,13 +311,11 @@ module ActiveRecord
309
311
  index_type = options[:unique] ? "UNIQUE" : ""
310
312
  index_name = options[:name].to_s if options.key?(:name)
311
313
  tablespace = tablespace_for(:index, options[:tablespace])
312
- max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length
313
- # TODO: This option is used for NOLOGGING, needs better argumetn name
314
+ # TODO: This option is used for NOLOGGING, needs better argument name
314
315
  index_options = options[:options]
315
316
 
316
- if index_name.to_s.length > max_index_length
317
- raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
318
- end
317
+ validate_index_length!(table_name, index_name, options.fetch(:internal, false))
318
+
319
319
  if table_exists?(table_name) && index_name_exists?(table_name, index_name)
320
320
  raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
321
321
  end
@@ -326,8 +326,8 @@ module ActiveRecord
326
326
 
327
327
  # Remove the given index from the table.
328
328
  # Gives warning if index does not exist
329
- def remove_index(table_name, options = {}) #:nodoc:
330
- index_name = index_name_for_remove(table_name, options)
329
+ def remove_index(table_name, column_name = nil, **options) #:nodoc:
330
+ index_name = index_name_for_remove(table_name, column_name, options)
331
331
  # TODO: It should execute only when index_type == "UNIQUE"
332
332
  execute "ALTER TABLE #{quote_table_name(table_name)} DROP CONSTRAINT #{quote_column_name(index_name)}" rescue nil
333
333
  execute "DROP INDEX #{quote_column_name(index_name)}"
@@ -364,8 +364,8 @@ module ActiveRecord
364
364
  # Will always query database and not index cache.
365
365
  def index_name_exists?(table_name, index_name)
366
366
  (_owner, table_name) = @connection.describe(table_name)
367
- result = select_value(<<~SQL.squish, "index name exists")
368
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ 1 FROM all_indexes i
367
+ result = select_value(<<~SQL.squish, "SCHEMA")
368
+ SELECT 1 FROM all_indexes i
369
369
  WHERE i.owner = SYS_CONTEXT('userenv', 'current_schema')
370
370
  AND i.table_owner = SYS_CONTEXT('userenv', 'current_schema')
371
371
  AND i.table_name = '#{table_name}'
@@ -443,7 +443,7 @@ module ActiveRecord
443
443
  change_column table_name, column_name, column.sql_type, null: null
444
444
  end
445
445
 
446
- def change_column(table_name, column_name, type, options = {}) #:nodoc:
446
+ def change_column(table_name, column_name, type, **options) #:nodoc:
447
447
  column = column_for(table_name, column_name)
448
448
 
449
449
  # remove :null option if its value is the same as current column definition
@@ -497,9 +497,10 @@ module ActiveRecord
497
497
  end
498
498
 
499
499
  def table_comment(table_name) #:nodoc:
500
+ # TODO
500
501
  (_owner, table_name) = @connection.describe(table_name)
501
- select_value(<<~SQL.squish, "Table comment", [bind_string("table_name", table_name)])
502
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ comments FROM all_tab_comments
502
+ select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
503
+ SELECT comments FROM all_tab_comments
503
504
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
504
505
  AND table_name = :table_name
505
506
  SQL
@@ -514,8 +515,8 @@ module ActiveRecord
514
515
  def column_comment(table_name, column_name) #:nodoc:
515
516
  # TODO: it does not exist in Abstract adapter
516
517
  (_owner, table_name) = @connection.describe(table_name)
517
- select_value(<<~SQL.squish, "Column comment", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
518
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ comments FROM all_col_comments
518
+ select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
519
+ SELECT comments FROM all_col_comments
519
520
  WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
520
521
  AND table_name = :table_name
521
522
  AND column_name = :column_name
@@ -531,8 +532,8 @@ module ActiveRecord
531
532
  end
532
533
 
533
534
  def tablespace(table_name)
534
- select_value(<<~SQL.squish, "tablespace")
535
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ tablespace_name
535
+ select_value(<<~SQL.squish, "SCHEMA")
536
+ SELECT tablespace_name
536
537
  FROM all_tables
537
538
  WHERE table_name='#{table_name.to_s.upcase}'
538
539
  AND owner = SYS_CONTEXT('userenv', 'current_schema')
@@ -543,8 +544,8 @@ module ActiveRecord
543
544
  def foreign_keys(table_name) #:nodoc:
544
545
  (_owner, desc_table_name) = @connection.describe(table_name)
545
546
 
546
- fk_info = select_all(<<~SQL.squish, "Foreign Keys", [bind_string("desc_table_name", desc_table_name)])
547
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ r.table_name to_table
547
+ fk_info = select_all(<<~SQL.squish, "SCHEMA", [bind_string("desc_table_name", desc_table_name)])
548
+ SELECT r.table_name to_table
548
549
  ,rc.column_name references_column
549
550
  ,cc.column_name
550
551
  ,c.constraint_name name
@@ -585,8 +586,8 @@ module ActiveRecord
585
586
  # REFERENTIAL INTEGRITY ====================================
586
587
 
587
588
  def disable_referential_integrity(&block) #:nodoc:
588
- old_constraints = select_all(<<~SQL.squish, "Foreign Keys to disable and enable")
589
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ constraint_name, owner, table_name
589
+ old_constraints = select_all(<<~SQL.squish, "SCHEMA")
590
+ SELECT constraint_name, owner, table_name
590
591
  FROM all_constraints
591
592
  WHERE constraint_type = 'R'
592
593
  AND status = 'ENABLED'
@@ -617,13 +618,12 @@ module ActiveRecord
617
618
  end
618
619
 
619
620
  private
620
-
621
621
  def schema_creation
622
622
  OracleEnhanced::SchemaCreation.new self
623
623
  end
624
624
 
625
- def create_table_definition(*args, **options)
626
- OracleEnhanced::TableDefinition.new(self, *args, **options)
625
+ def create_table_definition(name, **options)
626
+ OracleEnhanced::TableDefinition.new(self, name, **options)
627
627
  end
628
628
 
629
629
  def new_column_from_field(table_name, field)
@@ -645,7 +645,7 @@ module ActiveRecord
645
645
  # If a default contains a newline these cleanup regexes need to
646
646
  # match newlines.
647
647
  field["data_default"].sub!(/^'(.*)'$/m, '\1')
648
- field["data_default"] = nil if field["data_default"] =~ /^(null|empty_[bc]lob\(\))$/i
648
+ field["data_default"] = nil if /^(null|empty_[bc]lob\(\))$/i.match?(field["data_default"])
649
649
  # TODO: Needs better fix to fallback "N" to false
650
650
  field["data_default"] = false if field["data_default"] == "N" && OracleEnhancedAdapter.emulate_booleans_from_strings
651
651
  end
@@ -702,7 +702,7 @@ module ActiveRecord
702
702
  return unless tablespace
703
703
 
704
704
  index_name = select_value(<<~SQL.squish, "Index name for primary key", [bind_string("table_name", table_name.upcase)])
705
- SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ index_name FROM all_constraints
705
+ SELECT index_name FROM all_constraints
706
706
  WHERE table_name = :table_name
707
707
  AND constraint_type = 'P'
708
708
  AND owner = SYS_CONTEXT('userenv', 'current_schema')