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

« back to all changes in this revision

Viewing changes to spec/core/schema_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:
13
13
  specify "should accept the table name in multiple formats" do
14
14
    @db.create_table(:cats__cats) {}
15
15
    @db.create_table("cats__cats1") {}
16
 
    @db.create_table(:cats__cats2.identifier) {}
17
 
    @db.create_table(:cats.qualify(:cats3)) {}
 
16
    @db.create_table(Sequel.identifier(:cats__cats2)) {}
 
17
    @db.create_table(Sequel.qualify(:cats3, :cats)) {}
18
18
    @db.sqls.should == ['CREATE TABLE cats.cats ()', 'CREATE TABLE cats__cats1 ()', 'CREATE TABLE cats__cats2 ()', 'CREATE TABLE cats3.cats ()']
19
19
  end
20
20
 
21
21
  specify "should raise an error if the table name argument is not valid" do
22
22
    proc{@db.create_table(1) {}}.should raise_error(Sequel::Error)
23
 
    proc{@db.create_table(:cats.as(:c)) {}}.should raise_error(Sequel::Error)
 
23
    proc{@db.create_table(Sequel.as(:cats, :c)) {}}.should raise_error(Sequel::Error)
24
24
  end
25
25
 
26
26
  specify "should remove cached schema entry" do
67
67
    @db.sqls.should == ['CREATE TABLE cats (o varchar(255) PRIMARY KEY AUTOINCREMENT, a varchar(255), b integer, c integer, d bigint, e double precision, f numeric, g date, h timestamp, i timestamp, j numeric, k blob, l boolean, m boolean, n integer, p date REFERENCES f)']
68
68
  end
69
69
 
 
70
  specify "should transform types given as ruby classes to database-specific types" do
 
71
    @db.default_string_column_size = 50
 
72
    @db.create_table(:cats) do
 
73
      String :a
 
74
      String :a2, :size=>13
 
75
      String :a3, :fixed=>true
 
76
      String :a4, :size=>13, :fixed=>true
 
77
      String :a5, :text=>true
 
78
      varchar :a6
 
79
      varchar :a7, :size=>13
 
80
    end
 
81
    @db.sqls.should == ['CREATE TABLE cats (a varchar(50), a2 varchar(13), a3 char(50), a4 char(13), a5 text, a6 varchar(50), a7 varchar(13))']
 
82
  end
 
83
 
70
84
  specify "should allow the use of modifiers with ruby class types" do
71
85
    @db.create_table(:cats) do
72
86
      String :a, :size=>50
99
113
    @db.sqls.should == ['CREATE TABLE cats (id serial PRIMARY KEY)']
100
114
  end
101
115
 
 
116
  specify "should allow naming primary key constraint with :primary_key_constraint_name option" do
 
117
    @db.create_table(:cats) do
 
118
      primary_key :id, :primary_key_constraint_name=>:foo
 
119
    end
 
120
    @db.sqls.should == ['CREATE TABLE cats (id integer CONSTRAINT foo PRIMARY KEY AUTOINCREMENT)']
 
121
  end
 
122
 
 
123
  specify "should handling splitting named column constraints into table constraints if unsupported" do
 
124
    def @db.supports_named_column_constraints?; false end
 
125
    @db.create_table(:cats) do
 
126
      primary_key :id, :primary_key_constraint_name=>:foo
 
127
      foreign_key :cat_id, :cats, :unique=>true, :unique_constraint_name=>:bar, :foreign_key_constraint_name=>:baz, :deferrable=>true, :key=>:foo_id, :on_delete=>:cascade, :on_update=>:restrict
 
128
    end
 
129
    @db.sqls.should == ['CREATE TABLE cats (id integer AUTOINCREMENT, cat_id integer, CONSTRAINT foo PRIMARY KEY (id), CONSTRAINT baz FOREIGN KEY (cat_id) REFERENCES cats(foo_id) ON DELETE CASCADE ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED, CONSTRAINT bar UNIQUE (cat_id))']
 
130
  end
 
131
 
102
132
  specify "should accept and literalize default values" do
103
133
    @db.create_table(:cats) do
104
134
      integer :id, :default => 123
133
163
    @db.sqls.should == ["CREATE TABLE cats (id integer, name text UNIQUE)"]
134
164
  end
135
165
  
 
166
  specify "should allow naming unique constraint with :unique_constraint_name option" do
 
167
    @db.create_table(:cats) do
 
168
      text :name, :unique => true, :unique_constraint_name=>:foo
 
169
    end
 
170
    @db.sqls.should == ["CREATE TABLE cats (name text CONSTRAINT foo UNIQUE)"]
 
171
  end
 
172
  
 
173
  specify "should handle not deferred unique constraints" do
 
174
    @db.create_table(:cats) do
 
175
      integer :id
 
176
      text :name
 
177
      unique :name, :deferrable=>false
 
178
    end
 
179
    @db.sqls.should == ["CREATE TABLE cats (id integer, name text, UNIQUE (name) NOT DEFERRABLE)"]
 
180
  end
 
181
  
 
182
  specify "should handle deferred unique constraints" do
 
183
    @db.create_table(:cats) do
 
184
      integer :id
 
185
      text :name
 
186
      unique :name, :deferrable=>true
 
187
    end
 
188
    @db.sqls.should == ["CREATE TABLE cats (id integer, name text, UNIQUE (name) DEFERRABLE INITIALLY DEFERRED)"]
 
189
  end
 
190
  
 
191
  specify "should handle deferred initially immediate unique constraints" do
 
192
    @db.create_table(:cats) do
 
193
      integer :id
 
194
      text :name
 
195
      unique :name, :deferrable=>:immediate
 
196
    end
 
197
    @db.sqls.should == ["CREATE TABLE cats (id integer, name text, UNIQUE (name) DEFERRABLE INITIALLY IMMEDIATE)"]
 
198
  end
 
199
  
136
200
  specify "should accept unsigned definition" do
137
201
    @db.create_table(:cats) do
138
202
      integer :value, :unsigned => true
186
250
    @db.sqls.should == ["CREATE TABLE cats (project_id integer DEFAULT 3 REFERENCES projects)"]
187
251
  end
188
252
  
 
253
  specify "should allowing naming foreign key constraint with :foreign_key_constraint_name option" do
 
254
    @db.create_table(:cats) do
 
255
      foreign_key :project_id, :projects, :foreign_key_constraint_name=>:foo
 
256
    end
 
257
    @db.sqls.should == ["CREATE TABLE cats (project_id integer CONSTRAINT foo REFERENCES projects)"]
 
258
  end
 
259
  
189
260
  specify "should raise an error if the table argument to foreign_key isn't a hash, symbol, or nil" do
190
261
    proc{@db.create_table(:cats){foreign_key :project_id, Object.new, :default=>3}}.should raise_error(Sequel::Error)
191
262
  end
318
389
    @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)"]
319
390
  end
320
391
 
321
 
  specify "should accept unique index definitions" do
 
392
  specify "should accept unique constraint definitions" do
322
393
    @db.create_table(:cats) do
323
394
      text :name
324
395
      unique :name
372
443
  end
373
444
 
374
445
  specify "should ignore errors if the database raises an error on an index creation statement and the :ignore_index_errors option is used" do
375
 
    @db.meta_def(:execute_ddl){|*a| raise Sequel::DatabaseError if /blah/.match(a.first); super(*a)}
 
446
    meta_def(@db, :execute_ddl){|*a| raise Sequel::DatabaseError if /blah/.match(a.first); super(*a)}
376
447
    lambda{@db.create_table(:cats){Integer :id; index :blah; index :id}}.should raise_error(Sequel::DatabaseError)
377
448
    @db.sqls.should == ['CREATE TABLE cats (id integer)']
378
 
    lambda{@db.create_table(:cats, :ignore_index_errors=>true){Integer :id; index :blah; index :id}}.should_not raise_error(Sequel::DatabaseError)
 
449
    lambda{@db.create_table(:cats, :ignore_index_errors=>true){Integer :id; index :blah; index :id}}.should_not raise_error
379
450
    @db.sqls.should == ['CREATE TABLE cats (id integer)', 'CREATE INDEX cats_id_index ON cats (id)']
380
451
  end
381
452
 
391
462
  specify "should accept functional indexes" do
392
463
    @db.create_table(:cats) do
393
464
      integer :id
394
 
      index :lower.sql_function(:name)
 
465
      index Sequel.function(:lower, :name)
395
466
    end
396
467
    @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_lower_name__index ON cats (lower(name))"]
397
468
  end
399
470
  specify "should accept indexes with identifiers" do
400
471
    @db.create_table(:cats) do
401
472
      integer :id
402
 
      index :lower__name.identifier
 
473
      index Sequel.identifier(:lower__name)
403
474
    end
404
475
    @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_lower__name_index ON cats (lower__name)"]
405
476
  end
431
502
  specify "should accept unnamed constraint definitions with blocks" do
432
503
    @db.create_table(:cats) do
433
504
      integer :score
434
 
      check {(:x.sql_number > 0) & (:y.sql_number < 1)}
 
505
      check{(x > 0) & (y < 1)}
435
506
    end
436
507
    @db.sqls.should == ["CREATE TABLE cats (score integer, CHECK ((x > 0) AND (y < 1)))"]
437
508
  end
438
509
 
 
510
  specify "should accept unnamed constraint definitions with function calls" do
 
511
    @db.create_table(:cats) do
 
512
      integer :score
 
513
      check{f(x)}
 
514
    end
 
515
    @db.sqls.should == ["CREATE TABLE cats (score integer, CHECK (f(x)))"]
 
516
  end
 
517
 
439
518
  specify "should accept unnamed constraint definitions" do
440
519
    @db.create_table(:cats) do
441
520
      check 'price < ?', 100
443
522
    @db.sqls.should == ["CREATE TABLE cats (CHECK (price < 100))"]
444
523
  end
445
524
 
 
525
  specify "should accept arrays of pairs constraints" do
 
526
    @db.create_table(:cats) do
 
527
      check [[:price, 100]]
 
528
    end
 
529
    @db.sqls.should == ["CREATE TABLE cats (CHECK (price = 100))"]
 
530
  end
 
531
 
446
532
  specify "should accept hash constraints" do
447
533
    @db.create_table(:cats) do
448
534
      check :price=>100
450
536
    @db.sqls.should == ["CREATE TABLE cats (CHECK (price = 100))"]
451
537
  end
452
538
 
 
539
  specify "should accept array constraints" do
 
540
    @db.create_table(:cats) do
 
541
      check [Sequel.expr(:x) > 0, Sequel.expr(:y) < 1]
 
542
    end
 
543
    @db.sqls.should == ["CREATE TABLE cats (CHECK ((x > 0) AND (y < 1)))"]
 
544
  end
 
545
 
453
546
  specify "should accept named constraint definitions" do
454
547
    @db.create_table(:cats) do
455
548
      integer :score
458
551
    @db.sqls.should == ["CREATE TABLE cats (score integer, CONSTRAINT valid_score CHECK (score <= 100))"]
459
552
  end
460
553
 
 
554
  specify "should accept named constraint definitions with options" do
 
555
    @db.create_table(:cats) do
 
556
      integer :score
 
557
      constraint({:name=>:valid_score, :deferrable=>true}, 'score <= 100')
 
558
    end
 
559
    @db.sqls.should == ["CREATE TABLE cats (score integer, CONSTRAINT valid_score CHECK (score <= 100) DEFERRABLE INITIALLY DEFERRED)"]
 
560
  end
 
561
 
461
562
  specify "should accept named constraint definitions with block" do
462
563
    @db.create_table(:cats) do
463
 
      constraint(:blah_blah) {(:x.sql_number > 0) & (:y.sql_number < 1)}
 
564
      constraint(:blah_blah){(x.sql_number > 0) & (y.sql_number < 1)}
464
565
    end
465
566
    @db.sqls.should == ["CREATE TABLE cats (CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1)))"]
466
567
  end
572
673
  end
573
674
  
574
675
  specify "should create the table if it does not exist" do
575
 
    @db.meta_def(:table_exists?){|a| false}
 
676
    meta_def(@db, :table_exists?){|a| false}
576
677
    @db.create_table!(:cats){|*a|}
577
678
    @db.sqls.should == ['CREATE TABLE cats ()']
578
679
  end
579
680
  
580
681
  specify "should drop the table before creating it if it already exists" do
581
 
    @db.meta_def(:table_exists?){|a| true}
 
682
    meta_def(@db, :table_exists?){|a| true}
582
683
    @db.create_table!(:cats){|*a|}
583
684
    @db.sqls.should == ['DROP TABLE cats', 'CREATE TABLE cats ()']
584
685
  end
590
691
  end
591
692
  
592
693
  specify "should not create the table if the table already exists" do
593
 
    @db.meta_def(:table_exists?){|a| true}
 
694
    meta_def(@db, :table_exists?){|a| true}
594
695
    @db.create_table?(:cats){|*a|}
595
696
    @db.sqls.should == []
596
697
  end
597
698
  
598
699
  specify "should create the table if the table doesn't already exist" do
599
 
    @db.meta_def(:table_exists?){|a| false}
 
700
    meta_def(@db, :table_exists?){|a| false}
600
701
    @db.create_table?(:cats){|*a|}
601
702
    @db.sqls.should == ['CREATE TABLE cats ()']
602
703
  end
603
704
  
604
705
  specify "should use IF NOT EXISTS if the database supports that" do
605
 
    @db.meta_def(:supports_create_table_if_not_exists?){true}
 
706
    meta_def(@db, :supports_create_table_if_not_exists?){true}
606
707
    @db.create_table?(:cats){|*a|}
607
708
    @db.sqls.should == ['CREATE TABLE IF NOT EXISTS cats ()']
608
709
  end
716
817
  end
717
818
  
718
819
  specify "should drop the table if it exists" do
719
 
    @db.meta_def(:table_exists?){|a| true}
 
820
    meta_def(@db, :table_exists?){|a| true}
720
821
    @db.drop_table?(:cats)
721
822
    @db.sqls.should == ["DROP TABLE cats"]
722
823
  end
723
824
  
724
825
  specify "should do nothing if the table does not exist" do
725
 
    @db.meta_def(:table_exists?){|a| false}
 
826
    meta_def(@db, :table_exists?){|a| false}
726
827
    @db.drop_table?(:cats)
727
828
    @db.sqls.should == []
728
829
  end
729
830
  
730
831
  specify "should operate on multiple tables at once" do
731
 
    @db.meta_def(:table_exists?){|a| a == :cats}
 
832
    meta_def(@db, :table_exists?){|a| a == :cats}
732
833
    @db.drop_table? :cats, :dogs
733
834
    @db.sqls.should == ['DROP TABLE cats']
734
835
  end
735
836
 
736
837
  specify "should take an options hash and support the :cascade option" do
737
 
    @db.meta_def(:table_exists?){|a| true}
 
838
    meta_def(@db, :table_exists?){|a| true}
738
839
    @db.drop_table? :cats, :dogs, :cascade=>true
739
840
    @db.sqls.should == ['DROP TABLE cats CASCADE', 'DROP TABLE dogs CASCADE']
740
841
  end
741
842
 
742
843
  specify "should use IF NOT EXISTS if the database supports that" do
743
 
    @db.meta_def(:supports_drop_table_if_exists?){true}
 
844
    meta_def(@db, :supports_drop_table_if_exists?){true}
744
845
    @db.drop_table? :cats, :dogs
745
846
    @db.sqls.should == ['DROP TABLE IF EXISTS cats', 'DROP TABLE IF EXISTS dogs']
746
847
  end
747
848
 
748
849
  specify "should use IF NOT EXISTS with CASCADE if the database supports that" do
749
 
    @db.meta_def(:supports_drop_table_if_exists?){true}
 
850
    meta_def(@db, :supports_drop_table_if_exists?){true}
750
851
    @db.drop_table? :cats, :dogs, :cascade=>true
751
852
    @db.sqls.should == ['DROP TABLE IF EXISTS cats CASCADE', 'DROP TABLE IF EXISTS dogs CASCADE']
752
853
  end
757
858
    @db = Sequel.mock
758
859
  end
759
860
  
760
 
  specify "should allow adding not null constraint" do
 
861
  specify "should allow adding not null constraint via set_column_allow_null with false argument" do
761
862
    @db.alter_table(:cats) do
762
863
      set_column_allow_null :score, false
763
864
    end
764
865
    @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score SET NOT NULL"]
765
866
  end
766
867
  
767
 
  specify "should allow droping not null constraint" do
 
868
  specify "should allow removing not null constraint via set_column_allow_null with true argument" do
768
869
    @db.alter_table(:cats) do
769
870
      set_column_allow_null :score, true
770
871
    end
771
872
    @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score DROP NOT NULL"]
772
873
  end
773
874
 
 
875
  specify "should allow adding not null constraint via set_column_not_null" do
 
876
    @db.alter_table(:cats) do
 
877
      set_column_not_null :score
 
878
    end
 
879
    @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score SET NOT NULL"]
 
880
  end
 
881
  
 
882
  specify "should allow removing not null constraint via set_column_allow_null without argument" do
 
883
    @db.alter_table(:cats) do
 
884
      set_column_allow_null :score
 
885
    end
 
886
    @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score DROP NOT NULL"]
 
887
  end
 
888
 
774
889
  specify "should support add_column" do
775
890
    @db.alter_table(:cats) do
776
891
      add_column :score, :integer
785
900
    @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT valid_score CHECK (score <= 100)"]
786
901
  end
787
902
 
 
903
  specify "should support add_constraint with options" do
 
904
    @db.alter_table(:cats) do
 
905
      add_constraint({:name=>:valid_score, :deferrable=>true}, 'score <= 100')
 
906
    end
 
907
    @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT valid_score CHECK (score <= 100) DEFERRABLE INITIALLY DEFERRED"]
 
908
  end
 
909
 
788
910
  specify "should support add_constraint with block" do
789
911
    @db.alter_table(:cats) do
790
 
      add_constraint(:blah_blah) {(:x.sql_number > 0) & (:y.sql_number < 1)}
 
912
      add_constraint(:blah_blah){(x.sql_number > 0) & (y.sql_number < 1)}
791
913
    end
792
914
    @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1))"]
793
915
  end
841
963
  end
842
964
 
843
965
  specify "should ignore errors if the database raises an error on an add_index call and the :ignore_errors option is used" do
844
 
    @db.meta_def(:execute_ddl){|*a| raise Sequel::DatabaseError}
 
966
    meta_def(@db, :execute_ddl){|*a| raise Sequel::DatabaseError}
845
967
    lambda{@db.add_index(:cats, :id)}.should raise_error(Sequel::DatabaseError)
846
 
    lambda{@db.add_index(:cats, :id, :ignore_errors=>true)}.should_not raise_error(Sequel::DatabaseError)
 
968
    lambda{@db.add_index(:cats, :id, :ignore_errors=>true)}.should_not raise_error
847
969
    @db.sqls.should == []
848
970
  end
849
971
 
894
1016
    @db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score CASCADE"]
895
1017
  end
896
1018
 
 
1019
  specify "should support drop_foreign_key" do
 
1020
    def @db.foreign_key_list(table_name)
 
1021
      [{:name=>:cats_node_id_fkey, :columns=>[:node_id]}] 
 
1022
    end
 
1023
    @db.alter_table(:cats) do
 
1024
      drop_foreign_key :node_id
 
1025
    end
 
1026
    @db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT cats_node_id_fkey", "ALTER TABLE cats DROP COLUMN node_id"]
 
1027
  end
 
1028
 
 
1029
  specify "should support drop_foreign_key with composite foreign keys" do
 
1030
    def @db.foreign_key_list(table_name)
 
1031
      [{:name=>:cats_node_id_prop_id_fkey, :columns=>[:node_id, :prop_id]}] 
 
1032
    end
 
1033
    @db.alter_table(:cats) do
 
1034
      drop_foreign_key [:node_id, :prop_id]
 
1035
    end
 
1036
    @db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT cats_node_id_prop_id_fkey"]
 
1037
 
 
1038
    @db.alter_table(:cats) do
 
1039
      drop_foreign_key [:node_id, :prop_id], :name => :cfk
 
1040
    end
 
1041
    @db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT cfk"]
 
1042
  end
 
1043
 
 
1044
  specify "should have drop_foreign_key raise Error if no name is found" do
 
1045
    def @db.foreign_key_list(table_name)
 
1046
      [{:name=>:cats_node_id_fkey, :columns=>[:foo_id]}] 
 
1047
    end
 
1048
    lambda{@db.alter_table(:cats){drop_foreign_key :node_id}}.should raise_error(Sequel::Error)
 
1049
  end
 
1050
 
 
1051
  specify "should have drop_foreign_key raise Error if multiple foreign keys found" do
 
1052
    def @db.foreign_key_list(table_name)
 
1053
      [{:name=>:cats_node_id_fkey, :columns=>[:node_id]}, {:name=>:cats_node_id_fkey2, :columns=>[:node_id]}] 
 
1054
    end
 
1055
    lambda{@db.alter_table(:cats){drop_foreign_key :node_id}}.should raise_error(Sequel::Error)
 
1056
  end
 
1057
 
897
1058
  specify "should support drop_index" do
898
1059
    @db.alter_table(:cats) do
899
1060
      drop_index :name
939
1100
      "ALTER TABLE cats ALTER COLUMN score TYPE varchar(30)",
940
1101
      "ALTER TABLE cats ALTER COLUMN score TYPE enum('a', 'b')"]
941
1102
  end
 
1103
 
 
1104
  specify "should combine operations into a single query if the database supports it" do
 
1105
    meta_def(@db, :supports_combining_alter_table_ops?){true}
 
1106
    @db.alter_table(:cats) do
 
1107
      add_column :a, Integer
 
1108
      drop_column :b
 
1109
      set_column_not_null :c
 
1110
      rename_column :d, :e
 
1111
      set_column_default :f, 'g'
 
1112
      set_column_type :h, Integer
 
1113
      add_constraint(:i){a > 1}
 
1114
      drop_constraint :j
 
1115
    end
 
1116
    @db.sqls.should == ["ALTER TABLE cats ADD COLUMN a integer, DROP COLUMN b, ALTER COLUMN c SET NOT NULL, RENAME COLUMN d TO e, ALTER COLUMN f SET DEFAULT 'g', ALTER COLUMN h TYPE integer, ADD CONSTRAINT i CHECK (a > 1), DROP CONSTRAINT j"]
 
1117
  end
 
1118
  
 
1119
  specify "should combine operations into consecutive groups of combinable operations if the database supports combining operations" do
 
1120
    meta_def(@db, :supports_combining_alter_table_ops?){true}
 
1121
    @db.alter_table(:cats) do
 
1122
      add_column :a, Integer
 
1123
      drop_column :b
 
1124
      set_column_not_null :c
 
1125
      rename_column :d, :e
 
1126
      add_index :e
 
1127
      set_column_default :f, 'g'
 
1128
      set_column_type :h, Integer
 
1129
      add_constraint(:i){a > 1}
 
1130
      drop_constraint :j
 
1131
    end
 
1132
    @db.sqls.should == ["ALTER TABLE cats ADD COLUMN a integer, DROP COLUMN b, ALTER COLUMN c SET NOT NULL, RENAME COLUMN d TO e",
 
1133
      "CREATE INDEX cats_e_index ON cats (e)",
 
1134
      "ALTER TABLE cats ALTER COLUMN f SET DEFAULT 'g', ALTER COLUMN h TYPE integer, ADD CONSTRAINT i CHECK (a > 1), DROP CONSTRAINT j"]
 
1135
  end
 
1136
  
942
1137
end
943
1138
 
944
1139
describe "Database#create_table" do
966
1161
    @db.sqls.should == ['CREATE TEMPORARY TABLE test_tmp (id integer NOT NULL PRIMARY KEY AUTOINCREMENT, name text)',
967
1162
      'CREATE UNIQUE INDEX test_tmp_name_index ON test_tmp (name)']
968
1163
  end
969
 
 
970
 
  specify "should not use default schema when creating a temporary table" do
971
 
    @db.default_schema = :foo
972
 
    @db.create_table :test_tmp, :temp => true do
973
 
      column :name, :text
974
 
    end
975
 
    @db.sqls.should == ['CREATE TEMPORARY TABLE test_tmp (name text)']
976
 
  end
977
1164
end
978
1165
 
979
1166
describe "Database#alter_table" do
1122
1309
  specify "should construct proper SQL with raw SQL" do
1123
1310
    @db.create_view :test, "SELECT * FROM xyz"
1124
1311
    @db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
1125
 
    @db.create_view :test.identifier, "SELECT * FROM xyz"
 
1312
    @db.create_view Sequel.identifier(:test), "SELECT * FROM xyz"
1126
1313
    @db.sqls.should == ['CREATE VIEW test AS SELECT * FROM xyz']
1127
1314
  end
1128
1315
  
1129
1316
  specify "should construct proper SQL with dataset" do
1130
1317
    @db.create_view :test, @db[:items].select(:a, :b).order(:c)
1131
1318
    @db.sqls.should == ['CREATE VIEW test AS SELECT a, b FROM items ORDER BY c']
 
1319
  end
 
1320
 
 
1321
  specify "should handle :columns option" do
 
1322
    @db.create_view :test, @db[:items].select(:a, :b).order(:c), :columns=>[:d, :e]
 
1323
    @db.sqls.should == ['CREATE VIEW test (d, e) AS SELECT a, b FROM items ORDER BY c']
 
1324
    @db.create_view :test, @db[:items].select(:a, :b).order(:c), :columns=>%w'd e'
 
1325
    @db.sqls.should == ['CREATE VIEW test (d, e) AS SELECT a, b FROM items ORDER BY c']
 
1326
    @db.create_view :test, @db[:items].select(:a, :b).order(:c), :columns=>[Sequel.identifier('d'), Sequel.lit('e')]
 
1327
    @db.sqls.should == ['CREATE VIEW test (d, e) AS SELECT a, b FROM items ORDER BY c']
 
1328
  end
 
1329
 
 
1330
  specify "should handle create_or_replace_view" do
1132
1331
    @db.create_or_replace_view :sch__test, "SELECT * FROM xyz"
1133
 
    @db.sqls.should == ['CREATE OR REPLACE VIEW sch.test AS SELECT * FROM xyz']
1134
 
  end
1135
 
 
1136
 
  specify "should construct proper SQL with dataset" do
 
1332
    @db.sqls.should == ['DROP VIEW sch.test', 'CREATE VIEW sch.test AS SELECT * FROM xyz']
1137
1333
    @db.create_or_replace_view :test, @db[:items].select(:a, :b).order(:c)
1138
 
    @db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
1139
 
    @db.create_or_replace_view :test.identifier, @db[:items].select(:a, :b).order(:c)
1140
 
    @db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT a, b FROM items ORDER BY c']
 
1334
    @db.sqls.should == ['DROP VIEW test', 'CREATE VIEW test AS SELECT a, b FROM items ORDER BY c']
 
1335
    @db.create_or_replace_view Sequel.identifier(:test), @db[:items].select(:a, :b).order(:c)
 
1336
    @db.sqls.should == ['DROP VIEW test', 'CREATE VIEW test AS SELECT a, b FROM items ORDER BY c']
 
1337
  end
 
1338
 
 
1339
  specify "should use CREATE OR REPLACE VIEW if such syntax is supported" do
 
1340
    def @db.supports_create_or_replace_view?() true end
 
1341
    @db.create_or_replace_view :test, @db[:items]
 
1342
    @db.sqls.should == ['CREATE OR REPLACE VIEW test AS SELECT * FROM items']
1141
1343
  end
1142
1344
end
1143
1345
 
1148
1350
  
1149
1351
  specify "should construct proper SQL" do
1150
1352
    @db.drop_view :test
1151
 
    @db.drop_view :test.identifier
 
1353
    @db.drop_view Sequel.identifier(:test)
1152
1354
    @db.drop_view :sch__test
1153
 
    @db.drop_view :test.qualify(:sch)
 
1355
    @db.drop_view Sequel.qualify(:sch, :test)
1154
1356
    @db.sqls.should == ['DROP VIEW test', 'DROP VIEW test', 'DROP VIEW sch.test', 'DROP VIEW sch.test']
1155
1357
  end
1156
1358
 
1178
1380
  end
1179
1381
 
1180
1382
  specify "should raise an error if there are no columns" do
1181
 
    @db.meta_def(:schema_parse_table) do |t, opts|
 
1383
    meta_def(@db, :schema_parse_table) do |t, opts|
1182
1384
      []
1183
1385
    end
1184
1386
    proc{@db.schema(:x)}.should raise_error(Sequel::Error)
1185
1387
  end
1186
1388
 
1187
1389
  specify "should cache data by default" do
1188
 
    @db.meta_def(:schema_parse_table) do |t, opts|
 
1390
    meta_def(@db, :schema_parse_table) do |t, opts|
1189
1391
      [[:a, {}]]
1190
1392
    end
1191
1393
    @db.schema(:x).should equal(@db.schema(:x))
1192
1394
  end
1193
1395
 
1194
1396
  specify "should not cache data if :reload=>true is given" do
1195
 
    @db.meta_def(:schema_parse_table) do |t, opts|
 
1397
    meta_def(@db, :schema_parse_table) do |t, opts|
1196
1398
      [[:a, {}]]
1197
1399
    end
1198
1400
    @db.schema(:x).should_not equal(@db.schema(:x, :reload=>true))
1200
1402
 
1201
1403
  specify "should not cache schema metadata if cache_schema is false" do
1202
1404
    @db.cache_schema = false
1203
 
    @db.meta_def(:schema_parse_table) do |t, opts|
 
1405
    meta_def(@db, :schema_parse_table) do |t, opts|
1204
1406
      [[:a, {}]]
1205
1407
    end
1206
1408
    @db.schema(:x).should_not equal(@db.schema(:x))
1208
1410
 
1209
1411
  specify "should provide options if given a table name" do
1210
1412
    c = nil
1211
 
    @db.meta_def(:schema_parse_table) do |t, opts|
 
1413
    meta_def(@db, :schema_parse_table) do |t, opts|
1212
1414
      c = [t, opts]
1213
1415
      [[:a, {:db_type=>t.to_s}]]
1214
1416
    end
1224
1426
  specify "should parse the schema correctly for a single table" do
1225
1427
    sqls = @sqls
1226
1428
    proc{@db.schema(:x)}.should raise_error(Sequel::Error)
1227
 
    @db.meta_def(:schema_parse_table) do |t, opts|
 
1429
    meta_def(@db, :schema_parse_table) do |t, opts|
1228
1430
      sqls << t
1229
1431
      [[:a, {:db_type=>t.to_s}]]
1230
1432
    end
1237
1439
  end
1238
1440
 
1239
1441
  specify "should convert various types of table name arguments" do
1240
 
    @db.meta_def(:schema_parse_table) do |t, opts|
1241
 
      [[t, {:db_type=>t}]]
 
1442
    meta_def(@db, :schema_parse_table) do |t, opts|
 
1443
      [[t, opts]]
1242
1444
    end
1243
1445
    s1 = @db.schema(:x)
1244
 
    s1.should == [['x', {:db_type=>'x', :ruby_default=>nil}]]
 
1446
    s1.should == [['x', {:ruby_default=>nil}]]
1245
1447
    @db.schema(:x).object_id.should == s1.object_id
1246
 
    @db.schema(:x.identifier).object_id.should == s1.object_id
 
1448
    @db.schema(Sequel.identifier(:x)).object_id.should == s1.object_id
 
1449
 
1247
1450
    s2 = @db.schema(:x__y)
1248
 
    s2.should == [['y', {:db_type=>'y', :ruby_default=>nil}]]
 
1451
    s2.should == [['y', {:schema=>'x', :ruby_default=>nil}]]
1249
1452
    @db.schema(:x__y).object_id.should == s2.object_id
1250
 
    @db.schema(:y.qualify(:x)).object_id.should == s2.object_id
 
1453
    @db.schema(Sequel.qualify(:x, :y)).object_id.should == s2.object_id
 
1454
 
 
1455
    s2 = @db.schema(Sequel.qualify(:v, :x__y))
 
1456
    s2.should == [['y', {:schema=>'x', :ruby_default=>nil, :information_schema_schema=>Sequel.identifier('v')}]]
 
1457
    @db.schema(Sequel.qualify(:v, :x__y)).object_id.should == s2.object_id
 
1458
    @db.schema(Sequel.qualify(:v__x, :y)).object_id.should == s2.object_id
 
1459
 
 
1460
    s2 = @db.schema(Sequel.qualify(:u__v, :x__y))
 
1461
    s2.should == [['y', {:schema=>'x', :ruby_default=>nil, :information_schema_schema=>Sequel.qualify('u', 'v')}]]
 
1462
    @db.schema(Sequel.qualify(:u__v, :x__y)).object_id.should == s2.object_id
 
1463
    @db.schema(Sequel.qualify(Sequel.qualify(:u, :v), Sequel.qualify(:x, :y))).object_id.should == s2.object_id
1251
1464
  end
1252
1465
 
1253
1466
  specify "should correctly parse all supported data types" do
1254
 
    @db.meta_def(:schema_parse_table) do |t, opts|
1255
 
      [[:x, {:type=>schema_column_type(t.to_s)}]]
 
1467
    sm = Module.new do
 
1468
      def schema_parse_table(t, opts)
 
1469
        [[:x, {:type=>schema_column_type(t.to_s)}]]
 
1470
      end
1256
1471
    end
 
1472
    @db.extend(sm)
1257
1473
    @db.schema(:tinyint).first.last[:type].should == :integer
1258
 
    @db.schema(:interval).first.last[:type].should == :interval
1259
1474
    @db.schema(:int).first.last[:type].should == :integer
1260
1475
    @db.schema(:integer).first.last[:type].should == :integer
1261
1476
    @db.schema(:bigint).first.last[:type].should == :integer
1277
1492
    @db.schema(:real).first.last[:type].should == :float
1278
1493
    @db.schema(:float).first.last[:type].should == :float
1279
1494
    @db.schema(:double).first.last[:type].should == :float
 
1495
    @db.schema(:"double(1,2)").first.last[:type].should == :float
1280
1496
    @db.schema(:"double precision").first.last[:type].should == :float
1281
1497
    @db.schema(:number).first.last[:type].should == :decimal
1282
1498
    @db.schema(:numeric).first.last[:type].should == :decimal
1284
1500
    @db.schema(:"number(10,0)").first.last[:type].should == :integer
1285
1501
    @db.schema(:"numeric(10, 10)").first.last[:type].should == :decimal
1286
1502
    @db.schema(:"decimal(10,1)").first.last[:type].should == :decimal
1287
 
    @db.schema(:money).first.last[:type].should == :decimal
1288
1503
    @db.schema(:bytea).first.last[:type].should == :blob
1289
1504
    @db.schema(:blob).first.last[:type].should == :blob
1290
1505
    @db.schema(:image).first.last[:type].should == :blob
1292
1507
    @db.schema(:nvarchar).first.last[:type].should == :string
1293
1508
    @db.schema(:ntext).first.last[:type].should == :string
1294
1509
    @db.schema(:smalldatetime).first.last[:type].should == :datetime
1295
 
    @db.schema(:smallmoney).first.last[:type].should == :decimal
1296
1510
    @db.schema(:binary).first.last[:type].should == :blob
1297
1511
    @db.schema(:varbinary).first.last[:type].should == :blob
1298
1512
    @db.schema(:enum).first.last[:type].should == :enum
 
1513
 
 
1514
    @db = Sequel.mock(:host=>'postgres')
 
1515
    @db.extend(sm)
 
1516
    @db.schema(:interval).first.last[:type].should == :interval
 
1517
 
 
1518
    @db = Sequel.mock(:host=>'mysql')
 
1519
    @db.extend(sm)
 
1520
    @db.schema(:set).first.last[:type].should == :set
 
1521
    @db.schema(:mediumint).first.last[:type].should == :integer
 
1522
    @db.schema(:mediumtext).first.last[:type].should == :string
1299
1523
  end
1300
1524
end