@@ -565,3 +565,223 @@ func TestSetColumnUnique(t *testing.T) {
565
565
},
566
566
})
567
567
}
568
+
569
+ func TestSetUniqueInMultiOperationMigrations (t * testing.T ) {
570
+ t .Parallel ()
571
+
572
+ ExecuteTests (t , TestCases {
573
+ {
574
+ name : "rename table, set unique" ,
575
+ migrations : []migrations.Migration {
576
+ {
577
+ Name : "01_create_table" ,
578
+ Operations : migrations.Operations {
579
+ & migrations.OpCreateTable {
580
+ Name : "items" ,
581
+ Columns : []migrations.Column {
582
+ {
583
+ Name : "id" ,
584
+ Type : "serial" ,
585
+ Pk : true ,
586
+ },
587
+ {
588
+ Name : "name" ,
589
+ Type : "varchar(255)" ,
590
+ Nullable : true ,
591
+ },
592
+ },
593
+ },
594
+ },
595
+ },
596
+ {
597
+ Name : "02_multi_operation" ,
598
+ Operations : migrations.Operations {
599
+ & migrations.OpRenameTable {
600
+ From : "items" ,
601
+ To : "products" ,
602
+ },
603
+ & migrations.OpAlterColumn {
604
+ Table : "products" ,
605
+ Column : "name" ,
606
+ Unique : & migrations.UniqueConstraint {
607
+ Name : "products_name_unique" ,
608
+ },
609
+ Up : "name || '-' || floor(random()*100000)::text" ,
610
+ Down : "name" ,
611
+ },
612
+ },
613
+ },
614
+ },
615
+ afterStart : func (t * testing.T , db * sql.DB , schema string ) {
616
+ // Can insert a row that meets the constraint into the new view
617
+ MustInsert (t , db , schema , "02_multi_operation" , "products" , map [string ]string {
618
+ "name" : "apple" ,
619
+ })
620
+
621
+ // Can't insert a row that violates the constraint into the new view
622
+ MustNotInsert (t , db , schema , "02_multi_operation" , "products" , map [string ]string {
623
+ "name" : "apple" ,
624
+ }, testutils .UniqueViolationErrorCode )
625
+
626
+ // Can insert a row that violates the constraint into the old view
627
+ MustInsert (t , db , schema , "01_create_table" , "items" , map [string ]string {
628
+ "name" : "apple" ,
629
+ })
630
+ },
631
+ afterRollback : func (t * testing.T , db * sql.DB , schema string ) {
632
+ // The table has been cleaned up
633
+ TableMustBeCleanedUp (t , db , schema , "items" , "name" )
634
+ },
635
+ afterComplete : func (t * testing.T , db * sql.DB , schema string ) {
636
+ // Can insert a row that meets the constraint into the new view
637
+ MustInsert (t , db , schema , "02_multi_operation" , "products" , map [string ]string {
638
+ "name" : "banana" ,
639
+ })
640
+
641
+ // Can't insert a row that violates the constraint into the new view
642
+ MustNotInsert (t , db , schema , "02_multi_operation" , "products" , map [string ]string {
643
+ "name" : "banana" ,
644
+ }, testutils .UniqueViolationErrorCode )
645
+ },
646
+ },
647
+ {
648
+ name : "rename table, rename column, set unique" ,
649
+ migrations : []migrations.Migration {
650
+ {
651
+ Name : "01_create_table" ,
652
+ Operations : migrations.Operations {
653
+ & migrations.OpCreateTable {
654
+ Name : "items" ,
655
+ Columns : []migrations.Column {
656
+ {
657
+ Name : "id" ,
658
+ Type : "serial" ,
659
+ Pk : true ,
660
+ },
661
+ {
662
+ Name : "name" ,
663
+ Type : "varchar(255)" ,
664
+ Nullable : true ,
665
+ },
666
+ },
667
+ },
668
+ },
669
+ },
670
+ {
671
+ Name : "02_multi_operation" ,
672
+ Operations : migrations.Operations {
673
+ & migrations.OpRenameTable {
674
+ From : "items" ,
675
+ To : "products" ,
676
+ },
677
+ & migrations.OpRenameColumn {
678
+ Table : "products" ,
679
+ From : "name" ,
680
+ To : "item_name" ,
681
+ },
682
+ & migrations.OpAlterColumn {
683
+ Table : "products" ,
684
+ Column : "item_name" ,
685
+ Unique : & migrations.UniqueConstraint {
686
+ Name : "products_name_unique" ,
687
+ },
688
+ Up : "item_name || '-' || floor(random()*100000)::text" ,
689
+ Down : "item_name" ,
690
+ },
691
+ },
692
+ },
693
+ },
694
+ afterStart : func (t * testing.T , db * sql.DB , schema string ) {
695
+ // Can insert a row that meets the constraint into the new view
696
+ MustInsert (t , db , schema , "02_multi_operation" , "products" , map [string ]string {
697
+ "item_name" : "apple" ,
698
+ })
699
+
700
+ // Can't insert a row that violates the constraint into the new view
701
+ MustNotInsert (t , db , schema , "02_multi_operation" , "products" , map [string ]string {
702
+ "item_name" : "apple" ,
703
+ }, testutils .UniqueViolationErrorCode )
704
+
705
+ // Can insert a row that violates the constraint into the old view
706
+ MustInsert (t , db , schema , "01_create_table" , "items" , map [string ]string {
707
+ "name" : "apple" ,
708
+ })
709
+ },
710
+ afterRollback : func (t * testing.T , db * sql.DB , schema string ) {
711
+ // The table has been cleaned up
712
+ TableMustBeCleanedUp (t , db , schema , "items" , "name" )
713
+ },
714
+ afterComplete : func (t * testing.T , db * sql.DB , schema string ) {
715
+ // Can insert a row that meets the constraint into the new view
716
+ MustInsert (t , db , schema , "02_multi_operation" , "products" , map [string ]string {
717
+ "item_name" : "banana" ,
718
+ })
719
+
720
+ // Can't insert a row that violates the constraint into the new view
721
+ MustNotInsert (t , db , schema , "02_multi_operation" , "products" , map [string ]string {
722
+ "item_name" : "banana" ,
723
+ }, testutils .UniqueViolationErrorCode )
724
+ },
725
+ },
726
+ {
727
+ name : "create table, set unique" ,
728
+ migrations : []migrations.Migration {
729
+ {
730
+ Name : "01_multi_operation" ,
731
+ Operations : migrations.Operations {
732
+ & migrations.OpCreateTable {
733
+ Name : "items" ,
734
+ Columns : []migrations.Column {
735
+ {
736
+ Name : "id" ,
737
+ Type : "serial" ,
738
+ Pk : true ,
739
+ },
740
+ {
741
+ Name : "name" ,
742
+ Type : "varchar(255)" ,
743
+ Nullable : true ,
744
+ },
745
+ },
746
+ },
747
+ & migrations.OpAlterColumn {
748
+ Table : "items" ,
749
+ Column : "name" ,
750
+ Unique : & migrations.UniqueConstraint {
751
+ Name : "items_name_unique" ,
752
+ },
753
+ Up : "name || '-' || floor(random()*100000)::text" ,
754
+ Down : "name" ,
755
+ },
756
+ },
757
+ },
758
+ },
759
+ afterStart : func (t * testing.T , db * sql.DB , schema string ) {
760
+ // Can insert a row into the new (only) schema that meets the constraint
761
+ MustInsert (t , db , schema , "01_multi_operation" , "items" , map [string ]string {
762
+ "name" : "apple" ,
763
+ })
764
+
765
+ // Can't insert a row into the new (only) schema that violates the constraint
766
+ MustNotInsert (t , db , schema , "01_multi_operation" , "items" , map [string ]string {
767
+ "name" : "apple" ,
768
+ }, testutils .UniqueViolationErrorCode )
769
+ },
770
+ afterRollback : func (t * testing.T , db * sql.DB , schema string ) {
771
+ // The table has been dropped
772
+ TableMustNotExist (t , db , schema , "items" )
773
+ },
774
+ afterComplete : func (t * testing.T , db * sql.DB , schema string ) {
775
+ // Can insert a row into the new (only) schema that meets the constraint
776
+ MustInsert (t , db , schema , "01_multi_operation" , "items" , map [string ]string {
777
+ "name" : "apple" ,
778
+ })
779
+
780
+ // Can't insert a row into the new (only) schema that violates the constraint
781
+ MustNotInsert (t , db , schema , "01_multi_operation" , "items" , map [string ]string {
782
+ "name" : "apple" ,
783
+ }, testutils .UniqueViolationErrorCode )
784
+ },
785
+ },
786
+ })
787
+ }
0 commit comments