activerecord-oracle_enhanced-adapter 7.0.0 → 7.1.1
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.
- checksums.yaml +4 -4
- data/History.md +64 -0
- data/README.md +11 -2
- data/VERSION +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/column.rb +5 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/connection.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/database_limits.rb +2 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb +35 -27
- data/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb +15 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_connection.rb +9 -2
- data/lib/active_record/connection_adapters/oracle_enhanced/jdbc_quoting.rb +3 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb +24 -15
- data/lib/active_record/connection_adapters/oracle_enhanced/oci_quoting.rb +3 -3
- data/lib/active_record/connection_adapters/oracle_enhanced/quoting.rb +7 -5
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_creation.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_definitions.rb +5 -0
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb +33 -24
- data/lib/active_record/connection_adapters/oracle_enhanced/structure_dump.rb +17 -17
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +73 -30
- data/lib/activerecord-oracle_enhanced-adapter.rb +8 -0
- data/lib/arel/visitors/oracle.rb +6 -3
- data/lib/arel/visitors/oracle12.rb +6 -5
- data/lib/arel/visitors/oracle_common.rb +46 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/compatibility_spec.rb +36 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/connection_spec.rb +30 -5
- data/spec/active_record/connection_adapters/oracle_enhanced/database_tasks_spec.rb +7 -2
- data/spec/active_record/connection_adapters/oracle_enhanced/dbms_output_spec.rb +2 -2
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb +3 -0
- data/spec/active_record/connection_adapters/oracle_enhanced/schema_statements_spec.rb +53 -15
- data/spec/active_record/connection_adapters/oracle_enhanced/structure_dump_spec.rb +15 -18
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +14 -10
- data/spec/active_record/oracle_enhanced/type/boolean_spec.rb +2 -2
- data/spec/active_record/oracle_enhanced/type/character_string_spec.rb +24 -0
- data/spec/active_record/oracle_enhanced/type/custom_spec.rb +90 -0
- data/spec/active_record/oracle_enhanced/type/dirty_spec.rb +4 -2
- data/spec/active_record/oracle_enhanced/type/integer_spec.rb +8 -0
- data/spec/active_record/oracle_enhanced/type/national_character_text_spec.rb +3 -3
- data/spec/active_record/oracle_enhanced/type/raw_spec.rb +15 -0
- data/spec/active_record/oracle_enhanced/type/text_spec.rb +18 -3
- data/spec/active_record/oracle_enhanced/type/timestamp_spec.rb +5 -1
- data/spec/spec_config.yaml.template +2 -2
- data/spec/spec_helper.rb +14 -3
- metadata +26 -9
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "oracle_common"
|
4
|
+
|
3
5
|
module Arel # :nodoc: all
|
4
6
|
module Visitors
|
5
7
|
class Oracle12 < Arel::Visitors::ToSql
|
8
|
+
include OracleCommon
|
9
|
+
|
6
10
|
private
|
7
11
|
def visit_Arel_Nodes_SelectStatement(o, collector)
|
8
12
|
# Oracle does not allow LIMIT clause with select for update
|
@@ -45,7 +49,6 @@ module Arel # :nodoc: all
|
|
45
49
|
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
46
50
|
in_clause_length = @connection.in_clause_length
|
47
51
|
values = o.casted_values.map { |v| @connection.quote(v) }
|
48
|
-
column_name = quote_table_name(o.table_name) + "." + quote_column_name(o.column_name)
|
49
52
|
operator =
|
50
53
|
if o.type == :in
|
51
54
|
" IN ("
|
@@ -54,7 +57,7 @@ module Arel # :nodoc: all
|
|
54
57
|
end
|
55
58
|
|
56
59
|
if !Array === values || values.length <= in_clause_length
|
57
|
-
|
60
|
+
visit o.left, collector
|
58
61
|
collector << operator
|
59
62
|
|
60
63
|
expr =
|
@@ -76,15 +79,13 @@ module Arel # :nodoc: all
|
|
76
79
|
collector << "("
|
77
80
|
values.each_slice(in_clause_length).each_with_index do |valuez, i|
|
78
81
|
collector << separator unless i == 0
|
79
|
-
|
82
|
+
visit o.left, collector
|
80
83
|
collector << operator
|
81
84
|
collector << valuez.join(",")
|
82
85
|
collector << ")"
|
83
86
|
end
|
84
87
|
collector << ")"
|
85
88
|
end
|
86
|
-
|
87
|
-
collector
|
88
89
|
end
|
89
90
|
|
90
91
|
def visit_Arel_Nodes_UpdateStatement(o, collector)
|
@@ -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
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe "compatibility migrations" do
|
4
|
+
include SchemaSpecHelper
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
8
|
+
@conn = ActiveRecord::Base.connection
|
9
|
+
schema_define do
|
10
|
+
create_table :test_employees, force: true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:all) do
|
15
|
+
schema_define do
|
16
|
+
drop_table :test_employees, if_exists: true
|
17
|
+
drop_table :new_test_employees, if_exists: true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should rename table on 7_0 and below" do
|
22
|
+
migration = Class.new(ActiveRecord::Migration[7.0]) {
|
23
|
+
def change
|
24
|
+
rename_table :test_employees, :new_test_employees
|
25
|
+
end
|
26
|
+
}.new
|
27
|
+
|
28
|
+
migration.migrate(:up)
|
29
|
+
expect(@conn.table_exists?(:new_test_employees)).to be_truthy
|
30
|
+
expect(@conn.table_exists?(:test_employees)).not_to be_truthy
|
31
|
+
|
32
|
+
migration.migrate(:down)
|
33
|
+
expect(@conn.table_exists?(:new_test_employees)).not_to be_truthy
|
34
|
+
expect(@conn.table_exists?(:test_employees)).to be_truthy
|
35
|
+
end
|
36
|
+
end
|
@@ -30,6 +30,12 @@ describe "OracleEnhancedAdapter establish connection" do
|
|
30
30
|
expect(ActiveRecord::Base.connection).to be_active
|
31
31
|
end
|
32
32
|
|
33
|
+
it "should be active after reconnection to database with restore_transactions: true" do
|
34
|
+
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
35
|
+
ActiveRecord::Base.connection.reconnect!(restore_transactions: true)
|
36
|
+
expect(ActiveRecord::Base.connection).to be_active
|
37
|
+
end
|
38
|
+
|
33
39
|
it "should use database default cursor_sharing parameter value force by default" do
|
34
40
|
# Use `SYSTEM_CONNECTION_PARAMS` to query v$parameter
|
35
41
|
ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS)
|
@@ -44,7 +50,7 @@ describe "OracleEnhancedAdapter establish connection" do
|
|
44
50
|
it "should not use JDBC statement caching" do
|
45
51
|
if ORACLE_ENHANCED_CONNECTION == :jdbc
|
46
52
|
ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS)
|
47
|
-
expect(ActiveRecord::Base.connection.raw_connection.getImplicitCachingEnabled).to
|
53
|
+
expect(ActiveRecord::Base.connection.raw_connection.getImplicitCachingEnabled).to be(false)
|
48
54
|
expect(ActiveRecord::Base.connection.raw_connection.getStatementCacheSize).to eq(-1)
|
49
55
|
end
|
50
56
|
end
|
@@ -52,12 +58,26 @@ describe "OracleEnhancedAdapter establish connection" do
|
|
52
58
|
it "should use JDBC statement caching" do
|
53
59
|
if ORACLE_ENHANCED_CONNECTION == :jdbc
|
54
60
|
ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_statement_cache_size: 100))
|
55
|
-
expect(ActiveRecord::Base.connection.raw_connection.getImplicitCachingEnabled).to
|
61
|
+
expect(ActiveRecord::Base.connection.raw_connection.getImplicitCachingEnabled).to be(true)
|
56
62
|
expect(ActiveRecord::Base.connection.raw_connection.getStatementCacheSize).to eq(100)
|
57
63
|
# else: don't raise error if OCI connection has parameter "jdbc_statement_cache_size", still ignore it
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
67
|
+
it "should not encrypt JDBC network connection" do
|
68
|
+
if ORACLE_ENHANCED_CONNECTION == :jdbc
|
69
|
+
@conn = ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_connect_properties: { "oracle.net.encryption_client" => "REJECTED" }))
|
70
|
+
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 }])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should encrypt JDBC network connection" do
|
75
|
+
if ORACLE_ENHANCED_CONNECTION == :jdbc
|
76
|
+
@conn = ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_connect_properties: { "oracle.net.encryption_client" => "REQUESTED" }))
|
77
|
+
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 }])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
61
81
|
it "should connect to database using service_name" do
|
62
82
|
ActiveRecord::Base.establish_connection(SERVICE_NAME_CONNECTION_PARAMS)
|
63
83
|
expect(ActiveRecord::Base.connection).not_to be_nil
|
@@ -227,7 +247,7 @@ describe "OracleEnhancedConnection" do
|
|
227
247
|
end
|
228
248
|
|
229
249
|
after(:all) do
|
230
|
-
Object.send(:remove_const, "Post")
|
250
|
+
Object.send(:remove_const, "Post") if defined?(Post)
|
231
251
|
ActiveRecord::Base.clear_cache!
|
232
252
|
end
|
233
253
|
|
@@ -392,7 +412,7 @@ describe "OracleEnhancedConnection" do
|
|
392
412
|
@conn.exec "DROP TABLE test_employees" rescue nil
|
393
413
|
end
|
394
414
|
|
395
|
-
it "should execute prepared statement with decimal bind parameter
|
415
|
+
it "should execute prepared statement with decimal bind parameter" do
|
396
416
|
cursor = @conn.prepare("INSERT INTO test_employees VALUES(:1)")
|
397
417
|
type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "NUMBER", type: :decimal, limit: 10, precision: nil, scale: 2)
|
398
418
|
column = ActiveRecord::ConnectionAdapters::OracleEnhanced::Column.new("age", nil, type_metadata, false, comment: nil)
|
@@ -414,7 +434,7 @@ describe "OracleEnhancedConnection" do
|
|
414
434
|
|
415
435
|
before(:all) do
|
416
436
|
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
|
417
|
-
@conn = ActiveRecord::Base.connection.
|
437
|
+
@conn = ActiveRecord::Base.connection.send(:_connection)
|
418
438
|
@sys_conn = ActiveRecord::ConnectionAdapters::OracleEnhanced::Connection.create(SYS_CONNECTION_PARAMS)
|
419
439
|
schema_define do
|
420
440
|
create_table :posts, force: true
|
@@ -447,6 +467,11 @@ describe "OracleEnhancedConnection" do
|
|
447
467
|
expect(@conn.exec("SELECT * FROM dual")).not_to be_nil
|
448
468
|
end
|
449
469
|
|
470
|
+
it "should reconnect and execute SQL statement if connection is lost and allow_retry is passed" do
|
471
|
+
kill_current_session
|
472
|
+
expect(@conn.exec("SELECT * FROM dual", allow_retry: true)).not_to be_nil
|
473
|
+
end
|
474
|
+
|
450
475
|
it "should not reconnect and execute SQL statement if connection is lost and auto retry is disabled" do
|
451
476
|
# @conn.auto_retry = false
|
452
477
|
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::
|
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::
|
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.+$/)
|
@@ -387,6 +387,34 @@ describe "OracleEnhancedAdapter schema definition" do
|
|
387
387
|
end
|
388
388
|
end
|
389
389
|
|
390
|
+
describe "add timestamps" do
|
391
|
+
before(:each) do
|
392
|
+
@conn = ActiveRecord::Base.connection
|
393
|
+
schema_define do
|
394
|
+
create_table :test_employees, force: true
|
395
|
+
end
|
396
|
+
class ::TestEmployee < ActiveRecord::Base; end
|
397
|
+
end
|
398
|
+
|
399
|
+
after(:each) do
|
400
|
+
schema_define do
|
401
|
+
drop_table :test_employees, if_exists: true
|
402
|
+
end
|
403
|
+
Object.send(:remove_const, "TestEmployee")
|
404
|
+
ActiveRecord::Base.clear_cache!
|
405
|
+
end
|
406
|
+
|
407
|
+
it "should add created_at and updated_at" do
|
408
|
+
expect do
|
409
|
+
@conn.add_timestamps("test_employees")
|
410
|
+
end.not_to raise_error
|
411
|
+
|
412
|
+
TestEmployee.reset_column_information
|
413
|
+
expect(TestEmployee.columns_hash["created_at"]).not_to be_nil
|
414
|
+
expect(TestEmployee.columns_hash["updated_at"]).not_to be_nil
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
390
418
|
describe "ignore options for LOB columns" do
|
391
419
|
after(:each) do
|
392
420
|
schema_define do
|
@@ -550,6 +578,7 @@ end
|
|
550
578
|
class ::TestPost < ActiveRecord::Base
|
551
579
|
end
|
552
580
|
end
|
581
|
+
|
553
582
|
it "should use default tablespace for clobs" do
|
554
583
|
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:clob] = DATABASE_NON_DEFAULT_TABLESPACE
|
555
584
|
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:nclob] = nil
|
@@ -880,7 +909,7 @@ end
|
|
880
909
|
expect(TestPost.columns_hash["a" * 128]).not_to be_nil
|
881
910
|
end
|
882
911
|
|
883
|
-
it "should add lob column with non_default tablespace" do
|
912
|
+
it "should add text type lob column with non_default tablespace" do
|
884
913
|
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:clob] = DATABASE_NON_DEFAULT_TABLESPACE
|
885
914
|
schema_define do
|
886
915
|
add_column :test_posts, :body, :text
|
@@ -888,7 +917,7 @@ end
|
|
888
917
|
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
918
|
end
|
890
919
|
|
891
|
-
it "should add lob column with non_default tablespace" do
|
920
|
+
it "should add ntext type lob column with non_default tablespace" do
|
892
921
|
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:nclob] = DATABASE_NON_DEFAULT_TABLESPACE
|
893
922
|
schema_define do
|
894
923
|
add_column :test_posts, :body, :ntext
|
@@ -995,12 +1024,12 @@ end
|
|
995
1024
|
|
996
1025
|
it "should include virtual columns and not try to update them" do
|
997
1026
|
tf = TestFraction.columns.detect { |c| c.virtual? }
|
998
|
-
expect(tf).not_to
|
1027
|
+
expect(tf).not_to be_nil
|
999
1028
|
expect(tf.name).to eq("percent")
|
1000
1029
|
expect(tf.virtual?).to be true
|
1001
1030
|
expect do
|
1002
1031
|
tf = TestFraction.new(numerator: 20, denominator: 100)
|
1003
|
-
expect(tf.percent).to
|
1032
|
+
expect(tf.percent).to be_nil # not whatever is in DATA_DEFAULT column
|
1004
1033
|
tf.save!
|
1005
1034
|
tf.reload
|
1006
1035
|
end.not_to raise_error
|
@@ -1013,11 +1042,11 @@ end
|
|
1013
1042
|
end
|
1014
1043
|
TestFraction.reset_column_information
|
1015
1044
|
tf = TestFraction.columns.detect { |c| c.name == "rem" }
|
1016
|
-
expect(tf).not_to
|
1045
|
+
expect(tf).not_to be_nil
|
1017
1046
|
expect(tf.virtual?).to be true
|
1018
1047
|
expect do
|
1019
1048
|
tf = TestFraction.new(numerator: 7, denominator: 5)
|
1020
|
-
expect(tf.rem).to
|
1049
|
+
expect(tf.rem).to be_nil
|
1021
1050
|
tf.save!
|
1022
1051
|
tf.reload
|
1023
1052
|
end.not_to raise_error
|
@@ -1030,13 +1059,13 @@ end
|
|
1030
1059
|
end
|
1031
1060
|
TestFraction.reset_column_information
|
1032
1061
|
tf = TestFraction.columns.detect { |c| c.name == "expression" }
|
1033
|
-
expect(tf).not_to
|
1062
|
+
expect(tf).not_to be_nil
|
1034
1063
|
expect(tf.virtual?).to be true
|
1035
1064
|
expect(tf.type).to be :string
|
1036
1065
|
expect(tf.limit).to be 100
|
1037
1066
|
expect do
|
1038
1067
|
tf = TestFraction.new(numerator: 7, denominator: 5)
|
1039
|
-
expect(tf.expression).to
|
1068
|
+
expect(tf.expression).to be_nil
|
1040
1069
|
tf.save!
|
1041
1070
|
tf.reload
|
1042
1071
|
end.not_to raise_error
|
@@ -1050,14 +1079,14 @@ end
|
|
1050
1079
|
end
|
1051
1080
|
TestFraction.reset_column_information
|
1052
1081
|
tf = TestFraction.columns.detect { |c| c.name == "percent" }
|
1053
|
-
expect(tf).not_to
|
1082
|
+
expect(tf).not_to be_nil
|
1054
1083
|
expect(tf.virtual?).to be true
|
1055
1084
|
expect(tf.type).to be :decimal
|
1056
1085
|
expect(tf.precision).to be 15
|
1057
1086
|
expect(tf.scale).to be 2
|
1058
1087
|
expect do
|
1059
1088
|
tf = TestFraction.new(numerator: 11, denominator: 17)
|
1060
|
-
expect(tf.percent).to
|
1089
|
+
expect(tf.percent).to be_nil
|
1061
1090
|
tf.save!
|
1062
1091
|
tf.reload
|
1063
1092
|
end.not_to raise_error
|
@@ -1070,14 +1099,14 @@ end
|
|
1070
1099
|
end
|
1071
1100
|
TestFraction.reset_column_information
|
1072
1101
|
tf = TestFraction.columns.detect { |c| c.name == "percent" }
|
1073
|
-
expect(tf).not_to
|
1102
|
+
expect(tf).not_to be_nil
|
1074
1103
|
expect(tf.virtual?).to be true
|
1075
1104
|
expect(tf.type).to be :decimal
|
1076
1105
|
expect(tf.precision).to be 12
|
1077
1106
|
expect(tf.scale).to be 5
|
1078
1107
|
expect do
|
1079
1108
|
tf = TestFraction.new(numerator: 11, denominator: 17)
|
1080
|
-
expect(tf.percent).to
|
1109
|
+
expect(tf.percent).to be_nil
|
1081
1110
|
tf.save!
|
1082
1111
|
tf.reload
|
1083
1112
|
end.not_to raise_error
|
@@ -1157,6 +1186,7 @@ end
|
|
1157
1186
|
@conn.drop_table :tablespace_tests, if_exists: true
|
1158
1187
|
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces.delete(:table)
|
1159
1188
|
end
|
1189
|
+
|
1160
1190
|
it "should use correct tablespace" do
|
1161
1191
|
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces[:table] = DATABASE_NON_DEFAULT_TABLESPACE
|
1162
1192
|
@conn.create_table :tablespace_tests do |t|
|
@@ -1171,6 +1201,7 @@ end
|
|
1171
1201
|
@conn.drop_table :tablespace_tests, if_exists: true
|
1172
1202
|
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_tablespaces.delete(:table)
|
1173
1203
|
end
|
1204
|
+
|
1174
1205
|
it "should use correct tablespace" do
|
1175
1206
|
@conn.create_table :tablespace_tests, id: false, organization: "INDEX INITRANS 4 COMPRESS 1", tablespace: "bogus" do |t|
|
1176
1207
|
t.integer :id
|
@@ -1206,7 +1237,14 @@ end
|
|
1206
1237
|
schema_define do
|
1207
1238
|
add_index :keyboards, "lower(name)", unique: true, name: :index_keyboards_on_lower_name
|
1208
1239
|
end
|
1209
|
-
expect(@would_execute_sql).not_to
|
1240
|
+
expect(@would_execute_sql).not_to include("ADD CONSTRAINT")
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
it "should add unique constraint only to the index where it was defined" do
|
1244
|
+
schema_define do
|
1245
|
+
add_index :keyboards, ["name"], unique: true, name: :this_index
|
1246
|
+
end
|
1247
|
+
expect(@would_execute_sql.lines.last).to match(/ALTER +TABLE .* ADD CONSTRAINT .* UNIQUE \(.*\) USING INDEX "THIS_INDEX";/)
|
1210
1248
|
end
|
1211
1249
|
end
|
1212
1250
|
|
@@ -1218,7 +1256,7 @@ end
|
|
1218
1256
|
before do
|
1219
1257
|
@conn = ActiveRecord::Base.connection
|
1220
1258
|
|
1221
|
-
ActiveRecord::
|
1259
|
+
ActiveRecord::Base.connection.schema_migration.create_table
|
1222
1260
|
end
|
1223
1261
|
|
1224
1262
|
context "multi insert is supported" do
|
@@ -1246,7 +1284,7 @@ end
|
|
1246
1284
|
end
|
1247
1285
|
|
1248
1286
|
after do
|
1249
|
-
ActiveRecord::
|
1287
|
+
ActiveRecord::Base.connection.schema_migration.drop_table
|
1250
1288
|
end
|
1251
1289
|
end
|
1252
1290
|
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::
|
342
|
-
ActiveRecord::SchemaMigration.create_table
|
337
|
+
ActiveRecord::Base.connection.schema_migration.create_table
|
343
338
|
versions.each do |i|
|
344
|
-
ActiveRecord::
|
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::
|
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/)
|