rwc9u-oracle-enhanced 1.1.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,11 @@
1
+ module ActiveRecord #:nodoc:
2
+ module ConnectionAdapters #:nodoc:
3
+ module OracleEnhancedVersion #:nodoc:
4
+ MAJOR = 1
5
+ MINOR = 1
6
+ TINY = 9
7
+
8
+ STRING = [MAJOR, MINOR, TINY].join('.')
9
+ end
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