Taobin-Recipe-Manager/server/helpers/misc.go
pakintada@gmail.com 09c21301d6 feat(merge_component): Add merge from website
Merge contents from patch selected by user into newer version

merge from client feature
2024-03-04 11:19:11 +07:00

173 lines
4.1 KiB
Go

package helpers
import (
"fmt"
"os"
"strconv"
"strings"
)
// DynamicCompare compares two values dynamically and returns true if they are equal.
//
// Parameters:
//
// - s: The first value to compare.
//
// - u: The second value to compare.
//
// Returns:
//
// - bool: True if the values are equal, false otherwise.
//
// - error: An error if the values cannot be compared.
func DynamicCompare(s interface{}, u interface{}) (bool, error) {
switch t := s.(type) {
case bool:
u, ok := u.(bool)
if !ok {
return false, fmt.Errorf("[bool] cannot compare %T and %T, %v and %v", t, u, s, u)
}
return t == u, nil
case string:
u, ok := u.(string)
if !ok {
return false, fmt.Errorf("[string] cannot compare %T and %T, %v and %v", t, u, s, u)
}
return t == u, nil
case int:
u, ok := u.(int)
if !ok {
return false, fmt.Errorf("[int] cannot compare %T and %T, %v and %v", t, u, s, u)
}
return t == u, nil
case float64:
u, ok := u.(float64)
// Log.Debug("[helpers] DynamicCompare", zap.Any("user", u), zap.Any("ok", ok), zap.Any("test_compare*(t==u)", t == u))
if t == u {
return t == u, nil
}
if !ok {
return false, fmt.Errorf("[float64] cannot compare %T and %T, %v and %v", t, u, s, u)
}
return t == u, nil
case nil:
return t == u, nil
case []interface{}:
for i := range t {
if ok, err := DynamicCompare(t[i], u); err != nil {
return false, err
} else if !ok {
return false, nil
}
}
break
case map[string]interface{}:
for _, v := range t {
if ok, err := DynamicCompare(v, u); err != nil {
return false, err
} else if !ok {
return false, nil
}
}
break
default:
return false, fmt.Errorf("[unknown] not in case. Cannot compare %T and %T, %v and %v", t, u, s, u)
}
if u == nil {
return false, fmt.Errorf("[empty] the compared value is nil while t is %T", s)
}
return false, fmt.Errorf("[unknown] unexpected error. [old] %v and [new] %v", s, u)
}
func GetTempFile(filename string, user string, suffix int) string {
// Check if the temp file exist
_, err := os.Stat(filename)
// Log.Debug("[helpers] GetTempFile", zap.Any("filename", filename), zap.Any("suffix", suffix), zap.Any("err", err))
// file not exists
if os.IsNotExist(err) {
// Create temp file
if suffix == 0 {
return strings.Replace(filename, ".json", "_"+user+".tmp"+strconv.Itoa(suffix), 1)
}
// change extension from json to tmp
filename = strings.Replace(filename, ".json", "_"+user+".tmp"+strconv.Itoa(suffix), 1)
return filename
} else {
if strings.Contains(filename, ".tmp") {
return GetTempFile(strings.Replace(filename, "_"+user+".tmp"+strconv.Itoa(suffix-1), "_"+user+".tmp"+strconv.Itoa(suffix), 1), user, suffix+1)
}
// recursive call
return GetTempFile(strings.Replace(filename, ".json", "_"+user+".tmp"+strconv.Itoa(suffix), 1), user, suffix+1)
}
}
// func PackTempToRealFile(data *data.Data, countryID string, filename string) {
// // list file that end with .tmp*
// files, err := filepath.Glob(filename + ".tmp*")
// // for all files, read and get configNumber
// if err != nil {
// Log.Error("[helpers] PackTempToRealFile", zap.Error(err))
// }
// // get configNumber from actual filename.json
// //
// base_recipe := data.GetRecipe(countryID, filename)
// // read file and apply tmp file from 0 to tmpX.
// // - if there is more than 1 user that access this file at the same time,
// // pack in order, and if conflict, stop
// if len(files) == 0 {
// return
// }
// // must check the changes
// for _, file := range files {
// var tmpdata models.Recipe
// tmpfile, err := os.Open(file)
// if err != nil {
// return
// }
// _ = json.NewDecoder(tmpfile).Decode(&tmpdata)
// // apply change
// // = tmpdata.Recipe01
// for key, val := range tmpdata.Recipe01 {
// test_bol, err := DynamicCompare(base_recipe.Recipe01[key], val)
// if err != nil {
// Log.Error("[helpers] PackTempToRealFile", zap.Error(err))
// }
// if !test_bol {
// base_recipe.Recipe01[key] = val
// }
// }
// }
// // verify changes between tmpX and actual filename.json
// // if changes, rename tmpX to filename (version +1) .json
// }