activerecord-oracle_enhanced-adapter 6.0.6 → 6.1.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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')