~ubuntu-branches/ubuntu/vivid/ruby-sequel/vivid

« back to all changes in this revision

Viewing changes to spec/extensions/schema_dumper_spec.rb

  • Committer: Package Import Robot
  • Author(s): Dmitry Borodaenko, Dmitry Borodaenko, Cédric Boutillier
  • Date: 2013-08-10 18:38:17 UTC
  • mfrom: (1.1.8)
  • Revision ID: package-import@ubuntu.com-20130810183817-iqanz804j32i5myi
Tags: 4.1.1-1
[ Dmitry Borodaenko ]
* New upstream release.
* Standards-Version upgraded to 3.9.4 (no changes).
* Added Build-Depend on ruby-sqlite3.

[ Cédric Boutillier ]
* debian/control: remove obsolete DM-Upload-Allowed flag.
* use canonical URI in Vcs-* fields.
* debian/copyright: use DEP5 copyright-format/1.0 official URL for Format
  field.
* Update debian/watch. Thanks Bart Martens.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
describe "Sequel::Schema::Generator dump methods" do
4
4
  before do
5
 
    @d = Sequel::Database.new
 
5
    @d = Sequel::Database.new.extension(:schema_dumper)
6
6
    @g = Sequel::Schema::Generator
7
7
  end
8
8
 
63
63
 
64
64
describe "Sequel::Database dump methods" do
65
65
  before do
66
 
    @d = Sequel::Database.new
 
66
    @d = Sequel::Database.new.extension(:schema_dumper)
67
67
    @d.meta_def(:tables){|o| [:t1, :t2]}
68
68
    @d.meta_def(:schema) do |t, *o|
69
69
      case t
70
 
      when :t1, 't__t1', :t__t1.identifier
 
70
      when :t1, 't__t1', Sequel.identifier(:t__t1)
71
71
        [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>false}],
72
72
         [:c2, {:db_type=>'varchar(20)', :allow_null=>true}]]
73
73
      when :t2
88
88
  end
89
89
 
90
90
  it "should support dumping table schemas when given an identifier" do
91
 
    @d.dump_table_schema(:t__t1.identifier).should == "create_table(\"t__t1\") do\n  primary_key :c1\n  String :c2, :size=>20\nend"
 
91
    @d.dump_table_schema(Sequel.identifier(:t__t1)).should == "create_table(\"t__t1\") do\n  primary_key :c1\n  String :c2, :size=>20\nend"
92
92
  end
93
93
 
94
94
  it "should dump non-Integer primary key columns with explicit :type" do
98
98
 
99
99
  it "should handle foreign keys" do
100
100
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
 
101
    @d.meta_def(:supports_foreign_key_parsing?){true}
101
102
    @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}]}
102
103
    @d.dump_table_schema(:t6).should == "create_table(:t6) do\n  foreign_key :c1, :t2, :key=>[:c2]\nend"
103
104
  end
104
105
 
105
106
  it "should handle primary keys that are also foreign keys" do
106
107
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
 
108
    @d.meta_def(:supports_foreign_key_parsing?){true}
107
109
    @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}]}
108
110
    s = @d.dump_table_schema(:t6)
109
111
    s.should =~ /create_table\(:t6\) do\n  primary_key :c1, /
113
115
 
114
116
  it "should handle foreign key options" do
115
117
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
 
118
    @d.meta_def(:supports_foreign_key_parsing?){true}
116
119
    @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}]}
117
120
    s = @d.dump_table_schema(:t6)
118
121
    s.should =~ /create_table\(:t6\) do\n  foreign_key :c1, :t2, /
124
127
 
125
128
  it "should handle foreign key options in the primary key" do
126
129
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
 
130
    @d.meta_def(:supports_foreign_key_parsing?){true}
127
131
    @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}]}
128
132
    s = @d.dump_table_schema(:t6)
129
133
    s.should =~ /create_table\(:t6\) do\n  primary_key :c1, /
136
140
 
137
141
  it "should omit foreign key options that are the same as defaults" do
138
142
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
 
143
    @d.meta_def(:supports_foreign_key_parsing?){true}
139
144
    @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}]}
140
145
    s = @d.dump_table_schema(:t6)
141
146
    s.should =~ /create_table\(:t6\) do\n  foreign_key :c1, :t2, /
147
152
 
148
153
  it "should omit foreign key options that are the same as defaults in the primary key" do
149
154
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
 
155
    @d.meta_def(:supports_foreign_key_parsing?){true}
150
156
    @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}]}
151
157
    s = @d.dump_table_schema(:t6)
152
158
    s.should =~ /create_table\(:t6\) do\n  primary_key :c1, /
168
174
 
169
175
  it "should use a composite foreign_key calls if there is a composite foreign key" do
170
176
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer'}], [:c2, {:db_type=>'integer'}]]}
 
177
    @d.meta_def(:supports_foreign_key_parsing?){true}
171
178
    @d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1, :c2], :table=>:t2, :key=>[:c3, :c4]}]}
172
179
    @d.dump_table_schema(:t1).should == "create_table(:t1) do\n  Integer :c1\n  Integer :c2\n  \n  foreign_key [:c1, :c2], :t2, :key=>[:c3, :c4]\nend"
173
180
  end
174
181
 
175
182
  it "should include index information if available" do
 
183
    @d.meta_def(:supports_index_parsing?){true}
176
184
    @d.meta_def(:indexes) do |t|
177
185
      {:i1=>{:columns=>[:c1], :unique=>false},
178
186
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
226
234
    @d.meta_def(:schema) do |t|
227
235
      t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer', :primary_key=>true}]]
228
236
    end
 
237
    @d.meta_def(:supports_foreign_key_parsing?){true}
229
238
    @d.meta_def(:foreign_key_list) do |t|
230
239
      t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
231
240
    end
249
258
    @d.meta_def(:schema) do |t|
250
259
      t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer'}]]
251
260
    end
 
261
    @d.meta_def(:supports_foreign_key_parsing?){true}
252
262
    @d.meta_def(:foreign_key_list) do |t|
253
263
      t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : [{:columns=>[:c1], :table=>:t1, :key=>[:c2]}]
254
264
    end
276
286
    @d.meta_def(:schema) do |t|
277
287
      t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer', :primary_key=>true}]]
278
288
    end
 
289
    @d.meta_def(:supports_foreign_key_parsing?){true}
279
290
    @d.meta_def(:foreign_key_list) do |t|
280
291
      raise Sequel::DatabaseError unless [:t1, :t2].include?(t)
281
292
      t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
317
328
  end
318
329
 
319
330
  it "should honor the :index_names => false option to not include names of indexes" do
 
331
    @d.meta_def(:supports_index_parsing?){true}
320
332
    @d.meta_def(:indexes) do |t|
321
333
      {:i1=>{:columns=>[:c1], :unique=>false},
322
334
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
348
360
  end
349
361
  
350
362
  it "should make :index_names => :namespace option a noop if there is a  global index namespace" do
 
363
    @d.meta_def(:supports_index_parsing?){true}
351
364
    @d.meta_def(:indexes) do |t|
352
365
      {:i1=>{:columns=>[:c1], :unique=>false},
353
366
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
380
393
 
381
394
  it "should honor the :index_names => :namespace option to include names of indexes with prepended table name if there is no global index namespace" do
382
395
    @d.meta_def(:global_index_namespace?){false}
 
396
    @d.meta_def(:supports_index_parsing?){true}
383
397
    @d.meta_def(:indexes) do |t|
384
398
      {:i1=>{:columns=>[:c1], :unique=>false},
385
399
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
411
425
  end
412
426
 
413
427
  it "should honor the :indexes => false option to not include indexes" do
 
428
    @d.meta_def(:supports_index_parsing?){true}
414
429
    @d.meta_def(:indexes) do |t|
415
430
      {:i1=>{:columns=>[:c1], :unique=>false},
416
431
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
443
458
  end
444
459
 
445
460
  it "should have :foreign_keys option override :indexes => false disabling of foreign keys" do
 
461
    @d.meta_def(:supports_foreign_key_parsing?){true}
446
462
    @d.meta_def(:foreign_key_list) do |t|
447
463
      t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
448
464
    end
451
467
 
452
468
  it "should support dumping just indexes as a migration" do
453
469
    @d.meta_def(:tables){|o| [:t1]}
 
470
    @d.meta_def(:supports_index_parsing?){true}
454
471
    @d.meta_def(:indexes) do |t|
455
472
      {:i1=>{:columns=>[:c1], :unique=>false},
456
473
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
467
484
 
468
485
  it "should honor the :index_names => false option to not include names of indexes when dumping just indexes as a migration" do
469
486
    @d.meta_def(:tables){|o| [:t1]}
 
487
    @d.meta_def(:supports_index_parsing?){true}
470
488
    @d.meta_def(:indexes) do |t|
471
489
      {:i1=>{:columns=>[:c1], :unique=>false},
472
490
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
483
501
 
484
502
  it "should honor the :index_names => :namespace option be a noop if there is a global index namespace" do
485
503
    @d.meta_def(:tables){|o| [:t1, :t2]}
 
504
    @d.meta_def(:supports_index_parsing?){true}
486
505
    @d.meta_def(:indexes) do |t|
487
506
      {:i1=>{:columns=>[:c1], :unique=>false},
488
507
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
503
522
  it "should honor the :index_names => :namespace option to include names of indexes with prepended table name when dumping just indexes as a migration if there is no global index namespace" do
504
523
    @d.meta_def(:global_index_namespace?){false}
505
524
    @d.meta_def(:tables){|o| [:t1, :t2]}
 
525
    @d.meta_def(:supports_index_parsing?){true}
506
526
    @d.meta_def(:indexes) do |t|
507
527
      {:i1=>{:columns=>[:c1], :unique=>false},
508
528
       :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
547
567
    @d.meta_def(:schema) do |t|
548
568
      t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer'}]]
549
569
    end
 
570
    @d.meta_def(:supports_foreign_key_parsing?){true}
550
571
    @d.meta_def(:foreign_key_list) do |t, *a|
551
572
      case t
552
573
      when :t1
588
609
       [:c7, {:db_type=>'date', :default=>"'2008-10-29'", :type=>:date, :allow_null=>true}],
589
610
       [:c8, {:db_type=>'datetime', :default=>"'2008-10-29 10:20:30'", :type=>:datetime, :allow_null=>true}],
590
611
       [:c9, {:db_type=>'time', :default=>"'10:20:30'", :type=>:time, :allow_null=>true}],
591
 
       [:c10, {:db_type=>'interval', :default=>"'6 weeks'", :type=>:interval, :allow_null=>true}]]
 
612
       [:c10, {:db_type=>'foo', :default=>"'6 weeks'", :type=>nil, :allow_null=>true}],
 
613
       [:c11, {:db_type=>'date', :default=>"CURRENT_DATE", :type=>:date, :allow_null=>true}],
 
614
       [:c12, {:db_type=>'timestamp', :default=>"now()", :type=>:datetime, :allow_null=>true}]]
592
615
      s.each{|_, c| c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])}
593
616
      s
594
617
    end
595
 
    @d.dump_table_schema(:t4).gsub(/[+-]\d\d:\d\d"\)/, '")').should == "create_table(:t4) do\n  TrueClass :c1, :default=>false\n  String :c2, :default=>\"blah\"\n  Integer :c3, :default=>-1\n  Float :c4, :default=>1.0\n  BigDecimal :c5, :default=>BigDecimal.new(\"0.1005E3\")\n  File :c6, :default=>Sequel::SQL::Blob.new(\"blah\")\n  Date :c7, :default=>Date.parse(\"2008-10-29\")\n  DateTime :c8, :default=>DateTime.parse(\"2008-10-29T10:20:30\")\n  Time :c9, :default=>Sequel::SQLTime.parse(\"10:20:30\"), :only_time=>true\n  String :c10\nend"
596
 
    @d.dump_table_schema(:t4, :same_db=>true).gsub(/[+-]\d\d:\d\d"\)/, '")').should == "create_table(:t4) do\n  column :c1, \"boolean\", :default=>false\n  column :c2, \"varchar\", :default=>\"blah\"\n  column :c3, \"integer\", :default=>-1\n  column :c4, \"float\", :default=>1.0\n  column :c5, \"decimal\", :default=>BigDecimal.new(\"0.1005E3\")\n  column :c6, \"blob\", :default=>Sequel::SQL::Blob.new(\"blah\")\n  column :c7, \"date\", :default=>Date.parse(\"2008-10-29\")\n  column :c8, \"datetime\", :default=>DateTime.parse(\"2008-10-29T10:20:30\")\n  column :c9, \"time\", :default=>Sequel::SQLTime.parse(\"10:20:30\")\n  column :c10, \"interval\", :default=>\"'6 weeks'\".lit\nend"
 
618
    @d.dump_table_schema(:t4).gsub(/[+-]\d\d\d\d"\)/, '")').gsub(/\.0+/, '.0').should == "create_table(:t4) do\n  TrueClass :c1, :default=>false\n  String :c2, :default=>\"blah\"\n  Integer :c3, :default=>-1\n  Float :c4, :default=>1.0\n  BigDecimal :c5, :default=>BigDecimal.new(\"0.1005E3\")\n  File :c6, :default=>Sequel::SQL::Blob.new(\"blah\")\n  Date :c7, :default=>Date.new(2008, 10, 29)\n  DateTime :c8, :default=>DateTime.parse(\"2008-10-29T10:20:30.0\")\n  Time :c9, :default=>Sequel::SQLTime.parse(\"10:20:30.0\"), :only_time=>true\n  String :c10\n  Date :c11, :default=>Sequel::CURRENT_DATE\n  DateTime :c12, :default=>Sequel::CURRENT_TIMESTAMP\nend"
 
619
    @d.dump_table_schema(:t4, :same_db=>true).gsub(/[+-]\d\d\d\d"\)/, '")').gsub(/\.0+/, '.0').should == "create_table(:t4) do\n  column :c1, \"boolean\", :default=>false\n  column :c2, \"varchar\", :default=>\"blah\"\n  column :c3, \"integer\", :default=>-1\n  column :c4, \"float\", :default=>1.0\n  column :c5, \"decimal\", :default=>BigDecimal.new(\"0.1005E3\")\n  column :c6, \"blob\", :default=>Sequel::SQL::Blob.new(\"blah\")\n  column :c7, \"date\", :default=>Date.new(2008, 10, 29)\n  column :c8, \"datetime\", :default=>DateTime.parse(\"2008-10-29T10:20:30.0\")\n  column :c9, \"time\", :default=>Sequel::SQLTime.parse(\"10:20:30.0\")\n  column :c10, \"foo\", :default=>Sequel::LiteralString.new(\"'6 weeks'\")\n  column :c11, \"date\", :default=>Sequel::CURRENT_DATE\n  column :c12, \"timestamp\", :default=>Sequel::CURRENT_TIMESTAMP\nend"
597
620
  end
598
621
  
599
 
  it "should not use a '...'.lit as a fallback if using MySQL with the :same_db option" do
 
622
  it "should not use a literal string as a fallback if using MySQL with the :same_db option" do
600
623
    @d.meta_def(:database_type){:mysql}
 
624
    @d.meta_def(:supports_index_parsing?){false}
 
625
    @d.meta_def(:supports_foreign_key_parsing?){false}
601
626
    @d.meta_def(:schema) do |t, *os|
602
 
      s = [[:c10, {:db_type=>'interval', :default=>"'6 weeks'", :type=>:interval, :allow_null=>true}]]
 
627
      s = [[:c10, {:db_type=>'foo', :default=>"'6 weeks'", :type=>nil, :allow_null=>true}]]
603
628
      s.each{|_, c| c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])}
604
629
      s
605
630
    end
606
 
    @d.dump_table_schema(:t5, :same_db=>true).should == "create_table(:t5) do\n  column :c10, \"interval\"\nend"
 
631
    @d.dump_table_schema(:t5, :same_db=>true).should == "create_table(:t5) do\n  column :c10, \"foo\"\nend"
607
632
  end
608
633
 
609
634
  it "should convert unknown database types to strings" do
712
737
END_MIG
713
738
  end
714
739
 
 
740
  it "should convert mysql types to ruby types" do
 
741
    types = ['double(15,2)', 'double(7,1) unsigned']
 
742
    @d.meta_def(:schema) do |t, *o|
 
743
      i = 0
 
744
      types.map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
 
745
    end
 
746
    @d.dump_table_schema(:x).should == (<<END_MIG).chomp
 
747
create_table(:x) do
 
748
  Float :c1
 
749
  Float :c2
 
750
  
 
751
  check Sequel::SQL::BooleanExpression.new(:>=, Sequel::SQL::Identifier.new(:c2), 0)
 
752
end
 
753
END_MIG
 
754
  end
 
755
 
715
756
  it "should use separate primary_key call with non autoincrementable types" do
716
757
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'varchar(8)', :primary_key=>true}]]}
717
758
    @d.dump_table_schema(:t3).should == "create_table(:t3) do\n  String :c1, :size=>8\n  \n  primary_key [:c1]\nend"
720
761
 
721
762
  it "should use explicit type for non integer foreign_key types" do
722
763
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'date', :primary_key=>true}]]}
 
764
    @d.meta_def(:supports_foreign_key_parsing?){true}
723
765
    @d.meta_def(:foreign_key_list){|t, *a| [{:columns=>[:c1], :table=>:t3, :key=>[:c1]}] if t == :t4}
724
766
    ["create_table(:t4) do\n  foreign_key :c1, :t3, :type=>Date, :key=>[:c1]\n  \n  primary_key [:c1]\nend",
725
767
     "create_table(:t4) do\n  foreign_key :c1, :t3, :key=>[:c1], :type=>Date\n  \n  primary_key [:c1]\nend"].should include(@d.dump_table_schema(:t4))
729
771
 
730
772
  it "should correctly handing autoincrementing primary keys that are also foreign keys" do
731
773
    @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true}]]}
 
774
    @d.meta_def(:supports_foreign_key_parsing?){true}
732
775
    @d.meta_def(:foreign_key_list){|t, *a| [{:columns=>[:c1], :table=>:t3, :key=>[:c1]}] if t == :t4}
733
776
    ["create_table(:t4) do\n  primary_key :c1, :table=>:t3, :key=>[:c1]\nend",
734
777
     "create_table(:t4) do\n  primary_key :c1, :key=>[:c1], :table=>:t3\nend"].should include(@d.dump_table_schema(:t4))