diff --git a/_example/example.json b/_example/example.json new file mode 100644 index 0000000..62c36bd --- /dev/null +++ b/_example/example.json @@ -0,0 +1,17 @@ +[ + { + "id": "1", + "name": "Apple", + "category": "Fruit" + }, + { + "id": "2", + "name": "Carrot", + "category": "Vegetable" + }, + { + "id": "3", + "name": "Orange", + "category": "Fruit" + } +] \ No newline at end of file diff --git a/error.go b/error.go new file mode 100644 index 0000000..00ddc7f --- /dev/null +++ b/error.go @@ -0,0 +1,27 @@ +package gfunc + +import ( + "fmt" + "log" + "reflect" +) + +func CheckStructPointer(data interface{}) error { + if reflect.TypeOf(data).Kind() == reflect.Struct { + if reflect.TypeOf(data).Kind() != reflect.Ptr { + err := ErrMsg("data must be of type pointer if struct") + log.SetFlags(0) + log.Println(err) + } + } + + return nil +} + +func ErrMsg(err string) string { + const redColor = "\033[31m" + const resetColor = "\033[0m" + + response := fmt.Sprintf("%serror%s: %s", redColor, resetColor, err) + return response +} diff --git a/go.mod b/go.mod index af9ca6e..42d7ea9 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,13 @@ module github.com/teranixbq/gfunc go 1.17 +require github.com/redis/go-redis/v9 v9.5.1 + require ( - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/redis/go-redis/v9 v9.5.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.9.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index baf0d66..0a6b9fd 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,17 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/jsonfile.go b/jsonfile.go new file mode 100644 index 0000000..a176e7a --- /dev/null +++ b/jsonfile.go @@ -0,0 +1,28 @@ +package gfunc + +import ( + "errors" + "os" + "strings" +) + +type Query struct { + jsonfile []byte +} + +func NewJsonFile(file string) (*Query, error) { + if !strings.HasSuffix(file, ".json") { + return nil, errors.New("file must be json") + } + + bytefile, err := os.ReadFile(file) + if err != nil { + return nil, err + } + + b := Query{ + jsonfile: bytefile, + } + + return &b, nil +} diff --git a/jsonquery.go b/jsonquery.go new file mode 100644 index 0000000..c3abd44 --- /dev/null +++ b/jsonquery.go @@ -0,0 +1,93 @@ +package gfunc + +import ( + "encoding/json" + "errors" + "reflect" +) + +func (q *Query) Find(data interface{}) error { + errPointer := CheckStructPointer(data) + if errPointer != nil { + return errPointer + } + + err := json.Unmarshal(q.jsonfile, data) + if err != nil { + return err + } + + return nil +} + +func (q *Query) FindBy(by, field string, dataList []interface{}, Selected interface{}) error { + + err := q.Find(&dataList) + if err != nil { + return err + } + + var all []interface{} + all = append(all, dataList...) + + for _, v := range all { + m, err := json.Marshal(v) + if err != nil { + return err + } + + var tempMap map[string]interface{} + if err := json.Unmarshal(m, &tempMap); err != nil { + return err + } + + value, found := tempMap[field] + if !found { + continue + } + + if value == by { + reflect.ValueOf(Selected).Elem().Set(reflect.ValueOf(v)) + return nil + } + } + + return errors.New("data not found") +} + +func (q *Query) FindAllBy(by, field string, dataList []interface{}, Selected *[]interface{}) error { + err := q.Find(&dataList) + if err != nil { + return err + } + + var all []interface{} + all = append(all, dataList...) + + for _, v := range all { + m, err := json.Marshal(v) + if err != nil { + return err + } + + var tempMap map[string]interface{} + if err := json.Unmarshal(m, &tempMap); err != nil { + return err + } + + value, found := tempMap[field] + if !found { + continue + } + + if value == by { + *Selected = append(*Selected, v) + } + } + + if len(*Selected) == 0 { + return errors.New("data not found") + } + + return nil +} diff --git a/jsonquery_test.go b/jsonquery_test.go new file mode 100644 index 0000000..f6fca08 --- /dev/null +++ b/jsonquery_test.go @@ -0,0 +1,60 @@ +package gfunc + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type data struct { + Id string `json:"id"` + Name string `json:"name"` + Category string `json:"category"` +} + +func TestFind(t *testing.T) { + listData := []data{} + + q, errJson := NewJsonFile("_example/example.json") + err := q.Find(&listData) + + assert.NoError(t, errJson) + assert.NoError(t, err) + assert.NotNil(t, listData) + assert.NotEmpty(t, listData) +} + +func TestFindBy(t *testing.T) { + findData := []data{} + var datalist []interface{} + var selectedData interface{} + + q, errJson := NewJsonFile("_example/example.json") + for _, item := range findData { + datalist = append(datalist, item) + } + + err := q.FindBy("3", "id", datalist, &selectedData) + + assert.NoError(t, errJson) + assert.NoError(t, err) + assert.NotNil(t, selectedData) + assert.NotEmpty(t, selectedData) + +} + +func TestFindAllBy(t *testing.T) { + findData := []data{} + var datalist []interface{} + var selectedData []interface{} + + q, errJson := NewJsonFile("_example/example.json") + for _, item := range findData { + datalist = append(datalist, item) + } + err := q.FindAllBy("Fruit", "category", datalist, &selectedData) + + assert.NoError(t, errJson) + assert.NoError(t, err) + assert.NotNil(t, findData) +} diff --git a/redis.go b/redis.go index 85ab1be..8fa32c5 100644 --- a/redis.go +++ b/redis.go @@ -3,7 +3,6 @@ package gfunc import ( "context" "encoding/json" - "fmt" "log" "reflect" "time" @@ -74,10 +73,3 @@ func (r *Redis) GetJSON(key string, data interface{}) error { return nil } -func ErrMsg(err string) string { - const redColor = "\033[31m" - const resetColor = "\033[0m" - - response := fmt.Sprintf("%serror%s: %s", redColor, resetColor, err) - return response -}