fix: types in m2m

This commit is contained in:
2025-03-16 18:59:27 +07:00
parent 4769971b56
commit 4b5580b1c8
17 changed files with 47 additions and 330 deletions

View File

@@ -1,6 +1,7 @@
package common
import (
"github.com/kuzgoga/fogg"
"go/ast"
"strings"
)
@@ -32,32 +33,10 @@ func GetRelatedModel(modelName string, models map[string]Model) *Model {
}
}
func FindParamValue(paramName string, params []string) *string {
for _, rawParam := range params {
pair := strings.Split(rawParam, ":")
if len(pair) < 2 {
return nil
}
if strings.ToLower(pair[0]) == strings.ToLower(paramName) {
return &pair[1]
}
}
return nil
}
func FindModelParam(paramName string, model Model) *Param {
func FindModelParam(paramName string, model Model) *fogg.TagParam {
for _, field := range model.Fields {
for _, param := range field.Params {
pair := strings.Split(param, ":")
if len(pair) < 2 {
return nil
}
if strings.ToLower(pair[0]) == strings.ToLower(paramName) {
return &Param{
Name: pair[0],
Value: pair[1],
}
}
if field.Tags.HasParam(paramName) {
return field.Tags.GetParam(paramName)
}
}
return nil
@@ -65,15 +44,13 @@ func FindModelParam(paramName string, model Model) *Param {
func FindReferencesInM2M(m2mReference Field, relatedModel Model) *Field {
/* Find `references` field in m2m relation */
referencesTagValue := FindParamValue("references", m2mReference.Params)
if referencesTagValue != nil {
return GetModelField(&relatedModel, *referencesTagValue)
referencesTag := m2mReference.Tags.GetParam("references")
if referencesTag != nil {
return GetModelField(&relatedModel, referencesTag.Value)
} else {
for _, field := range relatedModel.Fields {
for _, opt := range field.Options {
if opt == "primaryKey" {
return &field
}
if field.Tags.HasOption("primaryKey") {
return &field
}
}
for _, field := range relatedModel.Fields {
@@ -87,7 +64,7 @@ func FindReferencesInM2M(m2mReference Field, relatedModel Model) *Field {
func FindBackReferenceInM2M(relationName string, relatedModel Model) *Field {
for _, field := range relatedModel.Fields {
m2mRelation := field.GetParam("many2many")
m2mRelation := field.Tags.GetParam("many2many")
if m2mRelation != nil {
if m2mRelation.Value == relationName {
return &field

View File

@@ -1,19 +1,18 @@
package common
import (
"github.com/kuzgoga/fogg"
"go/ast"
"go/token"
"strings"
)
type Field struct {
Name string
Type ast.Expr
Tags *string
Options []string // contains options like "autoCreateTime" or "null"
Params []string // contains params like "foreignKey:CustomerId" or "constrain:OnDelete:Cascade"
Tag *string
Pos token.Pos
Comment string
Tags fogg.Tag
}
type Model struct {
@@ -27,45 +26,3 @@ type Param struct {
Name string
Value string
}
func (model *Model) GetParam(name string) *Param {
for _, field := range model.Fields {
for _, param := range field.Params {
pair := strings.SplitN(param, ":", 2)
if len(pair) != 2 {
return nil
}
if strings.ToLower(pair[0]) == strings.ToLower(name) {
return &Param{
Name: pair[0],
Value: pair[1],
}
}
}
}
return nil
}
func (model *Model) HasParam(name string) bool {
return model.GetParam(name) != nil
}
func (field *Field) HasParam(name string) bool {
return field.GetParam(name) != nil
}
func (field *Field) GetParam(name string) *Param {
for _, param := range field.Params {
pair := strings.SplitN(param, ":", 2)
if len(pair) != 2 {
return nil
}
if strings.ToLower(pair[0]) == strings.ToLower(name) {
return &Param{
Name: pair[0],
Value: pair[1],
}
}
}
return nil
}

10
common/model_methods.go Normal file
View File

@@ -0,0 +1,10 @@
package common
func (model *Model) HasPrimaryKey() bool {
for _, field := range model.Fields {
if field.Tags.HasParam("primaryKey") || field.Tags.HasOption("primaryKey") {
return true
}
}
return false
}

View File

@@ -1,10 +1,9 @@
package common
import (
"github.com/fatih/structtag"
"github.com/kuzgoga/fogg"
"go/ast"
"golang.org/x/tools/go/analysis"
"strings"
)
func ParseModels(pass *analysis.Pass, models *map[string]Model) {
@@ -49,29 +48,17 @@ func ParseModels(pass *analysis.Pass, models *map[string]Model) {
structField.Type = field.Type
if field.Tag != nil {
structField.Tags = &field.Tag.Value
tags, err := structtag.Parse(NormalizeStructTags(field.Tag.Value))
structField.Tag = &field.Tag.Value
var structTag string
structTag = field.Tag.Value[1 : len(field.Tag.Value)-1]
tags, err := fogg.Parse(structTag)
if err != nil {
pass.Reportf(field.Pos(), "Invalid structure tag: %s\n", err)
pass.Reportf(field.Pos(), "Invalid struct tag: %s\n", err)
return false
}
if tags != nil {
gormTag, parseErr := tags.Get("gorm")
if gormTag != nil && parseErr == nil {
gormTag.Options = append([]string{gormTag.Name}, gormTag.Options...)
for _, opt := range gormTag.Options {
if strings.Contains(opt, ":") {
structField.Params = append(structField.Params, opt)
} else {
structField.Options = append(structField.Options, opt)
}
}
}
if parseErr != nil {
pass.Reportf(field.Pos(), "Invalid structure tag: %s\n", parseErr)
return false
}
gormTag := tags.GetTag("gorm")
if gormTag != nil {
structField.Tags = *gormTag
}
}
model.Fields[structField.Name] = structField

View File

@@ -1,10 +0,0 @@
package common
import "strings"
func NormalizeStructTags(tags string) string {
// todo: process case with check with ';' literal
tagWithoutQuotes := tags[1 : len(tags)-1]
tagWithoutSemicolons := strings.ReplaceAll(tagWithoutQuotes, ";", ",")
return tagWithoutSemicolons
}