rwc9u-oracle-enhanced 1.1.9.4
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.
- data/History.txt +89 -0
- data/License.txt +20 -0
- data/Manifest.txt +23 -0
- data/README.txt +51 -0
- data/lib/active_record/connection_adapters/emulation/oracle_adapter.rb +5 -0
- data/lib/active_record/connection_adapters/oracle_enhanced.rake +44 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +1137 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_cpk.rb +21 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +39 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_procedures.rb +110 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_reserved_words.rb +126 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_tasks.rb +11 -0
- data/lib/active_record/connection_adapters/oracle_enhanced_version.rb +11 -0
- data/oracle-enhanced.gemspec +35 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +535 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb +32 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +826 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +85 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb +21 -0
- data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +272 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +42 -0
- metadata +88 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
module ConnectionAdapters #:nodoc:
|
3
|
+
module OracleEnhancedCpk #:nodoc:
|
4
|
+
|
5
|
+
# This mightn't be in Core, but count(distinct x,y) doesn't work for me
|
6
|
+
# RSI: return that not supported if composite_primary_keys gem is required
|
7
|
+
def supports_count_distinct? #:nodoc:
|
8
|
+
@supports_count_distinct ||= ! defined?(CompositePrimaryKeys)
|
9
|
+
end
|
10
|
+
|
11
|
+
def concat(*columns)
|
12
|
+
"(#{columns.join('||')})"
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
|
20
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedCpk
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
module ConnectionAdapters #:nodoc:
|
3
|
+
module OracleEnhancedDirty #:nodoc:
|
4
|
+
|
5
|
+
module InstanceMethods
|
6
|
+
private
|
7
|
+
|
8
|
+
def field_changed?(attr, old, value)
|
9
|
+
if column = column_for_attribute(attr)
|
10
|
+
# RSI: added also :decimal type
|
11
|
+
if (column.type == :integer || column.type == :decimal) && column.null && (old.nil? || old == 0)
|
12
|
+
# For nullable integer columns, NULL gets stored in database for blank (i.e. '') values.
|
13
|
+
# Hence we don't record it as a change if the value changes from nil to ''.
|
14
|
+
# If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
|
15
|
+
# be typecast back to 0 (''.to_i => 0)
|
16
|
+
value = nil if value.blank?
|
17
|
+
# RSI: Oracle stores empty string '' or empty text (CLOB) as NULL
|
18
|
+
# therefore need to convert empty string value to nil if old value is nil
|
19
|
+
elsif (column.type == :string || column.type == :text) && column.null && old.nil?
|
20
|
+
value = nil if value == ''
|
21
|
+
else
|
22
|
+
value = column.type_cast(value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
old != value
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if ActiveRecord::Base.instance_methods.include?('changed?')
|
36
|
+
ActiveRecord::Base.class_eval do
|
37
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedDirty::InstanceMethods
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# define accessors before requiring ruby-plsql as these accessors are used in clob writing callback and should be
|
2
|
+
# available also if ruby-plsql could not be loaded
|
3
|
+
ActiveRecord::Base.class_eval do
|
4
|
+
class_inheritable_accessor :custom_create_method, :custom_update_method, :custom_delete_method
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'ruby_plsql'
|
8
|
+
require 'activesupport'
|
9
|
+
|
10
|
+
module ActiveRecord #:nodoc:
|
11
|
+
module ConnectionAdapters #:nodoc:
|
12
|
+
module OracleEnhancedProcedures #:nodoc:
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def set_create_method(&block)
|
16
|
+
include_with_custom_methods
|
17
|
+
self.custom_create_method = block
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_update_method(&block)
|
21
|
+
include_with_custom_methods
|
22
|
+
self.custom_update_method = block
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_delete_method(&block)
|
26
|
+
include_with_custom_methods
|
27
|
+
self.custom_delete_method = block
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def include_with_custom_methods
|
32
|
+
unless included_modules.include? InstanceMethods
|
33
|
+
include InstanceMethods
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module InstanceMethods
|
39
|
+
def self.included(base)
|
40
|
+
base.instance_eval do
|
41
|
+
alias_method_chain :create, :custom_method
|
42
|
+
# insert after dirty checking in Rails 2.1
|
43
|
+
if private_instance_methods.include?('update_without_dirty')
|
44
|
+
alias_method :update_without_custom_method, :update_without_dirty
|
45
|
+
alias_method :update_without_dirty, :update_with_custom_method
|
46
|
+
else
|
47
|
+
alias_method_chain :update, :custom_method
|
48
|
+
end
|
49
|
+
private :create, :update
|
50
|
+
alias_method_chain :destroy, :custom_method
|
51
|
+
public :destroy
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
# Creates a record with custom create method
|
58
|
+
# and returns its id.
|
59
|
+
def create_with_custom_method
|
60
|
+
# check if class has custom create method
|
61
|
+
return create_without_custom_method unless self.class.custom_create_method
|
62
|
+
self.class.connection.log_custom_method("custom create method", "#{self.class.name} Create") do
|
63
|
+
self.id = self.class.custom_create_method.bind(self).call
|
64
|
+
end
|
65
|
+
@new_record = false
|
66
|
+
id
|
67
|
+
end
|
68
|
+
|
69
|
+
# Updates the associated record with custom update method
|
70
|
+
# Returns the number of affected rows.
|
71
|
+
def update_with_custom_method(attribute_names = @attributes.keys)
|
72
|
+
# check if class has custom create method
|
73
|
+
return update_without_custom_method unless self.class.custom_update_method
|
74
|
+
return 0 if attribute_names.empty?
|
75
|
+
self.class.connection.log_custom_method("custom update method with #{self.class.primary_key}=#{self.id}", "#{self.class.name} Update") do
|
76
|
+
self.class.custom_update_method.bind(self).call
|
77
|
+
end
|
78
|
+
1
|
79
|
+
end
|
80
|
+
|
81
|
+
# Deletes the record in the database with custom delete method
|
82
|
+
# and freezes this instance to reflect that no changes should
|
83
|
+
# be made (since they can't be persisted).
|
84
|
+
def destroy_with_custom_method
|
85
|
+
# check if class has custom create method
|
86
|
+
return destroy_without_custom_method unless self.class.custom_delete_method
|
87
|
+
unless new_record?
|
88
|
+
self.class.connection.log_custom_method("custom delete method with #{self.class.primary_key}=#{self.id}", "#{self.class.name} Destroy") do
|
89
|
+
self.class.custom_delete_method.bind(self).call
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
freeze
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
ActiveRecord::Base.class_eval do
|
103
|
+
extend ActiveRecord::ConnectionAdapters::OracleEnhancedProcedures::ClassMethods
|
104
|
+
end
|
105
|
+
|
106
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
|
107
|
+
# public alias to log method which could be used from other objects
|
108
|
+
alias_method :log_custom_method, :log
|
109
|
+
public :log_custom_method
|
110
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
module ConnectionAdapters #:nodoc:
|
3
|
+
module OracleEnhancedReservedWords #:nodoc:
|
4
|
+
|
5
|
+
RESERVED_WORDS = {
|
6
|
+
"ACCESS" => true,
|
7
|
+
"ADD" => true,
|
8
|
+
"ALL" => true,
|
9
|
+
"ALTER" => true,
|
10
|
+
"AND" => true,
|
11
|
+
"ANY" => true,
|
12
|
+
"AS" => true,
|
13
|
+
"ASC" => true,
|
14
|
+
"AUDIT" => true,
|
15
|
+
"BETWEEN" => true,
|
16
|
+
"BY" => true,
|
17
|
+
"CHAR" => true,
|
18
|
+
"CHECK" => true,
|
19
|
+
"CLUSTER" => true,
|
20
|
+
"COLUMN" => true,
|
21
|
+
"COMMENT" => true,
|
22
|
+
"COMPRESS" => true,
|
23
|
+
"CONNECT" => true,
|
24
|
+
"CREATE" => true,
|
25
|
+
"CURRENT" => true,
|
26
|
+
"DATE" => true,
|
27
|
+
"DECIMAL" => true,
|
28
|
+
"DEFAULT" => true,
|
29
|
+
"DELETE" => true,
|
30
|
+
"DESC" => true,
|
31
|
+
"DISTINCT" => true,
|
32
|
+
"DROP" => true,
|
33
|
+
"ELSE" => true,
|
34
|
+
"EXCLUSIVE" => true,
|
35
|
+
"EXISTS" => true,
|
36
|
+
"FILE" => true,
|
37
|
+
"FLOAT" => true,
|
38
|
+
"FOR" => true,
|
39
|
+
"FROM" => true,
|
40
|
+
"GRANT" => true,
|
41
|
+
"GROUP" => true,
|
42
|
+
"HAVING" => true,
|
43
|
+
"IDENTIFIED" => true,
|
44
|
+
"IMMEDIATE" => true,
|
45
|
+
"IN" => true,
|
46
|
+
"INCREMENT" => true,
|
47
|
+
"INDEX" => true,
|
48
|
+
"INITIAL" => true,
|
49
|
+
"INSERT" => true,
|
50
|
+
"INTEGER" => true,
|
51
|
+
"INTERSECT" => true,
|
52
|
+
"INTO" => true,
|
53
|
+
"IS" => true,
|
54
|
+
"LEVEL" => true,
|
55
|
+
"LIKE" => true,
|
56
|
+
"LOCK" => true,
|
57
|
+
"LONG" => true,
|
58
|
+
"MAXEXTENTS" => true,
|
59
|
+
"MINUS" => true,
|
60
|
+
"MLSLABEL" => true,
|
61
|
+
"MODE" => true,
|
62
|
+
"MODIFY" => true,
|
63
|
+
"NOAUDIT" => true,
|
64
|
+
"NOCOMPRESS" => true,
|
65
|
+
"NOT" => true,
|
66
|
+
"NOWAIT" => true,
|
67
|
+
"NULL" => true,
|
68
|
+
"NUMBER" => true,
|
69
|
+
"OF" => true,
|
70
|
+
"OFFLINE" => true,
|
71
|
+
"ON" => true,
|
72
|
+
"ONLINE" => true,
|
73
|
+
"OPTION" => true,
|
74
|
+
"OR" => true,
|
75
|
+
"ORDER" => true,
|
76
|
+
"PCTFREE" => true,
|
77
|
+
"PRIOR" => true,
|
78
|
+
"PRIVILEGES" => true,
|
79
|
+
"PUBLIC" => true,
|
80
|
+
"RAW" => true,
|
81
|
+
"RENAME" => true,
|
82
|
+
"RESOURCE" => true,
|
83
|
+
"REVOKE" => true,
|
84
|
+
"ROW" => true,
|
85
|
+
"ROWID" => true,
|
86
|
+
"ROWNUM" => true,
|
87
|
+
"ROWS" => true,
|
88
|
+
"SELECT" => true,
|
89
|
+
"SESSION" => true,
|
90
|
+
"SET" => true,
|
91
|
+
"SHARE" => true,
|
92
|
+
"SIZE" => true,
|
93
|
+
"SMALLINT" => true,
|
94
|
+
"START" => true,
|
95
|
+
"SUCCESSFUL" => true,
|
96
|
+
"SYNONYM" => true,
|
97
|
+
"SYSDATE" => true,
|
98
|
+
"TABLE" => true,
|
99
|
+
"THEN" => true,
|
100
|
+
"TO" => true,
|
101
|
+
"TRIGGER" => true,
|
102
|
+
"UID" => true,
|
103
|
+
"UNION" => true,
|
104
|
+
"UNIQUE" => true,
|
105
|
+
"UPDATE" => true,
|
106
|
+
"USER" => true,
|
107
|
+
"VALIDATE" => true,
|
108
|
+
"VALUES" => true,
|
109
|
+
"VARCHAR" => true,
|
110
|
+
"VARCHAR2" => true,
|
111
|
+
"VIEW" => true,
|
112
|
+
"WHENEVER" => true,
|
113
|
+
"WHERE" => true,
|
114
|
+
"WITH" => true
|
115
|
+
}
|
116
|
+
|
117
|
+
def quote_oracle_reserved_words(name)
|
118
|
+
RESERVED_WORDS[name.to_s.upcase].nil? ? name : "\"#{name}\""
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
|
125
|
+
include ActiveRecord::ConnectionAdapters::OracleEnhancedReservedWords
|
126
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# RSI: implementation idea taken from JDBC adapter
|
2
|
+
if defined?(Rake.application) && Rake.application
|
3
|
+
oracle_enhanced_rakefile = File.dirname(__FILE__) + "/oracle_enhanced.rake"
|
4
|
+
if Rake.application.lookup("environment")
|
5
|
+
# rails tasks already defined; load the override tasks now
|
6
|
+
load oracle_enhanced_rakefile
|
7
|
+
else
|
8
|
+
# rails tasks not loaded yet; load as an import
|
9
|
+
Rake.application.add_import(oracle_enhanced_rakefile)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{oracle-enhanced}
|
5
|
+
s.version = "1.1.9.4"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Raimonds Simanovskis (patched by Rob Christie"]
|
9
|
+
s.date = %q{2009-01-21}
|
10
|
+
s.description = %q{Oracle enhanced adapter for Active Record. Additional patches to support ActiveRecord unit tests}
|
11
|
+
s.email = ["robchristie@gmail.com"]
|
12
|
+
s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "README.txt"]
|
13
|
+
s.files = ["#oracle-enhanced.gemspec#", "History.txt", "License.txt", "Manifest.txt", "README.txt", "lib/active_record/connection_adapters/emulation/oracle_adapter.rb", "lib/active_record/connection_adapters/oracle_enhanced.rake", "lib/active_record/connection_adapters/oracle_enhanced_adapter.rb", "lib/active_record/connection_adapters/oracle_enhanced_cpk.rb", "lib/active_record/connection_adapters/oracle_enhanced_dirty.rb", "lib/active_record/connection_adapters/oracle_enhanced_procedures.rb", "lib/active_record/connection_adapters/oracle_enhanced_reserved_words.rb", "lib/active_record/connection_adapters/oracle_enhanced_tasks.rb", "lib/active_record/connection_adapters/oracle_enhanced_version.rb", "oracle-enhanced.gemspec", "spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb", "spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb", "spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb", "spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb", "spec/active_record/connection_adapters/oracle_enhanced_emulate_oracle_adapter_spec.rb", "spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://oracle-enhanced.rubyforge.org}
|
16
|
+
s.post_install_message = %q{}
|
17
|
+
s.rdoc_options = ["--main", "README.txt"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubyforge_project = %q{oracle-enhanced}
|
20
|
+
s.rubygems_version = %q{1.3.1}
|
21
|
+
s.summary = %q{Oracle enhaced adapter for Active Record}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 2
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<hoe>, [">= 1.8.0"])
|
31
|
+
end
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<hoe>, [">= 1.8.0"])
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,535 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
+
|
3
|
+
describe "OracleEnhancedAdapter establish connection" do
|
4
|
+
|
5
|
+
it "should connect to database" do
|
6
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
7
|
+
:database => "xe",
|
8
|
+
:username => "hr",
|
9
|
+
:password => "hr")
|
10
|
+
ActiveRecord::Base.connection.should_not be_nil
|
11
|
+
ActiveRecord::Base.connection.class.should == ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should connect to database as SYSDBA" do
|
15
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
16
|
+
:database => "xe",
|
17
|
+
:username => "sys",
|
18
|
+
:password => "manager",
|
19
|
+
:privilege => :SYSDBA)
|
20
|
+
ActiveRecord::Base.connection.should_not be_nil
|
21
|
+
ActiveRecord::Base.connection.class.should == ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "OracleEnhancedAdapter schema dump" do
|
27
|
+
|
28
|
+
before(:all) do
|
29
|
+
@old_conn = ActiveRecord::Base.oracle_connection(
|
30
|
+
:database => "xe",
|
31
|
+
:username => "hr",
|
32
|
+
:password => "hr")
|
33
|
+
@old_conn.class.should == ActiveRecord::ConnectionAdapters::OracleAdapter
|
34
|
+
@new_conn = ActiveRecord::Base.oracle_enhanced_connection(
|
35
|
+
:database => "xe",
|
36
|
+
:username => "hr",
|
37
|
+
:password => "hr")
|
38
|
+
@new_conn.class.should == ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return the same tables list as original oracle adapter" do
|
42
|
+
@new_conn.tables.should == @old_conn.tables
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return the same index list as original oracle adapter" do
|
46
|
+
@new_conn.indexes('employees').should == @old_conn.indexes('employees')
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return the same pk_and_sequence_for as original oracle adapter" do
|
50
|
+
@new_conn.tables.each do |t|
|
51
|
+
@new_conn.pk_and_sequence_for(t).should == @old_conn.pk_and_sequence_for(t)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return the same structure dump as original oracle adapter" do
|
56
|
+
@new_conn.structure_dump.should == @old_conn.structure_dump
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return the same structure drop as original oracle adapter" do
|
60
|
+
@new_conn.structure_drop.should == @old_conn.structure_drop
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return the character size of nvarchar fields" do
|
64
|
+
@new_conn.execute <<-SQL
|
65
|
+
CREATE TABLE nvarchartable (
|
66
|
+
session_id NVARCHAR2(255) DEFAULT NULL
|
67
|
+
)
|
68
|
+
SQL
|
69
|
+
if /.*session_id nvarchar2\((\d+)\).*/ =~ @new_conn.structure_dump
|
70
|
+
"#$1".should == "255"
|
71
|
+
end
|
72
|
+
@new_conn.execute "DROP TABLE nvarchartable"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "OracleEnhancedAdapter database stucture dump extentions" do
|
77
|
+
before(:all) do
|
78
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
79
|
+
:database => "xe",
|
80
|
+
:username => "hr",
|
81
|
+
:password => "hr")
|
82
|
+
@conn = ActiveRecord::Base.connection
|
83
|
+
@conn.execute <<-SQL
|
84
|
+
CREATE TABLE nvarchartable (
|
85
|
+
unq_nvarchar NVARCHAR2(255) DEFAULT NULL
|
86
|
+
)
|
87
|
+
SQL
|
88
|
+
end
|
89
|
+
|
90
|
+
after(:all) do
|
91
|
+
@conn.execute "DROP TABLE nvarchartable"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should return the character size of nvarchar fields" do
|
95
|
+
if /.*unq_nvarchar nvarchar2\((\d+)\).*/ =~ @conn.structure_dump
|
96
|
+
"#$1".should == "255"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "OracleEnhancedAdapter database session store" do
|
102
|
+
before(:all) do
|
103
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
104
|
+
:database => "xe",
|
105
|
+
:username => "hr",
|
106
|
+
:password => "hr")
|
107
|
+
@conn = ActiveRecord::Base.connection
|
108
|
+
@conn.execute <<-SQL
|
109
|
+
CREATE TABLE sessions (
|
110
|
+
id NUMBER(38,0) NOT NULL,
|
111
|
+
session_id VARCHAR2(255) DEFAULT NULL,
|
112
|
+
data CLOB DEFAULT NULL,
|
113
|
+
created_at DATE DEFAULT NULL,
|
114
|
+
updated_at DATE DEFAULT NULL,
|
115
|
+
PRIMARY KEY (ID)
|
116
|
+
)
|
117
|
+
SQL
|
118
|
+
@conn.execute <<-SQL
|
119
|
+
CREATE SEQUENCE sessions_seq MINVALUE 1 MAXVALUE 999999999999999999999999999
|
120
|
+
INCREMENT BY 1 START WITH 10040 CACHE 20 NOORDER NOCYCLE
|
121
|
+
SQL
|
122
|
+
end
|
123
|
+
|
124
|
+
after(:all) do
|
125
|
+
@conn.execute "DROP TABLE sessions"
|
126
|
+
@conn.execute "DROP SEQUENCE sessions_seq"
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should create sessions table" do
|
130
|
+
ActiveRecord::Base.connection.tables.grep("sessions").should_not be_empty
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should save session data" do
|
134
|
+
@session = CGI::Session::ActiveRecordStore::Session.new :session_id => "111111", :data => "something" #, :updated_at => Time.now
|
135
|
+
@session.save!
|
136
|
+
@session = CGI::Session::ActiveRecordStore::Session.find_by_session_id("111111")
|
137
|
+
@session.data.should == "something"
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should change session data when partial updates enabled" do
|
141
|
+
return pending("Not in this ActiveRecord version") unless CGI::Session::ActiveRecordStore::Session.respond_to?(:partial_updates=)
|
142
|
+
CGI::Session::ActiveRecordStore::Session.partial_updates = true
|
143
|
+
@session = CGI::Session::ActiveRecordStore::Session.new :session_id => "222222", :data => "something" #, :updated_at => Time.now
|
144
|
+
@session.save!
|
145
|
+
@session = CGI::Session::ActiveRecordStore::Session.find_by_session_id("222222")
|
146
|
+
@session.data = "other thing"
|
147
|
+
@session.save!
|
148
|
+
# second save should call again blob writing callback
|
149
|
+
@session.save!
|
150
|
+
@session = CGI::Session::ActiveRecordStore::Session.find_by_session_id("222222")
|
151
|
+
@session.data.should == "other thing"
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should have one enhanced_write_lobs callback" do
|
155
|
+
return pending("Not in this ActiveRecord version") unless CGI::Session::ActiveRecordStore::Session.respond_to?(:after_save_callback_chain)
|
156
|
+
CGI::Session::ActiveRecordStore::Session.after_save_callback_chain.select{|cb| cb.method == :enhanced_write_lobs}.should have(1).record
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should not set sessions table session_id column type as integer if emulate_integers_by_column_name is true" do
|
160
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_integers_by_column_name = true
|
161
|
+
columns = @conn.columns('sessions')
|
162
|
+
column = columns.detect{|c| c.name == "session_id"}
|
163
|
+
column.type.should == :string
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "OracleEnhancedAdapter ignore specified table columns" do
|
169
|
+
before(:all) do
|
170
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
171
|
+
:database => "xe",
|
172
|
+
:username => "hr",
|
173
|
+
:password => "hr")
|
174
|
+
@conn = ActiveRecord::Base.connection
|
175
|
+
@conn.execute <<-SQL
|
176
|
+
CREATE TABLE test_employees (
|
177
|
+
id NUMBER,
|
178
|
+
first_name VARCHAR2(20),
|
179
|
+
last_name VARCHAR2(25),
|
180
|
+
email VARCHAR2(25),
|
181
|
+
phone_number VARCHAR2(20),
|
182
|
+
hire_date DATE,
|
183
|
+
job_id NUMBER,
|
184
|
+
salary NUMBER,
|
185
|
+
commission_pct NUMBER(2,2),
|
186
|
+
manager_id NUMBER(6),
|
187
|
+
department_id NUMBER(4,0),
|
188
|
+
created_at DATE
|
189
|
+
)
|
190
|
+
SQL
|
191
|
+
@conn.execute <<-SQL
|
192
|
+
CREATE SEQUENCE test_employees_seq MINVALUE 1
|
193
|
+
INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE
|
194
|
+
SQL
|
195
|
+
end
|
196
|
+
|
197
|
+
after(:all) do
|
198
|
+
@conn.execute "DROP TABLE test_employees"
|
199
|
+
@conn.execute "DROP SEQUENCE test_employees_seq"
|
200
|
+
end
|
201
|
+
|
202
|
+
after(:each) do
|
203
|
+
Object.send(:remove_const, "TestEmployee")
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should ignore specified table columns" do
|
207
|
+
class TestEmployee < ActiveRecord::Base
|
208
|
+
ignore_table_columns :phone_number, :hire_date
|
209
|
+
end
|
210
|
+
TestEmployee.connection.columns('test_employees').select{|c| ['phone_number','hire_date'].include?(c.name) }.should be_empty
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should ignore specified table columns specified in several lines" do
|
214
|
+
class TestEmployee < ActiveRecord::Base
|
215
|
+
ignore_table_columns :phone_number
|
216
|
+
ignore_table_columns :hire_date
|
217
|
+
end
|
218
|
+
TestEmployee.connection.columns('test_employees').select{|c| ['phone_number','hire_date'].include?(c.name) }.should be_empty
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should not ignore unspecified table columns" do
|
222
|
+
class TestEmployee < ActiveRecord::Base
|
223
|
+
ignore_table_columns :phone_number, :hire_date
|
224
|
+
end
|
225
|
+
TestEmployee.connection.columns('test_employees').select{|c| c.name == 'email' }.should_not be_empty
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "OracleEnhancedAdapter table and sequence creation with non-default primary key" do
|
232
|
+
|
233
|
+
before(:all) do
|
234
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
235
|
+
:database => "xe",
|
236
|
+
:username => "hr",
|
237
|
+
:password => "hr")
|
238
|
+
ActiveRecord::Schema.define do
|
239
|
+
suppress_messages do
|
240
|
+
create_table :keyboards, :force => true, :id => false do |t|
|
241
|
+
t.primary_key :key_number
|
242
|
+
t.string :name
|
243
|
+
end
|
244
|
+
create_table :id_keyboards, :force => true do |t|
|
245
|
+
t.string :name
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
class Keyboard < ActiveRecord::Base
|
250
|
+
set_primary_key :key_number
|
251
|
+
end
|
252
|
+
class IdKeyboard < ActiveRecord::Base
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
after(:all) do
|
257
|
+
ActiveRecord::Schema.define do
|
258
|
+
suppress_messages do
|
259
|
+
drop_table :keyboards
|
260
|
+
drop_table :id_keyboards
|
261
|
+
end
|
262
|
+
end
|
263
|
+
Object.send(:remove_const, "Keyboard")
|
264
|
+
Object.send(:remove_const, "IdKeyboard")
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should create sequence for non-default primary key" do
|
268
|
+
ActiveRecord::Base.connection.next_sequence_value(Keyboard.sequence_name).should_not be_nil
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should create sequence for default primary key" do
|
272
|
+
ActiveRecord::Base.connection.next_sequence_value(IdKeyboard.sequence_name).should_not be_nil
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
describe "OracleEnhancedAdapter without composite_primary_keys" do
|
277
|
+
|
278
|
+
before(:all) do
|
279
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
280
|
+
:database => "xe",
|
281
|
+
:username => "hr",
|
282
|
+
:password => "hr")
|
283
|
+
Object.send(:remove_const, 'CompositePrimaryKeys') if defined?(CompositePrimaryKeys)
|
284
|
+
class Employee < ActiveRecord::Base
|
285
|
+
set_primary_key :employee_id
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should tell ActiveRecord that count distinct is supported" do
|
290
|
+
ActiveRecord::Base.connection.supports_count_distinct?.should be_true
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should execute correct SQL COUNT DISTINCT statement" do
|
294
|
+
lambda { Employee.count(:employee_id, :distinct => true) }.should_not raise_error
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
describe "OracleEnhancedAdapter sequence creation parameters" do
|
300
|
+
|
301
|
+
before(:all) do
|
302
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
303
|
+
:database => "xe",
|
304
|
+
:username => "hr",
|
305
|
+
:password => "hr")
|
306
|
+
end
|
307
|
+
|
308
|
+
def create_test_employees_table(sequence_start_value = nil)
|
309
|
+
ActiveRecord::Schema.define do
|
310
|
+
suppress_messages do
|
311
|
+
create_table :test_employees, sequence_start_value ? {:sequence_start_value => sequence_start_value} : {} do |t|
|
312
|
+
t.string :first_name
|
313
|
+
t.string :last_name
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def save_default_sequence_start_value
|
320
|
+
@saved_sequence_start_value = ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value
|
321
|
+
end
|
322
|
+
|
323
|
+
def restore_default_sequence_start_value
|
324
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value = @saved_sequence_start_value
|
325
|
+
end
|
326
|
+
|
327
|
+
before(:each) do
|
328
|
+
save_default_sequence_start_value
|
329
|
+
end
|
330
|
+
after(:each) do
|
331
|
+
restore_default_sequence_start_value
|
332
|
+
ActiveRecord::Schema.define do
|
333
|
+
suppress_messages do
|
334
|
+
drop_table :test_employees
|
335
|
+
end
|
336
|
+
end
|
337
|
+
Object.send(:remove_const, "TestEmployee")
|
338
|
+
end
|
339
|
+
|
340
|
+
it "should use default sequence start value 10000" do
|
341
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value.should == 10000
|
342
|
+
|
343
|
+
create_test_employees_table
|
344
|
+
class TestEmployee < ActiveRecord::Base; end
|
345
|
+
|
346
|
+
employee = TestEmployee.create!
|
347
|
+
employee.id.should == 10000
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should use specified default sequence start value" do
|
351
|
+
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.default_sequence_start_value = 1
|
352
|
+
|
353
|
+
create_test_employees_table
|
354
|
+
class TestEmployee < ActiveRecord::Base; end
|
355
|
+
|
356
|
+
employee = TestEmployee.create!
|
357
|
+
employee.id.should == 1
|
358
|
+
end
|
359
|
+
|
360
|
+
it "should use sequence start value from table definition" do
|
361
|
+
create_test_employees_table(10)
|
362
|
+
class TestEmployee < ActiveRecord::Base; end
|
363
|
+
|
364
|
+
employee = TestEmployee.create!
|
365
|
+
employee.id.should == 10
|
366
|
+
end
|
367
|
+
|
368
|
+
it "should use sequence start value and other options from table definition" do
|
369
|
+
create_test_employees_table("100 NOCACHE INCREMENT BY 10")
|
370
|
+
class TestEmployee < ActiveRecord::Base; end
|
371
|
+
|
372
|
+
employee = TestEmployee.create!
|
373
|
+
employee.id.should == 100
|
374
|
+
employee = TestEmployee.create!
|
375
|
+
employee.id.should == 110
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
describe "OracleEnhancedAdapter table and column comments" do
|
381
|
+
|
382
|
+
before(:all) do
|
383
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
384
|
+
:database => "xe",
|
385
|
+
:username => "hr",
|
386
|
+
:password => "hr")
|
387
|
+
@conn = ActiveRecord::Base.connection
|
388
|
+
end
|
389
|
+
|
390
|
+
def create_test_employees_table(table_comment=nil, column_comments={})
|
391
|
+
ActiveRecord::Schema.define do
|
392
|
+
suppress_messages do
|
393
|
+
create_table :test_employees, :comment => table_comment do |t|
|
394
|
+
t.string :first_name, :comment => column_comments[:first_name]
|
395
|
+
t.string :last_name, :comment => column_comments[:last_name]
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
after(:each) do
|
402
|
+
ActiveRecord::Schema.define do
|
403
|
+
suppress_messages do
|
404
|
+
drop_table :test_employees
|
405
|
+
end
|
406
|
+
end
|
407
|
+
Object.send(:remove_const, "TestEmployee")
|
408
|
+
ActiveRecord::Base.table_name_prefix = nil
|
409
|
+
end
|
410
|
+
|
411
|
+
it "should create table with table comment" do
|
412
|
+
table_comment = "Test Employees"
|
413
|
+
create_test_employees_table(table_comment)
|
414
|
+
class TestEmployee < ActiveRecord::Base; end
|
415
|
+
|
416
|
+
@conn.table_comment("test_employees").should == table_comment
|
417
|
+
TestEmployee.table_comment.should == table_comment
|
418
|
+
end
|
419
|
+
|
420
|
+
it "should create table with columns comment" do
|
421
|
+
column_comments = {:first_name => "Given Name", :last_name => "Surname"}
|
422
|
+
create_test_employees_table(nil, column_comments)
|
423
|
+
class TestEmployee < ActiveRecord::Base; end
|
424
|
+
|
425
|
+
[:first_name, :last_name].each do |attr|
|
426
|
+
@conn.column_comment("test_employees", attr.to_s).should == column_comments[attr]
|
427
|
+
end
|
428
|
+
[:first_name, :last_name].each do |attr|
|
429
|
+
TestEmployee.columns_hash[attr.to_s].comment.should == column_comments[attr]
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
it "should create table with table and columns comment and custom table name prefix" do
|
434
|
+
ActiveRecord::Base.table_name_prefix = "xxx_"
|
435
|
+
table_comment = "Test Employees"
|
436
|
+
column_comments = {:first_name => "Given Name", :last_name => "Surname"}
|
437
|
+
create_test_employees_table(table_comment, column_comments)
|
438
|
+
class TestEmployee < ActiveRecord::Base; end
|
439
|
+
|
440
|
+
@conn.table_comment(TestEmployee.table_name).should == table_comment
|
441
|
+
TestEmployee.table_comment.should == table_comment
|
442
|
+
[:first_name, :last_name].each do |attr|
|
443
|
+
@conn.column_comment(TestEmployee.table_name, attr.to_s).should == column_comments[attr]
|
444
|
+
end
|
445
|
+
[:first_name, :last_name].each do |attr|
|
446
|
+
TestEmployee.columns_hash[attr.to_s].comment.should == column_comments[attr]
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
end
|
451
|
+
|
452
|
+
describe "OracleEnhancedAdapter column quoting" do
|
453
|
+
|
454
|
+
before(:all) do
|
455
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
456
|
+
:database => "xe",
|
457
|
+
:username => "hr",
|
458
|
+
:password => "hr")
|
459
|
+
@conn = ActiveRecord::Base.connection
|
460
|
+
end
|
461
|
+
|
462
|
+
def create_test_reserved_words_table
|
463
|
+
ActiveRecord::Schema.define do
|
464
|
+
suppress_messages do
|
465
|
+
create_table :test_reserved_words do |t|
|
466
|
+
t.string :varchar2
|
467
|
+
t.integer :integer
|
468
|
+
end
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
after(:each) do
|
474
|
+
ActiveRecord::Schema.define do
|
475
|
+
suppress_messages do
|
476
|
+
drop_table :test_reserved_words
|
477
|
+
end
|
478
|
+
end
|
479
|
+
Object.send(:remove_const, "TestReservedWord")
|
480
|
+
ActiveRecord::Base.table_name_prefix = nil
|
481
|
+
end
|
482
|
+
|
483
|
+
it "should allow creation of a table with oracle reserved words as column names" do
|
484
|
+
create_test_reserved_words_table
|
485
|
+
class TestReservedWord < ActiveRecord::Base; end
|
486
|
+
|
487
|
+
[:varchar2, :integer].each do |attr|
|
488
|
+
TestReservedWord.columns_hash[attr.to_s].name.should == attr.to_s
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
end
|
493
|
+
|
494
|
+
describe "OracleEnhancedAdapter table quoting" do
|
495
|
+
|
496
|
+
before(:all) do
|
497
|
+
ActiveRecord::Base.establish_connection(:adapter => "oracle_enhanced",
|
498
|
+
:database => "xe",
|
499
|
+
:username => "hr",
|
500
|
+
:password => "hr")
|
501
|
+
@conn = ActiveRecord::Base.connection
|
502
|
+
end
|
503
|
+
|
504
|
+
def create_warehouse_things_table
|
505
|
+
ActiveRecord::Schema.define do
|
506
|
+
suppress_messages do
|
507
|
+
create_table "warehouse-things" do |t|
|
508
|
+
t.string :name
|
509
|
+
t.integer :foo
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
after(:each) do
|
516
|
+
ActiveRecord::Schema.define do
|
517
|
+
suppress_messages do
|
518
|
+
drop_table "warehouse-things"
|
519
|
+
end
|
520
|
+
end
|
521
|
+
Object.send(:remove_const, "WarehouseThing")
|
522
|
+
ActiveRecord::Base.table_name_prefix = nil
|
523
|
+
end
|
524
|
+
|
525
|
+
it "should allow creation of a table with non alphanumeric characters" do
|
526
|
+
create_warehouse_things_table
|
527
|
+
class WarehouseThing < ActiveRecord::Base
|
528
|
+
set_table_name "warehouse-things"
|
529
|
+
end
|
530
|
+
|
531
|
+
wh = WarehouseThing.create!(:name => "Foo", :foo => 2)
|
532
|
+
wh.id.should_not be_nil
|
533
|
+
end
|
534
|
+
|
535
|
+
end
|