goctl model reactor (#15)

* reactor sql generation

* reactor sql generation

* add console & example

* optimize unit test & add document

* modify default config

* remove test file

* Revert "remove test file"

This reverts commit 81041f9e

* fix stringx.go & optimize example

* remove unused code
This commit is contained in:
Keson
2020-08-19 10:41:19 +08:00
committed by GitHub
parent 1252bd9cde
commit d21d770b5b
64 changed files with 1505 additions and 2306 deletions

View File

@@ -0,0 +1,97 @@
package builderx
import (
"fmt"
"reflect"
"github.com/go-xorm/builder"
)
const dbTag = "db"
func NewEq(in interface{}) builder.Eq {
return builder.Eq(ToMap(in))
}
func NewGt(in interface{}) builder.Gt {
return builder.Gt(ToMap(in))
}
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
}
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
}
func FieldNamesAlias(in interface{}, alias string) []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)
tagName := ""
if tagv := fi.Tag.Get(dbTag); tagv != "" {
tagName = tagv
} else {
tagName = fi.Name
}
if len(alias) > 0 {
tagName = alias + "." + tagName
}
out = append(out, tagName)
}
return out
}

View File

@@ -0,0 +1,101 @@
package builderx
import (
"fmt"
"testing"
"github.com/go-xorm/builder"
"github.com/stretchr/testify/assert"
)
type (
User 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 userFields = FieldNames(User{})
func TestFieldNames(t *testing.T) {
var u User
out := FieldNames(&u)
fmt.Println(out)
actual := []string{"id", "user_name", "sex", "uuid", "age"}
assert.Equal(t, out, actual)
}
func TestNewEq(t *testing.T) {
u := &User{
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 := &User{
Id: "123123",
}
fields := FieldNames(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) {
var eq = builder.Eq{}
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)
}
func TestBuilderSqlIn(t *testing.T) {
u := &User{
Age: 18,
}
gtU := NewGt(u)
in := builder.In("id", []string{"1", "2", "3"})
sql, args, err := builder.Select(userFields...).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(userFields...).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)
}