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
@@ -7,6 +7,8 @@ if ActiveRecord::Base.method_defined?(:changed?)
7
7
  before(:all) do
8
8
  ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
9
9
  @conn = ActiveRecord::Base.connection
10
+ @conn.execute "DROP TABLE test_employees" rescue nil
11
+ @conn.execute "DROP SEQUENCE test_employees_seq" rescue nil
10
12
  @conn.execute <<-SQL
11
13
  CREATE TABLE test_employees (
12
14
  id NUMBER PRIMARY KEY,
@@ -116,6 +118,24 @@ if ActiveRecord::Base.method_defined?(:changed?)
116
118
  @employee.should_not be_changed
117
119
  end
118
120
 
121
+ it "should not update unchanged CLOBs" do
122
+ @employee = TestEmployee.create!(
123
+ :comments => "initial"
124
+ )
125
+ @employee.save!.should be_true
126
+ @employee.reload
127
+ @employee.comments.should == 'initial'
128
+
129
+ oci_conn = @conn.instance_variable_get('@connection')
130
+ class << oci_conn
131
+ def write_lob(lob, value, is_binary = false); raise "don't do this'"; end
132
+ end
133
+ @employee.save!.should_not raise_exception(RuntimeError, "don't do this'")
134
+ class << oci_conn
135
+ remove_method :write_lob
136
+ end
137
+ end
138
+
119
139
  end
120
140
 
121
141
  end
@@ -107,8 +107,12 @@ describe "OracleEnhancedAdapter custom methods for create, update and destroy" d
107
107
 
108
108
  before(:each) do
109
109
  class ::TestEmployee < ActiveRecord::Base
110
- set_primary_key :employee_id
111
-
110
+ if self.respond_to?(:primary_key=)
111
+ self.primary_key = :employee_id
112
+ else
113
+ set_primary_key :employee_id
114
+ end
115
+
112
116
  validates_presence_of :first_name, :last_name, :hire_date
113
117
 
114
118
  # should return ID of new record
@@ -34,7 +34,7 @@ describe "OracleEnhancedAdapter schema dump" do
34
34
  rescue
35
35
  nil
36
36
  end
37
-
37
+
38
38
  describe "tables" do
39
39
  after(:each) do
40
40
  drop_test_posts_table
@@ -161,7 +161,7 @@ describe "OracleEnhancedAdapter schema dump" do
161
161
  end
162
162
  end
163
163
  end
164
-
164
+
165
165
  after(:each) do
166
166
  schema_define do
167
167
  remove_foreign_key :test_comments, :test_posts rescue nil
@@ -228,15 +228,15 @@ describe "OracleEnhancedAdapter schema dump" do
228
228
  schema_define do
229
229
  add_column :test_posts, :baz_id, :integer
230
230
  add_column :test_posts, :fooz_id, :integer
231
-
231
+
232
232
  execute <<-SQL
233
- ALTER TABLE TEST_POSTS
233
+ ALTER TABLE TEST_POSTS
234
234
  ADD CONSTRAINT UK_FOOZ_BAZ UNIQUE (BAZ_ID,FOOZ_ID)
235
235
  SQL
236
-
236
+
237
237
  add_column :test_comments, :baz_id, :integer
238
238
  add_column :test_comments, :fooz_id, :integer
239
-
239
+
240
240
  add_foreign_key :test_comments, :test_posts, :columns => ["baz_id", "fooz_id"], :name => 'comments_posts_baz_fooz_fk'
241
241
  end
242
242
  standard_dump.should =~ /add_foreign_key "test_comments", "test_posts", :columns => \["baz_id", "fooz_id"\], :name => "comments_posts_baz_fooz_fk"/
@@ -300,7 +300,7 @@ describe "OracleEnhancedAdapter schema dump" do
300
300
  after(:each) do
301
301
  drop_test_posts_table
302
302
  end
303
-
303
+
304
304
  it "should include temporary options" do
305
305
  create_test_posts_table(:temporary => true)
306
306
  standard_dump.should =~ /create_table "test_posts", :temporary => true/
@@ -347,34 +347,92 @@ describe "OracleEnhancedAdapter schema dump" do
347
347
 
348
348
  describe 'virtual columns' do
349
349
  before(:all) do
350
- oracle11g = @oracle11g
351
- schema_define do
352
- create_table :test_names, :force => true do |t|
353
- t.string :first_name
354
- t.string :last_name
355
- t.virtual :full_name, :default=>"first_name || ', ' || last_name" if oracle11g
350
+ if @oracle11g
351
+ schema_define do
352
+ create_table :test_names, :force => true do |t|
353
+ t.string :first_name
354
+ t.string :last_name
355
+ t.virtual :full_name, :as => "first_name || ', ' || last_name"
356
+ t.virtual :short_name, :as => "COALESCE(first_name, last_name)", :type => :string, :limit => 300
357
+ t.virtual :abbrev_name, :as => "SUBSTR(first_name,1,50) || ' ' || SUBSTR(last_name,1,1) || '.'", :type => "VARCHAR(100)"
358
+ t.column :full_name_length, :virtual, :as => "length(first_name || ', ' || last_name)", :type => :integer
359
+ t.virtual :field_with_leading_space, :as => "' ' || first_name || ' '", :limit => 300, :type => :string
360
+ end
356
361
  end
362
+ else
363
+ pending "Not supported in this database version"
357
364
  end
358
365
  end
366
+
359
367
  before(:each) do
360
- class ::TestName < ActiveRecord::Base
361
- set_table_name "test_names"
368
+ if @oracle11g
369
+ class ::TestName < ActiveRecord::Base
370
+ if self.respond_to?(:table_name=)
371
+ self.table_name = "test_names"
372
+ else
373
+ set_table_name "test_names"
374
+ end
375
+ end
362
376
  end
363
377
  end
364
378
 
365
379
  after(:all) do
366
- schema_define do
367
- drop_table :test_names
380
+ if @oracle11g
381
+ schema_define do
382
+ drop_table :test_names
383
+ end
368
384
  end
369
385
  end
370
386
 
371
387
  it 'should dump correctly' do
372
- pending "Not supported in this database version" unless @oracle11g
373
- standard_dump.should =~ /t.virtual "full_name",(\s*):limit => 512,(\s*):default => "/
388
+ standard_dump.should =~ /t\.virtual "full_name",(\s*):limit => 512,(\s*):as => "\\"FIRST_NAME\\"\|\|', '\|\|\\"LAST_NAME\\"",(\s*):type => :string/
389
+ standard_dump.should =~ /t\.virtual "short_name",(\s*):limit => 300,(\s*):as =>(.*),(\s*):type => :string/
390
+ standard_dump.should =~ /t\.virtual "full_name_length",(\s*):precision => 38,(\s*):scale => 0,(\s*):as =>(.*),(\s*):type => :integer/
391
+ standard_dump.should =~ /t\.virtual "abbrev_name",(\s*):limit => 100,(\s*):as =>(.*),(\s*):type => :string/
392
+ standard_dump.should =~ /t\.virtual "field_with_leading_space",(\s*):limit => 300,(\s*):as => "' '\|\|\\"FIRST_NAME\\"\|\|' '",(\s*):type => :string/
374
393
  end
375
394
 
376
- end
395
+ context 'with column cache' do
396
+ before(:all) do
397
+ @old_cache = ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns
398
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = true
399
+ end
400
+ after(:all) do
401
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.cache_columns = @old_cache
402
+ end
403
+ it 'should not change column defaults after several dumps' do
404
+ col = TestName.columns.detect{|c| c.name == 'full_name'}
405
+ col.should_not be_nil
406
+ col.virtual_column_data_default.should_not =~ /:as/
377
407
 
408
+ standard_dump
409
+ col.virtual_column_data_default.should_not =~ /:as/
378
410
 
379
- end
411
+ standard_dump
412
+ col.virtual_column_data_default.should_not =~ /:as/
413
+ end
414
+ end
380
415
 
416
+ context "with index on virtual column" do
417
+ before(:all) do
418
+ if @oracle11g
419
+ schema_define do
420
+ add_index 'test_names', 'field_with_leading_space', :name => "index_on_virtual_col"
421
+ end
422
+ end
423
+ end
424
+ after(:all) do
425
+ if @oracle11g
426
+ schema_define do
427
+ remove_index 'test_names', :name => 'index_on_virtual_col'
428
+ end
429
+ end
430
+ end
431
+ it 'should dump correctly' do
432
+ standard_dump.should_not =~ /add_index "test_names".+FIRST_NAME.+$/
433
+ standard_dump.should =~ /add_index "test_names".+field_with_leading_space.+$/
434
+ end
435
+ end
436
+ end
437
+
438
+ end
@@ -22,7 +22,11 @@ describe "OracleEnhancedAdapter schema definition" do
22
22
  end
23
23
  end
24
24
  class ::Keyboard < ActiveRecord::Base
25
- set_primary_key :key_number
25
+ if self.respond_to?(:primary_key=)
26
+ self.primary_key = :key_number
27
+ else
28
+ set_primary_key :key_number
29
+ end
26
30
  end
27
31
  class ::IdKeyboard < ActiveRecord::Base
28
32
  end
@@ -207,7 +211,7 @@ describe "OracleEnhancedAdapter schema definition" do
207
211
  insert_id = @conn.insert("INSERT INTO test_employees (first_name) VALUES ('Raimonds')", nil, "id")
208
212
  @conn.select_value("SELECT test_employees_seq.currval FROM dual").should == insert_id
209
213
  end
210
-
214
+
211
215
  it "should create new record for model" do
212
216
  e = TestEmployee.create!(:first_name => 'Raimonds')
213
217
  @conn.select_value("SELECT test_employees_seq.currval FROM dual").should == e.id
@@ -222,7 +226,11 @@ describe "OracleEnhancedAdapter schema definition" do
222
226
  @sequence_name = "test_employees_s"
223
227
  create_table_with_trigger(:primary_key => @primary_key, :sequence_name => @sequence_name)
224
228
  class ::TestEmployee < ActiveRecord::Base
225
- set_primary_key "employee_id"
229
+ if self.respond_to?(:primary_key=)
230
+ self.primary_key = "employee_id"
231
+ else
232
+ set_primary_key "employee_id"
233
+ end
226
234
  end
227
235
  end
228
236
 
@@ -254,7 +262,11 @@ describe "OracleEnhancedAdapter schema definition" do
254
262
  @sequence_name = "test_employees_s"
255
263
  create_table_with_trigger(:sequence_name => @sequence_name, :trigger_name => "test_employees_t1")
256
264
  class ::TestEmployee < ActiveRecord::Base
257
- set_sequence_name :autogenerated
265
+ if self.respond_to?(:sequence_name=)
266
+ self.sequence_name = :autogenerated
267
+ else
268
+ set_sequence_name :autogenerated
269
+ end
258
270
  end
259
271
  end
260
272
 
@@ -542,7 +554,7 @@ end
542
554
  belongs_to :test_post
543
555
  end
544
556
  end
545
-
557
+
546
558
  after(:each) do
547
559
  Object.send(:remove_const, "TestPost")
548
560
  Object.send(:remove_const, "TestComment")
@@ -618,26 +630,26 @@ end
618
630
  TestPost.delete(p.id)
619
631
  TestComment.find_by_id(c.id).test_post_id.should be_nil
620
632
  end
621
-
633
+
622
634
  it "should add a composite foreign key" do
623
635
  schema_define do
624
636
  add_column :test_posts, :baz_id, :integer
625
637
  add_column :test_posts, :fooz_id, :integer
626
-
638
+
627
639
  execute <<-SQL
628
- ALTER TABLE TEST_POSTS
640
+ ALTER TABLE TEST_POSTS
629
641
  ADD CONSTRAINT UK_FOOZ_BAZ UNIQUE (BAZ_ID,FOOZ_ID)
630
642
  SQL
631
-
643
+
632
644
  add_column :test_comments, :baz_id, :integer
633
645
  add_column :test_comments, :fooz_id, :integer
634
-
646
+
635
647
  add_foreign_key :test_comments, :test_posts, :columns => ["baz_id", "fooz_id"]
636
648
  end
637
-
649
+
638
650
  lambda do
639
651
  TestComment.create(:body => "test", :fooz_id => 1, :baz_id => 1)
640
- end.should raise_error() {|e| e.message.should =~
652
+ end.should raise_error() {|e| e.message.should =~
641
653
  /ORA-02291.*\.TES_COM_BAZ_ID_FOO_ID_FK/}
642
654
  end
643
655
 
@@ -645,18 +657,18 @@ end
645
657
  schema_define do
646
658
  add_column :test_posts, :baz_id, :integer
647
659
  add_column :test_posts, :fooz_id, :integer
648
-
660
+
649
661
  execute <<-SQL
650
- ALTER TABLE TEST_POSTS
662
+ ALTER TABLE TEST_POSTS
651
663
  ADD CONSTRAINT UK_FOOZ_BAZ UNIQUE (BAZ_ID,FOOZ_ID)
652
664
  SQL
653
-
665
+
654
666
  add_column :test_comments, :baz_id, :integer
655
667
  add_column :test_comments, :fooz_id, :integer
656
-
668
+
657
669
  add_foreign_key :test_comments, :test_posts, :columns => ["baz_id", "fooz_id"], :name => 'comments_posts_baz_fooz_fk'
658
670
  end
659
-
671
+
660
672
  lambda do
661
673
  TestComment.create(:body => "test", :baz_id => 1, :fooz_id => 1)
662
674
  end.should raise_error() {|e| e.message.should =~ /ORA-02291.*\.COMMENTS_POSTS_BAZ_FOOZ_FK/}
@@ -708,7 +720,7 @@ end
708
720
  belongs_to :test_post
709
721
  end
710
722
  end
711
-
723
+
712
724
  after(:each) do
713
725
  Object.send(:remove_const, "TestPost")
714
726
  Object.send(:remove_const, "TestComment")
@@ -862,7 +874,11 @@ end
862
874
 
863
875
  before(:each) do
864
876
  class ::TestPost < ActiveRecord::Base
865
- set_table_name "synonym_to_posts"
877
+ if self.respond_to?(:table_name=)
878
+ self.table_name = "synonym_to_posts"
879
+ else
880
+ set_table_name "synonym_to_posts"
881
+ end
866
882
  end
867
883
  end
868
884
 
@@ -918,6 +934,7 @@ end
918
934
  schema_define do
919
935
  create_table :test_posts, :force => true do |t|
920
936
  t.string :title, :null => false
937
+ t.string :content
921
938
  end
922
939
  end
923
940
  class ::TestPost < ActiveRecord::Base; end
@@ -979,46 +996,197 @@ end
979
996
  TestPost.columns_hash['title'].should be_nil
980
997
  end
981
998
 
999
+ it "should remove column when using change_table" do
1000
+ schema_define do
1001
+ change_table :test_posts do |t|
1002
+ t.remove :title
1003
+ end
1004
+ end
1005
+ TestPost.reset_column_information
1006
+ TestPost.columns_hash['title'].should be_nil
1007
+ end
1008
+
1009
+ it "should remove multiple columns when using change_table" do
1010
+ schema_define do
1011
+ change_table :test_posts do |t|
1012
+ t.remove :title, :content
1013
+ end
1014
+ end
1015
+ TestPost.reset_column_information
1016
+ TestPost.columns_hash['title'].should be_nil
1017
+ TestPost.columns_hash['content'].should be_nil
1018
+ end
1019
+ end
1020
+
1021
+ describe 'virtual columns in create_table' do
1022
+ before(:each) do
1023
+ pending "Not supported in this database version" unless @oracle11g
1024
+ end
1025
+
1026
+ it 'should create virtual column with old syntax' do
1027
+ schema_define do
1028
+ create_table :test_fractions, :force => true do |t|
1029
+ t.integer :field1
1030
+ t.virtual :field2, :default => 'field1 + 1'
1031
+ end
1032
+ end
1033
+ class ::TestFraction < ActiveRecord::Base
1034
+ if self.respond_to?(:table_name=)
1035
+ self.table_name = "test_fractions"
1036
+ else
1037
+ set_table_name "test_fractions"
1038
+ end
1039
+ end
1040
+
1041
+ TestFraction.reset_column_information
1042
+ tf = TestFraction.columns.detect { |c| c.virtual? }
1043
+ tf.should_not be nil
1044
+ tf.name.should == "field2"
1045
+ tf.virtual?.should be true
1046
+ lambda do
1047
+ tf = TestFraction.new(:field1=>10)
1048
+ tf.field2.should be nil # not whatever is in DATA_DEFAULT column
1049
+ tf.save!
1050
+ tf.reload
1051
+ end.should_not raise_error
1052
+ tf.field2.to_i.should == 11
1053
+
1054
+ schema_define do
1055
+ drop_table :test_fractions
1056
+ end
1057
+ end
1058
+
1059
+ it 'should raise error if column expression is not provided' do
1060
+ lambda {
1061
+ schema_define do
1062
+ create_table :test_fractions do |t|
1063
+ t.integer :field1
1064
+ t.virtual :field2
1065
+ end
1066
+ end
1067
+ }.should raise_error
1068
+ end
982
1069
  end
983
1070
 
984
1071
  describe 'virtual columns' do
985
- before(:all) do
986
- oracle11g = @oracle11g
1072
+ before(:each) do
1073
+ pending "Not supported in this database version" unless @oracle11g
1074
+ expr = "( numerator/NULLIF(denominator,0) )*100"
987
1075
  schema_define do
988
- expr = "( numerator/NULLIF(denominator,0) )*100"
989
1076
  create_table :test_fractions, :force => true do |t|
990
1077
  t.integer :numerator, :default=>0
991
1078
  t.integer :denominator, :default=>0
992
- t.virtual :percent, :default=>expr if oracle11g
1079
+ t.virtual :percent, :as => expr
993
1080
  end
994
1081
  end
995
- end
996
- before(:each) do
997
1082
  class ::TestFraction < ActiveRecord::Base
998
- set_table_name "test_fractions"
1083
+ if self.respond_to?(:table_name=)
1084
+ self.table_name = "test_fractions"
1085
+ else
1086
+ set_table_name "test_fractions"
1087
+ end
999
1088
  end
1089
+ TestFraction.reset_column_information
1000
1090
  end
1001
1091
 
1002
- after(:all) do
1003
- schema_define do
1004
- drop_table :test_fractions
1092
+ after(:each) do
1093
+ if @oracle11g
1094
+ schema_define do
1095
+ drop_table :test_fractions
1096
+ end
1005
1097
  end
1006
1098
  end
1007
1099
 
1008
1100
  it 'should include virtual columns and not try to update them' do
1009
- pending "Not supported in this database version" unless @oracle11g
1010
1101
  tf = TestFraction.columns.detect { |c| c.virtual? }
1011
1102
  tf.should_not be nil
1012
1103
  tf.name.should == "percent"
1013
1104
  tf.virtual?.should be true
1014
1105
  lambda do
1015
1106
  tf = TestFraction.new(:numerator=>20, :denominator=>100)
1016
- tf.percent.should==0 # not whatever is in DATA_DEFAULT column
1107
+ tf.percent.should be nil # not whatever is in DATA_DEFAULT column
1017
1108
  tf.save!
1018
1109
  tf.reload
1019
1110
  end.should_not raise_error
1020
1111
  tf.percent.to_i.should == 20
1021
1112
  end
1113
+
1114
+ it 'should add virtual column' do
1115
+ schema_define do
1116
+ add_column :test_fractions, :rem, :virtual, :as => 'remainder(numerator, NULLIF(denominator,0))'
1117
+ end
1118
+ TestFraction.reset_column_information
1119
+ tf = TestFraction.columns.detect { |c| c.name == 'rem' }
1120
+ tf.should_not be nil
1121
+ tf.virtual?.should be true
1122
+ lambda do
1123
+ tf = TestFraction.new(:numerator=>7, :denominator=>5)
1124
+ tf.rem.should be nil
1125
+ tf.save!
1126
+ tf.reload
1127
+ end.should_not raise_error
1128
+ tf.rem.to_i.should == 2
1129
+ end
1130
+
1131
+ it 'should add virtual column with explicit type' do
1132
+ schema_define do
1133
+ add_column :test_fractions, :expression, :virtual, :as => "TO_CHAR(numerator) || '/' || TO_CHAR(denominator)", :type => :string, :limit => 100
1134
+ end
1135
+ TestFraction.reset_column_information
1136
+ tf = TestFraction.columns.detect { |c| c.name == 'expression' }
1137
+ tf.should_not be nil
1138
+ tf.virtual?.should be true
1139
+ tf.type.should be :string
1140
+ tf.limit.should be 100
1141
+ lambda do
1142
+ tf = TestFraction.new(:numerator=>7, :denominator=>5)
1143
+ tf.expression.should be nil
1144
+ tf.save!
1145
+ tf.reload
1146
+ end.should_not raise_error
1147
+ tf.expression.should == '7/5'
1148
+ end
1149
+
1150
+ it 'should change virtual column definition' do
1151
+ schema_define do
1152
+ change_column :test_fractions, :percent, :virtual,
1153
+ :as => "ROUND((numerator/NULLIF(denominator,0))*100, 2)", :type => :decimal, :precision => 15, :scale => 2
1154
+ end
1155
+ TestFraction.reset_column_information
1156
+ tf = TestFraction.columns.detect { |c| c.name == 'percent' }
1157
+ tf.should_not be nil
1158
+ tf.virtual?.should be true
1159
+ tf.type.should be :decimal
1160
+ tf.precision.should be 15
1161
+ tf.scale.should be 2
1162
+ lambda do
1163
+ tf = TestFraction.new(:numerator=>11, :denominator=>17)
1164
+ tf.percent.should be nil
1165
+ tf.save!
1166
+ tf.reload
1167
+ end.should_not raise_error
1168
+ tf.percent.should == '64.71'.to_d
1169
+ end
1170
+
1171
+ it 'should change virtual column type' do
1172
+ schema_define do
1173
+ change_column :test_fractions, :percent, :virtual, :type => :decimal, :precision => 12, :scale => 5
1174
+ end
1175
+ TestFraction.reset_column_information
1176
+ tf = TestFraction.columns.detect { |c| c.name == 'percent' }
1177
+ tf.should_not be nil
1178
+ tf.virtual?.should be true
1179
+ tf.type.should be :decimal
1180
+ tf.precision.should be 12
1181
+ tf.scale.should be 5
1182
+ lambda do
1183
+ tf = TestFraction.new(:numerator=>11, :denominator=>17)
1184
+ tf.percent.should be nil
1185
+ tf.save!
1186
+ tf.reload
1187
+ end.should_not raise_error
1188
+ tf.percent.should == '64.70588'.to_d
1189
+ end
1022
1190
  end
1023
1191
 
1024
1192
  describe "miscellaneous options" do
@@ -1040,7 +1208,7 @@ end
1040
1208
  end
1041
1209
  @conn.instance_eval{ remove_instance_variable :@would_execute_sql }
1042
1210
  end
1043
-
1211
+
1044
1212
  it "should support the :options option to create_table" do
1045
1213
  schema_define do
1046
1214
  create_table :test_posts, :options=>'NOLOGGING', :force => true do |t|
@@ -1049,7 +1217,7 @@ end
1049
1217
  end
1050
1218
  @would_execute_sql.should =~ /CREATE +TABLE .* \(.*\) NOLOGGING/
1051
1219
  end
1052
-
1220
+
1053
1221
  it "should support the :tablespace option to create_table" do
1054
1222
  schema_define do
1055
1223
  create_table :test_posts, :tablespace=>'bogus', :force => true do |t|
@@ -1085,14 +1253,14 @@ end
1085
1253
  @would_execute_sql.should =~ /CREATE +TABLE .*\(.*\)\s+ORGANIZATION INDEX INITRANS 4 COMPRESS 1 TABLESPACE bogus/
1086
1254
  end
1087
1255
  end
1088
-
1256
+
1089
1257
  it "should support the :options option to add_index" do
1090
1258
  schema_define do
1091
1259
  add_index :keyboards, :name, :options=>'NOLOGGING'
1092
1260
  end
1093
1261
  @would_execute_sql.should =~ /CREATE +INDEX .* ON .* \(.*\) NOLOGGING/
1094
1262
  end
1095
-
1263
+
1096
1264
  it "should support the :tablespace option to add_index" do
1097
1265
  schema_define do
1098
1266
  add_index :keyboards, :name, :tablespace=>'bogus'