From 731b056a56058869b6e7f57b403fcb37049c2496 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 20 Jan 2019 11:53:53 +0800 Subject: [PATCH] Join support builder (#1002) * join support builder * add tests * fix tests * fix tests * fix join sub query --- session_query_test.go | 44 +++++++++++++++++++++++++++++++++++++++++++ statement.go | 27 ++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/session_query_test.go b/session_query_test.go index 5ce89a4a..b644b74e 100644 --- a/session_query_test.go +++ b/session_query_test.go @@ -334,3 +334,47 @@ func TestQueryWithBuilder(t *testing.T) { assert.NoError(t, err) assertResult(t, results) } + +func TestJoinWithSubQuery(t *testing.T) { + assert.NoError(t, prepareEngine()) + + type JoinWithSubQuery1 struct { + Id int64 `xorm:"autoincr pk"` + Msg string `xorm:"varchar(255)"` + DepartId int64 + Money float32 + } + + type JoinWithSubQueryDepart struct { + Id int64 `xorm:"autoincr pk"` + Name string + } + + testEngine.ShowSQL(true) + + assert.NoError(t, testEngine.Sync2(new(JoinWithSubQuery1), new(JoinWithSubQueryDepart))) + + var depart = JoinWithSubQueryDepart{ + Name: "depart1", + } + cnt, err := testEngine.Insert(&depart) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + var q = JoinWithSubQuery1{ + Msg: "message", + DepartId: depart.Id, + Money: 3000, + } + + cnt, err = testEngine.Insert(&q) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + var querys []JoinWithSubQuery1 + err = testEngine.Join("INNER", builder.Select("id").From(testEngine.Quote(testEngine.TableName("join_with_sub_query_depart", true))), + "join_with_sub_query_depart.id = join_with_sub_query1.depart_id").Find(&querys) + assert.NoError(t, err) + assert.EqualValues(t, 1, len(querys)) + assert.EqualValues(t, q, querys[0]) +} diff --git a/statement.go b/statement.go index ec43ce56..cd59c376 100644 --- a/statement.go +++ b/statement.go @@ -757,9 +757,32 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition fmt.Fprintf(&buf, "%v JOIN ", joinOP) } - tbName := statement.Engine.TableName(tablename, true) + switch tp := tablename.(type) { + case builder.Builder: + subSQL, subQueryArgs, err := tp.ToSQL() + if err != nil { + statement.lastError = err + return statement + } + tbs := strings.Split(tp.TableName(), ".") + var aliasName = strings.Trim(tbs[len(tbs)-1], statement.Engine.QuoteStr()) + fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition) + statement.joinArgs = append(statement.joinArgs, subQueryArgs...) + case *builder.Builder: + subSQL, subQueryArgs, err := tp.ToSQL() + if err != nil { + statement.lastError = err + return statement + } + tbs := strings.Split(tp.TableName(), ".") + var aliasName = strings.Trim(tbs[len(tbs)-1], statement.Engine.QuoteStr()) + fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition) + statement.joinArgs = append(statement.joinArgs, subQueryArgs...) + default: + tbName := statement.Engine.TableName(tablename, true) + fmt.Fprintf(&buf, "%s ON %v", tbName, condition) + } - fmt.Fprintf(&buf, "%s ON %v", tbName, condition) statement.JoinStr = buf.String() statement.joinArgs = append(statement.joinArgs, args...) return statement