From a2b98adead91dab9ff22c8b7905454066da2bd1f Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Tue, 31 Jan 2023 19:58:01 +0800 Subject: [PATCH] Implement clause.Expression interface for field.Expr (#750) --- do.go | 25 ++++++++++++++++++------- field/expr.go | 16 ++++++++++------ tests/go.mod | 14 ++++++++------ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/do.go b/do.go index f84b0e84..ebe07753 100644 --- a/do.go +++ b/do.go @@ -256,11 +256,16 @@ func (d *DO) Order(columns ...field.Expr) Dao { func (d *DO) toOrderValue(columns ...field.Expr) string { // eager build Columns - orderArray := make([]string, len(columns)) + stmt := &gorm.Statement{DB: d.db.Statement.DB, Table: d.db.Statement.Table, Schema: d.db.Statement.Schema} + for i, c := range columns { - orderArray[i] = c.Build(d.db.Statement).String() + if i != 0 { + stmt.WriteByte(',') + } + c.Build(stmt) } - return strings.Join(orderArray, ",") + + return stmt.SQL.String() } // Distinct ... @@ -281,11 +286,17 @@ func (d *DO) Group(columns ...field.Expr) Dao { if len(columns) == 0 { return d } - name := string(columns[0].Build(d.db.Statement)) - for _, col := range columns[1:] { - name += "," + string(col.Build(d.db.Statement)) + + stmt := &gorm.Statement{DB: d.db.Statement.DB, Table: d.db.Statement.Table, Schema: d.db.Statement.Schema} + + for i, c := range columns { + if i != 0 { + stmt.WriteByte(',') + } + c.Build(stmt) } - return d.getInstance(d.db.Group(name)) + + return d.getInstance(d.db.Group(stmt.SQL.String())) } // Having ... diff --git a/field/expr.go b/field/expr.go index 8e2747a4..2b2a71d0 100644 --- a/field/expr.go +++ b/field/expr.go @@ -18,10 +18,12 @@ type AssignExpr interface { // Expr a query expression about field type Expr interface { + // Clause Expression interface + Build(clause.Builder) + As(alias string) Expr ColumnName() sql BuildColumn(*gorm.Statement, ...BuildOpt) sql - Build(*gorm.Statement) sql BuildWithArgs(*gorm.Statement) (query sql, args []interface{}) RawExpr() expression @@ -110,13 +112,15 @@ func (e expr) BuildColumn(stmt *gorm.Statement, opts ...BuildOpt) sql { return sql(stmt.Quote(col)) } -func (e expr) Build(stmt *gorm.Statement) sql { +func (e expr) Build(builder clause.Builder) { if e.e == nil { - return sql(e.BuildColumn(stmt, WithAll)) + if stmt, ok := builder.(*gorm.Statement); ok { + builder.WriteString(string(e.BuildColumn(stmt, WithAll))) + return + } } - newStmt := &gorm.Statement{DB: stmt.DB, Table: stmt.Table, Schema: stmt.Schema} - e.e.Build(newStmt) - return sql(newStmt.SQL.String()) + + e.e.Build(builder) } func (e expr) BuildWithArgs(stmt *gorm.Statement) (sql, []interface{}) { diff --git a/tests/go.mod b/tests/go.mod index 827e4db6..b9c58522 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -3,13 +3,15 @@ module gorm.io/gen/tests go 1.16 require ( - golang.org/x/mod v0.6.0 // indirect - gorm.io/driver/mysql v1.4.3 - gorm.io/driver/sqlite v1.4.3 - gorm.io/gen v0.3.16 - gorm.io/gorm v1.24.0 + github.com/mattn/go-sqlite3 v1.14.16 // indirect + golang.org/x/tools v0.5.0 // indirect + gorm.io/datatypes v1.1.0 // indirect + gorm.io/driver/mysql v1.4.5 + gorm.io/driver/sqlite v1.4.4 + gorm.io/gen v0.3.19 + gorm.io/gorm v1.24.3 gorm.io/hints v1.1.1 // indirect - gorm.io/plugin/dbresolver v1.3.0 + gorm.io/plugin/dbresolver v1.4.0 ) replace gorm.io/gen => ../