Basics
This commit is contained in:
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ VERSION_TAG=$$(date +%y%m%d.%H%M)
|
|||||||
|
|
||||||
|
|
||||||
run:
|
run:
|
||||||
@air
|
go run app/main.go
|
||||||
|
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|||||||
31
app/main.go
31
app/main.go
@ -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...")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
97
app/repository/smartfilter.go
Normal file
97
app/repository/smartfilter.go
Normal 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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user