join with conditions
This commit is contained in:
		
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							@@ -2,3 +2,6 @@ run:
 | 
				
			|||||||
	go run ./cmd -o ./example/db ./example/schema.sql
 | 
						go run ./cmd -o ./example/db ./example/schema.sql
 | 
				
			||||||
bench-select:
 | 
					bench-select:
 | 
				
			||||||
	go test ./example -bench BenchmarkSelect -memprofile memprofile.out -cpuprofile profile.out
 | 
						go test ./example -bench BenchmarkSelect -memprofile memprofile.out -cpuprofile profile.out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test:
 | 
				
			||||||
 | 
						go test ./playground
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,7 +60,31 @@ func TestSelectWithHaving(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BenchmarkSelect-12    	  668817	      1753 ns/op	    4442 B/op	      59 allocs/op
 | 
					func TestSelectWithJoin(t *testing.T) {
 | 
				
			||||||
 | 
						got := db.User.Select(user.Email, user.FirstName).
 | 
				
			||||||
 | 
							Join(db.UserSession, user.ID, usersession.UserID).
 | 
				
			||||||
 | 
							LeftJoin(db.BranchUser, user.ID, branchuser.UserID, pgm.Or(branchuser.RoleID.Eq("1"), branchuser.RoleID.Eq("2"))).
 | 
				
			||||||
 | 
							Where(
 | 
				
			||||||
 | 
								user.ID.Eq(3),
 | 
				
			||||||
 | 
								pgm.Or(
 | 
				
			||||||
 | 
									user.StatusID.Eq(4),
 | 
				
			||||||
 | 
									user.UpdatedAt.Eq(5),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
							).
 | 
				
			||||||
 | 
							Limit(10).
 | 
				
			||||||
 | 
							Offset(100).
 | 
				
			||||||
 | 
							String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := "SELECT users.email, users.first_name " +
 | 
				
			||||||
 | 
							"FROM users JOIN user_sessions ON users.id = user_sessions.user_id " +
 | 
				
			||||||
 | 
							"LEFT JOIN branch_users ON users.id = branch_users.user_id AND (branch_users.role_id = $1 OR branch_users.role_id = $2) " +
 | 
				
			||||||
 | 
							"WHERE users.id = $3 AND (users.status_id = $4 OR users.updated_at = $5) " +
 | 
				
			||||||
 | 
							"LIMIT 10 OFFSET 100"
 | 
				
			||||||
 | 
						if expected != got {
 | 
				
			||||||
 | 
							t.Errorf("\nexpected: %q\ngot: %q", expected, got)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BenchmarkSelect-12    	  638901	      1860 ns/op	    4266 B/op	      61 allocs/op
 | 
					// BenchmarkSelect-12    	  638901	      1860 ns/op	    4266 B/op	      61 allocs/op
 | 
				
			||||||
func BenchmarkSelect(b *testing.B) {
 | 
					func BenchmarkSelect(b *testing.B) {
 | 
				
			||||||
	for b.Loop() {
 | 
						for b.Loop() {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								qry.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								qry.go
									
									
									
									
									
								
							@@ -21,10 +21,10 @@ type (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	SelectClause interface {
 | 
						SelectClause interface {
 | 
				
			||||||
		// Join and Inner Join are same
 | 
							// Join and Inner Join are same
 | 
				
			||||||
		Join(m Table, t1Field, t2Field Field) SelectClause
 | 
							Join(m Table, t1Field, t2Field Field, cond ...Conditioner) SelectClause
 | 
				
			||||||
		LeftJoin(m Table, t1Field, t2Field Field) SelectClause
 | 
							LeftJoin(m Table, t1Field, t2Field Field, cond ...Conditioner) SelectClause
 | 
				
			||||||
		RightJoin(m Table, t1Field, t2Field Field) SelectClause
 | 
							RightJoin(m Table, t1Field, t2Field Field, cond ...Conditioner) SelectClause
 | 
				
			||||||
		FullJoin(m Table, t1Field, t2Field Field) SelectClause
 | 
							FullJoin(m Table, t1Field, t2Field Field, cond ...Conditioner) SelectClause
 | 
				
			||||||
		CrossJoin(m Table) SelectClause
 | 
							CrossJoin(m Table) SelectClause
 | 
				
			||||||
		WhereClause
 | 
							WhereClause
 | 
				
			||||||
		OrderByClause
 | 
							OrderByClause
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,23 +62,46 @@ func (t Table) Select(field ...Field) SelectClause {
 | 
				
			|||||||
	return qb
 | 
						return qb
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q *selectQry) Join(t Table, t1Field, t2Field Field) SelectClause {
 | 
					func (q *selectQry) Join(t Table, t1Field, t2Field Field, cond ...Conditioner) SelectClause {
 | 
				
			||||||
	q.join = append(q.join, "JOIN "+t.Name+" ON "+t1Field.String()+" = "+t2Field.String())
 | 
						return q.buildJoin(t, "JOIN", t1Field, t2Field, cond...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *selectQry) LeftJoin(t Table, t1Field, t2Field Field, cond ...Conditioner) SelectClause {
 | 
				
			||||||
 | 
						return q.buildJoin(t, "LEFT JOIN", t1Field, t2Field, cond...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *selectQry) RightJoin(t Table, t1Field, t2Field Field, cond ...Conditioner) SelectClause {
 | 
				
			||||||
 | 
						return q.buildJoin(t, "RIGHT JOIN", t1Field, t2Field, cond...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *selectQry) FullJoin(t Table, t1Field, t2Field Field, cond ...Conditioner) SelectClause {
 | 
				
			||||||
 | 
						return q.buildJoin(t, "FULL JOIN", t1Field, t2Field, cond...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (q *selectQry) buildJoin(t Table, joinKW string, t1Field, t2Field Field, cond ...Conditioner) SelectClause {
 | 
				
			||||||
 | 
						str := joinKW + " " + t.Name + " ON " + t1Field.String() + " = " + t2Field.String()
 | 
				
			||||||
 | 
						if len(cond) == 0 { // Join with no condition
 | 
				
			||||||
 | 
							q.join = append(q.join, str)
 | 
				
			||||||
		return q
 | 
							return q
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q *selectQry) LeftJoin(t Table, t1Field, t2Field Field) SelectClause {
 | 
						// Join has condition(s)
 | 
				
			||||||
	q.join = append(q.join, "LEFT JOIN "+t.Name+" ON "+t1Field.String()+" = "+t2Field.String())
 | 
						sb := getSB()
 | 
				
			||||||
	return q
 | 
						defer putSB(sb)
 | 
				
			||||||
 | 
						sb.Grow(len(str) * 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sb.WriteString(str + " AND ")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var argIdx int
 | 
				
			||||||
 | 
						for i, c := range cond {
 | 
				
			||||||
 | 
							argIdx = len(q.args)
 | 
				
			||||||
 | 
							if i > 0 {
 | 
				
			||||||
 | 
								sb.WriteString(" AND ")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							sb.WriteString(c.Condition(&q.args, argIdx))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q *selectQry) RightJoin(t Table, t1Field, t2Field Field) SelectClause {
 | 
						q.join = append(q.join, sb.String())
 | 
				
			||||||
	q.join = append(q.join, "RIGHT JOIN "+t.Name+" ON "+t1Field.String()+" = "+t2Field.String())
 | 
					 | 
				
			||||||
	return q
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (q *selectQry) FullJoin(t Table, t1Field, t2Field Field) SelectClause {
 | 
					 | 
				
			||||||
	q.join = append(q.join, "FULL JOIN "+t.Name+" ON "+t1Field.String()+" = "+t2Field.String())
 | 
					 | 
				
			||||||
	return q
 | 
						return q
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user