mirror of https://github.com/go-gorm/gorm.git
Make FirstOrInit FirstOrCreate works!
This commit is contained in:
parent
94bd2eb8d5
commit
1ecf9d76be
13
chain.go
13
chain.go
|
@ -171,24 +171,29 @@ func (s *Chain) Exec(sql string) *Chain {
|
||||||
func (s *Chain) First(out interface{}, where ...interface{}) *Chain {
|
func (s *Chain) First(out interface{}, where ...interface{}) *Chain {
|
||||||
do := s.do(out)
|
do := s.do(out)
|
||||||
do.limitStr = "1"
|
do.limitStr = "1"
|
||||||
do.query(where...)
|
do.where(where...).query()
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Chain) FirstOrInit(out interface{}, where ...interface{}) *Chain {
|
func (s *Chain) FirstOrInit(out interface{}, where ...interface{}) *Chain {
|
||||||
if s.First(out).Error != nil {
|
if s.First(out, where...).Error != nil {
|
||||||
s.do(out).initializedWithSearchCondition()
|
s.do(out).where(where...).initializeWithSearchCondition()
|
||||||
s.deleteLastError()
|
s.deleteLastError()
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Chain) FirstOrCreate(out interface{}, where ...interface{}) *Chain {
|
func (s *Chain) FirstOrCreate(out interface{}, where ...interface{}) *Chain {
|
||||||
|
if s.First(out, where...).Error != nil {
|
||||||
|
s.do(out).where(where...).initializeWithSearchCondition()
|
||||||
|
s.deleteLastError()
|
||||||
|
s.Save(out)
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Chain) Find(out interface{}, where ...interface{}) *Chain {
|
func (s *Chain) Find(out interface{}, where ...interface{}) *Chain {
|
||||||
s.do(out).query(where...)
|
s.do(out).where(where...).query()
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
do.go
16
do.go
|
@ -206,11 +206,7 @@ func (s *Do) prepareQuerySql() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Do) query(where ...interface{}) {
|
func (s *Do) query() {
|
||||||
if len(where) > 0 {
|
|
||||||
s.where(where[0], where[1:len(where)]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
is_slice bool
|
is_slice bool
|
||||||
dest_type reflect.Type
|
dest_type reflect.Type
|
||||||
|
@ -320,9 +316,11 @@ func (s *Do) pluck(column string, value interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Do) where(querystring interface{}, args ...interface{}) {
|
func (s *Do) where(where ...interface{}) *Do {
|
||||||
s.whereClause = append(s.whereClause, map[string]interface{}{"query": querystring, "args": args})
|
if len(where) > 0 {
|
||||||
return
|
s.whereClause = append(s.whereClause, map[string]interface{}{"query": where[0], "args": where[1:len(where)]})
|
||||||
|
}
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Do) primaryCondiation(value interface{}) string {
|
func (s *Do) primaryCondiation(value interface{}) string {
|
||||||
|
@ -466,7 +464,7 @@ func (s *Do) createTable() *Do {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Do) initializedWithSearchCondition() {
|
func (s *Do) initializeWithSearchCondition() {
|
||||||
m := Model{data: s.value, driver: s.driver}
|
m := Model{data: s.value, driver: s.driver}
|
||||||
|
|
||||||
for _, clause := range s.whereClause {
|
for _, clause := range s.whereClause {
|
||||||
|
|
27
gorm_test.go
27
gorm_test.go
|
@ -800,14 +800,27 @@ func TestSoftDelete(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFindOrInitialize(t *testing.T) {
|
func TestFindOrInitialize(t *testing.T) {
|
||||||
var user1 User
|
var user1, user2 User
|
||||||
db.Where(&User{Name: "hello world", Age: 33}).FirstOrInit(&user1)
|
db.Where(&User{Name: "find or init", Age: 33}).FirstOrInit(&user1)
|
||||||
if user1.Name != "hello world" || user1.Id != 0 || user1.Age != 33 {
|
if user1.Name != "find or init" || user1.Id != 0 || user1.Age != 33 {
|
||||||
t.Errorf("user should be initialized with search value")
|
t.Errorf("user should be initialized with search value")
|
||||||
}
|
}
|
||||||
|
|
||||||
// db.FirstOrInit(&user2, map[string]interface{}{"name": "hahaha"})
|
db.FirstOrInit(&user2, map[string]interface{}{"name": "find or init 2"})
|
||||||
// if user2.Name != "hahaha" || user2.Id != 0 {
|
if user2.Name != "find or init 2" || user2.Id != 0 {
|
||||||
// t.Errorf("user should be initialized with search value")
|
t.Errorf("user should be initialized with inline search value")
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindOrCreate(t *testing.T) {
|
||||||
|
var user1, user2 User
|
||||||
|
db.Where(&User{Name: "find or create", Age: 33}).FirstOrCreate(&user1)
|
||||||
|
if user1.Name != "find or create" || user1.Id == 0 || user1.Age != 33 {
|
||||||
|
t.Errorf("user should be created with search value")
|
||||||
|
}
|
||||||
|
|
||||||
|
db.FirstOrCreate(&user2, map[string]interface{}{"name": "find or create 2"})
|
||||||
|
if user2.Name != "find or create 2" || user2.Id == 0 {
|
||||||
|
t.Errorf("user should be created with inline search value")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue