activerecord-oracle_enhanced-adapter 1.4.1 → 1.4.2.rc1

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.
Files changed (28) hide show
  1. data/Gemfile +1 -0
  2. data/History.md +16 -1
  3. data/README.md +60 -35
  4. data/Rakefile +14 -1
  5. data/VERSION +1 -1
  6. data/activerecord-oracle_enhanced-adapter.gemspec +2 -2
  7. data/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb +27 -9
  8. data/lib/active_record/connection_adapters/oracle_enhanced_base_ext.rb +13 -1
  9. data/lib/active_record/connection_adapters/oracle_enhanced_column.rb +7 -2
  10. data/lib/active_record/connection_adapters/oracle_enhanced_context_index.rb +31 -0
  11. data/lib/active_record/connection_adapters/oracle_enhanced_dirty.rb +6 -1
  12. data/lib/active_record/connection_adapters/oracle_enhanced_jdbc_connection.rb +17 -5
  13. data/lib/active_record/connection_adapters/oracle_enhanced_oci_connection.rb +2 -1
  14. data/lib/active_record/connection_adapters/oracle_enhanced_schema_definitions.rb +29 -11
  15. data/lib/active_record/connection_adapters/oracle_enhanced_schema_dumper.rb +9 -4
  16. data/lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb +31 -7
  17. data/lib/active_record/connection_adapters/oracle_enhanced_structure_dump.rb +5 -1
  18. data/spec/active_record/connection_adapters/oracle_enhanced_adapter_spec.rb +34 -5
  19. data/spec/active_record/connection_adapters/oracle_enhanced_connection_spec.rb +22 -0
  20. data/spec/active_record/connection_adapters/oracle_enhanced_context_index_spec.rb +1 -0
  21. data/spec/active_record/connection_adapters/oracle_enhanced_data_types_spec.rb +52 -6
  22. data/spec/active_record/connection_adapters/oracle_enhanced_dirty_spec.rb +20 -0
  23. data/spec/active_record/connection_adapters/oracle_enhanced_procedures_spec.rb +6 -2
  24. data/spec/active_record/connection_adapters/oracle_enhanced_schema_dump_spec.rb +79 -21
  25. data/spec/active_record/connection_adapters/oracle_enhanced_schema_statements_spec.rb +203 -35
  26. data/spec/active_record/connection_adapters/oracle_enhanced_structure_dump_spec.rb +17 -1
  27. data/spec/spec_helper.rb +3 -1
  28. metadata +74 -51
@@ -23,7 +23,8 @@ begin
23
23
  end
24
24
  end
25
25
 
26
- java.sql.DriverManager.registerDriver Java::oracle.jdbc.OracleDriver.new
26
+ ORACLE_DRIVER = Java::oracle.jdbc.OracleDriver.new
27
+ java.sql.DriverManager.registerDriver ORACLE_DRIVER
27
28
 
28
29
  # set tns_admin property from TNS_ADMIN environment variable
29
30
  if !java.lang.System.get_property("oracle.net.tns_admin") && ENV["TNS_ADMIN"]
@@ -94,15 +95,19 @@ module ActiveRecord
94
95
  # to_s needed if username, password or database is specified as number in database.yml file
95
96
  username = config[:username] && config[:username].to_s
96
97
  password = config[:password] && config[:password].to_s
97
- database = config[:database] && config[:database].to_s
98
+ database = config[:database] && config[:database].to_s || 'XE'
98
99
  host, port = config[:host], config[:port]
99
100
  privilege = config[:privilege] && config[:privilege].to_s
100
101
 
101
102
  # connection using TNS alias
102
103
  if database && !host && !config[:url] && ENV['TNS_ADMIN']
103
- url = "jdbc:oracle:thin:@#{database || 'XE'}"
104
+ url = "jdbc:oracle:thin:@#{database}"
104
105
  else
105
- url = config[:url] || "jdbc:oracle:thin:@#{host || 'localhost'}:#{port || 1521}:#{database || 'XE'}"
106
+ unless database.match(/^(\:|\/)/)
107
+ # assume database is a SID if no colon or slash are supplied (backward-compatibility)
108
+ database = ":#{database}"
109
+ end
110
+ url = config[:url] || "jdbc:oracle:thin:@#{host || 'localhost'}:#{port || 1521}#{database}"
106
111
  end
107
112
 
108
113
  prefetch_rows = config[:prefetch_rows] || 100
@@ -115,7 +120,14 @@ module ActiveRecord
115
120
  properties.put("defaultRowPrefetch", "#{prefetch_rows}") if prefetch_rows
116
121
  properties.put("internal_logon", privilege) if privilege
117
122
 
118
- @raw_connection = java.sql.DriverManager.getConnection(url, properties)
123
+ begin
124
+ @raw_connection = java.sql.DriverManager.getConnection(url, properties)
125
+ rescue
126
+ # bypass DriverManager to work in cases where ojdbc*.jar
127
+ # is added to the load path at runtime and not on the
128
+ # system classpath
129
+ @raw_connection = ORACLE_DRIVER.connect(url, properties)
130
+ end
119
131
 
120
132
  # Set session time zone to current time zone
121
133
  @raw_connection.setSessionTimeZone(time_zone)
@@ -309,7 +309,8 @@ module ActiveRecord
309
309
  host ||= 'localhost'
310
310
  host = "[#{host}]" if host =~ /^[^\[].*:/ # IPv6
311
311
  port ||= 1521
312
- "//#{host}:#{port}/#{database}"
312
+ database = "/#{database}" unless database.match(/^\//)
313
+ "//#{host}:#{port}#{database}"
313
314
  # if no host is specified then assume that
314
315
  # database parameter is TNS alias or TNS connection string
315
316
  else
@@ -19,8 +19,9 @@ module ActiveRecord
19
19
  end
20
20
 
21
21
  def to_sql_with_virtual_columns
22
- if type==:virtual
23
- "#{base.quote_column_name(name)} AS (#{default})"
22
+ if type == :virtual
23
+ sql_type = base.type_to_sql(default[:type], limit, precision, scale) if default[:type]
24
+ "#{base.quote_column_name(name)} #{sql_type} AS (#{default[:as]})"
24
25
  else
25
26
  to_sql_without_virtual_columns
26
27
  end
@@ -56,22 +57,39 @@ module ActiveRecord
56
57
  alias to_s :to_sql
57
58
  end
58
59
 
59
- def raw(name, options={})
60
- column(name, :raw, options)
61
- end
62
-
63
60
  def self.included(base) #:nodoc:
64
61
  base.class_eval do
65
62
  alias_method_chain :references, :foreign_keys
66
63
  alias_method_chain :to_sql, :foreign_keys
67
64
 
68
- def virtual(* args)
69
- options = args.extract_options!
70
- column_names = args
71
- column_names.each { |name| column(name, :virtual, options) }
72
- end
65
+ alias_method_chain :column, :virtual_columns
66
+ end
67
+ end
73
68
 
69
+ def raw(name, options={})
70
+ column(name, :raw, options)
71
+ end
72
+
73
+ def virtual(* args)
74
+ options = args.extract_options!
75
+ column_names = args
76
+ column_names.each { |name| column(name, :virtual, options) }
77
+ end
78
+
79
+ def column_with_virtual_columns(name, type, options = {})
80
+ if type == :virtual
81
+ default = {:type => options[:type]}
82
+ if options[:as]
83
+ default[:as] = options[:as]
84
+ elsif options[:default]
85
+ warn "[DEPRECATION] virtual column `:default` option is deprecated. Please use `:as` instead."
86
+ default[:as] = options[:default]
87
+ else
88
+ raise "No virtual column definition found."
89
+ end
90
+ options[:default] = default
74
91
  end
92
+ column_without_virtual_columns(name, type, options)
75
93
  end
76
94
 
77
95
  # Adds a :foreign_key option to TableDefinition.references.
@@ -176,18 +176,23 @@ module ActiveRecord #:nodoc:
176
176
  spec = {}
177
177
  spec[:name] = column.name.inspect
178
178
  spec[:type] = column.virtual? ? 'virtual' : column.type.to_s
179
+ spec[:type] = column.virtual? ? 'virtual' : column.type.to_s
180
+ spec[:virtual_type] = column.type.inspect if column.virtual?
179
181
  spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && column.type != :decimal
180
182
  spec[:precision] = column.precision.inspect if !column.precision.nil?
181
183
  spec[:scale] = column.scale.inspect if !column.scale.nil?
182
184
  spec[:null] = 'false' if !column.null
183
- spec[:default] = column.virtual_column_data_default if column.virtual?
184
- spec[:default] ||= default_string(column.default) if column.has_default?
185
- (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")}
185
+ spec[:as] = column.virtual_column_data_default if column.virtual?
186
+ spec[:default] = default_string(column.default) if column.has_default? && !column.virtual?
187
+ (spec.keys - [:name, :type]).each do |k|
188
+ key_s = (k == :virtual_type ? ":type => " : "#{k.inspect} => ")
189
+ spec[k] = key_s + spec[k]
190
+ end
186
191
  spec
187
192
  end.compact
188
193
 
189
194
  # find all migration keys used in this table
190
- keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map(&:keys).flatten
195
+ keys = [:name, :limit, :precision, :scale, :default, :null, :as, :virtual_type] & column_specs.map(&:keys).flatten
191
196
 
192
197
  # figure out the lengths for each column based on above keys
193
198
  lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max }
@@ -210,9 +210,16 @@ module ActiveRecord
210
210
  end
211
211
 
212
212
  def add_column(table_name, column_name, type, options = {}) #:nodoc:
213
- add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
213
+ if type.to_sym == :virtual
214
+ type = options[:type]
215
+ end
216
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} "
217
+ add_column_sql << type_to_sql(type, options[:limit], options[:precision], options[:scale]) if type
218
+
214
219
  add_column_options!(add_column_sql, options.merge(:type=>type, :column_name=>column_name, :table_name=>table_name))
215
- add_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, table_name, column_name)
220
+
221
+ add_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, table_name, column_name) if type
222
+
216
223
  execute(add_column_sql)
217
224
  ensure
218
225
  clear_table_columns_cache(table_name)
@@ -242,10 +249,16 @@ module ActiveRecord
242
249
  if options.has_key?(:null) && options[:null] == column.null
243
250
  options[:null] = nil
244
251
  end
252
+ if type.to_sym == :virtual
253
+ type = options[:type]
254
+ end
255
+ change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} "
256
+ change_column_sql << "#{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" if type
245
257
 
246
- change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
247
258
  add_column_options!(change_column_sql, options.merge(:type=>type, :column_name=>column_name, :table_name=>table_name))
248
- change_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, options[:table_name], options[:column_name])
259
+
260
+ change_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, options[:table_name], options[:column_name]) if type
261
+
249
262
  execute(change_column_sql)
250
263
  ensure
251
264
  clear_table_columns_cache(table_name)
@@ -257,8 +270,19 @@ module ActiveRecord
257
270
  clear_table_columns_cache(table_name)
258
271
  end
259
272
 
260
- def remove_column(table_name, column_name) #:nodoc:
261
- execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
273
+ def remove_column(table_name, *column_names) #:nodoc:
274
+ major, minor = ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR
275
+ is_deprecated = (major == 3 and minor >= 2) or major > 3
276
+
277
+ if column_names.flatten! and is_deprecated
278
+ message = 'Passing array to remove_columns is deprecated, please use ' +
279
+ 'multiple arguments, like: `remove_columns(:posts, :foo, :bar)`'
280
+ ActiveSupport::Deprecation.warn message, caller
281
+ end
282
+
283
+ column_names.each do |column_name|
284
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
285
+ end
262
286
  ensure
263
287
  clear_table_columns_cache(table_name)
264
288
  end
@@ -341,7 +365,7 @@ module ActiveRecord
341
365
 
342
366
  create_primary_key_trigger(table_name, options) if options[:primary_key_trigger]
343
367
  end
344
-
368
+
345
369
  def create_primary_key_trigger(table_name, options)
346
370
  seq_name = options[:sequence_name] || default_sequence_name(table_name)
347
371
  trigger_name = options[:trigger_name] || default_trigger_name(table_name)
@@ -117,7 +117,7 @@ module ActiveRecord #:nodoc:
117
117
  else
118
118
  index_type = options
119
119
  end
120
- quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
120
+ quoted_column_names = column_names.map { |e| quote_column_name_or_expression(e) }.join(", ")
121
121
  "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
122
122
  end
123
123
  end
@@ -232,6 +232,10 @@ module ActiveRecord #:nodoc:
232
232
  elsif options[:null] == true
233
233
  sql << " NULL" unless type == :primary_key
234
234
  end
235
+ # add AS expression for virtual columns
236
+ if options[:as].present?
237
+ sql << " AS (#{options[:as]})"
238
+ end
235
239
  end
236
240
 
237
241
  def execute_structure_dump(string)
@@ -209,7 +209,11 @@ describe "OracleEnhancedAdapter" do
209
209
  end
210
210
  # Another class using the same table
211
211
  class ::TestEmployee2 < ActiveRecord::Base
212
- set_table_name "test_employees"
212
+ if self.respond_to?(:table_name=)
213
+ self.table_name = "test_employees"
214
+ else
215
+ set_table_name "test_employees"
216
+ end
213
217
  end
214
218
  end
215
219
 
@@ -332,7 +336,11 @@ describe "OracleEnhancedAdapter" do
332
336
  SQL
333
337
  Object.send(:remove_const, 'CompositePrimaryKeys') if defined?(CompositePrimaryKeys)
334
338
  class ::TestEmployee < ActiveRecord::Base
335
- set_primary_key :employee_id
339
+ if self.respond_to?(:primary_key=)
340
+ self.primary_key = :employee_id
341
+ else
342
+ set_primary_key :employee_id
343
+ end
336
344
  end
337
345
  end
338
346
 
@@ -509,7 +517,11 @@ describe "OracleEnhancedAdapter" do
509
517
  it "should allow creation of a table with non alphanumeric characters" do
510
518
  create_warehouse_things_table
511
519
  class ::WarehouseThing < ActiveRecord::Base
512
- set_table_name "warehouse-things"
520
+ if self.respond_to?(:table_name=)
521
+ self.table_name = "warehouse-things"
522
+ else
523
+ set_table_name "warehouse-things"
524
+ end
513
525
  end
514
526
 
515
527
  wh = WarehouseThing.create!(:name => "Foo", :foo => 2)
@@ -521,7 +533,11 @@ describe "OracleEnhancedAdapter" do
521
533
  it "should allow creation of a table with CamelCase name" do
522
534
  create_camel_case_table
523
535
  class ::CamelCase < ActiveRecord::Base
524
- set_table_name "CamelCase"
536
+ if self.respond_to?(:table_name=)
537
+ self.table_name = "CamelCase"
538
+ else
539
+ set_table_name "CamelCase"
540
+ end
525
541
  end
526
542
 
527
543
  cc = CamelCase.create!(:name => "Foo", :foo => 2)
@@ -553,7 +569,11 @@ describe "OracleEnhancedAdapter" do
553
569
  @conn.execute "CREATE OR REPLACE SYNONYM test_posts_seq FOR test_posts_seq@#{@db_link}"
554
570
  class ::TestPost < ActiveRecord::Base
555
571
  end
556
- TestPost.set_table_name "test_posts"
572
+ if TestPost.respond_to?(:table_name=)
573
+ TestPost.table_name = "test_posts"
574
+ else
575
+ TestPost.set_table_name "test_posts"
576
+ end
557
577
  end
558
578
 
559
579
  after(:all) do
@@ -724,6 +744,7 @@ describe "OracleEnhancedAdapter" do
724
744
 
725
745
  describe "explain" do
726
746
  before(:all) do
747
+ @conn = ActiveRecord::Base.connection
727
748
  schema_define do
728
749
  drop_table :test_posts rescue nil
729
750
  create_table :test_posts
@@ -745,5 +766,13 @@ describe "OracleEnhancedAdapter" do
745
766
  explain.should include("Cost")
746
767
  explain.should include("INDEX UNIQUE SCAN")
747
768
  end
769
+
770
+ it "should explain query with binds" do
771
+ pk = TestPost.columns.find { |c| c.primary }
772
+ sub = @conn.substitute_at(pk, 0)
773
+ explain = TestPost.where(TestPost.arel_table[pk.name].eq(sub)).bind([pk, 1]).explain
774
+ explain.should include("Cost")
775
+ explain.should include("INDEX UNIQUE SCAN")
776
+ end
748
777
  end if ENV['RAILS_GEM_VERSION'] >= '3.2'
749
778
  end
@@ -74,6 +74,18 @@ describe "OracleEnhancedConnection" do
74
74
  end
75
75
  end
76
76
 
77
+ describe "with slash-prefixed database name (service name)" do
78
+ before(:all) do
79
+ params = CONNECTION_PARAMS.dup
80
+ params[:database] = "/#{params[:database]}" unless params[:database].match(/^\//)
81
+ @conn = ActiveRecord::ConnectionAdapters::OracleEnhancedConnection.create(params)
82
+ end
83
+
84
+ it "should create new connection" do
85
+ @conn.should be_active
86
+ end
87
+ end
88
+
77
89
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
78
90
 
79
91
  describe "create JDBC connection" do
@@ -143,6 +155,16 @@ describe "OracleEnhancedConnection" do
143
155
 
144
156
  end
145
157
 
158
+ it "should fall back to directly instantiating OracleDriver" do
159
+ params = CONNECTION_PARAMS.dup
160
+ params[:url] = "jdbc:oracle:thin:@#{DATABASE_HOST && "#{DATABASE_HOST}:"}#{DATABASE_PORT && "#{DATABASE_PORT}:"}#{DATABASE_NAME}"
161
+ params[:host] = nil
162
+ params[:database] = nil
163
+ java.sql.DriverManager.stub!(:getConnection).and_raise('no suitable driver found')
164
+ @conn = ActiveRecord::ConnectionAdapters::OracleEnhancedConnection.create(params)
165
+ @conn.should be_active
166
+ end
167
+
146
168
  end
147
169
 
148
170
  describe "SQL execution" do
@@ -406,6 +406,7 @@ describe "OracleEnhancedAdapter context index" do
406
406
  :name => 'xxx_post_and_comments_i',
407
407
  :index_column => :all_text, :index_column_trigger_on => :updated_at,
408
408
  :lexer => { :type => "BASIC_LEXER", :base_letter_type => 'GENERIC', :base_letter => true },
409
+ :wordlist => { :type => "BASIC_WORDLIST", :prefix_index => true },
409
410
  :sync => 'ON COMMIT'
410
411
  }
411
412
  schema_define do
@@ -5,6 +5,8 @@ describe "OracleEnhancedAdapter date type detection based on column names" do
5
5
  before(:all) do
6
6
  ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
7
7
  @conn = ActiveRecord::Base.connection
8
+ @conn.execute "DROP TABLE test_employees" rescue nil
9
+ @conn.execute "DROP SEQUENCE test_employees_seq" rescue nil
8
10
  @conn.execute <<-SQL
9
11
  CREATE TABLE test_employees (
10
12
  employee_id NUMBER(6,0) PRIMARY KEY,
@@ -87,7 +89,11 @@ describe "OracleEnhancedAdapter date type detection based on column names" do
87
89
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
88
90
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = false
89
91
  class ::TestEmployee < ActiveRecord::Base
90
- set_primary_key :employee_id
92
+ if self.respond_to?(:primary_key=)
93
+ self.primary_key = "employee_id"
94
+ else
95
+ set_primary_key "employee_id"
96
+ end
91
97
  end
92
98
  end
93
99
 
@@ -563,7 +569,11 @@ describe "OracleEnhancedAdapter timestamp with timezone support" do
563
569
  describe "/ TIMESTAMP WITH TIME ZONE values from ActiveRecord model" do
564
570
  before(:all) do
565
571
  class ::TestEmployee < ActiveRecord::Base
566
- set_primary_key :employee_id
572
+ if self.respond_to?(:primary_key=)
573
+ self.primary_key = "employee_id"
574
+ else
575
+ set_primary_key "employee_id"
576
+ end
567
577
  end
568
578
  end
569
579
 
@@ -645,7 +655,11 @@ describe "OracleEnhancedAdapter date and timestamp with different NLS date forma
645
655
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates = false
646
656
  ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.emulate_dates_by_column_name = false
647
657
  class ::TestEmployee < ActiveRecord::Base
648
- set_primary_key :employee_id
658
+ if self.respond_to?(:primary_key=)
659
+ self.primary_key = "employee_id"
660
+ else
661
+ set_primary_key "employee_id"
662
+ end
649
663
  end
650
664
  @today = Date.new(2008,6,28)
651
665
  @now = Time.local(2008,6,28,13,34,33)
@@ -730,7 +744,11 @@ describe "OracleEnhancedAdapter assign string to :date and :datetime columns" do
730
744
  INCREMENT BY 1 CACHE 20 NOORDER NOCYCLE
731
745
  SQL
732
746
  class ::TestEmployee < ActiveRecord::Base
733
- set_primary_key :employee_id
747
+ if self.respond_to?(:primary_key=)
748
+ self.primary_key = "employee_id"
749
+ else
750
+ set_primary_key "employee_id"
751
+ end
734
752
  end
735
753
  @today = Date.new(2008,6,28)
736
754
  @today_iso = "2008-06-28"
@@ -899,6 +917,10 @@ describe "OracleEnhancedAdapter handling of CLOB columns" do
899
917
  class ::Test2Employee < ActiveRecord::Base
900
918
  serialize :comments
901
919
  end
920
+ class ::TestEmployeeReadOnlyClob < ActiveRecord::Base
921
+ set_table_name :test_employees
922
+ attr_readonly :comments
923
+ end
902
924
  end
903
925
 
904
926
  after(:all) do
@@ -908,6 +930,7 @@ describe "OracleEnhancedAdapter handling of CLOB columns" do
908
930
  @conn.execute "DROP SEQUENCE test2_employees_seq"
909
931
  Object.send(:remove_const, "TestEmployee")
910
932
  Object.send(:remove_const, "Test2Employee")
933
+ Object.send(:remove_const, "TestEmployeeReadOnlyClob")
911
934
  ActiveRecord::Base.clear_cache! if ActiveRecord::Base.respond_to?(:"clear_cache!")
912
935
  end
913
936
 
@@ -926,6 +949,21 @@ describe "OracleEnhancedAdapter handling of CLOB columns" do
926
949
  @employee.should be_valid
927
950
  end
928
951
 
952
+ it "should respect attr_readonly setting for CLOB column" do
953
+ @employee = TestEmployeeReadOnlyClob.create!(
954
+ :first_name => "First",
955
+ :comments => "initial"
956
+ )
957
+ @employee.should be_valid
958
+ @employee.reload
959
+ @employee.comments.should == 'initial'
960
+ @employee.comments = "changed"
961
+ @employee.save.should == true
962
+ @employee.reload
963
+ @employee.comments.should == 'initial'
964
+ end
965
+
966
+
929
967
  it "should create record with CLOB data" do
930
968
  @employee = TestEmployee.create!(
931
969
  :first_name => "First",
@@ -1043,7 +1081,11 @@ describe "OracleEnhancedAdapter handling of BLOB columns" do
1043
1081
 
1044
1082
  before(:each) do
1045
1083
  class ::TestEmployee < ActiveRecord::Base
1046
- set_primary_key :employee_id
1084
+ if self.respond_to?(:primary_key=)
1085
+ self.primary_key = "employee_id"
1086
+ else
1087
+ set_primary_key "employee_id"
1088
+ end
1047
1089
  end
1048
1090
  end
1049
1091
 
@@ -1169,7 +1211,11 @@ describe "OracleEnhancedAdapter handling of RAW columns" do
1169
1211
 
1170
1212
  before(:each) do
1171
1213
  class ::TestEmployee < ActiveRecord::Base
1172
- set_primary_key :employee_id
1214
+ if self.respond_to?(:primary_key=)
1215
+ self.primary_key = "employee_id"
1216
+ else
1217
+ set_primary_key "employee_id"
1218
+ end
1173
1219
  end
1174
1220
  end
1175
1221