Merge branch 'master' into fix_migrate_default
This commit is contained in:
commit
7c7db3d4a1
@ -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)
|
||||
|
@ -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"}},
|
||||
|
@ -351,10 +351,10 @@ func (db *DB) FirstOrCreate(dest interface{}, conds ...interface{}) (tx *DB) {
|
||||
}
|
||||
|
||||
return tx.Model(dest).Updates(assigns)
|
||||
}
|
||||
} else {
|
||||
tx.Error = result.Error
|
||||
}
|
||||
}
|
||||
return tx
|
||||
}
|
||||
|
||||
|
9
scan.go
9
scan.go
@ -193,16 +193,23 @@ 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:] {
|
||||
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 {
|
||||
fields[idx] = field
|
||||
selectedColumnsMap[column] = idx
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user