Files
simpleorm/table.go
T
gdulai 01336bb911
Go Tests / test (push) Failing after 6s
Implement DML func and related tests
2026-05-04 21:33:29 +02:00

186 lines
3.7 KiB
Go

package simpleorm
import (
"errors"
"reflect"
"strings"
"time"
)
type Table struct {
Name string
Type reflect.Type
Columns []Column
Constraints []Constraint
}
func (t Table) ToDDL() string {
var ddl strings.Builder
ddl.WriteString("CREATE TABLE IF NOT EXISTS " + t.Name + " (")
for i, col := range t.Columns {
if i != 0 {
ddl.WriteString(", ")
}
ddl.WriteString(col.ToDDL())
}
for _, constr := range t.Constraints {
ddl.WriteString(", " + constr.ToDDL())
}
ddl.WriteString(");")
return ddl.String()
}
func (t Table) ToSelectDML() string {
var dml strings.Builder
dml.WriteString("SELECT ")
for i, col := range t.Columns {
if i != 0 {
dml.WriteString(", ")
}
dml.WriteString(col.Name)
}
dml.WriteString(" FROM " + t.Name)
return dml.String()
}
func (t Table) ToInsertDML(count int) string {
var dml strings.Builder
dml.WriteString("INSERT INTO " + camelToSnake(t.Type.Name()) + " (")
columnsLen := len(t.Columns)
effectiveColumnsLen := 0
for i, col := range t.Columns {
_, ok := col.Modifiers["pk"]
if ok {
continue
}
dml.WriteString(col.Name)
if i != columnsLen-1 {
dml.WriteString(", ")
}
effectiveColumnsLen++
}
dml.WriteString(") VALUES")
for i := range count {
if i != 0 {
dml.WriteString(", ")
}
for j := range effectiveColumnsLen {
if j == 0 {
dml.WriteString("(")
}
if j != effectiveColumnsLen-1 {
dml.WriteString("?, ")
} else {
dml.WriteString("?)")
}
}
}
return dml.String()
}
func (t Table) ToUpdateDML(src any) string {
var dml strings.Builder
dml.WriteString("UPDATE " + camelToSnake(t.Type.Name()) + " SET ")
var pkCol string
// Colum names
for i := 0; i < t.Type.NumField(); i++ {
field := t.Type.Field(i)
modifiers := determineModifiers(field.Tag)
_, ok := modifiers["pk"]
if ok {
pkCol = camelToSnake(field.Name)
continue
}
if i != t.Type.NumField()-1 {
dml.WriteString(camelToSnake(field.Name) + " = ?, ")
} else {
dml.WriteString(camelToSnake(field.Name) + " = ? ")
}
}
dml.WriteString("WHERE " + pkCol + " = ?")
return dml.String()
}
func (t Table) ToDeleteDML(src any) string {
var dml strings.Builder
dml.WriteString("DELETE FROM " + camelToSnake(t.Type.Name()) + " WHERE ")
for i := 0; i < t.Type.NumField(); i++ {
field := t.Type.Field(i)
modifiers := determineModifiers(field.Tag)
_, ok := modifiers["pk"]
if ok {
dml.WriteString(camelToSnake(field.Name) + " = ?")
return dml.String()
}
}
return ""
}
func (t Table) createSelectResultContainer() []any {
vals := make([]any, t.Type.NumField())
for i := range vals {
switch t.Type.Field(i).Type.Kind().String() {
case "string":
var fieldContainer string
vals[i] = &fieldContainer
case "int":
var fieldContainer int
vals[i] = &fieldContainer
case "int64", "time.Time":
var fieldContainer int64
vals[i] = &fieldContainer
}
}
return vals
}
func (t Table) prepareParams(src any) []any {
var params []any
for i := 0; i < t.Type.NumField(); i++ {
field := t.Type.Field(i)
modifiers := determineModifiers(field.Tag)
_, ok := modifiers["pk"]
if ok {
continue
}
typStr := field.Type.String()
switch typStr {
case "time.Time":
time := reflect.ValueOf(src).Field(i).Interface().(time.Time)
params = append(params, time.UnixMilli())
default:
params = append(params, reflect.ValueOf(src).Field(i).Interface())
}
}
return params
}
func (t Table) getPk(src any) (any, error) {
for i := 0; i < t.Type.NumField(); i++ {
field := t.Type.Field(i)
modifiers := determineModifiers(field.Tag)
_, ok := modifiers["pk"]
if ok {
return reflect.ValueOf(src).Field(i).Interface(), nil
}
}
return nil, errors.New("Could not determine pk column!")
}