Prechádzať zdrojové kódy

Avoid Errors in postgres when creating a row without a GORM defined primary key (but defined db-side)

Paolo Galeone 9 rokov pred
rodič
commit
0fa1335555
4 zmenil súbory, kde vykonal 25 pridanie a 12 odobranie
  1. 9 2
      callback_create.go
  2. 9 1
      create_test.go
  3. 1 9
      migration_test.go
  4. 6 0
      structs_test.go

+ 9 - 2
callback_create.go

@@ -34,10 +34,17 @@ func Create(scope *Scope) {
 			}
 		}
 
+		returningField := ""
+		if scope.PrimaryKey() == "" {
+			returningField = "*"
+		} else {
+			returningField = scope.PrimaryKey()
+		}
+
 		if len(columns) == 0 {
 			scope.Raw(fmt.Sprintf("INSERT INTO %v DEFAULT VALUES %v",
 				scope.QuotedTableName(),
-				scope.Dialect().ReturningStr(scope.PrimaryKey()),
+				scope.Dialect().ReturningStr(returningField),
 			))
 		} else {
 			scope.Raw(fmt.Sprintf(
@@ -45,7 +52,7 @@ func Create(scope *Scope) {
 				scope.QuotedTableName(),
 				strings.Join(columns, ","),
 				strings.Join(sqls, ","),
-				scope.Dialect().ReturningStr(scope.PrimaryKey()),
+				scope.Dialect().ReturningStr(returningField),
 			))
 		}
 

+ 9 - 1
create_test.go

@@ -56,10 +56,18 @@ func TestCreate(t *testing.T) {
 	}
 }
 
+func TestCreateWithNoGORMPrimayKey(t *testing.T) {
+	jt := JoinTable{From: 1, To: 2}
+	err := DB.Create(&jt).Error
+	if err != nil {
+		t.Errorf("No error should happen when create a record without a GORM primary key. But in the database this primary key exists and is the union of 2 or more fields\n But got: %s", err)
+	}
+}
+
 func TestCreateWithNoStdPrimaryKeyAndDefaultValues(t *testing.T) {
 	animal := Animal{Name: "Ferdinand"}
 	if DB.Save(&animal).Error != nil {
-		t.Errorf("No error should happen when create an record without std primary key")
+		t.Errorf("No error should happen when create a record without std primary key")
 	}
 
 	if animal.Counter == 0 {

+ 1 - 9
migration_test.go

@@ -15,19 +15,11 @@ func runMigration() {
 		DB.Exec(fmt.Sprintf("drop table %v;", table))
 	}
 
-	values := []interface{}{&Product{}, &Email{}, &Address{}, &CreditCard{}, &Company{}, &Role{}, &Language{}, &HNPost{}, &EngadgetPost{}}
+	values := []interface{}{&Product{}, &Email{}, &Address{}, &CreditCard{}, &Company{}, &Role{}, &Language{}, &HNPost{}, &EngadgetPost{}, &Animal{}, &User{}, &JoinTable{}}
 	for _, value := range values {
 		DB.DropTable(value)
 	}
 
-	if err := DB.CreateTable(&Animal{}).Error; err != nil {
-		panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
-	}
-
-	if err := DB.CreateTable(User{}).Error; err != nil {
-		panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
-	}
-
 	if err := DB.AutoMigrate(values...).Error; err != nil {
 		panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
 	}

+ 6 - 0
structs_test.go

@@ -134,6 +134,12 @@ type Animal struct {
 	UpdatedAt  time.Time
 }
 
+type JoinTable struct {
+	From uint64
+	To   uint64
+	Time time.Time `sql:"default: null"`
+}
+
 type Post struct {
 	Id             int64
 	CategoryId     sql.NullInt64