Skip to content

Commit

Permalink
Merge branch 'cyberbeast-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Shivam010 committed Dec 26, 2020
2 parents a9d5a7f + 9d03b1d commit 37e0315
Show file tree
Hide file tree
Showing 11 changed files with 284 additions and 98 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Go-ReJSON - a golang client for ReJSON (a JSON data type for Redis)
Go-ReJSON is a [Go](https://golang.org/) client for [ReJSON](https://github.com/RedisLabsModules/rejson) Redis Module.

Go-ReJSON is a [Go](https://golang.org/) client for [ReJSON](https://github.com/RedisLabsModules/rejson) Redis Module.

[![GoDoc](https://godoc.org/github.com/nitishm/go-rejson?status.svg)](https://godoc.org/github.com/nitishm/go-rejson)
[![Build Status](https://travis-ci.org/nitishm/go-rejson.svg?branch=master)](https://travis-ci.org/nitishm/go-rejson)
Expand All @@ -8,25 +9,26 @@ Go-ReJSON is a [Go](https://golang.org/) client for [ReJSON](https://github.com/

> ReJSON is a Redis module that implements ECMA-404 The JSON Data Interchange Standard as a native data type. It allows storing, updating and fetching JSON values from Redis keys (documents).

Primary features of ReJSON Module:

* Full support of the JSON standard
* JSONPath-like syntax for selecting element inside documents
* Documents are stored as binary data in a tree structure, allowing fast access to sub-elements
* Typed atomic operations for all JSON values types

Each and every feature of ReJSON Module is fully incorporated in the project.
Each and every feature of ReJSON Module is fully incorporated in the project.

Enjoy ReJSON with the type-safe Redis client, [`Go-Redis/Redis`](https://github.com/go-redis/redis) or use the print-like Redis-api client [`GoModule/Redigo`](https://github.com/gomodule/redigo).
Go-ReJSON supports both the clients. Use any of the above two client you want, Go-ReJSON helps you out with all its features and functionalities in a more generic and standard way.

Support for `mediocregopher/radix` and other Redis clients is in our RoadMap. Any contributions on the support for other clients is hearty welcome.

## Installation
go get github.com/nitishm/go-rejson

go get github.com/nitishm/go-rejson

## Example usage

```golang
package main

Expand All @@ -37,7 +39,7 @@ import (
"log"

"github.com/nitishm/go-rejson"
goredis "github.com/go-redis/redis/v7"
goredis "github.com/go-redis/redis/v8"
"github.com/gomodule/redigo/redis"
)

Expand Down
63 changes: 40 additions & 23 deletions clients/goredis.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
package clients

import (
"context"
"fmt"
goredis "github.com/go-redis/redis/v7"
"github.com/nitishm/go-rejson/rjs"
"strings"

goredis "github.com/go-redis/redis/v8"
"github.com/nitishm/go-rejson/rjs"
)

// GoRedis implements ReJSON interface for Go-Redis/Redis Redis client
// Link: https://github.com/go-redis/redis
type GoRedis struct {
Conn *goredis.Client // import goredis "github.com/go-redis/redis/v7"
Conn *goredis.Client // import goredis "github.com/go-redis/redis/v8"

// ctx defines context for the provided connection
ctx context.Context
}

// NewGoRedisClient returns a new GoRedis ReJSON client with the provided context
// and connection, if ctx is nil default context.Background will be used
func NewGoRedisClient(ctx context.Context, conn *goredis.Client) *GoRedis {
if ctx == nil {
ctx = context.Background()
}
return &GoRedis{
ctx: ctx,
Conn: conn,
}
}

// JSONSet used to set a json object
Expand All @@ -35,7 +52,7 @@ func (r *GoRedis) JSONSet(key string, path string, obj interface{}, opts ...rjs.
return nil, err
}
args = append([]interface{}{name}, args...)
res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()

if err != nil && err.Error() == rjs.ErrGoRedisNil.Error() {
err = nil
Expand Down Expand Up @@ -71,7 +88,7 @@ func (r *GoRedis) JSONGet(key, path string, opts ...rjs.GetOption) (res interfac
}

args = append([]interface{}{name}, args...)
res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()
if err != nil {
return
}
Expand Down Expand Up @@ -99,7 +116,7 @@ func (r *GoRedis) JSONMGet(path string, keys ...string) (res interface{}, err er
return nil, err
}
args = append([]interface{}{name}, args...)
res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()
if err != nil {
return
}
Expand Down Expand Up @@ -127,7 +144,7 @@ func (r *GoRedis) JSONDel(key string, path string) (res interface{}, err error)
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONType to get the type of key or member at path.
Expand All @@ -142,7 +159,7 @@ func (r *GoRedis) JSONType(key, path string) (res interface{}, err error) {
return nil, err
}
args = append([]interface{}{name}, args...)
res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()

if err != nil && err.Error() == rjs.ErrGoRedisNil.Error() {
err = nil
Expand All @@ -162,7 +179,7 @@ func (r *GoRedis) JSONNumIncrBy(key, path string, number int) (res interface{},
return nil, err
}
args = append([]interface{}{name}, args...)
res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()
if err != nil {
return
}
Expand All @@ -181,7 +198,7 @@ func (r *GoRedis) JSONNumMultBy(key, path string, number int) (res interface{},
return nil, err
}
args = append([]interface{}{name}, args...)
res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()
if err != nil {
return
}
Expand All @@ -200,7 +217,7 @@ func (r *GoRedis) JSONStrAppend(key, path, jsonstring string) (res interface{},
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONStrLen to return the length of a string member
Expand All @@ -215,7 +232,7 @@ func (r *GoRedis) JSONStrLen(key, path string) (res interface{}, err error) {
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONArrAppend to append json value into array at path
Expand All @@ -237,7 +254,7 @@ func (r *GoRedis) JSONArrAppend(key, path string, values ...interface{}) (res in
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONArrLen returns the length of the json array at path
Expand All @@ -252,7 +269,7 @@ func (r *GoRedis) JSONArrLen(key, path string) (res interface{}, err error) {
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONArrPop removes and returns element from the index in the array
Expand All @@ -269,7 +286,7 @@ func (r *GoRedis) JSONArrPop(key, path string, index int) (res interface{}, err
}
args = append([]interface{}{name}, args...)

res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()
if err != nil {
return
}
Expand Down Expand Up @@ -299,7 +316,7 @@ func (r *GoRedis) JSONArrIndex(key, path string, jsonValue interface{}, optional
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONArrTrim trims an array so that it contains only the specified inclusive range of elements
Expand All @@ -314,7 +331,7 @@ func (r *GoRedis) JSONArrTrim(key, path string, start, end int) (res interface{}
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONArrInsert inserts the json value(s) into the array at path before the index (shifts to the right).
Expand All @@ -336,7 +353,7 @@ func (r *GoRedis) JSONArrInsert(key, path string, index int, values ...interface
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONObjKeys returns the keys in the object that's referenced by path
Expand All @@ -351,7 +368,7 @@ func (r *GoRedis) JSONObjKeys(key, path string) (res interface{}, err error) {
return nil, err
}
args = append([]interface{}{name}, args...)
res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()
if err != nil {
return
}
Expand All @@ -376,7 +393,7 @@ func (r *GoRedis) JSONObjLen(key, path string) (res interface{}, err error) {
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONDebug reports information
Expand All @@ -397,7 +414,7 @@ func (r *GoRedis) JSONDebug(subcommand rjs.DebugSubCommand, key, path string) (r
return nil, err
}
args = append([]interface{}{name}, args...)
res, err = r.Conn.Do(args...).Result()
res, err = r.Conn.Do(r.ctx, args...).Result()
if err != nil {
return
}
Expand Down Expand Up @@ -426,7 +443,7 @@ func (r *GoRedis) JSONForget(key, path string) (res interface{}, err error) {
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}

// JSONResp returns the JSON in key in Redis Serialization Protocol (RESP).
Expand All @@ -441,5 +458,5 @@ func (r *GoRedis) JSONResp(key, path string) (res interface{}, err error) {
return nil, err
}
args = append([]interface{}{name}, args...)
return r.Conn.Do(args...).Result()
return r.Conn.Do(r.ctx, args...).Result()
}
30 changes: 30 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package rejson

import (
"context"
"github.com/nitishm/go-rejson/clients"
"github.com/nitishm/go-rejson/rjs"
)

// SetContext helps redis-clients, provide use of command level context
// in the ReJSON commands.
// Currently, only go-redis@v8 supports command level context, therefore
// a separate method is added to support it, maintaining the support for
// other clients and for backward compatibility. (nitishm/go-rejson#46)
func (r *Handler) SetContext(ctx context.Context) *Handler {
if r == nil {
return r // nil
}

if r.clientName == rjs.ClientGoRedis {
if old, ok := r.implementation.(*clients.GoRedis); ok {
return &Handler{
clientName: r.clientName,
implementation: clients.NewGoRedisClient(ctx, old.Conn),
}
}
}

// for other clients, context is of no use, hence return same
return r
}
10 changes: 7 additions & 3 deletions examples/json_array/json_array.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package main

import (
"context"
"encoding/json"
"flag"
"fmt"
"github.com/nitishm/go-rejson/rjs"
"log"

goredis "github.com/go-redis/redis/v7"
"github.com/nitishm/go-rejson/rjs"

goredis "github.com/go-redis/redis/v8"
"github.com/gomodule/redigo/redis"
"github.com/nitishm/go-rejson"
)

var ctx = context.Background()

func Example_JSONArray(rh *rejson.Handler) {
ArrIn := []string{"one", "two", "three", "four", "five"}
res, err := rh.JSONSet("arr", ".", ArrIn)
Expand Down Expand Up @@ -158,7 +162,7 @@ func main() {
// GoRedis Client
cli := goredis.NewClient(&goredis.Options{Addr: *addr})
defer func() {
if err := cli.FlushAll().Err(); err != nil {
if err := cli.FlushAll(ctx).Err(); err != nil {
log.Fatalf("goredis - failed to flush: %v", err)
}
if err := cli.Close(); err != nil {
Expand Down
10 changes: 7 additions & 3 deletions examples/json_obj/json_obj.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package main

import (
"context"
"encoding/json"
"flag"
"fmt"
"log"

"github.com/nitishm/go-rejson"
"github.com/nitishm/go-rejson/rjs"
"log"

goredis "github.com/go-redis/redis/v7"
goredis "github.com/go-redis/redis/v8"
"github.com/gomodule/redigo/redis"
)

var ctx = context.Background()

func Example_JSONObj(rh *rejson.Handler) {

type Object struct {
Expand Down Expand Up @@ -108,7 +112,7 @@ func main() {
// GoRedis Client
cli := goredis.NewClient(&goredis.Options{Addr: *addr})
defer func() {
if err := cli.FlushAll().Err(); err != nil {
if err := cli.FlushAll(ctx).Err(); err != nil {
log.Fatalf("goredis - failed to flush: %v", err)
}
if err := cli.Close(); err != nil {
Expand Down
7 changes: 5 additions & 2 deletions examples/json_set/json_set.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package main

import (
"context"
"encoding/json"
"flag"
"fmt"
"log"

goredis "github.com/go-redis/redis/v7"
goredis "github.com/go-redis/redis/v8"
"github.com/gomodule/redigo/redis"
"github.com/nitishm/go-rejson"
)

var ctx = context.Background()

// Name - student name
type Name struct {
First string `json:"first,omitempty"`
Expand Down Expand Up @@ -87,7 +90,7 @@ func main() {
// GoRedis Client
cli := goredis.NewClient(&goredis.Options{Addr: *addr})
defer func() {
if err := cli.FlushAll().Err(); err != nil {
if err := cli.FlushAll(ctx).Err(); err != nil {
log.Fatalf("goredis - failed to flush: %v", err)
}
if err := cli.Close(); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ module github.com/nitishm/go-rejson
go 1.14

require (
github.com/go-redis/redis/v7 v7.4.0
github.com/gomodule/redigo v1.8.2
github.com/go-redis/redis/v8 v8.4.4
github.com/gomodule/redigo v1.8.3
)
Loading

0 comments on commit 37e0315

Please sign in to comment.