fullstack-lang / gong

Gong (go+ng) is a go sub-language that compiles to go and angular. All valid go is valid gong and vice versa. Gong enables fast development of web applications. Gong is model centric and by default, a UML diagram editor of the model is embedded in each application.
MIT License
11 stars 1 forks source link

Probe: use reverse pointers and reverse slice of pointers of the stage (and not in the orm) #439

Closed thomaspeugeot closed 10 months ago

thomaspeugeot commented 10 months ago

analysis

the probe uses the reverse pointers to in the table construction and the form construction. Both call GetReverseFieldOwnerName

test2/go/orm/get_reverse_field_owner_name.go

        case "A":
            switch reverseField.Fieldname {
            case "Bs":
                if tmp != nil && tmp.A_BsDBID.Int64 != 0 {
                    id := uint(tmp.A_BsDBID.Int64)
                    reservePointerTarget := backRepo.BackRepoA.Map_ADBID_APtr[id]
                    res = reservePointerTarget.Name
                }
            }

We need the store the reverse information in another way. Two solutions:

  1. Store reverse field info in the Stage or the BackRepo. It is the source side (A), no the target side (B) because it cannot be scaled to multi package models. It can be reused, especialy for the Stage.
  2. Store reverse field into the probe itself. Problem it can hardly be reusable

Store at the stage level

In the Stage,

type A struct {
... Bs []*B
}

type StageStruct struct {
    path string

    // insertion point for definition of arrays registering instances
    As           map[*A]any
    As_mapString map[string]*A

One can store the map of B that points to A

        A_Bs_reverseMap map[*B]*A

Have a function in the gong.go

// ComputeReverseMaps computes the reverse map, for all intances, for all slice to pointers field
// Its complexity is in O(n)O(p) where p is the number of pointers
func (stage *StageStruct) ComputeReverseMaps() {
    clear(stage.A_Bs_reverseMap)
    for a := range stage.As {
        _ = a
        for _, _b := range a.Bs {
            stage.A_Bs_reverseMap[_b] = a
        }
    }
}

// in the probe package


func GetReverseFieldOwnerName[T models.Gongstruct](
...
    case *models.B:
        tmp := GetInstanceDBFromInstance[models.B, BDB](
            stage, backRepo, inst,
        )
        _ = tmp
        switch reverseField.GongstructName {
        // insertion point
        case "A":
            switch reverseField.Fieldname {
            case "Bs":
                res = stage.A_Bs_reverseMap[inst].Name
            }
...
func GetReverseFieldOwner[T models.Gongstruct](
...
    case *models.B:
        tmp := GetInstanceDBFromInstance[models.B, BDB](
            stage, backRepo, inst,
        )
        _ = tmp
        switch reverseField.GongstructName {
        // insertion point
        case "A":
            switch reverseField.Fieldname {
            case "Bs":
                res = stage.A_Bs_reverseMap[inst]
            }