gorm/apaas/types.go
2025-05-28 14:28:49 +08:00

236 lines
5.8 KiB
Go

package apaas
import (
"strings"
)
const (
TagID = "apass_engine_lookup_id"
TagValue = "apass_engine_lookup_value"
MaxTagDeep = 4
)
type ApaasFieldType uint8
type FieldType uint8
const (
_skipFieldType FieldType = iota
FieldBool
FieldInt
FieldInt64
FieldFloat
FieldFloat64
FieldString
FieldTime
FieldBit
FieldBin
FieldArray
FieldObject
)
const (
_skipApaasFieldType ApaasFieldType = iota
ApaasLookupID
ApaasLookupValue
ApaasExtraType
ApaasFormulaType
)
var FieldMapString = []string{
"_skipApaasFieldTyle",
"FieldBool",
"FieldInt",
"FieldInt64",
"FieldFloat",
"FieldFloat64",
"FieldString",
"FieldTime",
"FieldBit",
"FieldBin",
"FieldArray",
"FieldObject",
}
func (p FieldType) String() string {
return FieldMapString[p]
}
/*
description: store dynamic field info when is an instance like tag
`apass_engine_lookup_value`
case:
type RoomAnchorView struct {
Room
Gender string `gorm:"column:gender" json:"gender" apass_engine_lookup_value:"anchor_id.uid.gender"`
Career string `gorm:"column:career" json:"career" apass_engine_lookup_value:"anchor_id.uid.career"`
Name string `gorm:"column:name" json:"name" apass_engine_lookup_value:"anchor_id.uid.name"`
}
type RoomAnchorFactionView struct {
Room
Gender string `gorm:"column:gender" json:"gender" apass_engine_lookup_value:"anchor_id.uid.gender"`
Career string `gorm:"column:career" json:"career" apass_engine_lookup_value:"anchor_id.uid.career"`
Name string `gorm:"column:name" json:"name" apass_engine_lookup_value:"anchor_id.uid.name"`
OrgName string `gorm:"column:org_name" json:"org_name" apass_engine_lookup_value:"anchor_id.faction_id.faction_name"`
UnionInfo string `gorm:"column:union_info" json:"union_info" apass_engine_lookup_value:"anchor_id.faction_id.org_id.union_info"`
}
*/
type ApaasLookupMeta struct {
// field gorm column tag name/table field's name. example: union_info
CName string
// lookup orgin meta. example: [anchor_id.faction_id.org_id.union_info]
/*
1. anchor_id; 2. faction_id; 3: org_id;
1. anchor.anchor_id;2. Vction.faction_id;3: union.org_id;
*/
LookupMeta []*LookupMeta
LastField string // org_name/union_name
/*
OrgTag only set value when used in SDK mode
*/
// lookup org tag [anchor_id, faction_id, org_id, org_name]
OrgTag []string
}
// lookup orgin meta. example: [anchor_id.faction_id.org_id.union_info]
type LookupMeta struct {
FieldName string
ForeignMeta ForeignMeta
}
type ApaasTable struct {
TableName string
DBName string
Fields []*ApaasField
FieldsByName map[string]*ApaasField
LookupIDField *ApaasField // example: room.room_id, user.uid, faction.faction_id
ForeignFields []*ApaasField // foreign key. example: room.anchor_id, named of relookupid
FormulaFields []*ApaasField // example: union.title=update_time + org_name
LookupValueFields []*ApaasField // example: org_id.org_name, anchor_id.org_id.union_id.union_name
ExtraFields []*ApaasField // example: anchor.extra, room.extra
}
type ApaasField struct {
Name string
Type string
FType FieldType
IsUniq bool
IsForeign bool
foreignMeta *ForeignMeta
IsApaasType bool
ApaasMeta *ApaasMeta
}
func (p *ApaasField) parseFieldType() {
tp := strings.ToUpper(p.Type)
ftp := _skipFieldType
switch tp {
case "BOOL":
ftp = FieldBool
case "INT", "TINYINT", "SMALLINT", "MEDIUMINT":
ftp = FieldInt
case "BIGINT":
ftp = FieldInt64
case "FLOAT":
ftp = FieldFloat
case "DOUBLE", "DECIMAL", "REAL":
ftp = FieldFloat64
case "DATE", "DATETIME", "TIMESTAMP", "TIME", "YEAR":
ftp = FieldTime
case "VARCHAR", "CHAR", "ENUM", "TEXT", "TINYTEXT", "MEDIUMTEXT", "LONGTEXT", "JSON":
ftp = FieldString
case "BLOB", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB", "BINARY", "VARBINARY":
ftp = FieldBin
case "BIT":
ftp = FieldBit
default:
ftp = FieldString
}
p.FType = ftp
}
func (p *ApaasField) GetApaasMeta() *ApaasMeta {
return p.ApaasMeta
}
type ForeignMeta struct {
DBName string
TName string
FName string
FTMeta *ApaasTable
}
type ApaasMeta struct {
ApaasFType ApaasFieldType
ExtraMeta map[string]*ExtraFieldMeta
FormulaMeta *FormulaMeta
LookupMeta *ApaasLookupMeta
Checker
}
func (p *ApaasMeta) IsApaasFieldType() bool {
return p.ApaasFType == _skipApaasFieldType
}
func (p *ApaasMeta) IsExtraField() bool {
return p.ApaasFType == ApaasExtraType
}
func (p *ApaasMeta) IsFormulaField() bool {
return p.ApaasFType == ApaasFormulaType
}
func (p *ApaasMeta) IsLookupID() bool {
return p.ApaasFType == ApaasLookupID
}
func (p *ApaasMeta) IsLookupValue() bool {
return p.ApaasFType == ApaasLookupValue
}
func (p *ApaasMeta) GetApaasFieldType() ApaasFieldType {
return p.ApaasFType
}
func (p *ApaasMeta) GetExtraMeta() map[string]*ExtraFieldMeta {
return p.ExtraMeta
}
func (p *ApaasMeta) GetFormulaMeta() *FormulaMeta {
return p.FormulaMeta
}
func (p *ApaasMeta) Check(extra string) error {
// step1: extra rule check
err := ExtraCheck(p.ExtraMeta, extra)
return err
}
type ExtraFieldMeta struct {
Key string
Type FieldType // Bool/Int/Float/String/Object/Array
ObjectMeta map[string]*ExtraFieldMeta // if Type is Object, use ObjectMeta
ArrayMeta []*ExtraFieldMeta // if Type is Array, need ArrayMeta
}
type FormulaMeta struct {
InputFields map[string]*ApaasField
FormulaRule *FormulaRule
}
type FormulaRule struct {
}
type DBMeta struct {
tableList []*ApaasTable
tableView map[string]*ApaasTable
lookupIDView map[string]*ApaasTable // each table has one one and only key to supprort lookup
}
func (p *DBMeta) GetTableByLookupID(lookID string) (*ApaasTable, bool) {
v, ok := p.lookupIDView[lookID]
return v, ok
}
func (p *DBMeta) GetTableByName(tableName string) (*ApaasTable, bool) {
v, ok := p.tableView[tableName]
return v, ok
}