activerecord-oracle_enhanced-adapter 7.0.3 → 7.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +24 -0
  3. data/README.md +0 -1
  4. data/VERSION +1 -1
  5. data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +5 -0
  6. data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +1 -1
  7. data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +2 -2
  8. data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +26 -21
  9. data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +15 -2
  10. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +9 -2
  11. data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +3 -3
  12. data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +24 -15
  13. data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +3 -3
  14. data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +2 -2
  15. data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +1 -1
  16. data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +5 -0
  17. data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +1 -1
  18. data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +22 -22
  19. data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +17 -17
  20. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +71 -28
  21. data/lib/activerecord-oracle_enhanced-adapter.rb +8 -0
  22. data/lib/arel/visitors/oracle.rb +6 -3
  23. data/lib/arel/visitors/oracle12.rb +6 -5
  24. data/lib/arel/visitors/oracle_common.rb +46 -0
  25. data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +24 -5
  26. data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +7 -2
  27. data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +2 -2
  28. data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +3 -0
  29. data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +25 -15
  30. data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +15 -18
  31. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +14 -10
  32. data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +2 -2
  33. data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +24 -0
  34. data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +4 -2
  35. data/spec/active_record/oracle_enhanced/type/integer_spec.rb +8 -0
  36. data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +3 -3
  37. data/spec/active_record/oracle_enhanced/type/raw_spec.rb +15 -0
  38. data/spec/active_record/oracle_enhanced/type/text_spec.rb +18 -3
  39. data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +5 -1
  40. data/spec/spec_config.yaml.template +2 -2
  41. data/spec/spec_helper.rb +14 -3
  42. metadata +8 -6
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ module OracleCommon
6
+ private
7
+ # Oracle can't compare CLOB columns with standard SQL operators for comparison.
8
+ # We need to replace standard equality for text/binary columns to use DBMS_LOB.COMPARE function.
9
+ # Fixes ORA-00932: inconsistent datatypes: expected - got CLOB
10
+ def visit_Arel_Nodes_Equality(o, collector)
11
+ left = o.left
12
+ return super unless %i(text binary).include?(cached_column_for(left)&.type)
13
+
14
+ # https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_lob.htm#i1016668
15
+ # returns 0 when the comparison succeeds
16
+ comparator = Arel::Nodes::NamedFunction.new("DBMS_LOB.COMPARE", [left, o.right])
17
+ collector = visit comparator, collector
18
+ collector << " = 0"
19
+ collector
20
+ end
21
+
22
+ def visit_Arel_Nodes_Matches(o, collector)
23
+ if !o.case_sensitive && o.left && o.right
24
+ o.left = Arel::Nodes::NamedFunction.new("UPPER", [o.left])
25
+ o.right = Arel::Nodes::NamedFunction.new("UPPER", [o.right])
26
+ end
27
+
28
+ super o, collector
29
+ end
30
+
31
+ def cached_column_for(attr)
32
+ return unless Arel::Attributes::Attribute === attr
33
+
34
+ table = attr.relation.name
35
+ return unless schema_cache.columns_hash?(table)
36
+
37
+ column = attr.name.to_s
38
+ schema_cache.columns_hash(table)[column]
39
+ end
40
+
41
+ def schema_cache
42
+ @connection.schema_cache
43
+ end
44
+ end
45
+ end
46
+ end
@@ -44,7 +44,7 @@ describe "OracleEnhancedAdapter establish connection" do
44
44
  it "should not use JDBC statement caching" do
45
45
  if ORACLE_ENHANCED_CONNECTION == :jdbc
46
46
  ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS)
47
- expect(ActiveRecord::Base.connection.raw_connection.getImplicitCachingEnabled).to eq(false)
47
+ expect(ActiveRecord::Base.connection.raw_connection.getImplicitCachingEnabled).to be(false)
48
48
  expect(ActiveRecord::Base.connection.raw_connection.getStatementCacheSize).to eq(-1)
49
49
  end
50
50
  end
@@ -52,12 +52,26 @@ describe "OracleEnhancedAdapter establish connection" do
52
52
  it "should use JDBC statement caching" do
53
53
  if ORACLE_ENHANCED_CONNECTION == :jdbc
54
54
  ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_statement_cache_size: 100))
55
- expect(ActiveRecord::Base.connection.raw_connection.getImplicitCachingEnabled).to eq(true)
55
+ expect(ActiveRecord::Base.connection.raw_connection.getImplicitCachingEnabled).to be(true)
56
56
  expect(ActiveRecord::Base.connection.raw_connection.getStatementCacheSize).to eq(100)
57
57
  # else: don't raise error if OCI connection has parameter "jdbc_statement_cache_size", still ignore it
58
58
  end
59
59
  end
60
60
 
61
+ it "should not encrypt JDBC network connection" do
62
+ if ORACLE_ENHANCED_CONNECTION == :jdbc
63
+ @conn = ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_connect_properties: { "oracle.net.encryption_client" => "REJECTED" }))
64
+ expect(@conn.select("SELECT COUNT(*) Records FROM v$Session_Connect_Info WHERE SID=SYS_CONTEXT('USERENV', 'SID') AND Network_Service_Banner LIKE '%Encryption service adapter%'")).to eq([{ "records" => 0 }])
65
+ end
66
+ end
67
+
68
+ it "should encrypt JDBC network connection" do
69
+ if ORACLE_ENHANCED_CONNECTION == :jdbc
70
+ @conn = ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_connect_properties: { "oracle.net.encryption_client" => "REQUESTED" }))
71
+ expect(@conn.select("SELECT COUNT(*) Records FROM v$Session_Connect_Info WHERE SID=SYS_CONTEXT('USERENV', 'SID') AND Network_Service_Banner LIKE '%Encryption service adapter%'")).to eq([{ "records" => 1 }])
72
+ end
73
+ end
74
+
61
75
  it "should connect to database using service_name" do
62
76
  ActiveRecord::Base.establish_connection(SERVICE_NAME_CONNECTION_PARAMS)
63
77
  expect(ActiveRecord::Base.connection).not_to be_nil
@@ -227,7 +241,7 @@ describe "OracleEnhancedConnection" do
227
241
  end
228
242
 
229
243
  after(:all) do
230
- Object.send(:remove_const, "Post")
244
+ Object.send(:remove_const, "Post") if defined?(Post)
231
245
  ActiveRecord::Base.clear_cache!
232
246
  end
233
247
 
@@ -392,7 +406,7 @@ describe "OracleEnhancedConnection" do
392
406
  @conn.exec "DROP TABLE test_employees" rescue nil
393
407
  end
394
408
 
395
- it "should execute prepared statement with decimal bind parameter " do
409
+ it "should execute prepared statement with decimal bind parameter" do
396
410
  cursor = @conn.prepare("INSERT INTO test_employees VALUES(:1)")
397
411
  type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "NUMBER", type: :decimal, limit: 10, precision: nil, scale: 2)
398
412
  column = ActiveRecord::ConnectionAdapters::OracleEnhanced::Column.new("age", nil, type_metadata, false, comment: nil)
@@ -414,7 +428,7 @@ describe "OracleEnhancedConnection" do
414
428
 
415
429
  before(:all) do
416
430
  ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
417
- @conn = ActiveRecord::Base.connection.instance_variable_get("@connection")
431
+ @conn = ActiveRecord::Base.connection.send(:_connection)
418
432
  @sys_conn = ActiveRecord::ConnectionAdapters::OracleEnhanced::Connection.create(SYS_CONNECTION_PARAMS)
419
433
  schema_define do
420
434
  create_table :posts, force: true
@@ -447,6 +461,11 @@ describe "OracleEnhancedConnection" do
447
461
  expect(@conn.exec("SELECT * FROM dual")).not_to be_nil
448
462
  end
449
463
 
464
+ it "should reconnect and execute SQL statement if connection is lost and allow_retry is passed" do
465
+ kill_current_session
466
+ expect(@conn.exec("SELECT * FROM dual", allow_retry: true)).not_to be_nil
467
+ end
468
+
450
469
  it "should not reconnect and execute SQL statement if connection is lost and auto retry is disabled" do
451
470
  # @conn.auto_retry = false
452
471
  ActiveRecord::Base.connection.auto_retry = false
@@ -16,6 +16,7 @@ describe "Oracle Enhanced adapter database tasks" do
16
16
  ActiveRecord::Tasks::DatabaseTasks.create(new_user_config)
17
17
  end
18
18
  end
19
+
19
20
  it "creates user" do
20
21
  query = "SELECT COUNT(*) FROM dba_users WHERE UPPER(username) = '#{new_user_config[:username].upcase}'"
21
22
  expect(ActiveRecord::Base.connection.select_value(query)).to eq(1)
@@ -62,6 +63,7 @@ describe "Oracle Enhanced adapter database tasks" do
62
63
 
63
64
  describe "drop" do
64
65
  before { ActiveRecord::Tasks::DatabaseTasks.drop(config) }
66
+
65
67
  it "drops all tables" do
66
68
  expect(ActiveRecord::Base.connection.table_exists?(:test_posts)).to be_falsey
67
69
  end
@@ -69,6 +71,7 @@ describe "Oracle Enhanced adapter database tasks" do
69
71
 
70
72
  describe "purge" do
71
73
  before { ActiveRecord::Tasks::DatabaseTasks.purge(config) }
74
+
72
75
  it "drops all tables" do
73
76
  expect(ActiveRecord::Base.connection.table_exists?(:test_posts)).to be_falsey
74
77
  expect(ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM RECYCLEBIN")).to eq(0)
@@ -78,12 +81,13 @@ describe "Oracle Enhanced adapter database tasks" do
78
81
  describe "structure" do
79
82
  let(:temp_file) { Tempfile.create(["oracle_enhanced", ".sql"]).path }
80
83
  before do
81
- ActiveRecord::SchemaMigration.create_table
84
+ ActiveRecord::Base.connection.schema_migration.create_table
82
85
  ActiveRecord::Base.connection.execute "INSERT INTO schema_migrations (version) VALUES ('20150101010000')"
83
86
  end
84
87
 
85
88
  describe "structure_dump" do
86
89
  before { ActiveRecord::Tasks::DatabaseTasks.structure_dump(config, temp_file) }
90
+
87
91
  it "dumps the database structure to a file without the schema information" do
88
92
  contents = File.read(temp_file)
89
93
  expect(contents).to include('CREATE TABLE "TEST_POSTS"')
@@ -97,6 +101,7 @@ describe "Oracle Enhanced adapter database tasks" do
97
101
  ActiveRecord::Tasks::DatabaseTasks.drop(config)
98
102
  ActiveRecord::Tasks::DatabaseTasks.structure_load(config, temp_file)
99
103
  end
104
+
100
105
  it "loads the database structure from a file" do
101
106
  expect(ActiveRecord::Base.connection.table_exists?(:test_posts)).to be_truthy
102
107
  end
@@ -104,7 +109,7 @@ describe "Oracle Enhanced adapter database tasks" do
104
109
 
105
110
  after do
106
111
  File.unlink(temp_file)
107
- ActiveRecord::SchemaMigration.drop_table
112
+ ActiveRecord::Base.connection.schema_migration.drop_table
108
113
  end
109
114
  end
110
115
 
@@ -47,7 +47,7 @@ describe "OracleEnhancedAdapter logging dbms_output from plsql" do
47
47
  expect(@logger.output(:debug)).not_to match(/^DBMS_OUTPUT/)
48
48
  end
49
49
 
50
- it "should log dbms output lines to the rails log" do
50
+ it "should log dbms output longer lines to the rails log" do
51
51
  @conn.enable_dbms_output
52
52
 
53
53
  expect(@conn.select_all("select more_than_five_characters_long('hi there') is_it_long from dual").to_a).to eq([{ "is_it_long" => 1 }])
@@ -57,7 +57,7 @@ describe "OracleEnhancedAdapter logging dbms_output from plsql" do
57
57
  expect(@logger.output(:debug)).to match(/^DBMS_OUTPUT: about to return: 1$/)
58
58
  end
59
59
 
60
- it "should log dbms output lines to the rails log" do
60
+ it "should log dbms output shorter lines to the rails log" do
61
61
  @conn.enable_dbms_output
62
62
 
63
63
  expect(@conn.select_all("select more_than_five_characters_long('short') is_it_long from dual").to_a).to eq([{ "is_it_long" => 0 }])
@@ -127,6 +127,7 @@ describe "OracleEnhancedAdapter schema dump" do
127
127
  remove_foreign_key :test_comments, name: "comments_posts_baz_fooz_fk" rescue nil
128
128
  end
129
129
  end
130
+
130
131
  after(:all) do
131
132
  schema_define do
132
133
  drop_table :test_comments, if_exists: true
@@ -383,6 +384,7 @@ describe "OracleEnhancedAdapter schema dump" do
383
384
  end
384
385
  end
385
386
  end
387
+
386
388
  after(:all) do
387
389
  if @oracle11g_or_higher
388
390
  schema_define do
@@ -390,6 +392,7 @@ describe "OracleEnhancedAdapter schema dump" do
390
392
  end
391
393
  end
392
394
  end
395
+
393
396
  it "should dump correctly" do
394
397
  output = dump_table_schema "test_names"
395
398
  expect(output).not_to match(/t\.index .+FIRST_NAME.+$/)
@@ -550,6 +550,7 @@ end
550
550
  class ::TestPost < ActiveRecord::Base
551
551
  end
552
552
  end
553
+
553
554
  it "should use default tablespace for clobs" do
554
555
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:clob] = DATABASE_NON_DEFAULT_TABLESPACE
555
556
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:nclob] = nil
@@ -880,7 +881,7 @@ end
880
881
  expect(TestPost.columns_hash["a" * 128]).not_to be_nil
881
882
  end
882
883
 
883
- it "should add lob column with non_default tablespace" do
884
+ it "should add text type lob column with non_default tablespace" do
884
885
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:clob] = DATABASE_NON_DEFAULT_TABLESPACE
885
886
  schema_define do
886
887
  add_column :test_posts, :body, :text
@@ -888,7 +889,7 @@ end
888
889
  expect(TestPost.connection.select_value("SELECT tablespace_name FROM user_lobs WHERE table_name='TEST_POSTS' and column_name = 'BODY'")).to eq(DATABASE_NON_DEFAULT_TABLESPACE)
889
890
  end
890
891
 
891
- it "should add lob column with non_default tablespace" do
892
+ it "should add ntext type lob column with non_default tablespace" do
892
893
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:nclob] = DATABASE_NON_DEFAULT_TABLESPACE
893
894
  schema_define do
894
895
  add_column :test_posts, :body, :ntext
@@ -995,12 +996,12 @@ end
995
996
 
996
997
  it "should include virtual columns and not try to update them" do
997
998
  tf = TestFraction.columns.detect { |c| c.virtual? }
998
- expect(tf).not_to be nil
999
+ expect(tf).not_to be_nil
999
1000
  expect(tf.name).to eq("percent")
1000
1001
  expect(tf.virtual?).to be true
1001
1002
  expect do
1002
1003
  tf = TestFraction.new(numerator: 20, denominator: 100)
1003
- expect(tf.percent).to be nil # not whatever is in DATA_DEFAULT column
1004
+ expect(tf.percent).to be_nil # not whatever is in DATA_DEFAULT column
1004
1005
  tf.save!
1005
1006
  tf.reload
1006
1007
  end.not_to raise_error
@@ -1013,11 +1014,11 @@ end
1013
1014
  end
1014
1015
  TestFraction.reset_column_information
1015
1016
  tf = TestFraction.columns.detect { |c| c.name == "rem" }
1016
- expect(tf).not_to be nil
1017
+ expect(tf).not_to be_nil
1017
1018
  expect(tf.virtual?).to be true
1018
1019
  expect do
1019
1020
  tf = TestFraction.new(numerator: 7, denominator: 5)
1020
- expect(tf.rem).to be nil
1021
+ expect(tf.rem).to be_nil
1021
1022
  tf.save!
1022
1023
  tf.reload
1023
1024
  end.not_to raise_error
@@ -1030,13 +1031,13 @@ end
1030
1031
  end
1031
1032
  TestFraction.reset_column_information
1032
1033
  tf = TestFraction.columns.detect { |c| c.name == "expression" }
1033
- expect(tf).not_to be nil
1034
+ expect(tf).not_to be_nil
1034
1035
  expect(tf.virtual?).to be true
1035
1036
  expect(tf.type).to be :string
1036
1037
  expect(tf.limit).to be 100
1037
1038
  expect do
1038
1039
  tf = TestFraction.new(numerator: 7, denominator: 5)
1039
- expect(tf.expression).to be nil
1040
+ expect(tf.expression).to be_nil
1040
1041
  tf.save!
1041
1042
  tf.reload
1042
1043
  end.not_to raise_error
@@ -1050,14 +1051,14 @@ end
1050
1051
  end
1051
1052
  TestFraction.reset_column_information
1052
1053
  tf = TestFraction.columns.detect { |c| c.name == "percent" }
1053
- expect(tf).not_to be nil
1054
+ expect(tf).not_to be_nil
1054
1055
  expect(tf.virtual?).to be true
1055
1056
  expect(tf.type).to be :decimal
1056
1057
  expect(tf.precision).to be 15
1057
1058
  expect(tf.scale).to be 2
1058
1059
  expect do
1059
1060
  tf = TestFraction.new(numerator: 11, denominator: 17)
1060
- expect(tf.percent).to be nil
1061
+ expect(tf.percent).to be_nil
1061
1062
  tf.save!
1062
1063
  tf.reload
1063
1064
  end.not_to raise_error
@@ -1070,14 +1071,14 @@ end
1070
1071
  end
1071
1072
  TestFraction.reset_column_information
1072
1073
  tf = TestFraction.columns.detect { |c| c.name == "percent" }
1073
- expect(tf).not_to be nil
1074
+ expect(tf).not_to be_nil
1074
1075
  expect(tf.virtual?).to be true
1075
1076
  expect(tf.type).to be :decimal
1076
1077
  expect(tf.precision).to be 12
1077
1078
  expect(tf.scale).to be 5
1078
1079
  expect do
1079
1080
  tf = TestFraction.new(numerator: 11, denominator: 17)
1080
- expect(tf.percent).to be nil
1081
+ expect(tf.percent).to be_nil
1081
1082
  tf.save!
1082
1083
  tf.reload
1083
1084
  end.not_to raise_error
@@ -1157,6 +1158,7 @@ end
1157
1158
  @conn.drop_table :tablespace_tests, if_exists: true
1158
1159
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces.delete(:table)
1159
1160
  end
1161
+
1160
1162
  it "should use correct tablespace" do
1161
1163
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:table] = DATABASE_NON_DEFAULT_TABLESPACE
1162
1164
  @conn.create_table :tablespace_tests do |t|
@@ -1171,6 +1173,7 @@ end
1171
1173
  @conn.drop_table :tablespace_tests, if_exists: true
1172
1174
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces.delete(:table)
1173
1175
  end
1176
+
1174
1177
  it "should use correct tablespace" do
1175
1178
  @conn.create_table :tablespace_tests, id: false, organization: "INDEX INITRANS 4 COMPRESS 1", tablespace: "bogus" do |t|
1176
1179
  t.integer :id
@@ -1206,7 +1209,14 @@ end
1206
1209
  schema_define do
1207
1210
  add_index :keyboards, "lower(name)", unique: true, name: :index_keyboards_on_lower_name
1208
1211
  end
1209
- expect(@would_execute_sql).not_to match(/ALTER +TABLE .* ADD CONSTRAINT .* UNIQUE \(.*\(.*\)\)/)
1212
+ expect(@would_execute_sql).not_to include("ADD CONSTRAINT")
1213
+ end
1214
+
1215
+ it "should add unique constraint only to the index where it was defined" do
1216
+ schema_define do
1217
+ add_index :keyboards, ["name"], unique: true, name: :this_index
1218
+ end
1219
+ expect(@would_execute_sql.lines.last).to match(/ALTER +TABLE .* ADD CONSTRAINT .* UNIQUE \(.*\) USING INDEX "THIS_INDEX";/)
1210
1220
  end
1211
1221
  end
1212
1222
 
@@ -1218,7 +1228,7 @@ end
1218
1228
  before do
1219
1229
  @conn = ActiveRecord::Base.connection
1220
1230
 
1221
- ActiveRecord::SchemaMigration.create_table
1231
+ ActiveRecord::Base.connection.schema_migration.create_table
1222
1232
  end
1223
1233
 
1224
1234
  context "multi insert is supported" do
@@ -1246,7 +1256,7 @@ end
1246
1256
  end
1247
1257
 
1248
1258
  after do
1249
- ActiveRecord::SchemaMigration.drop_table
1259
+ ActiveRecord::Base.connection.schema_migration.drop_table
1250
1260
  end
1251
1261
  end
1252
1262
  end
@@ -9,6 +9,7 @@ describe "OracleEnhancedAdapter structure dump" do
9
9
  @oracle11g_or_higher = !! @conn.select_value(
10
10
  "select * from product_component_version where product like 'Oracle%' and to_number(substr(version,1,2)) >= 11")
11
11
  end
12
+
12
13
  describe "structure dump" do
13
14
  before(:each) do
14
15
  @conn.create_table :test_posts, force: true do |t|
@@ -228,25 +229,13 @@ describe "OracleEnhancedAdapter structure dump" do
228
229
  dump = ActiveRecord::Base.connection.structure_dump
229
230
  expect(dump).to match(/#{comment_sql}/)
230
231
  end
231
-
232
- it "should dump table comments" do
233
- comment_sql = %Q(COMMENT ON TABLE "TEST_POSTS" IS 'Test posts with ''some'' "quotes"')
234
- @conn.execute comment_sql
235
- dump = ActiveRecord::Base.connection.structure_dump
236
- expect(dump).to match(/#{comment_sql}/)
237
- end
238
-
239
- it "should dump column comments" do
240
- comment_sql = %Q(COMMENT ON COLUMN "TEST_POSTS"."TITLE" IS 'The title of the post with ''some'' "quotes"')
241
- @conn.execute comment_sql
242
- dump = ActiveRecord::Base.connection.structure_dump
243
- expect(dump).to match(/#{comment_sql}/)
244
- end
245
232
  end
233
+
246
234
  describe "temporary tables" do
247
235
  after(:all) do
248
236
  @conn.drop_table :test_comments, if_exists: true
249
237
  end
238
+
250
239
  it "should dump correctly" do
251
240
  @conn.create_table :test_comments, temporary: true, id: false do |t|
252
241
  t.integer :post_id
@@ -261,26 +250,32 @@ describe "OracleEnhancedAdapter structure dump" do
261
250
  before(:each) do
262
251
  @conn.execute sql
263
252
  end
253
+
264
254
  after(:each) do
265
255
  @conn.execute "drop SEQUENCE \"#{sequence_name}\""
266
256
  end
257
+
267
258
  subject do
268
259
  ActiveRecord::Base.connection.structure_dump
269
260
  end
261
+
270
262
  context "default sequence" do
271
263
  let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\"" }
272
264
  it { is_expected.to_not match(%r{CREATE SEQUENCE "#{sequence_name}" MAXVALUE \d+ MINVALUE \d+ NOORDER NOCYCLE}) }
273
265
  end
266
+
274
267
  context "noorder" do
275
268
  let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" NOORDER" }
276
269
  it { is_expected.to include("NOORDER") }
277
270
  it { is_expected.to_not include(" ORDER") }
278
271
  end
272
+
279
273
  context "order" do
280
274
  let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" ORDER" }
281
275
  it { is_expected.to include(" ORDER") }
282
276
  it { is_expected.to_not include("NOORDER") }
283
277
  end
278
+
284
279
  context "min max values" do
285
280
  let(:sql) { "CREATE SEQUENCE \"#{sequence_name}\" MINVALUE 7 MAXVALUE 444" }
286
281
  it { is_expected.to include("MINVALUE 7") }
@@ -317,6 +312,7 @@ describe "OracleEnhancedAdapter structure dump" do
317
312
  t.string :foo
318
313
  end
319
314
  end
315
+
320
316
  it "should dump drop sql for just temp tables" do
321
317
  dump = @conn.temp_table_drop
322
318
  expect(dump).to match(/DROP TABLE "TEMP_TBL"/)
@@ -338,10 +334,9 @@ describe "OracleEnhancedAdapter structure dump" do
338
334
  let(:dump) { ActiveRecord::Base.connection.dump_schema_information }
339
335
 
340
336
  before do
341
- ActiveRecord::SchemaMigration.reset_table_name
342
- ActiveRecord::SchemaMigration.create_table
337
+ ActiveRecord::Base.connection.schema_migration.create_table
343
338
  versions.each do |i|
344
- ActiveRecord::SchemaMigration.create!(version: i)
339
+ ActiveRecord::Base.connection.schema_migration.create_version(i)
345
340
  end
346
341
  end
347
342
 
@@ -381,7 +376,7 @@ describe "OracleEnhancedAdapter structure dump" do
381
376
  end
382
377
 
383
378
  after do
384
- ActiveRecord::SchemaMigration.drop_table
379
+ ActiveRecord::Base.connection.schema_migration.drop_table
385
380
  end
386
381
  end
387
382
 
@@ -444,6 +439,7 @@ describe "OracleEnhancedAdapter structure dump" do
444
439
  create or replace type full_drop_test_type as table of number
445
440
  SQL
446
441
  end
442
+
447
443
  after(:each) do
448
444
  @conn.drop_table :full_drop_test
449
445
  @conn.drop_table :full_drop_test_temp
@@ -455,6 +451,7 @@ describe "OracleEnhancedAdapter structure dump" do
455
451
  @conn.execute "DROP PROCEDURE FULL_DROP_TEST_PROCEDURE" rescue nil
456
452
  @conn.execute "DROP TYPE FULL_DROP_TEST_TYPE" rescue nil
457
453
  end
454
+
458
455
  it "should contain correct sql" do
459
456
  drop = @conn.full_drop
460
457
  expect(drop).to match(/DROP TABLE "FULL_DROP_TEST" CASCADE CONSTRAINTS/)
@@ -83,7 +83,7 @@ describe "OracleEnhancedAdapter" do
83
83
  expect(@logger.logged(:debug).last).to match(/select .* from all_constraints/im)
84
84
  end
85
85
 
86
- it "should get primary key from database at first time" do
86
+ it "should get primary key from database at second time without query" do
87
87
  expect(TestEmployee.connection.pk_and_sequence_for("test_employees")).to eq(["id", "test_employees_seq"])
88
88
  @logger.clear(:debug)
89
89
  expect(TestEmployee.connection.pk_and_sequence_for("test_employees")).to eq(["id", "test_employees_seq"])
@@ -129,6 +129,7 @@ describe "OracleEnhancedAdapter" do
129
129
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:clob] = "UNUSED"
130
130
  @conn = ActiveRecord::Base.connection
131
131
  end
132
+
132
133
  after(:all) do
133
134
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces = {}
134
135
  end
@@ -136,6 +137,7 @@ describe "OracleEnhancedAdapter" do
136
137
  after(:each) do
137
138
  @conn.drop_table :foos, if_exists: true
138
139
  end
140
+
139
141
  it "should create ok" do
140
142
  @conn.create_table :foos, temporary: true, id: false do |t|
141
143
  t.integer :id
@@ -441,7 +443,7 @@ describe "OracleEnhancedAdapter" do
441
443
  end
442
444
  end
443
445
  class ::TestSerializedColumn < ActiveRecord::Base
444
- serialize :serialized, Array
446
+ serialize :serialized, type: Array
445
447
  end
446
448
  end
447
449
 
@@ -470,12 +472,12 @@ describe "OracleEnhancedAdapter" do
470
472
  serialized_column.serialized << new_value
471
473
  expect(serialized_column.serialized).to eq([new_value])
472
474
  serialized_column.save
473
- expect(serialized_column.save!).to eq(true)
475
+ expect(serialized_column.save!).to be(true)
474
476
 
475
477
  serialized_column.reload
476
478
  expect(serialized_column.serialized).to eq([new_value])
477
479
  serialized_column.serialized = []
478
- expect(serialized_column.save!).to eq(true)
480
+ expect(serialized_column.save!).to be(true)
479
481
  end
480
482
  end
481
483
 
@@ -514,7 +516,7 @@ describe "OracleEnhancedAdapter" do
514
516
  binary_column_object = TestBinaryColumn.new
515
517
  binary_column_object.attachment = binary_value
516
518
 
517
- expect(binary_column_object.save!).to eq(true)
519
+ expect(binary_column_object.save!).to be(true)
518
520
  end
519
521
  end
520
522
 
@@ -622,8 +624,8 @@ describe "OracleEnhancedAdapter" do
622
624
  end
623
625
 
624
626
  it "should test table existence" do
625
- expect(@conn.table_exists?("TEST_POSTS")).to eq true
626
- expect(@conn.table_exists?("NOT_EXISTING")).to eq false
627
+ expect(@conn.table_exists?("TEST_POSTS")).to be true
628
+ expect(@conn.table_exists?("NOT_EXISTING")).to be false
627
629
  end
628
630
 
629
631
  it "should return array from indexes with bind usage" do
@@ -648,13 +650,13 @@ describe "OracleEnhancedAdapter" do
648
650
  expect(@logger.logged(:debug).last).to match(/\["table_name", "TEST_POSTS"\]/)
649
651
  end
650
652
 
651
- it "should not raise missing IN/OUT parameter like issue 1687 " do
653
+ it "should not raise missing IN/OUT parameter like issue 1678" do
652
654
  # "to_sql" enforces unprepared_statement including dictionary access SQLs
653
655
  expect { User.joins(:group).to_sql }.not_to raise_exception
654
656
  end
655
657
 
656
658
  it "should return false from temporary_table? with bind usage" do
657
- expect(@conn.temporary_table?("TEST_POSTS")).to eq false
659
+ expect(@conn.temporary_table?("TEST_POSTS")).to be false
658
660
  expect(@logger.logged(:debug).last).to match(/:table_name/)
659
661
  expect(@logger.logged(:debug).last).to match(/\["table_name", "TEST_POSTS"\]/)
660
662
  end
@@ -721,12 +723,14 @@ describe "OracleEnhancedAdapter" do
721
723
  end
722
724
  end
723
725
  end
726
+
724
727
  after(:all) do
725
728
  schema_define do
726
729
  drop_table :table_with_name_thats_just_ok,
727
730
  sequence_name: "suitably_short_seq" rescue nil
728
731
  end
729
732
  end
733
+
730
734
  it "should create table with custom sequence name" do
731
735
  expect(@conn.select_value("select suitably_short_seq.nextval from dual")).to eq(1)
732
736
  end
@@ -767,7 +771,7 @@ describe "OracleEnhancedAdapter" do
767
771
  expect(post.explain).to include("| TABLE ACCESS FULL| TEST_POSTS |")
768
772
  end
769
773
 
770
- it "should explain considers hints with /*+ */ " do
774
+ it "should explain considers hints with /*+ */" do
771
775
  post = TestPost.optimizer_hints("/*+ FULL (\"TEST_POSTS\") */")
772
776
  post = post.where(id: 1)
773
777
  expect(post.explain).to include("| TABLE ACCESS FULL| TEST_POSTS |")
@@ -151,10 +151,10 @@ describe "OracleEnhancedAdapter boolean type detection based on string column ty
151
151
  expect(@employee3.test_boolean_before_type_cast).to eq("N")
152
152
  create_employee3(test_boolean: nil)
153
153
  expect(@employee3.test_boolean.class).to eq(NilClass)
154
- expect(@employee3.test_boolean_before_type_cast).to eq(nil)
154
+ expect(@employee3.test_boolean_before_type_cast).to be_nil
155
155
  create_employee3(test_boolean: "")
156
156
  expect(@employee3.test_boolean.class).to eq(NilClass)
157
- expect(@employee3.test_boolean_before_type_cast).to eq(nil)
157
+ expect(@employee3.test_boolean_before_type_cast).to be_nil
158
158
  end
159
159
 
160
160
  it "should return string value from VARCHAR2 column with boolean column name but attribute is set to :string" do
@@ -24,6 +24,7 @@ describe "OracleEnhancedAdapter processing CHAR column" do
24
24
  end
25
25
 
26
26
  after(:each) do
27
+ TestItem.delete_all
27
28
  Object.send(:remove_const, "TestItem")
28
29
  ActiveRecord::Base.clear_cache!
29
30
  end
@@ -40,4 +41,27 @@ describe "OracleEnhancedAdapter processing CHAR column" do
40
41
  item_reloaded = TestItem.first
41
42
  expect(item_reloaded.padded).to eq(str)
42
43
  end
44
+
45
+ it "should support case sensitive matching" do
46
+ TestItem.create!(
47
+ padded: "First",
48
+ )
49
+ TestItem.create!(
50
+ padded: "first",
51
+ )
52
+
53
+ expect(TestItem.where(TestItem.arel_table[:padded].matches("first%", "\\", true))).to have_attributes(count: 1)
54
+ end
55
+
56
+ it "should support case insensitive matching" do
57
+ TestItem.create!(
58
+ padded: "First",
59
+ )
60
+ TestItem.create!(
61
+ padded: "first",
62
+ )
63
+
64
+ expect(TestItem.where(TestItem.arel_table[:padded].matches("first%", "\\", false))).to have_attributes(count: 2)
65
+ expect(TestItem.where(TestItem.arel_table[:padded].matches("first%"))).to have_attributes(count: 2)
66
+ end
43
67
  end
@@ -113,7 +113,7 @@ describe "OracleEnhancedAdapter dirty object tracking" do
113
113
 
114
114
  it "should not update unchanged CLOBs" do
115
115
  @conn = nil
116
- @connection = nil
116
+ @raw_connection = nil
117
117
  @employee = TestEmployee.create!(
118
118
  comments: "initial"
119
119
  )
@@ -121,10 +121,12 @@ describe "OracleEnhancedAdapter dirty object tracking" do
121
121
  @employee.reload
122
122
  expect(@employee.comments).to eq("initial")
123
123
 
124
- oci_conn = @conn.instance_variable_get("@connection")
124
+ oci_conn = @conn.instance_variable_get("@raw_connection")
125
125
  class << oci_conn
126
126
  def write_lob(lob, value, is_binary = false); raise "don't do this'"; end
127
127
  end
128
+ @employee.comments = +"initial"
129
+ expect(@employee.comments_changed?).to be false
128
130
  expect { @employee.save! }.not_to raise_error
129
131
  class << oci_conn
130
132
  remove_method :write_lob