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 {
|
if v == '@' && !inName {
|
||||||
inName = true
|
inName = true
|
||||||
name = []byte{}
|
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 inName {
|
||||||
if nv, ok := namedMap[string(name)]; ok {
|
if nv, ok := namedMap[string(name)]; ok {
|
||||||
builder.AddVar(builder, nv)
|
builder.AddVar(builder, nv)
|
||||||
|
@ -94,6 +94,16 @@ func TestNamedExpr(t *testing.T) {
|
|||||||
Vars: []interface{}{sql.Named("name", "jinzhu")},
|
Vars: []interface{}{sql.Named("name", "jinzhu")},
|
||||||
Result: "name1 = ? AND name2 = ?;",
|
Result: "name1 = ? AND name2 = ?;",
|
||||||
ExpectedVars: []interface{}{"jinzhu", "jinzhu"},
|
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: "?",
|
SQL: "?",
|
||||||
Vars: []interface{}{clause.Column{Table: "table", Name: "col"}},
|
Vars: []interface{}{clause.Column{Table: "table", Name: "col"}},
|
||||||
|
@ -351,9 +351,9 @@ func (db *DB) FirstOrCreate(dest interface{}, conds ...interface{}) (tx *DB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return tx.Model(dest).Updates(assigns)
|
return tx.Model(dest).Updates(assigns)
|
||||||
} else {
|
|
||||||
tx.Error = result.Error
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
tx.Error = result.Error
|
||||||
}
|
}
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
17
scan.go
17
scan.go
@ -193,14 +193,21 @@ func Scan(rows Rows, db *DB, mode ScanMode) {
|
|||||||
|
|
||||||
// Not Pluck
|
// Not Pluck
|
||||||
if sch != nil {
|
if sch != nil {
|
||||||
|
schFieldsCount := len(sch.Fields)
|
||||||
for idx, column := range columns {
|
for idx, column := range columns {
|
||||||
if field := sch.LookUpField(column); field != nil && field.Readable {
|
if field := sch.LookUpField(column); field != nil && field.Readable {
|
||||||
if curIndex, ok := selectedColumnsMap[column]; ok {
|
if curIndex, ok := selectedColumnsMap[column]; ok {
|
||||||
for fieldIndex, selectField := range sch.Fields[curIndex+1:] {
|
fields[idx] = field // handle duplicate fields
|
||||||
if selectField.DBName == column && selectField.Readable {
|
offset := curIndex + 1
|
||||||
selectedColumnsMap[column] = curIndex + fieldIndex + 1
|
// handle sch inconsistent with database
|
||||||
fields[idx] = selectField
|
// like Raw(`...`).Scan
|
||||||
break
|
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 {
|
} else {
|
||||||
|
@ -476,6 +476,13 @@ func TestOmitWithCreate(t *testing.T) {
|
|||||||
CheckUser(t, result2, user2)
|
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) {
|
func TestFirstOrCreateWithPrimaryKey(t *testing.T) {
|
||||||
company := Company{ID: 100, Name: "company100_with_primarykey"}
|
company := Company{ID: 100, Name: "company100_with_primarykey"}
|
||||||
DB.FirstOrCreate(&company)
|
DB.FirstOrCreate(&company)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/schema"
|
"gorm.io/gorm/schema"
|
||||||
. "gorm.io/gorm/utils/tests"
|
. "gorm.io/gorm/utils/tests"
|
||||||
@ -848,3 +849,38 @@ func findColumnType(dest interface{}, columnName string) (
|
|||||||
}
|
}
|
||||||
return
|
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 {
|
if !addressMatched {
|
||||||
t.Errorf("Failed, no address matched")
|
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 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() {
|
func init() {
|
||||||
var err error
|
var err error
|
||||||
@ -49,13 +54,13 @@ func OpenTestConnection() (db *gorm.DB, err error) {
|
|||||||
case "mysql":
|
case "mysql":
|
||||||
log.Println("testing mysql...")
|
log.Println("testing mysql...")
|
||||||
if dbDSN == "" {
|
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{})
|
db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{})
|
||||||
case "postgres":
|
case "postgres":
|
||||||
log.Println("testing postgres...")
|
log.Println("testing postgres...")
|
||||||
if dbDSN == "" {
|
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{
|
db, err = gorm.Open(postgres.New(postgres.Config{
|
||||||
DSN: dbDSN,
|
DSN: dbDSN,
|
||||||
@ -72,7 +77,7 @@ func OpenTestConnection() (db *gorm.DB, err error) {
|
|||||||
// GO
|
// GO
|
||||||
log.Println("testing sqlserver...")
|
log.Println("testing sqlserver...")
|
||||||
if dbDSN == "" {
|
if dbDSN == "" {
|
||||||
dbDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
|
dbDSN = sqlserverDSN
|
||||||
}
|
}
|
||||||
db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{})
|
db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{})
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user