diff --git a/go.mod b/go.mod index fb9b7b5..8bb1176 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,17 @@ module git.gsuntres.com/general/structful go 1.25.0 require ( - git.gsuntres.com/general/mongo v0.0.0-20260329162359-b18c1ab94cb0 + git.gsuntres.com/general/commons v0.0.0-20260329160148-434ecef67a94 + git.gsuntres.com/general/mongo v0.0.0-20260329164619-eff6c4ecee15 + github.com/ianlancetaylor/jsonschema v0.0.0-20251021232724-46ecbf32a0a5 + github.com/spf13/cast v1.10.0 go.mongodb.org/mongo-driver/v2 v2.5.0 ) require ( - git.gsuntres.com/general/commons v0.0.0-20260329160148-434ecef67a94 // indirect git.gsuntres.com/general/sys v0.0.0-20260329160429-49966ca31027 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/ianlancetaylor/jsonschema v0.0.0-20251021232724-46ecbf32a0a5 // indirect github.com/klauspost/compress v1.18.2 // indirect github.com/matoous/go-nanoid/v2 v2.1.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect diff --git a/go.sum b/go.sum index ab9ebfe..66726b6 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= git.gsuntres.com/general/commons v0.0.0-20260329160148-434ecef67a94 h1:U0R2Mg00oC9dWNkXWZMRCBj8Fx6out3HHNIR24srWJ8= git.gsuntres.com/general/commons v0.0.0-20260329160148-434ecef67a94/go.mod h1:gVqoj8oD7D81CnU7vWZbv2jbSYXQDtHBcXs4t6E3rWM= -git.gsuntres.com/general/mongo v0.0.0-20260329162359-b18c1ab94cb0 h1:OBv3GvoFb63OzmuvlTC6nUghJ6pEz2kTIWaHWFj7ps8= -git.gsuntres.com/general/mongo v0.0.0-20260329162359-b18c1ab94cb0/go.mod h1:AUb/BDG+dVPHpKmO5GsoZqIbDO8uqbxBabEqtqAB4tw= +git.gsuntres.com/general/mongo v0.0.0-20260329164619-eff6c4ecee15 h1:MD2fRF3oIQ7g/ToW+toCZH3/LL8bBsSz9PhEQyjOpk0= +git.gsuntres.com/general/mongo v0.0.0-20260329164619-eff6c4ecee15/go.mod h1:AUb/BDG+dVPHpKmO5GsoZqIbDO8uqbxBabEqtqAB4tw= git.gsuntres.com/general/sys v0.0.0-20260329160429-49966ca31027 h1:4pmcjxEDM4rzv+iimQ7wTgCAQ1VnAoeGiHLuf6wC6Fw= git.gsuntres.com/general/sys v0.0.0-20260329160429-49966ca31027/go.mod h1:OVs7w4/tJO1GT7cLIeEsb90LuZqH2xYIVQODI5P1GJs= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= @@ -38,6 +38,8 @@ github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -54,6 +56,10 @@ github.com/ianlancetaylor/jsonschema v0.0.0-20251021232724-46ecbf32a0a5 h1:x2QxK github.com/ianlancetaylor/jsonschema v0.0.0-20251021232724-46ecbf32a0a5/go.mod h1:KtN3dTgXsLnC5GJBRNmOPd/HUInNcQ84lUCrKJPrvDc= github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= @@ -86,10 +92,14 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/testcontainers/testcontainers-go v0.41.0 h1:mfpsD0D36YgkxGj2LrIyxuwQ9i2wCKAD+ESsYM1wais= diff --git a/seed.go b/seed.go new file mode 100644 index 0000000..ced6438 --- /dev/null +++ b/seed.go @@ -0,0 +1,126 @@ +package structful + +import ( + "log" + "fmt" + "os" + "encoding/json" + "crypto/md5" + + "github.com/spf13/cast" + + "git.gsuntres.com/general/commons" + +) + +func SeedStructful(files []string) error { + for _, file := range files { + + // 1. Read the file bytes + content, err := os.ReadFile(file) + if err != nil { + log.Fatalf("Error reading file: %v", err) + } + + // 2. Define the target map + var data map[string]any + + // 3. Unmarshal (parse) the JSON into the map + err = json.Unmarshal(content, &data) + if err != nil { + if syntaxErr, ok := err.(*json.SyntaxError); ok { + min := commons.MathMin(int64(50), syntaxErr.Offset) + + from := syntaxErr.Offset - min + to := syntaxErr.Offset + min + + sliceBuf := content[from:to] + log.Printf("Failed to unmarshal %#v \n %s", syntaxErr, string(sliceBuf)) + } + + return err + } + + // 4. Check if composite + isComposite := false + isCompositeVal, ok := data["_composite"] + if ok { + isComposite = isCompositeVal.(bool) + } + + var name string + nameVal, nameOk := data["_name"] + if nameOk { + name = cast.ToString(nameVal) + } + + var version string + versionVal, versionOk := data["_version"] + if versionOk { + version = cast.ToString(versionVal) + } + + if isComposite { + // if composite extract entries + entries := make([]any, 0) + entriesVal, entriesOk := data["_entries"] + if entriesOk { + entries = entriesVal.([]any) + + for _, entry := range entries { + reg := Current() + + d, err := cast.ToStringMapE(entry) + if err != nil { + log.Printf("failed to cast %v", err) + + continue + } + + toHash, err := json.Marshal(d) + if err != nil { + log.Printf("failed to hash %v", err) + + continue + } + + hashed := fmt.Sprintf("%x", md5.Sum(toHash)) + + d["_hash"] = hashed + d["_name"] = name + d["_version"] = version + + if !reg.CheckHash(hashed) { + err = reg.Save(d) + if err != nil { + log.Printf("failed to save %v", err) + + continue + } + } + } + } + } else { + toHash, err := json.Marshal(data) + if err != nil { + log.Printf("failed to hash %v", err) + + continue + } + + hashed := fmt.Sprintf("%x", md5.Sum(toHash)) + + // 5. Save it + reg := Current() + data["_hash"] = hashed + if !reg.CheckHash(hashed) { + err = reg.Save(data) + if err != nil { + return err + } + } + } + } + + return nil +}