forked from mirror/gorm
Joins support parameters, close #673
This commit is contained in:
parent
5883c70478
commit
115789960a
|
@ -929,7 +929,7 @@ db.Table("users").Select("users.name, emails.email").Joins("left join emails on
|
||||||
db.Joins("inner join emails on emails.user_id = users.id").Where("emails.email = ?", "x@example.org").Find(&user)
|
db.Joins("inner join emails on emails.user_id = users.id").Where("emails.email = ?", "x@example.org").Find(&user)
|
||||||
|
|
||||||
// find all email addresses for a user
|
// find all email addresses for a user
|
||||||
db.Joins("left join users on users.id = emails.user_id").Where("users.name = ?", "jinzhu").Find(&emails)
|
db.Joins("LEFT JOIN users ON users.id = emails.user_id AND users.name = ?", "jinzhu").Find(&emails)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Transactions
|
## Transactions
|
||||||
|
|
4
main.go
4
main.go
|
@ -171,8 +171,8 @@ func (s *DB) Having(query string, values ...interface{}) *DB {
|
||||||
return s.clone().search.Having(query, values...).db
|
return s.clone().search.Having(query, values...).db
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DB) Joins(query string) *DB {
|
func (s *DB) Joins(query string, args ...interface{}) *DB {
|
||||||
return s.clone().search.Joins(query).db
|
return s.clone().search.Joins(query, args...).db
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
|
func (s *DB) Scopes(funcs ...func(*DB) *DB) *DB {
|
||||||
|
|
14
main_test.go
14
main_test.go
|
@ -506,10 +506,16 @@ func TestJoins(t *testing.T) {
|
||||||
}
|
}
|
||||||
DB.Save(&user)
|
DB.Save(&user)
|
||||||
|
|
||||||
var result User
|
var users1 []User
|
||||||
DB.Joins("left join emails on emails.user_id = users.id").Where("name = ?", "joins").First(&result)
|
DB.Joins("left join emails on emails.user_id = users.id").Where("name = ?", "joins").Find(&users1)
|
||||||
if result.Name != "joins" || result.Id != user.Id {
|
if len(users1) != 2 {
|
||||||
t.Errorf("Should find all two emails with Join")
|
t.Errorf("should find two users using left join")
|
||||||
|
}
|
||||||
|
|
||||||
|
var users2 []User
|
||||||
|
DB.Joins("left join emails on emails.user_id = users.id AND emails.email = ?", "join1@example.com").Where("name = ?", "joins").First(&users2)
|
||||||
|
if len(users2) != 1 {
|
||||||
|
t.Errorf("should find one users using left join with conditions")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@ var hasCountRegexp = regexp.MustCompile(`(?i)count\(.+\)`)
|
||||||
|
|
||||||
func (scope *Scope) selectSql() string {
|
func (scope *Scope) selectSql() string {
|
||||||
if len(scope.Search.selects) == 0 {
|
if len(scope.Search.selects) == 0 {
|
||||||
if scope.Search.joins != "" {
|
if len(scope.Search.joinConditions) > 0 {
|
||||||
return fmt.Sprintf("%v.*", scope.QuotedTableName())
|
return fmt.Sprintf("%v.*", scope.QuotedTableName())
|
||||||
}
|
}
|
||||||
return "*"
|
return "*"
|
||||||
|
@ -263,12 +263,11 @@ func (scope *Scope) groupSql() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scope *Scope) havingSql() string {
|
func (scope *Scope) havingSql() string {
|
||||||
if scope.Search.havingConditions == nil {
|
if len(scope.Search.havingConditions) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var andConditions []string
|
var andConditions []string
|
||||||
|
|
||||||
for _, clause := range scope.Search.havingConditions {
|
for _, clause := range scope.Search.havingConditions {
|
||||||
if sql := scope.buildWhereCondition(clause); sql != "" {
|
if sql := scope.buildWhereCondition(clause); sql != "" {
|
||||||
andConditions = append(andConditions, sql)
|
andConditions = append(andConditions, sql)
|
||||||
|
@ -284,7 +283,14 @@ func (scope *Scope) havingSql() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scope *Scope) joinsSql() string {
|
func (scope *Scope) joinsSql() string {
|
||||||
return scope.Search.joins + " "
|
var joinConditions []string
|
||||||
|
for _, clause := range scope.Search.joinConditions {
|
||||||
|
if sql := scope.buildWhereCondition(clause); sql != "" {
|
||||||
|
joinConditions = append(joinConditions, strings.TrimSuffix(strings.TrimPrefix(sql, "("), ")"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(joinConditions, " ") + " "
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scope *Scope) prepareQuerySql() {
|
func (scope *Scope) prepareQuerySql() {
|
||||||
|
|
|
@ -8,12 +8,12 @@ type search struct {
|
||||||
orConditions []map[string]interface{}
|
orConditions []map[string]interface{}
|
||||||
notConditions []map[string]interface{}
|
notConditions []map[string]interface{}
|
||||||
havingConditions []map[string]interface{}
|
havingConditions []map[string]interface{}
|
||||||
|
joinConditions []map[string]interface{}
|
||||||
initAttrs []interface{}
|
initAttrs []interface{}
|
||||||
assignAttrs []interface{}
|
assignAttrs []interface{}
|
||||||
selects map[string]interface{}
|
selects map[string]interface{}
|
||||||
omits []string
|
omits []string
|
||||||
orders []string
|
orders []string
|
||||||
joins string
|
|
||||||
preload []searchPreload
|
preload []searchPreload
|
||||||
offset int
|
offset int
|
||||||
limit int
|
limit int
|
||||||
|
@ -102,8 +102,8 @@ func (s *search) Having(query string, values ...interface{}) *search {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *search) Joins(query string) *search {
|
func (s *search) Joins(query string, values ...interface{}) *search {
|
||||||
s.joins = query
|
s.joinConditions = append(s.joinConditions, map[string]interface{}{"query": query, "args": values})
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue