This commit is contained in:
Eden Kirin
2024-06-18 23:43:21 +02:00
parent 21dcabe180
commit 0a0ed77794
4 changed files with 130 additions and 2 deletions

View File

@ -6,7 +6,7 @@ VERSION_TAG=$$(date +%y%m%d.%H%M)
run: run:
@air go run app/main.go
.PHONY: test .PHONY: test

View File

@ -5,9 +5,38 @@ import (
"repo-pattern/app/lib/cfg" "repo-pattern/app/lib/cfg"
"repo-pattern/app/lib/db" "repo-pattern/app/lib/db"
"repo-pattern/app/lib/logging" "repo-pattern/app/lib/logging"
"repo-pattern/app/models"
"repo-pattern/app/repository" "repo-pattern/app/repository"
"gorm.io/gorm"
) )
var (
TRUE = true
FALSE = false
)
func doMagic(db *gorm.DB) {
var err error
query := db
f := repository.SmartCertFilter[models.Cert]{
Alive: &TRUE,
}
query, err = f.ToQuery(query)
if err != nil {
panic(err)
}
var certs []models.Cert
query.Find(&certs)
for n, cert := range certs {
fmt.Printf(">> [%d] %+v\n", n, cert.Id)
}
}
func main() { func main() {
cfg.Init() cfg.Init()
logging.Init() logging.Init()
@ -16,5 +45,7 @@ func main() {
db := db.InitDB() db := db.InitDB()
repository.Dao = repository.CreateDAO(db) repository.Dao = repository.CreateDAO(db)
doMagic(db)
fmt.Println("Running...") fmt.Println("Running...")
} }

View File

@ -23,6 +23,6 @@ type Cert struct {
UpdatedAt time.Time `faker:"-"` UpdatedAt time.Time `faker:"-"`
} }
func (m *Cert) TableName() string { func (m Cert) TableName() string {
return "certificates" return "certificates"
} }

View File

@ -0,0 +1,97 @@
package repository
import (
"fmt"
"reflect"
"slices"
"strings"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
const TAG_NAME = "filterfield"
const TAG_VALUE_SEPARATOR = ","
type Operator string
const (
OperatorEQ Operator = "EQ"
OperatorIN Operator = "IN"
)
var OPERATORS = []Operator{OperatorEQ, OperatorIN}
type FilterField struct {
Name string
Operator Operator
}
type SmartCertFilter[T schema.Tabler] struct {
Model T
Alive *bool `filterfield:"alive,EQ"`
Id *uuid.UUID `filterfield:"id,EQ"`
Ids *[]uuid.UUID `filterfield:"id,IN"`
CompanyId *uuid.UUID `filterfield:"company_id,EQ"`
}
func (f SmartCertFilter[T]) ToQuery(query *gorm.DB) (*gorm.DB, error) {
tableName := f.Model.TableName()
fmt.Printf("Table name: %s\n", tableName)
fmt.Printf("%+v\n", f)
st := reflect.TypeOf(f)
modelName := st.Name()
for i := 0; i < st.NumField(); i++ {
field := st.Field(i)
tagValue := field.Tag.Get(TAG_NAME)
if len(tagValue) == 0 {
continue
}
filterField, err := getFilterField(tagValue)
if err != nil {
return nil, fmt.Errorf("%s.%s: %s", modelName, field.Name, err)
}
fmt.Printf(
"tagValue: %s, Name: %s, Operator: %s\n",
tagValue,
filterField.Name,
filterField.Operator,
)
switch filterField.Operator {
case OperatorEQ:
query = applyFilterEQ(query, tableName, filterField)
}
}
// query = query.Where("certificates.alive=?", true)
return query, nil
}
func applyFilterEQ(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB {
return query
}
func getFilterField(tagValue string) (*FilterField, error) {
values := strings.Split(tagValue, TAG_VALUE_SEPARATOR)
if len(values) != 2 {
return nil, fmt.Errorf("incorrect number of tag values: %s", tagValue)
}
operator := Operator(values[1])
if !slices.Contains(OPERATORS, operator) {
return nil, fmt.Errorf("unknown operator: %s", operator)
}
f := FilterField{
Operator: operator,
}
return &f, nil
}