feat: many2many relations check

This commit is contained in:
2025-01-01 17:11:34 +07:00
parent caee1b8eff
commit a6574924fe
10 changed files with 303 additions and 0 deletions

100
common/finders.go Normal file
View File

@@ -0,0 +1,100 @@
package common
import (
"go/ast"
"strings"
)
func GetModelField(model *Model, fieldName string) *Field {
field, fieldExists := model.Fields[fieldName]
if fieldExists {
return &field
} else {
return nil
}
}
func GetModelFromType(modelType ast.Expr, models map[string]Model) *Model {
baseType := ResolveBaseType(modelType)
if baseType != nil {
return GetRelatedModel(*baseType, models)
} else {
return nil
}
}
func GetRelatedModel(modelName string, models map[string]Model) *Model {
model, modelExists := models[modelName]
if modelExists {
return &model
} else {
return nil
}
}
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 {
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],
}
}
}
}
return nil
}
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)
} else {
for _, field := range relatedModel.Fields {
for _, opt := range field.Options {
if opt == "primaryKey" {
return &field
}
}
}
for _, field := range relatedModel.Fields {
if strings.ToLower(field.Name) == "id" {
return &field
}
}
return nil
}
}
func FindBackReferenceInM2M(relationName string, relatedModel Model) *Field {
for _, field := range relatedModel.Fields {
m2mRelation := field.GetParam("many2many")
if m2mRelation != nil {
if m2mRelation.Value == relationName {
return &field
}
}
}
return nil
}
//func findForeignKey()

11
common/isSlice.go Normal file
View File

@@ -0,0 +1,11 @@
package common
import "go/ast"
func IsSlice(expr ast.Expr) bool {
arrayType, ok := expr.(*ast.ArrayType)
if !ok {
return false
}
return arrayType.Len == nil
}

View File

@@ -3,6 +3,7 @@ package common
import (
"go/ast"
"go/token"
"strings"
)
type Field struct {
@@ -21,3 +22,50 @@ type Model struct {
Pos token.Pos
Comment string
}
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
}