tmain.go: skip metadata rows without cpt data - ags-upload - Insert AGS files to a database
 (HTM) git clone git://src.adamsgaard.dk/ags-upload
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit e6f6b24b71451b45e650a2605e9e784f34cecee8
 (DIR) parent d25fead8fb5625035f6205cc2a056e156fe99e46
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Wed,  8 Oct 2025 14:58:29 +0200
       
       main.go: skip metadata rows without cpt data
       
       Diffstat:
         M cmd/main.go                         |      78 +++++++++++++++++++------------
       
       1 file changed, 49 insertions(+), 29 deletions(-)
       ---
 (DIR) diff --git a/cmd/main.go b/cmd/main.go
       t@@ -289,42 +289,62 @@ func main() {
                        }
        
                        err = db.Transaction(func(tx *gorm.DB) error {
       -                        // Upsert CptInfo by (LocationId, TestReference) and build a key->ID lookup
       -                        lookup := make(map[string]uint, len(infos))
       -                        for i := range infos {
       -                                ci := infos[i] // copy for pointer stability
       -                                if err := tx.
       -                                        Where("location_id = ? AND test_reference = ?", ci.LocationId, ci.TestReference).
       -                                        Assign(&ci).
       -                                        FirstOrCreate(&ci).Error; err != nil {
       -                                        return err
       -                                }
       -                                lookup[ci.LocationId+"\x00"+ci.TestReference] = ci.ID
       -                        }
       -
       -                        out := make([]Cpt, 0, len(cpts))
       -                        for i := range cpts {
       -                                if id := lookup[cpts[i].LocationId+"\x00"+cpts[i].TestReference]; id != 0 {
       -                                        cpts[i].InfoId = id
       -                                        out = append(out, cpts[i])
       -                                }
       -                        }
       -
       -                        if len(out) > 0 {
       -                                if err := tx.CreateInBatches(out, 2000).Error; err != nil {
       -                                        return err
       -                                }
       -                        }
       -                        return nil
       +            scptKeys := make(map[string]struct{}, len(cpts))
       +            key := func(locID, tesn string) string { return locID + "\x00" + tesn }
       +            for i := range cpts {
       +                if cpts[i].LocationId == "" || cpts[i].TestReference == "" {
       +                    continue
       +                }
       +                scptKeys[key(cpts[i].LocationId, cpts[i].TestReference)] = struct{}{}
       +            }
       +
       +            filtered := make([]CptInfo, 0, len(infos))
       +            for i := range infos {
       +                k := key(infos[i].LocationId, infos[i].TestReference)
       +                if _, ok := scptKeys[k]; ok {
       +                    filtered = append(filtered, infos[i])
       +                }
       +            }
       +
       +            lookup := make(map[string]uint, len(filtered))
       +            for i := range filtered {
       +                ci := filtered[i] // copy for pointer stability
       +                if err := tx.
       +                    Where("location_id = ? AND test_reference = ?", ci.LocationId, ci.TestReference).
       +                    Assign(&ci).
       +                    FirstOrCreate(&ci).Error; err != nil {
       +                    return err
       +                }
       +                lookup[key(ci.LocationId, ci.TestReference)] = ci.ID
       +            }
       +
       +            out := make([]Cpt, 0, len(cpts))
       +            for i := range cpts {
       +                id := lookup[key(cpts[i].LocationId, cpts[i].TestReference)]
       +                if id == 0 {
       +                    continue // SCPT without a matching filtered info (or missing key) → skip
       +                }
       +                cpts[i].InfoId = id
       +                out = append(out, cpts[i])
       +            }
       +
       +            if len(out) > 0 {
       +                if err := tx.CreateInBatches(out, 2000).Error; err != nil {
       +                    return err
       +                }
       +            }
       +
       +            // Optional: if nothing to insert at all, you might return an error or 204 outside
       +            return nil
                        })
       +
                        if err != nil {
                                c.String(http.StatusInternalServerError, "db error: %v", err)
                                return
                        }
        
                        c.JSON(http.StatusCreated, gin.H{
       -                        "infos": len(infos),
       -                        "cpts":  len(cpts),
       +                        "n_cpts":  len(cpts),
                        })
                })