Giter Site home page Giter Site logo

rejonson's Introduction

Rejonson

Redis rejson extension built upon go-redis

Build Status Coverage Status

Table of Contents

  1. Quick start
  2. API
  3. Dependencies
  4. Testing
  5. License
  6. Contact

Quick start

Install

go-redis v6

go get github.com/KromDaniel/rejonson

go-redis v7

go get github.com/KromDaniel/rejonson/v7

go-redis v8

go get github.com/KromDaniel/rejonson/v8

go-redis v9

go get github.com/KromDaniel/rejonson/v9

Quick Start

import (
	"github.com/KromDaniel/rejonson"
	"github.com/go-redis/redis"
)

func FunctionalApi(client *redis.Client) {
  // all rejonson.JsonX functions accepts redis.Client or redis.Pipeline
	// notice that some versions of go-redis also require context.Context (which is supported by rejonson)
	jsonStringCmd := rejonson.JsonGet(client, "key")
	if err := jsonStringCmd.Err(); err != nil {
		panic(err)
	}

	pipeline := client.Pipeline()
	rejonson.JsonGet(pipeline, "key")
	cmds, err := pipeline.Exec()
	// do something with cmds, err
}

func ExtendClient(client *redis.Client) *rejonson.Client {
  // You can extend go-redis client to rejonson.Client
  // that will have all JSON API as methods
	rejonsonClient := rejonson.ExtendClient(client)
	pingCmd := rejonsonClient.Ping()
	jsonCmd := rejonsonClient.JsonDel("key")

	return rejonsonClient
}

Functional API

Rejonson exports JsonX functions, all of them accept RedisProcessor as first parameter and context.Context (for go-redis versions >= 8) as second parameter, the other parameters are command specific

RedisProcessor

RedisProcessor is interface with the following definition:

type RedisProcessor interface {
	Process(redis.Cmder) error
}

go-redis >= 8

type RedisProcessor interface {
	Process(context.Context, redis.Cmder) error
}

By default all *redis.Client, redis.Pipeliner, *redis.ClusterClient, *redis.SentinelClient implenets that interface, so you can pass any of them to the rejonson functional API

example

client := redis.NewClient(&redis.Options{ /*...*/ })

res := rejonson.JsonMGet(client, "key1", "key2", "$..a")
if res.Err() != nil {
	// handle error
}

for _, value := range res.Val() {
	// do something with value
}

Extend Client

Extends go-redis client with all ReJSON abilities, so you can use directly the rejson client for all redis usage and commands.

// go redis client
goRedisClient := redis.NewClient(&redis.Options{
  Addr: "localhost:6379",
})

client := rejonson.ExtendClient(goRedisClient)
defer client.Close()

arr := []interface{}{"hello", "world", 1, map[string]interface{}{"key": 12}}
js, err := json.Marshal(arr)
if err != nil {
  // handle
}
// redis "native" command
client.Set("go-redis-cmd", "hello", time.Second)
// rejson command
client.JsonSet("rejson-cmd", ".", string(js))

// int command
arrLen, err := client.JsonArrLen("rejson-cmd", ".").Result()
if err != nil {
  // handle
}

fmt.Printf("Array length: %d", arrLen)
// Output: Array length: 4

Pipeline

Client will also return extended Pipeline and TXPipeline

goRedisClient := redis.NewClient(&redis.Options{
  Addr: "localhost:6379",
})

client := rejonson.ExtendClient(goRedisClient)

pipeline := client.Pipeline()
pipeline.JsonSet("rejson-cmd-pipeline", ".", "[10]")
pipeline.JsonNumMultBy("rejson-cmd-pipeline", "[0]", 10)
pipeline.Set("go-redis-pipeline-command", "hello from go-redis", time.Second)

_, err := pipeline.Exec()
if err != nil {
  // handle error
}
jsonString, err := client.JsonGet("rejson-cmd-pipeline").Result()
if err != nil {
  // handle error
}

fmt.Printf("Array %s", jsonString)

// Output: Array [100]

API

Rejonson implements all the methods as described at ReJson Commands except for JSON.DEBUG and JSON.RESP.

The args will be serialized to redis directly so make sure to read ReJSON command docs

All the rejson methods starts with the prefix of Json e.g JsonDel, JsonArrIndex, JsonMGet.
Each command returns specific go-redis.Cmder by the specific request.


Due to some ReJSON bug - #issue-76, some empty strings will be ignored.

Dependencies

Rejonson depends only on go-redis. The testing also depends on assert library

Test

Rejonson tests must use real redis with ReJson module to run

It is recommended to run the tests when using rejonson.
The unit tests will make sure your go-redis version is compatible and your rejson plugin supports all the methods and working as expected.

The testing library depends on assert library

License

Apache 2.0

Contact

For any question or contribution, feel free to open an issue.

rejonson's People

Contributors

dkrompalo avatar kromdaniel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

rejonson's Issues

Returning Error on Setting JSON

Trying to save a json using reJonson. getting Error

log.Println("Map",saveJson) //convert to unsafe text jsonString:=bytes.NewBuffer(jsonBytes).String() _,err=reJsonClient.JsonSet(key,".",jsonString).Result() if err!=nil{ log.Println("error",err) return false }

Error Log:

error ERR unknown commandJSON.SET, with args beginning with: test1, ., {"check":"salary","future":"uncertain","satisfied":"work"}`,

`

ERR Client sent AUTH, but no password is set

I am connecting to a redis service that requires a password:

    goRedisClient := redis.NewClient(&redis.Options{
        Addr:     "abc.com:8000",
        Password: "xxxxxxxxx",
        DB:       0,
    })

When I call client.JsonGet() method, I get an error message:

ERR Client sent AUTH, but no password is set

Looks like something went wrong about the password.

go-redis/v8 and UniversalClient support

ExtendClient currently on works with the unversioned branch of go-redis (which is currently stuck at v6 for me). The go-redis project currently recommends using their v8 client which gives me a type error.

One nice thing added into the v8 client is the UniversalClient (https://pkg.go.dev/github.com/go-redis/redis/v8#UniversalClient) which will automatically create a regular redis, sentinel, or cluster client based on opts passed.

I'm not sure how difficult these would be to support, but if you have a general outline of what needs added I can try adding in a PR for them if it's not something you plan or have time to add.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.