From 926898b8e1199f37ac353e07d92dbdea83533553 Mon Sep 17 00:00:00 2001 From: Gabriel Tomazi Date: Wed, 15 Jan 2020 11:25:16 -0300 Subject: [PATCH 1/3] Added JSONQGet function, which is used on RedisJSON2 to combine RedisJSON and RediSearch, making a GET with Query --- clients/goredis.go | 35 ++++++++++++++++++++++++++++++++++- clients/redigo.go | 27 ++++++++++++++++++++++++++- rejson.go | 10 ++++++++++ rjs/commands.go | 9 +++++++++ rjs/constants.go | 3 +++ 5 files changed, 82 insertions(+), 2 deletions(-) mode change 100644 => 100755 clients/goredis.go mode change 100644 => 100755 clients/redigo.go mode change 100644 => 100755 rejson.go mode change 100644 => 100755 rjs/commands.go mode change 100644 => 100755 rjs/constants.go diff --git a/clients/goredis.go b/clients/goredis.go old mode 100644 new mode 100755 index bcb2541..49601ec --- a/clients/goredis.go +++ b/clients/goredis.go @@ -2,9 +2,10 @@ package clients import ( "fmt" + "strings" + goredis "github.com/go-redis/redis" "github.com/nitishm/go-rejson/rjs" - "strings" ) // GoRedis implements ReJSON interface for Go-Redis/Redis Redis client @@ -78,6 +79,38 @@ func (r *GoRedis) JSONGet(key, path string, opts ...rjs.GetOption) (res interfac return rjs.StringToBytes(res), err } +//JSONQGet - +func (r *GoRedis) JSONQGet(key string, params ...string) (res interface{}, err error) { + + args := make([]interface{}, 0) + arrParam := make([]string, 0) + args = append(args, key) + + strParam := `'` + for _, param := range params { + arrParam = append(arrParam, param) + } + strParam += strings.Join(arrParam, " ") + strParam += `'` + + args = append(args, strParam) + + name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandQGET, args...) + if err != nil { + return nil, err + } + + args = append([]interface{}{name}, args...) + + res, err = r.Conn.Do(args...).Result() + if err != nil { + fmt.Println(err.Error()) + return + } + + return rjs.StringToBytes(res), err +} + // JSONMGet used to get path values from multiple keys // // ReJSON syntax: diff --git a/clients/redigo.go b/clients/redigo.go old mode 100644 new mode 100755 index a2fd91a..0cccf6e --- a/clients/redigo.go +++ b/clients/redigo.go @@ -2,9 +2,10 @@ package clients import ( "fmt" + "strings" + redigo "github.com/gomodule/redigo/redis" "github.com/nitishm/go-rejson/rjs" - "strings" ) // Redigo implements ReJSON interface for GoModule/Redigo Redis client @@ -67,6 +68,30 @@ func (r *Redigo) JSONGet(key, path string, opts ...rjs.GetOption) (res interface return r.Conn.Do(name, args...) } +//JSONQGet - +func (r *Redigo) JSONQGet(key string, params ...string) (res interface{}, err error) { + + args := make([]interface{}, 0) + arrParam := make([]string, 0) + args = append(args, key) + + strParam := `'` + for _, param := range params { + arrParam = append(arrParam, param) + } + strParam += strings.Join(arrParam, " ") + strParam += `'` + + args = append(args, strParam) + + name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandQGET, args...) + if err != nil { + return nil, err + } + + return r.Conn.Do(name, args...) +} + // JSONMGet used to get path values from multiple keys // // ReJSON syntax: diff --git a/rejson.go b/rejson.go old mode 100644 new mode 100755 index 70e5ef8..60b48b4 --- a/rejson.go +++ b/rejson.go @@ -19,6 +19,8 @@ type ReJSON interface { JSONGet(key, path string, opts ...rjs.GetOption) (res interface{}, err error) + JSONQGet(key string, params ...string) (res interface{}, err error) + JSONMGet(path string, keys ...string) (res interface{}, err error) JSONDel(key, path string) (res interface{}, err error) @@ -88,6 +90,14 @@ func (r *Handler) JSONGet(key, path string, opts ...rjs.GetOption) (res interfac return r.implementation.JSONGet(key, path, opts...) } +//JSONQGet - +func (r *Handler) JSONQGet(key string, params ...string) (res interface{}, err error) { + if r.clientName == rjs.ClientInactive { + return nil, rjs.ErrNoClientSet + } + return r.implementation.JSONQGet(key, params...) +} + // JSONMGet used to get path values from multiple keys // // ReJSON syntax: diff --git a/rjs/commands.go b/rjs/commands.go old mode 100644 new mode 100755 index 6ee407a..4706ed1 --- a/rjs/commands.go +++ b/rjs/commands.go @@ -43,6 +43,15 @@ func commandJSONGet(argsIn ...interface{}) (argsOut []interface{}, err error) { return } +func commandJSONQGet(argsIn ...interface{}) (argsOut []interface{}, err error) { + key := argsIn[0] + params := argsIn[1] + argsOut = append(argsOut, key) + argsOut = append(argsOut, params) + + return +} + func commandJSONGeneric(argsIn ...interface{}) (argsOut []interface{}, err error) { key := argsIn[0] path := argsIn[1] diff --git a/rjs/constants.go b/rjs/constants.go old mode 100644 new mode 100755 index 1665fcc..54cb2cb --- a/rjs/constants.go +++ b/rjs/constants.go @@ -50,6 +50,7 @@ const ( ReJSONCommandDEBUG ReJSONCommandID = 17 ReJSONCommandFORGET ReJSONCommandID = 18 ReJSONCommandRESP ReJSONCommandID = 19 + ReJSONCommandQGET ReJSONCommandID = 20 // JSONSET command Options SetOptionNX SetOption = "NX" @@ -86,12 +87,14 @@ var commandName = map[ReJSONCommandID]string{ ReJSONCommandDEBUG: "JSON.DEBUG", ReJSONCommandFORGET: "JSON.FORGET", ReJSONCommandRESP: "JSON.RESP", + ReJSONCommandQGET: "JSON.QGET", } // commandMux maps command id to their Command Builder functions var commandMux = map[ReJSONCommandID]CommandBuilderFunc{ ReJSONCommandSET: commandJSONSet, ReJSONCommandGET: commandJSONGet, + ReJSONCommandQGET: commandJSONQGet, ReJSONCommandDEL: commandJSONGeneric, ReJSONCommandMGET: commandJSONMGet, ReJSONCommandTYPE: commandJSONGeneric, From c5f1b7fedc0520eb6c2b65e379c8bd5c88633a3a Mon Sep 17 00:00:00 2001 From: Gabriel Tomazi Date: Fri, 17 Jan 2020 14:27:41 -0300 Subject: [PATCH 2/3] Added functions JSONIndexAdd JSONSetWithIndex --- clients/goredis.go | 55 +++++++++++++++++++++++++++++++++++++++++++++- clients/redigo.go | 42 ++++++++++++++++++++++++++++++++++- rejson.go | 37 ++++++++++++++++++++++++++++++- rjs/commands.go | 11 ++++++++++ rjs/constants.go | 3 +++ 5 files changed, 145 insertions(+), 3 deletions(-) diff --git a/clients/goredis.go b/clients/goredis.go index 49601ec..29f22fa 100755 --- a/clients/goredis.go +++ b/clients/goredis.go @@ -44,6 +44,54 @@ func (r *GoRedis) JSONSet(key string, path string, obj interface{}, opts ...rjs. return } +// JSONSetWithIndex used to set a json object +// +// ReJSON syntax: +// JSON.SET +// +func (r *GoRedis) JSONSetWithIndex(key string, path string, obj interface{}, index string) (res interface{}, err error) { // nolint: lll + + args := make([]interface{}, 0, 6) + args = append(args, key, path, obj, "INDEX "+index) + + name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandSET, args...) + if err != nil { + return nil, err + } + args = append([]interface{}{name}, args...) + fmt.Println(args) + res, err = r.Conn.Do(args...).Result() + + if err != nil && err.Error() == rjs.ErrGoRedisNil.Error() { + err = nil + } + return +} + +// JSONIndexAdd used to set a json object +// +// ReJSON syntax: +// JSON.INDEX ADD +// +func (r *GoRedis) JSONIndexAdd(index string, field string, path string) (res interface{}, err error) { // nolint: lll + + args := make([]interface{}, 0, 6) + args = append(args, "ADD", index, field, `$`+path) + + name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandINDEXADD, args...) + if err != nil { + return nil, err + } + args = append([]interface{}{name}, args...) + fmt.Println(args) + res, err = r.Conn.Do(args...).Result() + + if err != nil && err.Error() == rjs.ErrGoRedisNil.Error() { + err = nil + } + return +} + // JSONGet used to get a json object // // ReJSON syntax: @@ -79,7 +127,12 @@ func (r *GoRedis) JSONGet(key, path string, opts ...rjs.GetOption) (res interfac return rjs.StringToBytes(res), err } -//JSONQGet - +// JSONQGet used to get a json object +// +// ReJSON syntax: +// JSON.QGET +// [params ...] +//Pass params like "@name:Tom" func (r *GoRedis) JSONQGet(key string, params ...string) (res interface{}, err error) { args := make([]interface{}, 0) diff --git a/clients/redigo.go b/clients/redigo.go index 0cccf6e..e81595f 100755 --- a/clients/redigo.go +++ b/clients/redigo.go @@ -38,6 +38,40 @@ func (r *Redigo) JSONSet(key string, path string, obj interface{}, opts ...rjs.S return r.Conn.Do(name, args...) } +// JSONSetWithIndex used to set a json object +// +// ReJSON syntax: +// JSON.SET +// +func (r *Redigo) JSONSetWithIndex(key string, path string, obj interface{}, index string) (res interface{}, err error) { + + args := make([]interface{}, 0, 6) + args = append(args, key, path, obj, "INDEX "+index) + + name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandSET, args...) + if err != nil { + return nil, err + } + return r.Conn.Do(name, args...) +} + +// JSONIndexAdd used to set a json object +// +// ReJSON syntax: +// JSON.INDEX ADD +// +func (r *Redigo) JSONIndexAdd(index string, field string, path string) (res interface{}, err error) { + + args := make([]interface{}, 0, 6) + args = append(args, "ADD", index, field, `$`+path) + + name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandINDEXADD, args...) + if err != nil { + return nil, err + } + return r.Conn.Do(name, args...) +} + // JSONGet used to get a json object // // ReJSON syntax: @@ -68,7 +102,13 @@ func (r *Redigo) JSONGet(key, path string, opts ...rjs.GetOption) (res interface return r.Conn.Do(name, args...) } -//JSONQGet - +// JSONQGet used to get a json object +// +// ReJSON syntax: +// JSON.QGET +// [params ...] +// +//Pass params like "@name:Tom" func (r *Redigo) JSONQGet(key string, params ...string) (res interface{}, err error) { args := make([]interface{}, 0) diff --git a/rejson.go b/rejson.go index 60b48b4..d20416d 100755 --- a/rejson.go +++ b/rejson.go @@ -17,10 +17,14 @@ func NewReJSONHandler() *Handler { type ReJSON interface { JSONSet(key, path string, obj interface{}, opts ...rjs.SetOption) (res interface{}, err error) + JSONSetWithIndex(key, path string, obj interface{}, index string) (res interface{}, err error) + JSONGet(key, path string, opts ...rjs.GetOption) (res interface{}, err error) JSONQGet(key string, params ...string) (res interface{}, err error) + JSONIndexAdd(key, field, path string) (res interface{}, err error) + JSONMGet(path string, keys ...string) (res interface{}, err error) JSONDel(key, path string) (res interface{}, err error) @@ -73,6 +77,20 @@ func (r *Handler) JSONSet(key string, path string, obj interface{}, opts ...rjs. return r.implementation.JSONSet(key, path, obj, opts...) } +// JSONSetWithIndex used to set a json object +// +// ReJSON syntax: +// JSON.SET +// +func (r *Handler) JSONSetWithIndex(key string, path string, obj interface{}, index string) ( + res interface{}, err error) { + + if r.clientName == rjs.ClientInactive { + return nil, rjs.ErrNoClientSet + } + return r.implementation.JSONSetWithIndex(key, path, obj, index) +} + // JSONGet used to get a json object // // ReJSON syntax: @@ -90,7 +108,12 @@ func (r *Handler) JSONGet(key, path string, opts ...rjs.GetOption) (res interfac return r.implementation.JSONGet(key, path, opts...) } -//JSONQGet - +// JSONQGet used to get a json object +// +// ReJSON syntax: +// JSON.QGET +// [params ...] +//Pass params like "@name:Tom" func (r *Handler) JSONQGet(key string, params ...string) (res interface{}, err error) { if r.clientName == rjs.ClientInactive { return nil, rjs.ErrNoClientSet @@ -98,6 +121,18 @@ func (r *Handler) JSONQGet(key string, params ...string) (res interface{}, err e return r.implementation.JSONQGet(key, params...) } +// JSONAddIndex used to get a json object +// +// ReJSON syntax: +// JSON.INDEX ADD +// +func (r *Handler) JSONIndexAdd(index, field, path string) (res interface{}, err error) { + if r.clientName == rjs.ClientInactive { + return nil, rjs.ErrNoClientSet + } + return r.implementation.JSONIndexAdd(index, field, path) +} + // JSONMGet used to get path values from multiple keys // // ReJSON syntax: diff --git a/rjs/commands.go b/rjs/commands.go index 4706ed1..91224aa 100755 --- a/rjs/commands.go +++ b/rjs/commands.go @@ -48,7 +48,18 @@ func commandJSONQGet(argsIn ...interface{}) (argsOut []interface{}, err error) { params := argsIn[1] argsOut = append(argsOut, key) argsOut = append(argsOut, params) + return +} +func commandJSONIndexAdd(argsIn ...interface{}) (argsOut []interface{}, err error) { + add := argsIn[0] + index := argsIn[1] + field := argsIn[2] + path := argsIn[3] + argsOut = append(argsOut, add) + argsOut = append(argsOut, index) + argsOut = append(argsOut, field) + argsOut = append(argsOut, path) return } diff --git a/rjs/constants.go b/rjs/constants.go index 54cb2cb..ba4eb47 100755 --- a/rjs/constants.go +++ b/rjs/constants.go @@ -51,6 +51,7 @@ const ( ReJSONCommandFORGET ReJSONCommandID = 18 ReJSONCommandRESP ReJSONCommandID = 19 ReJSONCommandQGET ReJSONCommandID = 20 + ReJSONCommandINDEXADD ReJSONCommandID = 21 // JSONSET command Options SetOptionNX SetOption = "NX" @@ -88,6 +89,7 @@ var commandName = map[ReJSONCommandID]string{ ReJSONCommandFORGET: "JSON.FORGET", ReJSONCommandRESP: "JSON.RESP", ReJSONCommandQGET: "JSON.QGET", + ReJSONCommandINDEXADD: "JSON.INDEX", } // commandMux maps command id to their Command Builder functions @@ -95,6 +97,7 @@ var commandMux = map[ReJSONCommandID]CommandBuilderFunc{ ReJSONCommandSET: commandJSONSet, ReJSONCommandGET: commandJSONGet, ReJSONCommandQGET: commandJSONQGet, + ReJSONCommandINDEXADD: commandJSONIndexAdd, ReJSONCommandDEL: commandJSONGeneric, ReJSONCommandMGET: commandJSONMGet, ReJSONCommandTYPE: commandJSONGeneric, From 478df73d232f2a83c767600ecab5f05f87bd00a7 Mon Sep 17 00:00:00 2001 From: Gabriel Tomazi Date: Fri, 17 Jan 2020 15:35:35 -0300 Subject: [PATCH 3/3] Command changed to JSONSetWithIndex --- clients/goredis.go | 8 ++++++-- clients/redigo.go | 2 +- rjs/commands.go | 18 ++++++++++++++++++ rjs/constants.go | 3 +++ rjs/helper.go | 2 +- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/clients/goredis.go b/clients/goredis.go index 29f22fa..8669170 100755 --- a/clients/goredis.go +++ b/clients/goredis.go @@ -52,14 +52,18 @@ func (r *GoRedis) JSONSet(key string, path string, obj interface{}, opts ...rjs. func (r *GoRedis) JSONSetWithIndex(key string, path string, obj interface{}, index string) (res interface{}, err error) { // nolint: lll args := make([]interface{}, 0, 6) + args = append(args, key, path, obj, "INDEX "+index) - name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandSET, args...) + name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandSETINDEX, args...) if err != nil { return nil, err } + args = append([]interface{}{name}, args...) + fmt.Println(args) + res, err = r.Conn.Do(args...).Result() if err != nil && err.Error() == rjs.ErrGoRedisNil.Error() { @@ -83,7 +87,7 @@ func (r *GoRedis) JSONIndexAdd(index string, field string, path string) (res int return nil, err } args = append([]interface{}{name}, args...) - fmt.Println(args) + res, err = r.Conn.Do(args...).Result() if err != nil && err.Error() == rjs.ErrGoRedisNil.Error() { diff --git a/clients/redigo.go b/clients/redigo.go index e81595f..d56641c 100755 --- a/clients/redigo.go +++ b/clients/redigo.go @@ -48,7 +48,7 @@ func (r *Redigo) JSONSetWithIndex(key string, path string, obj interface{}, inde args := make([]interface{}, 0, 6) args = append(args, key, path, obj, "INDEX "+index) - name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandSET, args...) + name, args, err := rjs.CommandBuilder(rjs.ReJSONCommandSETINDEX, args...) if err != nil { return nil, err } diff --git a/rjs/commands.go b/rjs/commands.go index 91224aa..a947072 100755 --- a/rjs/commands.go +++ b/rjs/commands.go @@ -34,6 +34,24 @@ func commandJSONSet(argsIn ...interface{}) (argsOut []interface{}, err error) { return } +func commandJSONSetWithIndex(argsIn ...interface{}) (argsOut []interface{}, err error) { + key := argsIn[0] + path := argsIn[1] + obj := argsIn[2] + index := argsIn[3] + + argsOut = append(argsOut, key, path) + + b, err := json.Marshal(obj) + if err != nil { + return nil, err + } + argsOut = append(argsOut, b) + argsOut = append(argsOut, index) + + return +} + func commandJSONGet(argsIn ...interface{}) (argsOut []interface{}, err error) { key := argsIn[0] path := argsIn[1] diff --git a/rjs/constants.go b/rjs/constants.go index ba4eb47..f9ed482 100755 --- a/rjs/constants.go +++ b/rjs/constants.go @@ -52,6 +52,7 @@ const ( ReJSONCommandRESP ReJSONCommandID = 19 ReJSONCommandQGET ReJSONCommandID = 20 ReJSONCommandINDEXADD ReJSONCommandID = 21 + ReJSONCommandSETINDEX ReJSONCommandID = 22 // JSONSET command Options SetOptionNX SetOption = "NX" @@ -90,11 +91,13 @@ var commandName = map[ReJSONCommandID]string{ ReJSONCommandRESP: "JSON.RESP", ReJSONCommandQGET: "JSON.QGET", ReJSONCommandINDEXADD: "JSON.INDEX", + ReJSONCommandSETINDEX: "JSON.SET", } // commandMux maps command id to their Command Builder functions var commandMux = map[ReJSONCommandID]CommandBuilderFunc{ ReJSONCommandSET: commandJSONSet, + ReJSONCommandSETINDEX: commandJSONSetWithIndex, ReJSONCommandGET: commandJSONGet, ReJSONCommandQGET: commandJSONQGet, ReJSONCommandINDEXADD: commandJSONIndexAdd, diff --git a/rjs/helper.go b/rjs/helper.go index 7d84237..6da30e1 100644 --- a/rjs/helper.go +++ b/rjs/helper.go @@ -33,7 +33,7 @@ func (r ReJSONCommandID) Value() int32 { // TypeSafety checks the validity of the command id func (r ReJSONCommandID) TypeSafety() error { - if r.Value() < 0 || r.Value() > 19 { + if r.Value() < 0 || r.Value() > 22 { return fmt.Errorf("error: invalid command id") } return nil