Skip to content

Commit

Permalink
Feature model fix (zeromicro#362)
Browse files Browse the repository at this point in the history
* fix sql builderx adding raw string quotation marks incompatibility bug

* add unit test

* remove comments

* fix sql builderx adding raw string quotation marks incompatibility bug
  • Loading branch information
anqiansong authored Jan 8, 2021
1 parent 57b73d8 commit 6c624a6
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 27 deletions.
28 changes: 26 additions & 2 deletions tools/goctl/model/sql/builderx/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func ToMap(in interface{}) map[string]interface{} {
return out
}

// deprecated: use RawFieldNames instead automaticly while model generating after goctl version v1.1.0
func FieldNames(in interface{}) []string {
out := make([]string, 0)
v := reflect.ValueOf(in)
Expand All @@ -61,9 +62,32 @@ func FieldNames(in interface{}) []string {
// gets us a StructField
fi := typ.Field(i)
if tagv := fi.Tag.Get(dbTag); tagv != "" {
out = append(out, fmt.Sprintf("`%v`", tagv))
out = append(out, tagv)
} else {
out = append(out, fmt.Sprintf("`%v`", fi.Name))
out = append(out, fi.Name)
}
}
return out
}

func RawFieldNames(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, fmt.Sprintf("`%s`", tagv))
} else {
out = append(out, fmt.Sprintf(`"%s"`, fi.Name))
}
}
return out
Expand Down
52 changes: 37 additions & 15 deletions tools/goctl/model/sql/builderx/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,23 @@ type (
}
)

var userFields = FieldNames(User{})
var userFieldsWithRawStringQuote = RawFieldNames(User{})
var userFieldsWithoutRawStringQuote = FieldNames(User{})

func TestFieldNames(t *testing.T) {
var u User
out := FieldNames(&u)
actual := []string{"`id`", "`user_name`", "`sex`", "`uuid`", "`age`"}
assert.Equal(t, out, actual)
t.Run("old", func(t *testing.T) {
var u User
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 User
out := RawFieldNames(&u)
expected := []string{"`id`", "`user_name`", "`sex`", "`uuid`", "`age`"}
assert.Equal(t, expected, out)
})
}

func TestNewEq(t *testing.T) {
Expand All @@ -48,7 +58,7 @@ func TestBuilderSql(t *testing.T) {
u := &User{
Id: "123123",
}
fields := FieldNames(u)
fields := RawFieldNames(u)
eq := NewEq(u)
sql, args, err := builder.Select(fields...).From("user").Where(eq).ToSQL()
fmt.Println(sql, args, err)
Expand All @@ -64,13 +74,25 @@ func TestBuildSqlDefaultValue(t *testing.T) {
eq["age"] = 0
eq["user_name"] = ""

sql, args, err := builder.Select(userFields...).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("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) {
Expand All @@ -79,7 +101,7 @@ func TestBuilderSqlIn(t *testing.T) {
}
gtU := NewGt(u)
in := builder.In("id", []string{"1", "2", "3"})
sql, args, err := builder.Select(userFields...).From("user").Where(in).And(gtU).ToSQL()
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>?"
Expand All @@ -90,7 +112,7 @@ func TestBuilderSqlIn(t *testing.T) {

func TestBuildSqlLike(t *testing.T) {
like := builder.Like{"name", "wang"}
sql, args, err := builder.Select(userFields...).From("user").Where(like).ToSQL()
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 ?"
Expand Down
10 changes: 5 additions & 5 deletions tools/goctl/model/sql/example/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

# generate model with cache from ddl
fromDDLWithCache:
goctl template clean;
goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/cache/user" -cache;
goctl template clean
goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/cache" -cache

fromDDLWithoutCache:
goctl template clean;
goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/nocache/user";
goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/nocache"


# generate model with cache from data source
Expand All @@ -17,5 +17,5 @@ datasource=127.0.0.1:3306
database=gozero

fromDataSource:
goctl template clean;
goctl model mysql datasource -url="$(user):$(password)@tcp($(datasource))/$(database)" -table="*" -dir ./model/cache -c -style gozero;
goctl template clean
goctl model mysql datasource -url="$(user):$(password)@tcp($(datasource))/$(database)" -table="*" -dir ./model/cache -c -style gozero
2 changes: 1 addition & 1 deletion tools/goctl/model/sql/gen/gen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestFields(t *testing.T) {
UpdateTime sql.NullTime `db:"update_time"`
}
var (
studentFieldNames = builderx.FieldNames(&Student{})
studentFieldNames = builderx.RawFieldNames(&Student{})
studentRows = strings.Join(studentFieldNames, ",")
studentRowsExpectAutoSet = strings.Join(stringx.Remove(studentFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
studentRowsWithPlaceHolder = strings.Join(stringx.Remove(studentFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
Expand Down
2 changes: 1 addition & 1 deletion tools/goctl/model/sql/template/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "fmt"

var Vars = fmt.Sprintf(`
var (
{{.lowerStartCamelObject}}FieldNames = builderx.FieldNames(&{{.upperStartCamelObject}}{})
{{.lowerStartCamelObject}}FieldNames = builderx.RawFieldNames(&{{.upperStartCamelObject}}{})
{{.lowerStartCamelObject}}Rows = strings.Join({{.lowerStartCamelObject}}FieldNames, ",")
{{.lowerStartCamelObject}}RowsExpectAutoSet = strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}",{{end}} "%screate_time%s", "%supdate_time%s"), ",")
{{.lowerStartCamelObject}}RowsWithPlaceHolder = strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", "%screate_time%s", "%supdate_time%s"), "=?,") + "=?"
Expand Down
2 changes: 1 addition & 1 deletion tools/goctl/model/sql/test/model/studentmodel.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

var (
studentFieldNames = builderx.FieldNames(&Student{})
studentFieldNames = builderx.RawFieldNames(&Student{})
studentRows = strings.Join(studentFieldNames, ",")
studentRowsExpectAutoSet = strings.Join(stringx.Remove(studentFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
studentRowsWithPlaceHolder = strings.Join(stringx.Remove(studentFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
Expand Down
4 changes: 2 additions & 2 deletions tools/goctl/model/sql/test/model/usermodel.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
var (
userFieldNames = builderx.FieldNames(&User{})
userRows = strings.Join(userFieldNames, ",")
userRowsExpectAutoSet = strings.Join(stringx.Remove(userFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
userRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
userRowsExpectAutoSet = strings.Join(stringx.Remove(userFieldNames, "id", "create_time", "update_time"), ",")
userRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, "id", "create_time", "update_time"), "=?,") + "=?"
)

type (
Expand Down

0 comments on commit 6c624a6

Please sign in to comment.