From d8fc2e9de968b286cb07d32fb8752f18fb846084 Mon Sep 17 00:00:00 2001 From: what Date: Sat, 22 Apr 2023 01:49:03 +0800 Subject: [PATCH] [feat] add ResField.ToQueryField func --- base/query_field.go | 125 ++++++++++++++++++++++++++++++++++++++++++++ base/res_field.go | 10 ++++ resource.go | 1 + 3 files changed, 136 insertions(+) create mode 100644 base/query_field.go diff --git a/base/query_field.go b/base/query_field.go new file mode 100644 index 0000000..dbc6c49 --- /dev/null +++ b/base/query_field.go @@ -0,0 +1,125 @@ +package base + +import ( + "reflect" + "strings" + "unicode" + + "git.fsdpf.net/go/contracts" + "git.fsdpf.net/go/contracts/res_type" + "git.fsdpf.net/go/db" +) + +type QueryField struct { + ResField + typ contracts.QueryDataType `db:"dataType"` + alias string `db:"alias"` + isExpr bool `db:"isExpr"` + isOmitempty bool + ignored bool +} + +func (this QueryField) Alias() string { + return this.alias +} + +func (this QueryField) Ignored() bool { + return this.ignored +} + +func (this QueryField) IsExpr() bool { + return this.isExpr +} + +func (this QueryField) IsOmitempty() bool { + return this.isOmitempty +} + +func (this QueryField) Type() contracts.QueryDataType { + return this.typ +} + +func (this *QueryField) SetOptions(options int) contracts.QueryField { + if options&contracts.QueryField_IsExpr != 0 { + this.isExpr = true + } + + if options&contracts.QueryField_IsOmitempty != 0 { + this.isOmitempty = true + } + + if options&contracts.QueryField_Ignored != 0 { + this.ignored = true + } + + return this +} + +func (this QueryField) GetCodeOrAlias() string { + if this.Alias() != "" { + return this.Alias() + } + + return this.Code +} + +func (this *QueryField) ToSql() db.Expression { + if this.Alias() != "" { + if this.IsExpr() { + if this.GetCode() == "" { + return db.Raw("null as `" + this.Alias() + "`") + } + return db.Raw("(" + this.GetCode() + ") as `" + this.Alias() + "`") + } + return db.Raw("`" + this.GetCodeResource() + "`.`" + this.GetCode() + "` as `" + this.Alias() + "`") + } + return db.Raw("`" + this.GetCodeResource() + "`.`" + this.GetCode() + "`") +} + +func (this *QueryField) ToStructField(tags ...string) reflect.StructField { + var typ reflect.Type + + fCode := this.GetCodeOrAlias() + + // 字段规则 + if !unicode.IsLetter(rune(fCode[0])) { + panic("struct field name invalid. " + fCode) + } + + fTag := `db:"` + fCode + + if this.ignored { + fTag = fTag + `" json:"-"` + } else if this.isOmitempty { + fTag = fTag + `" json:"` + fCode + `,omitempty"` + } else { + fTag = fTag + `" json:"` + fCode + `"` + } + + if len(tags) > 0 { + fTag = strings.Join(tags, " ") + " " + fTag + } + + switch this.typ { + case contracts.QueryDataType_String: + typ = reflect.TypeOf(res_type.ResFieldByString("")) + case contracts.QueryDataType_Number: + typ = reflect.TypeOf(res_type.ResFieldByNumber(0)) + case contracts.QueryDataType_Integer: + typ = reflect.TypeOf(res_type.ResFieldByInteger(0)) + case contracts.QueryDataType_Float: + typ = reflect.TypeOf(res_type.ResFieldByFloat(0)) + case contracts.QueryDataType_Bool: + typ = reflect.TypeOf(true) + case contracts.QueryDataType_Array: + typ = reflect.TypeOf(res_type.ResFieldByAnys{}) + case contracts.QueryDataType_Json: + typ = reflect.TypeOf(res_type.ResFieldByMap{}) + } + + return reflect.StructField{ + Name: strings.ToUpper(fCode[:1]) + fCode[1:], + Tag: reflect.StructTag(fTag), + Type: typ, + } +} diff --git a/base/res_field.go b/base/res_field.go index 8d8ba0f..f6e4664 100644 --- a/base/res_field.go +++ b/base/res_field.go @@ -269,3 +269,13 @@ func (this ResField) ToBlueprint(table *schema.Blueprint) (temp *schema.ColumnDe return temp } + +func (this ResField) ToQueryField(t contracts.QueryDataType, alias string, options int) contracts.QueryField { + o := &QueryField{ + ResField: this, + typ: t, + alias: alias, + } + + return o.SetOptions(options) +} diff --git a/resource.go b/resource.go index d3d4368..ca52986 100644 --- a/resource.go +++ b/resource.go @@ -73,6 +73,7 @@ type ResField interface { ToStructField(tags ...string) reflect.StructField ToValue(any) any ToBlueprint(table *schema.Blueprint) *schema.ColumnDefinition + ToQueryField(t QueryDataType, alias string, options int) QueryField } // 资源