1
0
Эх сурвалжийг харах

Fix issue 1205 (#1211)

* fix #1205

* move builder into stores

* remove xrom

* Remove unused code

* Remove unused code

* refactor builderx to builder

Co-authored-by: anqiansong <anqiansong@bytedance.com>
anqiansong 3 жил өмнө
parent
commit
69a4d213a3

+ 63 - 0
core/stores/builder/builder.go

@@ -0,0 +1,63 @@
+package builder
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+)
+
+const dbTag = "db"
+
+// RawFieldNames converts golang struct field into slice string.
+func RawFieldNames(in interface{}, postgresSql ...bool) []string {
+	out := make([]string, 0)
+	v := reflect.ValueOf(in)
+	if v.Kind() == reflect.Ptr {
+		v = v.Elem()
+	}
+
+	var pg bool
+	if len(postgresSql) > 0 {
+		pg = postgresSql[0]
+	}
+
+	// we only accept structs
+	if v.Kind() != reflect.Struct {
+		panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
+	}
+
+	typ := v.Type()
+	for i := 0; i < v.NumField(); i++ {
+		// gets us a StructField
+		fi := typ.Field(i)
+		if tagv := fi.Tag.Get(dbTag); tagv != "" {
+			if pg {
+				out = append(out, tagv)
+			} else {
+				out = append(out, fmt.Sprintf("`%s`", tagv))
+			}
+		} else {
+			if pg {
+				out = append(out, fi.Name)
+			} else {
+				out = append(out, fmt.Sprintf("`%s`", fi.Name))
+			}
+		}
+	}
+
+	return out
+}
+
+// PostgreSqlJoin concatenates the given elements into a string.
+func PostgreSqlJoin(elems []string) string {
+	b := new(strings.Builder)
+	for index, e := range elems {
+		b.WriteString(fmt.Sprintf("%s = $%d, ", e, index+2))
+	}
+
+	if b.Len() == 0 {
+		return b.String()
+	}
+
+	return b.String()[0 : b.Len()-2]
+}

+ 24 - 0
core/stores/builder/builder_test.go

@@ -0,0 +1,24 @@
+package builder
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+type mockedUser struct {
+	ID       string `db:"id" json:"id,omitempty"`
+	UserName string `db:"user_name" json:"userName,omitempty"`
+	Sex      int    `db:"sex" json:"sex,omitempty"`
+	UUID     string `db:"uuid" uuid:"uuid,omitempty"`
+	Age      int    `db:"age" json:"age"`
+}
+
+func TestFieldNames(t *testing.T) {
+	t.Run("new", func(t *testing.T) {
+		var u mockedUser
+		out := RawFieldNames(&u)
+		expected := []string{"`id`", "`user_name`", "`sex`", "`uuid`", "`age`"}
+		assert.Equal(t, expected, out)
+	})
+}

+ 0 - 1
go.mod

@@ -13,7 +13,6 @@ require (
 	github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8
 	github.com/go-redis/redis v6.15.9+incompatible
 	github.com/go-sql-driver/mysql v1.6.0
-	github.com/go-xorm/builder v0.3.4
 	github.com/golang-jwt/jwt v3.2.1+incompatible
 	github.com/golang/mock v1.6.0
 	github.com/google/uuid v1.3.0

+ 0 - 4
go.sum

@@ -154,10 +154,6 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC
 github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
-github.com/go-xorm/builder v0.3.4 h1:FxkeGB4Cggdw3tPwutLCpfjng2jugfkg6LDMrd/KsoY=
-github.com/go-xorm/builder v0.3.4/go.mod h1:KxkQkNN1DpPKTedxXyTQcmH+rXfvk4LZ9SOOBoZBAxw=
-github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
-github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=

+ 7 - 123
tools/goctl/model/sql/builderx/builder.go

@@ -1,136 +1,20 @@
 package builderx
 
 import (
-	"fmt"
-	"reflect"
-	"strings"
-
-	"github.com/go-xorm/builder"
+	"github.com/tal-tech/go-zero/core/stores/builder"
 )
 
-const dbTag = "db"
-
-// NewEq wraps builder.Eq.
-func NewEq(in interface{}) builder.Eq {
-	return builder.Eq(ToMap(in))
-}
-
-// NewGt wraps builder.Gt.
-func NewGt(in interface{}) builder.Gt {
-	return builder.Gt(ToMap(in))
-}
-
-// ToMap converts interface into map.
-func ToMap(in interface{}) map[string]interface{} {
-	out := make(map[string]interface{})
-	v := reflect.ValueOf(in)
-	if v.Kind() == reflect.Ptr {
-		v = v.Elem()
-	}
-
-	// we only accept structs
-	if v.Kind() != reflect.Struct {
-		panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
-	}
-
-	typ := v.Type()
-	for i := 0; i < v.NumField(); i++ {
-		// gets us a StructField
-		fi := typ.Field(i)
-		if tagv := fi.Tag.Get(dbTag); tagv != "" {
-			// set key of map to value in struct field
-			val := v.Field(i)
-			zero := reflect.Zero(val.Type()).Interface()
-			current := val.Interface()
-
-			if reflect.DeepEqual(current, zero) {
-				continue
-			}
-			out[tagv] = current
-		}
-	}
-
-	return out
-}
-
-// FieldNames returns field names from given in.
-// deprecated: use RawFieldNames instead automatically while model generating after goctl version v1.1.0
+// Deprecated: Use github.com/tal-tech/go-zero/core/stores/builder.RawFieldNames instead.
 func FieldNames(in interface{}) []string {
-	out := make([]string, 0)
-	v := reflect.ValueOf(in)
-	if v.Kind() == reflect.Ptr {
-		v = v.Elem()
-	}
-
-	// we only accept structs
-	if v.Kind() != reflect.Struct {
-		panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
-	}
-
-	typ := v.Type()
-	for i := 0; i < v.NumField(); i++ {
-		// gets us a StructField
-		fi := typ.Field(i)
-		if tagv := fi.Tag.Get(dbTag); tagv != "" {
-			out = append(out, tagv)
-		} else {
-			out = append(out, fi.Name)
-		}
-	}
-
-	return out
+	return builder.RawFieldNames(in)
 }
 
-// RawFieldNames converts golang struct field into slice string.
+// Deprecated: Use github.com/tal-tech/go-zero/core/stores/builder.RawFieldNames instead.
 func RawFieldNames(in interface{}, postgresSql ...bool) []string {
-	out := make([]string, 0)
-	v := reflect.ValueOf(in)
-	if v.Kind() == reflect.Ptr {
-		v = v.Elem()
-	}
-
-	var pg bool
-	if len(postgresSql) > 0 {
-		pg = postgresSql[0]
-	}
-
-	// we only accept structs
-	if v.Kind() != reflect.Struct {
-		panic(fmt.Errorf("ToMap only accepts structs; got %T", v))
-	}
-
-	typ := v.Type()
-	for i := 0; i < v.NumField(); i++ {
-		// gets us a StructField
-		fi := typ.Field(i)
-		if tagv := fi.Tag.Get(dbTag); tagv != "" {
-			if pg {
-				out = append(out, tagv)
-			} else {
-				out = append(out, fmt.Sprintf("`%s`", tagv))
-			}
-		} else {
-			if pg {
-				out = append(out, fi.Name)
-			} else {
-				out = append(out, fmt.Sprintf("`%s`", fi.Name))
-			}
-		}
-	}
-
-	return out
+	return builder.RawFieldNames(in, postgresSql...)
 }
 
-// PostgreSqlJoin concatenates the given elements into a string.
+// Deprecated: Use github.com/tal-tech/go-zero/core/stores/builderx.PostgreSqlJoin instead.
 func PostgreSqlJoin(elems []string) string {
-	b := new(strings.Builder)
-	for index, e := range elems {
-		b.WriteString(fmt.Sprintf("%s = $%d, ", e, index+2))
-	}
-
-	if b.Len() == 0 {
-		return b.String()
-	}
-
-	return b.String()[0 : b.Len()-2]
+	return builder.PostgreSqlJoin(elems)
 }

+ 0 - 125
tools/goctl/model/sql/builderx/builder_test.go

@@ -1,125 +0,0 @@
-package builderx
-
-import (
-	"fmt"
-	"testing"
-
-	"github.com/go-xorm/builder"
-	"github.com/stretchr/testify/assert"
-)
-
-type mockedUser struct {
-	// 自增id
-	ID string `db:"id" json:"id,omitempty"`
-	// 姓名
-	UserName string `db:"user_name" json:"userName,omitempty"`
-	// 1男,2女
-	Sex  int    `db:"sex" json:"sex,omitempty"`
-	UUID string `db:"uuid" uuid:"uuid,omitempty"`
-	Age  int    `db:"age" json:"age"`
-}
-
-var (
-	userFieldsWithRawStringQuote    = RawFieldNames(mockedUser{})
-	userFieldsWithoutRawStringQuote = FieldNames(mockedUser{})
-)
-
-func TestFieldNames(t *testing.T) {
-	t.Run("old", func(t *testing.T) {
-		var u mockedUser
-		out := FieldNames(&u)
-		expected := []string{"id", "user_name", "sex", "uuid", "age"}
-		assert.Equal(t, expected, out)
-	})
-
-	t.Run("new", func(t *testing.T) {
-		var u mockedUser
-		out := RawFieldNames(&u)
-		expected := []string{"`id`", "`user_name`", "`sex`", "`uuid`", "`age`"}
-		assert.Equal(t, expected, out)
-	})
-}
-
-func TestNewEq(t *testing.T) {
-	u := &mockedUser{
-		ID:       "123456",
-		UserName: "wahaha",
-	}
-	out := NewEq(u)
-	fmt.Println(out)
-	actual := builder.Eq{"id": "123456", "user_name": "wahaha"}
-	assert.Equal(t, out, actual)
-}
-
-// @see https://github.com/go-xorm/builder
-func TestBuilderSql(t *testing.T) {
-	u := &mockedUser{
-		ID: "123123",
-	}
-	fields := RawFieldNames(u)
-	eq := NewEq(u)
-	sql, args, err := builder.Select(fields...).From("user").Where(eq).ToSQL()
-	fmt.Println(sql, args, err)
-
-	actualSQL := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE id=?"
-	actualArgs := []interface{}{"123123"}
-	assert.Equal(t, sql, actualSQL)
-	assert.Equal(t, args, actualArgs)
-}
-
-func TestBuildSqlDefaultValue(t *testing.T) {
-	eq := builder.Eq{}
-	eq["age"] = 0
-	eq["user_name"] = ""
-
-	t.Run("raw", func(t *testing.T) {
-		sql, args, err := builder.Select(userFieldsWithRawStringQuote...).From("user").Where(eq).ToSQL()
-		fmt.Println(sql, args, err)
-
-		actualSQL := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE age=? AND user_name=?"
-		actualArgs := []interface{}{0, ""}
-		assert.Equal(t, sql, actualSQL)
-		assert.Equal(t, args, actualArgs)
-	})
-
-	t.Run("withour raw quote", func(t *testing.T) {
-		sql, args, err := builder.Select(userFieldsWithoutRawStringQuote...).From("user").Where(eq).ToSQL()
-		fmt.Println(sql, args, err)
-
-		actualSQL := "SELECT id,user_name,sex,uuid,age FROM user WHERE age=? AND user_name=?"
-		actualArgs := []interface{}{0, ""}
-		assert.Equal(t, sql, actualSQL)
-		assert.Equal(t, args, actualArgs)
-	})
-}
-
-func TestBuilderSqlIn(t *testing.T) {
-	u := &mockedUser{
-		Age: 18,
-	}
-	gtU := NewGt(u)
-	in := builder.In("id", []string{"1", "2", "3"})
-	sql, args, err := builder.Select(userFieldsWithRawStringQuote...).From("user").Where(in).And(gtU).ToSQL()
-	fmt.Println(sql, args, err)
-
-	actualSQL := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE id IN (?,?,?) AND age>?"
-	actualArgs := []interface{}{"1", "2", "3", 18}
-	assert.Equal(t, sql, actualSQL)
-	assert.Equal(t, args, actualArgs)
-}
-
-func TestBuildSqlLike(t *testing.T) {
-	like := builder.Like{"name", "wang"}
-	sql, args, err := builder.Select(userFieldsWithRawStringQuote...).From("user").Where(like).ToSQL()
-	fmt.Println(sql, args, err)
-
-	actualSQL := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE name LIKE ?"
-	actualArgs := []interface{}{"%wang%"}
-	assert.Equal(t, sql, actualSQL)
-	assert.Equal(t, args, actualArgs)
-}
-
-func TestJoin(t *testing.T) {
-	ret := PostgreSqlJoin([]string{"name", "age"})
-	assert.Equal(t, "name = $2, age = $3", ret)
-}

+ 2 - 2
tools/goctl/model/sql/template/import.go

@@ -12,7 +12,7 @@ var (
 	"github.com/tal-tech/go-zero/core/stores/sqlc"
 	"github.com/tal-tech/go-zero/core/stores/sqlx"
 	"github.com/tal-tech/go-zero/core/stringx"
-	"github.com/tal-tech/go-zero/tools/goctl/model/sql/builderx"
+	"github.com/tal-tech/go-zero/core/stores/builderx"
 )
 `
 	// ImportsNoCache defines a import template for model in normal case
@@ -25,7 +25,7 @@ var (
 	"github.com/tal-tech/go-zero/core/stores/sqlc"
 	"github.com/tal-tech/go-zero/core/stores/sqlx"
 	"github.com/tal-tech/go-zero/core/stringx"
-	"github.com/tal-tech/go-zero/tools/goctl/model/sql/builderx"
+	"github.com/tal-tech/go-zero/core/stores/builderx"
 )
 `
 )

+ 3 - 3
tools/goctl/model/sql/template/insert.go

@@ -2,7 +2,7 @@ package template
 
 // Insert defines a template for insert code in model
 var Insert = `
-func (m *default{{.upperStartCamelObject}}Model) Insert(data {{.upperStartCamelObject}}) (sql.Result,error) {
+func (m *default{{.upperStartCamelObject}}Model) Insert(data *{{.upperStartCamelObject}}) (sql.Result,error) {
 	{{if .withCache}}{{if .containsIndexCache}}{{.keys}}
     ret, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {
 		query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet)
@@ -15,5 +15,5 @@ func (m *default{{.upperStartCamelObject}}Model) Insert(data {{.upperStartCamelO
 }
 `
 
-// InsertMethod defines a interface method template for insert code in model
-var InsertMethod = `Insert(data {{.upperStartCamelObject}}) (sql.Result,error)`
+// InsertMethod defines an interface method template for insert code in model
+var InsertMethod = `Insert(data *{{.upperStartCamelObject}}) (sql.Result,error)`

+ 2 - 2
tools/goctl/model/sql/template/update.go

@@ -2,7 +2,7 @@ package template
 
 // Update defines a template for generating update codes
 var Update = `
-func (m *default{{.upperStartCamelObject}}Model) Update(data {{.upperStartCamelObject}}) error {
+func (m *default{{.upperStartCamelObject}}Model) Update(data *{{.upperStartCamelObject}}) error {
 	{{if .withCache}}{{.keys}}
     _, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {
 		query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
@@ -14,4 +14,4 @@ func (m *default{{.upperStartCamelObject}}Model) Update(data {{.upperStartCamelO
 `
 
 // UpdateMethod defines an interface method template for generating update codes
-var UpdateMethod = `Update(data {{.upperStartCamelObject}}) error`
+var UpdateMethod = `Update(data *{{.upperStartCamelObject}}) error`