package tests_test import ( "testing" "time" "github.com/google/uuid" "github.com/lib/pq" "gorm.io/gorm" "gorm.io/gorm/clause" . "gorm.io/gorm/utils/tests" ) func TestPostgresReturningIDWhichHasStringType(t *testing.T) { if DB.Dialector.Name() != "postgres" { t.Skip() } type Yasuo struct { ID string `gorm:"default:gen_random_uuid()"` Name string CreatedAt time.Time `gorm:"type:TIMESTAMP WITHOUT TIME ZONE"` UpdatedAt time.Time `gorm:"type:TIMESTAMP WITHOUT TIME ZONE;default:current_timestamp"` } if err := DB.Exec("CREATE EXTENSION IF NOT EXISTS pgcrypto;").Error; err != nil { t.Errorf("Failed to create extension pgcrypto, got error %v", err) } DB.Migrator().DropTable(&Yasuo{}) if err := DB.AutoMigrate(&Yasuo{}); err != nil { t.Fatalf("Failed to migrate for uuid default value, got error: %v", err) } yasuo := Yasuo{Name: "jinzhu"} if err := DB.Create(&yasuo).Error; err != nil { t.Fatalf("should be able to create data, but got %v", err) } if yasuo.ID == "" { t.Fatal("should be able to has ID, but got zero value") } var result Yasuo if err := DB.First(&result, "id = ?", yasuo.ID).Error; err != nil || yasuo.Name != "jinzhu" { t.Errorf("No error should happen, but got %v", err) } if err := DB.Where("id = $1", yasuo.ID).First(&Yasuo{}).Error; err != nil || yasuo.Name != "jinzhu" { t.Errorf("No error should happen, but got %v", err) } yasuo.Name = "jinzhu1" if err := DB.Save(&yasuo).Error; err != nil { t.Errorf("Failed to update date, got error %v", err) } if err := DB.First(&result, "id = ?", yasuo.ID).Error; err != nil || yasuo.Name != "jinzhu1" { t.Errorf("No error should happen, but got %v", err) } } func TestPostgres(t *testing.T) { if DB.Dialector.Name() != "postgres" { t.Skip() } type Harumph struct { gorm.Model Name string `gorm:"check:name_checker,name <> ''"` Test uuid.UUID `gorm:"type:uuid;not null;default:gen_random_uuid()"` CreatedAt time.Time `gorm:"type:TIMESTAMP WITHOUT TIME ZONE"` UpdatedAt time.Time `gorm:"type:TIMESTAMP WITHOUT TIME ZONE;default:current_timestamp"` Things pq.StringArray `gorm:"type:text[]"` } if err := DB.Exec("CREATE EXTENSION IF NOT EXISTS pgcrypto;").Error; err != nil { t.Errorf("Failed to create extension pgcrypto, got error %v", err) } DB.Migrator().DropTable(&Harumph{}) if err := DB.AutoMigrate(&Harumph{}); err != nil { t.Fatalf("Failed to migrate for uuid default value, got error: %v", err) } harumph := Harumph{} if err := DB.Create(&harumph).Error; err == nil { t.Fatalf("should failed to create data, name can't be blank") } harumph = Harumph{Name: "jinzhu"} if err := DB.Create(&harumph).Error; err != nil { t.Fatalf("should be able to create data, but got %v", err) } var result Harumph if err := DB.First(&result, "id = ?", harumph.ID).Error; err != nil || harumph.Name != "jinzhu" { t.Errorf("No error should happen, but got %v", err) } if err := DB.Where("id = $1", harumph.ID).First(&Harumph{}).Error; err != nil || harumph.Name != "jinzhu" { t.Errorf("No error should happen, but got %v", err) } harumph.Name = "jinzhu1" if err := DB.Save(&harumph).Error; err != nil { t.Errorf("Failed to update date, got error %v", err) } if err := DB.First(&result, "id = ?", harumph.ID).Error; err != nil || harumph.Name != "jinzhu1" { t.Errorf("No error should happen, but got %v", err) } DB.Migrator().DropTable("log_usage") if err := DB.Exec(` CREATE TABLE public.log_usage ( log_id bigint NOT NULL ); ALTER TABLE public.log_usage ALTER COLUMN log_id ADD GENERATED BY DEFAULT AS IDENTITY ( SEQUENCE NAME public.log_usage_log_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1 ); `).Error; err != nil { t.Fatalf("failed to create table, got error %v", err) } columns, err := DB.Migrator().ColumnTypes("log_usage") if err != nil { t.Fatalf("failed to get columns, got error %v", err) } hasLogID := false for _, column := range columns { if column.Name() == "log_id" { hasLogID = true autoIncrement, ok := column.AutoIncrement() if !ok || !autoIncrement { t.Fatalf("column log_id should be auto incrementment") } } } if !hasLogID { t.Fatalf("failed to found column log_id") } } type Post struct { ID uuid.UUID `gorm:"primary_key;type:uuid;default:uuid_generate_v4();"` Title string Categories []*Category `gorm:"Many2Many:post_categories"` } type Category struct { ID uuid.UUID `gorm:"primary_key;type:uuid;default:uuid_generate_v4();"` Title string Posts []*Post `gorm:"Many2Many:post_categories"` } func TestMany2ManyWithDefaultValueUUID(t *testing.T) { if DB.Dialector.Name() != "postgres" { t.Skip() } if err := DB.Exec(`create extension if not exists "uuid-ossp"`).Error; err != nil { t.Fatalf("Failed to create 'uuid-ossp' extension, but got error %v", err) } DB.Migrator().DropTable(&Post{}, &Category{}, "post_categories") DB.AutoMigrate(&Post{}, &Category{}) post := Post{ Title: "Hello World", Categories: []*Category{ {Title: "Coding"}, {Title: "Golang"}, }, } if err := DB.Create(&post).Error; err != nil { t.Errorf("Failed, got error: %v", err) } } func TestPostgresOnConstraint(t *testing.T) { if DB.Dialector.Name() != "postgres" { t.Skip() } type Thing struct { gorm.Model SomeID string OtherID string Data string } DB.Migrator().DropTable(&Thing{}) DB.Migrator().CreateTable(&Thing{}) if err := DB.Exec("ALTER TABLE things ADD CONSTRAINT some_id_other_id_unique UNIQUE (some_id, other_id)").Error; err != nil { t.Error(err) } thing := Thing{ SomeID: "1234", OtherID: "1234", Data: "something", } DB.Create(&thing) thing2 := Thing{ SomeID: "1234", OtherID: "1234", Data: "something else", } result := DB.Clauses(clause.OnConflict{ OnConstraint: "some_id_other_id_unique", UpdateAll: true, }).Create(&thing2) if result.Error != nil { t.Errorf("creating second thing: %v", result.Error) } var things []Thing if err := DB.Find(&things).Error; err != nil { t.Errorf("Failed, got error: %v", err) } if len(things) > 1 { t.Errorf("expected 1 thing got more") } } type CompanyNew struct { ID int Name int } func TestAlterColumnDataType(t *testing.T) { DB.AutoMigrate(Company{}) if err := DB.Table("companies").Migrator().AlterColumn(CompanyNew{}, "name"); err != nil { t.Fatalf("failed to alter column from string to int, got error %v", err) } DB.AutoMigrate(Company{}) }