From 6272731088829b47e2b69d0bea8e2fc99a4f5420 Mon Sep 17 00:00:00 2001 From: Ting-Lan Wang Date: Fri, 19 Sep 2025 16:42:11 -0400 Subject: [PATCH 1/2] exclues autoincremented fields from the update sql, and fix SkipQuoteIdentifiers --- oracle/clause_builder.go | 2 + oracle/create.go | 10 ++- oracle/delete.go | 6 +- oracle/update.go | 6 +- tests/config_test.go | 175 ++++++++++++++++++++++++++++++++------- 5 files changed, 161 insertions(+), 38 deletions(-) diff --git a/oracle/clause_builder.go b/oracle/clause_builder.go index b588d59..5a0b7a2 100644 --- a/oracle/clause_builder.go +++ b/oracle/clause_builder.go @@ -503,6 +503,8 @@ func shouldIncludeColumn(stmt *gorm.Statement, columnName string) bool { stmt.Schema.PrioritizedPrimaryField.AutoIncrement && stmt.Schema.PrioritizedPrimaryField.DBName == columnName { return false + } else if stmt.Schema.LookUpField(columnName).AutoIncrement { + return false } return true } diff --git a/oracle/create.go b/oracle/create.go index e7ba921..ab49831 100644 --- a/oracle/create.go +++ b/oracle/create.go @@ -398,6 +398,8 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau schema.PrioritizedPrimaryField.AutoIncrement && strings.EqualFold(schema.PrioritizedPrimaryField.DBName, column.Name) { isAutoIncrement = true + } else if stmt.Schema.LookUpField(column.Name).AutoIncrement { + isAutoIncrement = true } if !isConflictColumn && !isAutoIncrement { @@ -520,7 +522,7 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau " IF l_affected_records.COUNT > %d THEN :%d := l_affected_records(%d).", rowIdx, outParamIndex+1, rowIdx+1, )) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) plsqlBuilder.WriteString("; END IF;\n") } else { // datatypes.JSON (text-based) -> serialize to CLOB @@ -529,13 +531,13 @@ func buildBulkMergePLSQL(db *gorm.DB, createValues clause.Values, onConflictClau " IF l_affected_records.COUNT > %d THEN :%d := JSON_SERIALIZE(l_affected_records(%d).", rowIdx, outParamIndex+1, rowIdx+1, )) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) plsqlBuilder.WriteString(" RETURNING CLOB); END IF;\n") } } else { stmt.Vars = append(stmt.Vars, sql.Out{Dest: createTypedDestination(field)}) plsqlBuilder.WriteString(fmt.Sprintf(" IF l_affected_records.COUNT > %d THEN :%d := l_affected_records(%d).", rowIdx, outParamIndex+1, rowIdx+1)) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) plsqlBuilder.WriteString("; END IF;\n") } outParamIndex++ @@ -696,6 +698,8 @@ func shouldIncludeColumnInInsert(stmt *gorm.Statement, columnName string) bool { stmt.Schema.PrioritizedPrimaryField.AutoIncrement && strings.EqualFold(stmt.Schema.PrioritizedPrimaryField.DBName, columnName) { return false + } else if stmt.Schema.LookUpField(columnName).AutoIncrement { + return false } return true } diff --git a/oracle/delete.go b/oracle/delete.go index b658971..56abcc9 100644 --- a/oracle/delete.go +++ b/oracle/delete.go @@ -299,14 +299,14 @@ func buildBulkDeletePLSQL(db *gorm.DB) { " IF l_deleted_records.COUNT > %d THEN :%d := l_deleted_records(%d).", rowIdx, outParamIndex+1, rowIdx+1, )) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) plsqlBuilder.WriteString("; END IF;\n") } else { // JSON -> text bind stmt.Vars = append(stmt.Vars, sql.Out{Dest: new(string)}) plsqlBuilder.WriteString(fmt.Sprintf(" IF l_deleted_records.COUNT > %d THEN\n", rowIdx)) plsqlBuilder.WriteString(fmt.Sprintf(" :%d := JSON_SERIALIZE(l_deleted_records(%d).", outParamIndex+1, rowIdx+1)) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) plsqlBuilder.WriteString(" RETURNING CLOB);\n") plsqlBuilder.WriteString(" END IF;\n") } @@ -316,7 +316,7 @@ func buildBulkDeletePLSQL(db *gorm.DB) { stmt.Vars = append(stmt.Vars, sql.Out{Dest: dest}) plsqlBuilder.WriteString(fmt.Sprintf(" IF l_deleted_records.COUNT > %d THEN\n", rowIdx)) plsqlBuilder.WriteString(fmt.Sprintf(" :%d := l_deleted_records(%d).", outParamIndex+1, rowIdx+1)) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) plsqlBuilder.WriteString(";\n") plsqlBuilder.WriteString(" END IF;\n") } diff --git a/oracle/update.go b/oracle/update.go index a54eebb..9de9e47 100644 --- a/oracle/update.go +++ b/oracle/update.go @@ -572,17 +572,17 @@ func buildUpdatePLSQL(db *gorm.DB) { if isJSONField(field) { if isRawMessageField(field) { plsqlBuilder.WriteString(fmt.Sprintf("l_updated_records(%d).", rowIdx+1)) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) } else { // serialize JSON so it binds as text plsqlBuilder.WriteString("JSON_SERIALIZE(") plsqlBuilder.WriteString(fmt.Sprintf("l_updated_records(%d).", rowIdx+1)) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) plsqlBuilder.WriteString(" RETURNING CLOB)") } } else { plsqlBuilder.WriteString(fmt.Sprintf("l_updated_records(%d).", rowIdx+1)) - writeQuotedIdentifier(&plsqlBuilder, column) + db.QuoteTo(&plsqlBuilder, column) } plsqlBuilder.WriteString("; END IF;\n") diff --git a/tests/config_test.go b/tests/config_test.go index 7fff870..1b56a71 100644 --- a/tests/config_test.go +++ b/tests/config_test.go @@ -39,23 +39,40 @@ package tests import ( + "errors" "regexp" + "sort" "testing" + "github.com/google/uuid" "github.com/oracle-samples/gorm-oracle/oracle" "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/utils/tests" ) -type Student struct { - ID uint - Name string +type FolderData struct { + ID string `gorm:"primaryKey;column:folder_id"` + Name string `gorm:"column:folder_nm"` + Properties []FolderProperty `gorm:"foreignKey:ID;PRELOAD:false"` } -func (s Student) TableName() string { - return "STUDENTS" +func (FolderData) TableName() string { + return "folder_data" } -func TestSkipQuoteIdentifiers(t *testing.T) { +type FolderProperty struct { + Seq uint64 `gorm:"autoIncrement"` + ID string `gorm:"primaryKey;column:folder_id"` + Key string `gorm:"primaryKey;unique"` + Value string +} + +func (FolderProperty) TableName() string { + return "folder_property" +} + +func TestSkipQuoteIdentifiersMigrator(t *testing.T) { db, err := openTestDBWithOptions( &oracle.Config{SkipQuoteIdentifiers: true}, &gorm.Config{Logger: newLogger}) @@ -63,41 +80,141 @@ func TestSkipQuoteIdentifiers(t *testing.T) { t.Fatalf("failed to connect database, got error %v", err) } - db.Migrator().DropTable(&Student{}) - db.Migrator().CreateTable(&Student{}) + db.Migrator().DropTable(&FolderData{}, &FolderProperty{}) + db.Migrator().CreateTable(&FolderData{}, &FolderProperty{}) - if !db.Migrator().HasTable(&Student{}) { - t.Errorf("Failed to get table: student") + folderDataTN := "FOLDER_DATA" + if !db.Migrator().HasTable(folderDataTN) { + t.Errorf("Failed to get table: %s", folderDataTN) } - if !db.Migrator().HasColumn(&Student{}, "ID") { - t.Errorf("Failed to get column: id") + if !db.Migrator().HasColumn(folderDataTN, "FOLDER_ID") { + t.Errorf("Failed to get column: FOLDER_ID") } - if !db.Migrator().HasColumn(&Student{}, "NAME") { - t.Errorf("Failed to get column: name") + if !db.Migrator().HasColumn(folderDataTN, "FOLDER_NM") { + t.Errorf("Failed to get column: FOLDER_NM") } - student := Student{ID: 1, Name: "John"} - if err := db.Model(&Student{}).Create(&student).Error; err != nil { - t.Errorf("Failed to insert student, got %v", err) + folderPropertyTN := "FOLDER_PROPERTY" + if !db.Migrator().HasTable(folderPropertyTN) { + t.Errorf("Failed to get table: %s", folderPropertyTN) } - var result Student - if err := db.First(&result).Error; err != nil { - t.Errorf("Failed to query first student, got %v", err) + if !db.Migrator().HasColumn(folderPropertyTN, "SEQ") { + t.Errorf("Failed to get column: SEQ") } - if result.ID != student.ID { - t.Errorf("id should be %v, but got %v", student.ID, result.ID) + if !db.Migrator().HasColumn(folderPropertyTN, "FOLDER_ID") { + t.Errorf("Failed to get column: FOLDER_ID") } - if result.Name != student.Name { - t.Errorf("name should be %v, but got %v", student.Name, result.Name) + if !db.Migrator().HasColumn(folderPropertyTN, "KEY") { + t.Errorf("Failed to get column: KEY") + } + + if !db.Migrator().HasColumn(folderPropertyTN, "VALUE") { + t.Errorf("Failed to get column: VALUE") } } +func TestSkipQuoteIdentifiers(t *testing.T) { + db, err := openTestDBWithOptions( + &oracle.Config{SkipQuoteIdentifiers: true}, + &gorm.Config{Logger: newLogger}) + if err != nil { + t.Fatalf("failed to connect database, got error %v", err) + } + + db.Migrator().DropTable(&FolderData{}, &FolderProperty{}) + db.Migrator().CreateTable(&FolderData{}, &FolderProperty{}) + + id := uuid.New().String() + folder := FolderData{ + ID: id, + Name: "My Folder", + Properties: []FolderProperty{ + { + ID: id, + Key: "foo1", + Value: "bar1", + }, + { + ID: id, + Key: "foo2", + Value: "bar2", + }, + }, + } + + if err := db.Create(&folder).Error; err != nil { + t.Errorf("Failed to insert data, got %v", err) + } + + createdFolder := FolderData{} + if err := db.Model(&FolderData{}).Preload("Properties").First(&createdFolder).Error; err != nil { + t.Errorf("Failed to query data, got %v", err) + } + + CheckFolderData(t, createdFolder, folder) + + createdFolder.Properties[1].Value = "baz1" + createdFolder.Properties = append(createdFolder.Properties, FolderProperty{ + ID: id, + Key: "foo3", + Value: "bar3", + }) + createdFolder.Properties = append(createdFolder.Properties, FolderProperty{ + ID: id, + Key: "foo4", + Value: "bar4", + }) + db.Save(&createdFolder) + + updatedFolder := FolderData{} + if err := db.Model(&FolderData{}).Preload("Properties").First(&updatedFolder).Error; err != nil { + t.Errorf("Failed to query data, got %v", err) + } + + CheckFolderData(t, updatedFolder, createdFolder) + + if err := db.Select(clause.Associations).Delete(&createdFolder).Error; err != nil { + t.Errorf("Failed to delete data, got %v", err) + } + + result := FolderData{} + if err := db.Where("folder_id = ?", createdFolder.ID).First(&result).Error; err == nil || !errors.Is(err, gorm.ErrRecordNotFound) { + t.Errorf("should returns record not found error, but got %v", err) + } +} + +func CheckFolderData(t *testing.T, folderData FolderData, expect FolderData) { + tests.AssertObjEqual(t, folderData, expect, "ID", "Name") + t.Run("Properties", func(t *testing.T) { + if len(folderData.Properties) != len(expect.Properties) { + t.Fatalf("properties should equal, expect: %v, got %v", len(expect.Properties), len(folderData.Properties)) + } + + sort.Slice(folderData.Properties, func(i, j int) bool { + return folderData.Properties[i].ID > folderData.Properties[j].ID + }) + + sort.Slice(expect.Properties, func(i, j int) bool { + return expect.Properties[i].ID > expect.Properties[j].ID + }) + + for idx, property := range folderData.Properties { + tests.AssertObjEqual(t, property, expect.Properties[idx], "Seq", "ID", "Key", "Value") + } + }) +} + func TestSkipQuoteIdentifiersSQL(t *testing.T) { + type Student struct { + ID uint + Name string + } + db, err := openTestDBWithOptions( &oracle.Config{SkipQuoteIdentifiers: true}, &gorm.Config{Logger: newLogger}) @@ -109,7 +226,7 @@ func TestSkipQuoteIdentifiersSQL(t *testing.T) { insertedStudent := Student{ID: 1, Name: "John"} result := dryrunDB.Model(&Student{}).Create(&insertedStudent) - if !regexp.MustCompile(`^INSERT INTO STUDENTS \(name,id\) VALUES \(:1,:2\)$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^INSERT INTO students \(name,id\) VALUES \(:1,:2\)$`).MatchString(result.Statement.SQL.String()) { t.Errorf("invalid insert SQL, got %v", result.Statement.SQL.String()) } @@ -117,26 +234,26 @@ func TestSkipQuoteIdentifiersSQL(t *testing.T) { var firstStudent Student result = dryrunDB.First(&firstStudent) - if !regexp.MustCompile(`^SELECT \* FROM STUDENTS ORDER BY STUDENTS\.id FETCH NEXT 1 ROW ONLY$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^SELECT \* FROM students ORDER BY students\.id FETCH NEXT 1 ROW ONLY$`).MatchString(result.Statement.SQL.String()) { t.Fatalf("SQL should include selected names, but got %v", result.Statement.SQL.String()) } // Test Find var foundStudent Student result = dryrunDB.Find(foundStudent, "id = ?", insertedStudent.ID) - if !regexp.MustCompile(`^SELECT \* FROM STUDENTS WHERE id = :1$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^SELECT \* FROM students WHERE id = :1$`).MatchString(result.Statement.SQL.String()) { t.Fatalf("SQL should include selected names, but got %v", result.Statement.SQL.String()) } // Test Save result = dryrunDB.Save(&Student{ID: 2, Name: "Mary"}) - if !regexp.MustCompile(`^UPDATE STUDENTS SET name=:1 WHERE id = :2$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^UPDATE students SET name=:1 WHERE id = :2$`).MatchString(result.Statement.SQL.String()) { t.Fatalf("SQL should include selected names, but got %v", result.Statement.SQL.String()) } // Update with conditions result = dryrunDB.Model(&Student{}).Where("id = ?", 1).Update("name", "hello") - if !regexp.MustCompile(`^UPDATE STUDENTS SET name=:1 WHERE id = :2$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^UPDATE students SET name=:1 WHERE id = :2$`).MatchString(result.Statement.SQL.String()) { t.Fatalf("SQL should include selected names, but got %v", result.Statement.SQL.String()) } } From 610a82e95e49633f381435ea0b09a6745e9ff940 Mon Sep 17 00:00:00 2001 From: Ting-Lan Wang Date: Fri, 19 Sep 2025 17:07:50 -0400 Subject: [PATCH 2/2] move TestSaveAssociationWithAutoIncrementField to association_test.go --- tests/associations_test.go | 65 ++++++++++++++ tests/config_test.go | 175 ++++++------------------------------- tests/helper_test.go | 21 +++++ tests/utils/models.go | 13 +++ 4 files changed, 128 insertions(+), 146 deletions(-) diff --git a/tests/associations_test.go b/tests/associations_test.go index 59cd185..2cd2c47 100644 --- a/tests/associations_test.go +++ b/tests/associations_test.go @@ -39,9 +39,11 @@ package tests import ( + "errors" "strings" "testing" + "github.com/google/uuid" . "github.com/oracle-samples/gorm-oracle/tests/utils" "gorm.io/gorm" @@ -543,3 +545,66 @@ func TestBasicManyToManyAssociation(t *testing.T) { AssertAssociationCount(t, user, "Languages", 0, "after clear") } + +func TestSaveAssociationWithAutoIncrementField(t *testing.T) { + DB.Migrator().DropTable(&FolderData{}, &FolderProperty{}) + DB.Migrator().CreateTable(&FolderData{}, &FolderProperty{}) + + id := uuid.New().String() + folder := FolderData{ + ID: id, + Name: "My Folder", + Properties: []FolderProperty{ + { + ID: id, + Key: "foo1", + Value: "bar1", + }, + { + ID: id, + Key: "foo2", + Value: "bar2", + }, + }, + } + + if err := DB.Create(&folder).Error; err != nil { + t.Errorf("Failed to insert data, got %v", err) + } + + createdFolder := FolderData{} + if err := DB.Model(&FolderData{}).Preload("Properties").First(&createdFolder).Error; err != nil { + t.Errorf("Failed to query data, got %v", err) + } + + CheckFolderData(t, createdFolder, folder) + + createdFolder.Properties[1].Value = "baz1" + createdFolder.Properties = append(createdFolder.Properties, FolderProperty{ + ID: id, + Key: "foo3", + Value: "bar3", + }) + createdFolder.Properties = append(createdFolder.Properties, FolderProperty{ + ID: id, + Key: "foo4", + Value: "bar4", + }) + DB.Save(&createdFolder) + + updatedFolder := FolderData{} + if err := DB.Model(&FolderData{}).Preload("Properties").First(&updatedFolder).Error; err != nil { + t.Errorf("Failed to query data, got %v", err) + } + + CheckFolderData(t, updatedFolder, createdFolder) + + if err := DB.Select(clause.Associations).Delete(&createdFolder).Error; err != nil { + t.Errorf("Failed to delete data, got %v", err) + } + + result := FolderData{} + if err := DB.Where("\"folder_id\" = ?", createdFolder.ID).First(&result).Error; err == nil || !errors.Is(err, gorm.ErrRecordNotFound) { + t.Errorf("should returns record not found error, but got %v", err) + } +} diff --git a/tests/config_test.go b/tests/config_test.go index 1b56a71..7fff870 100644 --- a/tests/config_test.go +++ b/tests/config_test.go @@ -39,83 +39,20 @@ package tests import ( - "errors" "regexp" - "sort" "testing" - "github.com/google/uuid" "github.com/oracle-samples/gorm-oracle/oracle" "gorm.io/gorm" - "gorm.io/gorm/clause" - "gorm.io/gorm/utils/tests" ) -type FolderData struct { - ID string `gorm:"primaryKey;column:folder_id"` - Name string `gorm:"column:folder_nm"` - Properties []FolderProperty `gorm:"foreignKey:ID;PRELOAD:false"` +type Student struct { + ID uint + Name string } -func (FolderData) TableName() string { - return "folder_data" -} - -type FolderProperty struct { - Seq uint64 `gorm:"autoIncrement"` - ID string `gorm:"primaryKey;column:folder_id"` - Key string `gorm:"primaryKey;unique"` - Value string -} - -func (FolderProperty) TableName() string { - return "folder_property" -} - -func TestSkipQuoteIdentifiersMigrator(t *testing.T) { - db, err := openTestDBWithOptions( - &oracle.Config{SkipQuoteIdentifiers: true}, - &gorm.Config{Logger: newLogger}) - if err != nil { - t.Fatalf("failed to connect database, got error %v", err) - } - - db.Migrator().DropTable(&FolderData{}, &FolderProperty{}) - db.Migrator().CreateTable(&FolderData{}, &FolderProperty{}) - - folderDataTN := "FOLDER_DATA" - if !db.Migrator().HasTable(folderDataTN) { - t.Errorf("Failed to get table: %s", folderDataTN) - } - - if !db.Migrator().HasColumn(folderDataTN, "FOLDER_ID") { - t.Errorf("Failed to get column: FOLDER_ID") - } - - if !db.Migrator().HasColumn(folderDataTN, "FOLDER_NM") { - t.Errorf("Failed to get column: FOLDER_NM") - } - - folderPropertyTN := "FOLDER_PROPERTY" - if !db.Migrator().HasTable(folderPropertyTN) { - t.Errorf("Failed to get table: %s", folderPropertyTN) - } - - if !db.Migrator().HasColumn(folderPropertyTN, "SEQ") { - t.Errorf("Failed to get column: SEQ") - } - - if !db.Migrator().HasColumn(folderPropertyTN, "FOLDER_ID") { - t.Errorf("Failed to get column: FOLDER_ID") - } - - if !db.Migrator().HasColumn(folderPropertyTN, "KEY") { - t.Errorf("Failed to get column: KEY") - } - - if !db.Migrator().HasColumn(folderPropertyTN, "VALUE") { - t.Errorf("Failed to get column: VALUE") - } +func (s Student) TableName() string { + return "STUDENTS" } func TestSkipQuoteIdentifiers(t *testing.T) { @@ -126,95 +63,41 @@ func TestSkipQuoteIdentifiers(t *testing.T) { t.Fatalf("failed to connect database, got error %v", err) } - db.Migrator().DropTable(&FolderData{}, &FolderProperty{}) - db.Migrator().CreateTable(&FolderData{}, &FolderProperty{}) + db.Migrator().DropTable(&Student{}) + db.Migrator().CreateTable(&Student{}) - id := uuid.New().String() - folder := FolderData{ - ID: id, - Name: "My Folder", - Properties: []FolderProperty{ - { - ID: id, - Key: "foo1", - Value: "bar1", - }, - { - ID: id, - Key: "foo2", - Value: "bar2", - }, - }, + if !db.Migrator().HasTable(&Student{}) { + t.Errorf("Failed to get table: student") } - if err := db.Create(&folder).Error; err != nil { - t.Errorf("Failed to insert data, got %v", err) + if !db.Migrator().HasColumn(&Student{}, "ID") { + t.Errorf("Failed to get column: id") } - createdFolder := FolderData{} - if err := db.Model(&FolderData{}).Preload("Properties").First(&createdFolder).Error; err != nil { - t.Errorf("Failed to query data, got %v", err) + if !db.Migrator().HasColumn(&Student{}, "NAME") { + t.Errorf("Failed to get column: name") } - CheckFolderData(t, createdFolder, folder) - - createdFolder.Properties[1].Value = "baz1" - createdFolder.Properties = append(createdFolder.Properties, FolderProperty{ - ID: id, - Key: "foo3", - Value: "bar3", - }) - createdFolder.Properties = append(createdFolder.Properties, FolderProperty{ - ID: id, - Key: "foo4", - Value: "bar4", - }) - db.Save(&createdFolder) - - updatedFolder := FolderData{} - if err := db.Model(&FolderData{}).Preload("Properties").First(&updatedFolder).Error; err != nil { - t.Errorf("Failed to query data, got %v", err) + student := Student{ID: 1, Name: "John"} + if err := db.Model(&Student{}).Create(&student).Error; err != nil { + t.Errorf("Failed to insert student, got %v", err) } - CheckFolderData(t, updatedFolder, createdFolder) - - if err := db.Select(clause.Associations).Delete(&createdFolder).Error; err != nil { - t.Errorf("Failed to delete data, got %v", err) + var result Student + if err := db.First(&result).Error; err != nil { + t.Errorf("Failed to query first student, got %v", err) } - result := FolderData{} - if err := db.Where("folder_id = ?", createdFolder.ID).First(&result).Error; err == nil || !errors.Is(err, gorm.ErrRecordNotFound) { - t.Errorf("should returns record not found error, but got %v", err) + if result.ID != student.ID { + t.Errorf("id should be %v, but got %v", student.ID, result.ID) } -} - -func CheckFolderData(t *testing.T, folderData FolderData, expect FolderData) { - tests.AssertObjEqual(t, folderData, expect, "ID", "Name") - t.Run("Properties", func(t *testing.T) { - if len(folderData.Properties) != len(expect.Properties) { - t.Fatalf("properties should equal, expect: %v, got %v", len(expect.Properties), len(folderData.Properties)) - } - - sort.Slice(folderData.Properties, func(i, j int) bool { - return folderData.Properties[i].ID > folderData.Properties[j].ID - }) - sort.Slice(expect.Properties, func(i, j int) bool { - return expect.Properties[i].ID > expect.Properties[j].ID - }) - - for idx, property := range folderData.Properties { - tests.AssertObjEqual(t, property, expect.Properties[idx], "Seq", "ID", "Key", "Value") - } - }) + if result.Name != student.Name { + t.Errorf("name should be %v, but got %v", student.Name, result.Name) + } } func TestSkipQuoteIdentifiersSQL(t *testing.T) { - type Student struct { - ID uint - Name string - } - db, err := openTestDBWithOptions( &oracle.Config{SkipQuoteIdentifiers: true}, &gorm.Config{Logger: newLogger}) @@ -226,7 +109,7 @@ func TestSkipQuoteIdentifiersSQL(t *testing.T) { insertedStudent := Student{ID: 1, Name: "John"} result := dryrunDB.Model(&Student{}).Create(&insertedStudent) - if !regexp.MustCompile(`^INSERT INTO students \(name,id\) VALUES \(:1,:2\)$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^INSERT INTO STUDENTS \(name,id\) VALUES \(:1,:2\)$`).MatchString(result.Statement.SQL.String()) { t.Errorf("invalid insert SQL, got %v", result.Statement.SQL.String()) } @@ -234,26 +117,26 @@ func TestSkipQuoteIdentifiersSQL(t *testing.T) { var firstStudent Student result = dryrunDB.First(&firstStudent) - if !regexp.MustCompile(`^SELECT \* FROM students ORDER BY students\.id FETCH NEXT 1 ROW ONLY$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^SELECT \* FROM STUDENTS ORDER BY STUDENTS\.id FETCH NEXT 1 ROW ONLY$`).MatchString(result.Statement.SQL.String()) { t.Fatalf("SQL should include selected names, but got %v", result.Statement.SQL.String()) } // Test Find var foundStudent Student result = dryrunDB.Find(foundStudent, "id = ?", insertedStudent.ID) - if !regexp.MustCompile(`^SELECT \* FROM students WHERE id = :1$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^SELECT \* FROM STUDENTS WHERE id = :1$`).MatchString(result.Statement.SQL.String()) { t.Fatalf("SQL should include selected names, but got %v", result.Statement.SQL.String()) } // Test Save result = dryrunDB.Save(&Student{ID: 2, Name: "Mary"}) - if !regexp.MustCompile(`^UPDATE students SET name=:1 WHERE id = :2$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^UPDATE STUDENTS SET name=:1 WHERE id = :2$`).MatchString(result.Statement.SQL.String()) { t.Fatalf("SQL should include selected names, but got %v", result.Statement.SQL.String()) } // Update with conditions result = dryrunDB.Model(&Student{}).Where("id = ?", 1).Update("name", "hello") - if !regexp.MustCompile(`^UPDATE students SET name=:1 WHERE id = :2$`).MatchString(result.Statement.SQL.String()) { + if !regexp.MustCompile(`^UPDATE STUDENTS SET name=:1 WHERE id = :2$`).MatchString(result.Statement.SQL.String()) { t.Fatalf("SQL should include selected names, but got %v", result.Statement.SQL.String()) } } diff --git a/tests/helper_test.go b/tests/helper_test.go index 535ef96..d07a5bd 100644 --- a/tests/helper_test.go +++ b/tests/helper_test.go @@ -357,3 +357,24 @@ func db(unscoped bool) *gorm.DB { return DB } } + +func CheckFolderData(t *testing.T, folderData FolderData, expect FolderData) { + tests.AssertObjEqual(t, folderData, expect, "ID", "Name") + t.Run("Properties", func(t *testing.T) { + if len(folderData.Properties) != len(expect.Properties) { + t.Fatalf("properties should equal, expect: %v, got %v", len(expect.Properties), len(folderData.Properties)) + } + + sort.Slice(folderData.Properties, func(i, j int) bool { + return folderData.Properties[i].ID > folderData.Properties[j].ID + }) + + sort.Slice(expect.Properties, func(i, j int) bool { + return expect.Properties[i].ID > expect.Properties[j].ID + }) + + for idx, property := range folderData.Properties { + tests.AssertObjEqual(t, property, expect.Properties[idx], "Seq", "ID", "Key", "Value") + } + }) +} diff --git a/tests/utils/models.go b/tests/utils/models.go index cca6fdc..2b033f6 100644 --- a/tests/utils/models.go +++ b/tests/utils/models.go @@ -102,3 +102,16 @@ type Child struct { ParentID *uint Parent *Parent } + +type FolderProperty struct { + Seq uint64 `gorm:"autoIncrement"` + ID string `gorm:"primaryKey;column:folder_id"` + Key string `gorm:"primaryKey;unique"` + Value string +} + +type FolderData struct { + ID string `gorm:"primaryKey;column:folder_id"` + Name string `gorm:"column:folder_nm"` + Properties []FolderProperty `gorm:"foreignKey:ID;PRELOAD:false"` +}