diff --git a/clients/goredis.go b/clients/goredis.go old mode 100644 new mode 100755 index bcb2541..8669170 --- 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 @@ -43,6 +44,58 @@ 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.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() { + 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...) + + 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: @@ -78,6 +131,43 @@ func (r *GoRedis) JSONGet(key, path string, opts ...rjs.GetOption) (res interfac return rjs.StringToBytes(res), err } +// 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) + 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..d56641c --- 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 @@ -37,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.ReJSONCommandSETINDEX, 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: @@ -67,6 +102,36 @@ func (r *Redigo) JSONGet(key, path string, opts ...rjs.GetOption) (res interface return r.Conn.Do(name, args...) } +// 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) + 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..d20416d --- a/rejson.go +++ b/rejson.go @@ -17,8 +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) @@ -71,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: @@ -88,6 +108,31 @@ func (r *Handler) JSONGet(key, path string, opts ...rjs.GetOption) (res interfac return r.implementation.JSONGet(key, path, opts...) } +// 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 + } + 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 old mode 100644 new mode 100755 index 6ee407a..a947072 --- 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] @@ -43,6 +61,26 @@ 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 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 +} + 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..f9ed482 --- a/rjs/constants.go +++ b/rjs/constants.go @@ -50,6 +50,9 @@ const ( ReJSONCommandDEBUG ReJSONCommandID = 17 ReJSONCommandFORGET ReJSONCommandID = 18 ReJSONCommandRESP ReJSONCommandID = 19 + ReJSONCommandQGET ReJSONCommandID = 20 + ReJSONCommandINDEXADD ReJSONCommandID = 21 + ReJSONCommandSETINDEX ReJSONCommandID = 22 // JSONSET command Options SetOptionNX SetOption = "NX" @@ -86,12 +89,18 @@ var commandName = map[ReJSONCommandID]string{ ReJSONCommandDEBUG: "JSON.DEBUG", ReJSONCommandFORGET: "JSON.FORGET", 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, ReJSONCommandDEL: commandJSONGeneric, ReJSONCommandMGET: commandJSONMGet, ReJSONCommandTYPE: commandJSONGeneric, 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