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, } }