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.
@@ -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