Merge branch 'master' into fix_migrate_default

This commit is contained in:
Jinzhu 2022-05-28 22:25:27 +08:00 committed by GitHub
commit 7c7db3d4a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 11 deletions

View File

@ -127,7 +127,7 @@ func (expr NamedExpr) Build(builder Builder) {
if v == '@' && !inName {
inName = true
name = []byte{}
} else if v == ' ' || v == ',' || v == ')' || v == '"' || v == '\'' || v == '`' || v == '\n' || v == ';' {
} else if v == ' ' || v == ',' || v == ')' || v == '"' || v == '\'' || v == '`' || v == '\r' || v == '\n' || v == ';' {
if inName {
if nv, ok := namedMap[string(name)]; ok {
builder.AddVar(builder, nv)

View File

@ -94,6 +94,16 @@ func TestNamedExpr(t *testing.T) {
Vars: []interface{}{sql.Named("name", "jinzhu")},
Result: "name1 = ? AND name2 = ?;",
ExpectedVars: []interface{}{"jinzhu", "jinzhu"},
}, {
SQL: "name1 = @name1\r\n AND name2 = @name2",
Vars: []interface{}{map[string]interface{}{"name1": "jinzhu", "name2": "jinzhu"}},
Result: "name1 = ?\r\n AND name2 = ?",
ExpectedVars: []interface{}{"jinzhu", "jinzhu"},
}, {
SQL: "name1 = @name1\r AND name2 = @name2",
Vars: []interface{}{map[string]interface{}{"name1": "jinzhu", "name2": "jinzhu"}},
Result: "name1 = ?\r AND name2 = ?",
ExpectedVars: []interface{}{"jinzhu", "jinzhu"},
}, {
SQL: "?",
Vars: []interface{}{clause.Column{Table: "table", Name: "col"}},

View File

@ -351,9 +351,9 @@ func (db *DB) FirstOrCreate(dest interface{}, conds ...interface{}) (tx *DB) {
}
return tx.Model(dest).Updates(assigns)
} else {
tx.Error = result.Error
}
} else {
tx.Error = result.Error
}
return tx
}

17
scan.go
View File

@ -193,14 +193,21 @@ func Scan(rows Rows, db *DB, mode ScanMode) {
// Not Pluck
if sch != nil {
schFieldsCount := len(sch.Fields)
for idx, column := range columns {
if field := sch.LookUpField(column); field != nil && field.Readable {
if curIndex, ok := selectedColumnsMap[column]; ok {
for fieldIndex, selectField := range sch.Fields[curIndex+1:] {
if selectField.DBName == column && selectField.Readable {
selectedColumnsMap[column] = curIndex + fieldIndex + 1
fields[idx] = selectField
break
fields[idx] = field // handle duplicate fields
offset := curIndex + 1
// handle sch inconsistent with database
// like Raw(`...`).Scan
if schFieldsCount > offset {
for fieldIndex, selectField := range sch.Fields[offset:] {
if selectField.DBName == column && selectField.Readable {
selectedColumnsMap[column] = curIndex + fieldIndex + 1
fields[idx] = selectField
break
}
}
}
} else {

View File

@ -476,6 +476,13 @@ func TestOmitWithCreate(t *testing.T) {
CheckUser(t, result2, user2)
}
func TestFirstOrCreateNotExistsTable(t *testing.T) {
company := Company{Name: "first_or_create_if_not_exists_table"}
if err := DB.Table("not_exists").FirstOrCreate(&company).Error; err == nil {
t.Errorf("not exists table, but err is nil")
}
}
func TestFirstOrCreateWithPrimaryKey(t *testing.T) {
company := Company{ID: 100, Name: "company100_with_primarykey"}
DB.FirstOrCreate(&company)

View File

@ -8,6 +8,7 @@ import (
"testing"
"time"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/schema"
. "gorm.io/gorm/utils/tests"
@ -848,3 +849,38 @@ func findColumnType(dest interface{}, columnName string) (
}
return
}
func TestInvalidCachedPlan(t *testing.T) {
if DB.Dialector.Name() != "postgres" {
return
}
db, err := gorm.Open(postgres.Open(postgresDSN), &gorm.Config{})
if err != nil {
t.Errorf("Open err:%v", err)
}
type Object1 struct{}
type Object2 struct {
Field1 string
}
type Object3 struct {
Field2 string
}
db.Migrator().DropTable("objects")
err = db.Table("objects").AutoMigrate(&Object1{})
if err != nil {
t.Errorf("AutoMigrate err:%v", err)
}
err = db.Table("objects").AutoMigrate(&Object2{})
if err != nil {
t.Errorf("AutoMigrate err:%v", err)
}
err = db.Table("objects").AutoMigrate(&Object3{})
if err != nil {
t.Errorf("AutoMigrate err:%v", err)
}
}

View File

@ -214,4 +214,29 @@ func TestScanToEmbedded(t *testing.T) {
if !addressMatched {
t.Errorf("Failed, no address matched")
}
personDupField := Person{ID: person1.ID}
if err := DB.Select("people.id, people.*").
First(&personDupField).Error; err != nil {
t.Errorf("Failed to run join query, got error: %v", err)
}
AssertEqual(t, person1, personDupField)
user := User{
Name: "TestScanToEmbedded_1",
Manager: &User{
Name: "TestScanToEmbedded_1_m1",
Manager: &User{Name: "TestScanToEmbedded_1_m1_m1"},
},
}
DB.Create(&user)
type UserScan struct {
ID uint
Name string
ManagerID *uint
}
var user2 UserScan
err := DB.Raw("SELECT * FROM users INNER JOIN users Manager ON users.manager_id = Manager.id WHERE users.id = ?", user.ID).Scan(&user2).Error
AssertEqual(t, err, nil)
}

View File

@ -17,6 +17,11 @@ import (
)
var DB *gorm.DB
var (
mysqlDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local"
postgresDSN = "user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai"
sqlserverDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
)
func init() {
var err error
@ -49,13 +54,13 @@ func OpenTestConnection() (db *gorm.DB, err error) {
case "mysql":
log.Println("testing mysql...")
if dbDSN == "" {
dbDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local"
dbDSN = mysqlDSN
}
db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{})
case "postgres":
log.Println("testing postgres...")
if dbDSN == "" {
dbDSN = "user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai"
dbDSN = postgresDSN
}
db, err = gorm.Open(postgres.New(postgres.Config{
DSN: dbDSN,
@ -72,7 +77,7 @@ func OpenTestConnection() (db *gorm.DB, err error) {
// GO
log.Println("testing sqlserver...")
if dbDSN == "" {
dbDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
dbDSN = sqlserverDSN
}
db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{})
default: