Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1935eb0

Browse files
a631807682jinzhu
andauthoredDec 24, 2022
feat: support inner join (#5583)
* feat: support inner join * test: mixed inner join and left join * chore: code comment * Update statement.go Co-authored-by: Jinzhu <wosmvp@gmail.com>
1 parent 775fa70 commit 1935eb0

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed
 

‎callbacks/query.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func BuildQuerySQL(db *gorm.DB) {
185185
}
186186

187187
fromClause.Joins = append(fromClause.Joins, clause.Join{
188-
Type: clause.LeftJoin,
188+
Type: join.JoinType,
189189
Table: clause.Table{Name: relation.FieldSchema.Table, Alias: tableAliasName},
190190
ON: clause.Where{Exprs: exprs},
191191
})

‎chainable_api.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,16 @@ func (db *DB) Or(query interface{}, args ...interface{}) (tx *DB) {
235235
// db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Find(&user)
236236
// db.Joins("Account", DB.Select("id").Where("user_id = users.id AND name = ?", "someName").Model(&Account{}))
237237
func (db *DB) Joins(query string, args ...interface{}) (tx *DB) {
238+
return joins(db, clause.LeftJoin, query, args...)
239+
}
240+
241+
// InnerJoins specify inner joins conditions
242+
// db.InnerJoins("Account").Find(&user)
243+
func (db *DB) InnerJoins(query string, args ...interface{}) (tx *DB) {
244+
return joins(db, clause.InnerJoin, query, args...)
245+
}
246+
247+
func joins(db *DB, joinType clause.JoinType, query string, args ...interface{}) (tx *DB) {
238248
tx = db.getInstance()
239249

240250
if len(args) == 1 {
@@ -248,7 +258,7 @@ func (db *DB) Joins(query string, args ...interface{}) (tx *DB) {
248258
}
249259
}
250260

251-
tx.Statement.Joins = append(tx.Statement.Joins, join{Name: query, Conds: args})
261+
tx.Statement.Joins = append(tx.Statement.Joins, join{Name: query, Conds: args, JoinType: joinType})
252262
return
253263
}
254264

‎statement.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,12 @@ type Statement struct {
4949
}
5050

5151
type join struct {
52-
Name string
53-
Conds []interface{}
54-
On *clause.Where
55-
Selects []string
56-
Omits []string
52+
Name string
53+
Conds []interface{}
54+
On *clause.Where
55+
Selects []string
56+
Omits []string
57+
JoinType clause.JoinType
5758
}
5859

5960
// StatementModifier statement modifier interface

‎tests/joins_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,28 @@ func TestJoinWithSoftDeleted(t *testing.T) {
230230
}
231231
}
232232

233+
func TestInnerJoins(t *testing.T) {
234+
user := *GetUser("inner-joins-1", Config{Company: true, Manager: true, Account: true, NamedPet: false})
235+
236+
DB.Create(&user)
237+
238+
var user2 User
239+
var err error
240+
err = DB.InnerJoins("Company").InnerJoins("Manager").InnerJoins("Account").First(&user2, "users.name = ?", user.Name).Error
241+
AssertEqual(t, err, nil)
242+
CheckUser(t, user2, user)
243+
244+
// inner join and NamedPet is nil
245+
err = DB.InnerJoins("NamedPet").InnerJoins("Company").InnerJoins("Manager").InnerJoins("Account").First(&user2, "users.name = ?", user.Name).Error
246+
AssertEqual(t, err, gorm.ErrRecordNotFound)
247+
248+
// mixed inner join and left join
249+
var user3 User
250+
err = DB.Joins("NamedPet").InnerJoins("Company").InnerJoins("Manager").InnerJoins("Account").First(&user3, "users.name = ?", user.Name).Error
251+
AssertEqual(t, err, nil)
252+
CheckUser(t, user3, user)
253+
}
254+
233255
func TestJoinWithSameColumnName(t *testing.T) {
234256
user := GetUser("TestJoinWithSameColumnName", Config{
235257
Languages: 1,

0 commit comments

Comments
 (0)
Please sign in to comment.