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>
This commit is contained in:
		
							parent
							
								
									775fa70af5
								
							
						
					
					
						commit
						1935eb0adb
					
				| @ -185,7 +185,7 @@ func BuildQuerySQL(db *gorm.DB) { | |||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					fromClause.Joins = append(fromClause.Joins, clause.Join{ | 					fromClause.Joins = append(fromClause.Joins, clause.Join{ | ||||||
| 						Type:  clause.LeftJoin, | 						Type:  join.JoinType, | ||||||
| 						Table: clause.Table{Name: relation.FieldSchema.Table, Alias: tableAliasName}, | 						Table: clause.Table{Name: relation.FieldSchema.Table, Alias: tableAliasName}, | ||||||
| 						ON:    clause.Where{Exprs: exprs}, | 						ON:    clause.Where{Exprs: exprs}, | ||||||
| 					}) | 					}) | ||||||
|  | |||||||
| @ -235,6 +235,16 @@ func (db *DB) Or(query interface{}, args ...interface{}) (tx *DB) { | |||||||
| //	db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Find(&user)
 | //	db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Find(&user)
 | ||||||
| //	db.Joins("Account", DB.Select("id").Where("user_id = users.id AND name = ?", "someName").Model(&Account{}))
 | //	db.Joins("Account", DB.Select("id").Where("user_id = users.id AND name = ?", "someName").Model(&Account{}))
 | ||||||
| func (db *DB) Joins(query string, args ...interface{}) (tx *DB) { | func (db *DB) Joins(query string, args ...interface{}) (tx *DB) { | ||||||
|  | 	return joins(db, clause.LeftJoin, query, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InnerJoins specify inner joins conditions
 | ||||||
|  | // db.InnerJoins("Account").Find(&user)
 | ||||||
|  | func (db *DB) InnerJoins(query string, args ...interface{}) (tx *DB) { | ||||||
|  | 	return joins(db, clause.InnerJoin, query, args...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func joins(db *DB, joinType clause.JoinType, query string, args ...interface{}) (tx *DB) { | ||||||
| 	tx = db.getInstance() | 	tx = db.getInstance() | ||||||
| 
 | 
 | ||||||
| 	if len(args) == 1 { | 	if len(args) == 1 { | ||||||
| @ -248,7 +258,7 @@ func (db *DB) Joins(query string, args ...interface{}) (tx *DB) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	tx.Statement.Joins = append(tx.Statement.Joins, join{Name: query, Conds: args}) | 	tx.Statement.Joins = append(tx.Statement.Joins, join{Name: query, Conds: args, JoinType: joinType}) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -54,6 +54,7 @@ type join struct { | |||||||
| 	On       *clause.Where | 	On       *clause.Where | ||||||
| 	Selects  []string | 	Selects  []string | ||||||
| 	Omits    []string | 	Omits    []string | ||||||
|  | 	JoinType clause.JoinType | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // StatementModifier statement modifier interface
 | // StatementModifier statement modifier interface
 | ||||||
|  | |||||||
| @ -230,6 +230,28 @@ func TestJoinWithSoftDeleted(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func TestInnerJoins(t *testing.T) { | ||||||
|  | 	user := *GetUser("inner-joins-1", Config{Company: true, Manager: true, Account: true, NamedPet: false}) | ||||||
|  | 
 | ||||||
|  | 	DB.Create(&user) | ||||||
|  | 
 | ||||||
|  | 	var user2 User | ||||||
|  | 	var err error | ||||||
|  | 	err = DB.InnerJoins("Company").InnerJoins("Manager").InnerJoins("Account").First(&user2, "users.name = ?", user.Name).Error | ||||||
|  | 	AssertEqual(t, err, nil) | ||||||
|  | 	CheckUser(t, user2, user) | ||||||
|  | 
 | ||||||
|  | 	// inner join and NamedPet is nil
 | ||||||
|  | 	err = DB.InnerJoins("NamedPet").InnerJoins("Company").InnerJoins("Manager").InnerJoins("Account").First(&user2, "users.name = ?", user.Name).Error | ||||||
|  | 	AssertEqual(t, err, gorm.ErrRecordNotFound) | ||||||
|  | 
 | ||||||
|  | 	// mixed inner join and left join
 | ||||||
|  | 	var user3 User | ||||||
|  | 	err = DB.Joins("NamedPet").InnerJoins("Company").InnerJoins("Manager").InnerJoins("Account").First(&user3, "users.name = ?", user.Name).Error | ||||||
|  | 	AssertEqual(t, err, nil) | ||||||
|  | 	CheckUser(t, user3, user) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestJoinWithSameColumnName(t *testing.T) { | func TestJoinWithSameColumnName(t *testing.T) { | ||||||
| 	user := GetUser("TestJoinWithSameColumnName", Config{ | 	user := GetUser("TestJoinWithSameColumnName", Config{ | ||||||
| 		Languages: 1, | 		Languages: 1, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Cr
						Cr