Files
gdulai 30e148f0e3
Go Tests / test (push) Successful in 1m3s
Multi struct test case
2026-06-06 10:34:47 +02:00

130 lines
2.5 KiB
Go

package schema
import (
"errors"
"reflect"
"strings"
"time"
)
type Column struct {
Name string
FieldName string
Type string
Modifiers map[string]string
}
func NewColumn(name string, typ string, fieldName string, tag reflect.StructTag) Column {
return Column{name, typ, fieldName, determineModifiers(tag)}
}
func determineModifiers(tag reflect.StructTag) map[string]string {
modifiers := make(map[string]string)
sqlTag := tag.Get("sql")
if sqlTag == "" {
return modifiers
}
rawModifiers := strings.SplitSeq(sqlTag, ";")
for rawModifier := range rawModifiers {
if strings.Contains(rawModifier, "=") {
keyValue := strings.Split(rawModifier, "=")
modifiers[keyValue[0]] = keyValue[1]
} else {
modifiers[rawModifier] = ""
}
}
return modifiers
}
func (c *Column) GetDDL() (string, error) {
var ddlBuilder strings.Builder
ddlBuilder.WriteString(c.Name)
ddlBuilder.WriteString(" ")
ddlBuilder.WriteString(c.Type)
inlineMods := c.inlineModifiers()
for _, mod := range inlineMods {
ddlBuilder.WriteString(" ")
ddlBuilder.WriteString(mod)
}
return ddlBuilder.String(), nil
}
func (c *Column) inlineModifiers() []string {
var mods []string
for k := range c.Modifiers {
switch k {
case "nn":
mods = append(mods, "NOT NULL")
}
}
return mods
}
func (c Column) GetSelectDML() (string, error) {
return c.Name, nil
}
func (c Column) GetInsertDML() (string, error) {
return c.Name, nil
}
func (c Column) GetUpdateDML() (string, error) {
return c.Name + " = ?", nil
}
func (Column) GetDeleteDML() (string, error) {
return "", errors.New("No delete DML for columns")
}
func (c *Column) IsPK() bool {
_, ok := c.Modifiers["pk"]
return ok
}
// Encodes the value to be DB compatible
func (c Column) Encode(value reflect.Value) any {
typ := value.Type().String()
var encoded any
switch typ {
case "time.Time":
timeVal := value.Interface().(time.Time)
encoded = timeVal.UnixMilli()
case "bool":
boolVal := value.Interface().(bool)
if boolVal {
encoded = 1
} else {
encoded = false
}
default:
encoded = value.Interface()
}
return encoded
}
// Decodes the raw value from the DBs
func (c Column) Decode(expected string, rawValue reflect.Value) any {
var decoded any
switch expected {
case "time.Time":
decoded = time.UnixMilli(rawValue.Interface().(int64))
case "bool":
rawValue := rawValue.Interface().(int)
if rawValue > 0 {
decoded = true
} else {
decoded = false
}
default:
decoded = rawValue.Interface()
}
return decoded
}