Browse Source

Join support builder

* join support builder

* add tests

* fix tests

* fix tests

* fix join sub query
xormplus 6 years ago
parent
commit
497b4c3aee
2 changed files with 69 additions and 2 deletions
  1. 44 0
      session_query_test.go
  2. 25 2
      statement.go

+ 44 - 0
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])
+}

+ 25 - 2
statement.go

@@ -786,9 +786,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