forked from ebhomengo/niki
1
0
Fork 0
niki/vendor/github.com/redis/go-redis/v9/json.go

1017 lines
18 KiB
Go
Raw Normal View History

2024-02-18 10:42:21 +00:00
package redis
import (
"context"
"encoding/json"
"strings"
"github.com/redis/go-redis/v9/internal/proto"
"github.com/redis/go-redis/v9/internal/util"
)
// -------------------------------------------
type JSONCmdable interface {
JSONArrAppend(ctx context.Context, key, path string, values ...interface{}) *IntSliceCmd
2024-02-18 10:42:21 +00:00
JSONArrIndex(ctx context.Context, key, path string, value ...interface{}) *IntSliceCmd
2024-02-18 10:42:21 +00:00
JSONArrIndexWithArgs(ctx context.Context, key, path string, options *JSONArrIndexArgs, value ...interface{}) *IntSliceCmd
2024-02-18 10:42:21 +00:00
JSONArrInsert(ctx context.Context, key, path string, index int64, values ...interface{}) *IntSliceCmd
2024-02-18 10:42:21 +00:00
JSONArrLen(ctx context.Context, key, path string) *IntSliceCmd
2024-02-18 10:42:21 +00:00
JSONArrPop(ctx context.Context, key, path string, index int) *StringSliceCmd
2024-02-18 10:42:21 +00:00
JSONArrTrim(ctx context.Context, key, path string) *IntSliceCmd
2024-02-18 10:42:21 +00:00
JSONArrTrimWithArgs(ctx context.Context, key, path string, options *JSONArrTrimArgs) *IntSliceCmd
2024-02-18 10:42:21 +00:00
JSONClear(ctx context.Context, key, path string) *IntCmd
2024-02-18 10:42:21 +00:00
JSONDebugMemory(ctx context.Context, key, path string) *IntCmd
2024-02-18 10:42:21 +00:00
JSONDel(ctx context.Context, key, path string) *IntCmd
2024-02-18 10:42:21 +00:00
JSONForget(ctx context.Context, key, path string) *IntCmd
2024-02-18 10:42:21 +00:00
JSONGet(ctx context.Context, key string, paths ...string) *JSONCmd
2024-02-18 10:42:21 +00:00
JSONGetWithArgs(ctx context.Context, key string, options *JSONGetArgs, paths ...string) *JSONCmd
2024-02-18 10:42:21 +00:00
JSONMerge(ctx context.Context, key, path string, value string) *StatusCmd
2024-02-18 10:42:21 +00:00
JSONMSetArgs(ctx context.Context, docs []JSONSetArgs) *StatusCmd
2024-02-18 10:42:21 +00:00
JSONMSet(ctx context.Context, params ...interface{}) *StatusCmd
2024-02-18 10:42:21 +00:00
JSONMGet(ctx context.Context, path string, keys ...string) *JSONSliceCmd
2024-02-18 10:42:21 +00:00
JSONNumIncrBy(ctx context.Context, key, path string, value float64) *JSONCmd
2024-02-18 10:42:21 +00:00
JSONObjKeys(ctx context.Context, key, path string) *SliceCmd
2024-02-18 10:42:21 +00:00
JSONObjLen(ctx context.Context, key, path string) *IntPointerSliceCmd
2024-02-18 10:42:21 +00:00
JSONSet(ctx context.Context, key, path string, value interface{}) *StatusCmd
2024-02-18 10:42:21 +00:00
JSONSetMode(ctx context.Context, key, path string, value interface{}, mode string) *StatusCmd
2024-02-18 10:42:21 +00:00
JSONStrAppend(ctx context.Context, key, path, value string) *IntPointerSliceCmd
2024-02-18 10:42:21 +00:00
JSONStrLen(ctx context.Context, key, path string) *IntPointerSliceCmd
2024-02-18 10:42:21 +00:00
JSONToggle(ctx context.Context, key, path string) *IntPointerSliceCmd
2024-02-18 10:42:21 +00:00
JSONType(ctx context.Context, key, path string) *JSONSliceCmd
}
type JSONSetArgs struct {
Key string
Path string
2024-02-18 10:42:21 +00:00
Value interface{}
}
type JSONArrIndexArgs struct {
Start int
Stop *int
2024-02-18 10:42:21 +00:00
}
type JSONArrTrimArgs struct {
Start int
Stop *int
2024-02-18 10:42:21 +00:00
}
type JSONCmd struct {
baseCmd
val string
2024-02-18 10:42:21 +00:00
expanded []interface{}
}
var _ Cmder = (*JSONCmd)(nil)
func newJSONCmd(ctx context.Context, args ...interface{}) *JSONCmd {
2024-02-18 10:42:21 +00:00
return &JSONCmd{
2024-02-18 10:42:21 +00:00
baseCmd: baseCmd{
ctx: ctx,
2024-02-18 10:42:21 +00:00
args: args,
},
}
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONCmd) String() string {
2024-02-18 10:42:21 +00:00
return cmdString(cmd, cmd.val)
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONCmd) SetVal(val string) {
2024-02-18 10:42:21 +00:00
cmd.val = val
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONCmd) Val() string {
2024-02-18 10:42:21 +00:00
if len(cmd.val) == 0 && cmd.expanded != nil {
2024-02-18 10:42:21 +00:00
val, err := json.Marshal(cmd.expanded)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
cmd.SetErr(err)
2024-02-18 10:42:21 +00:00
return ""
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return string(val)
} else {
2024-02-18 10:42:21 +00:00
return cmd.val
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONCmd) Result() (string, error) {
2024-02-18 10:42:21 +00:00
return cmd.Val(), cmd.Err()
2024-02-18 10:42:21 +00:00
}
func (cmd JSONCmd) Expanded() (interface{}, error) {
2024-02-18 10:42:21 +00:00
if len(cmd.val) != 0 && cmd.expanded == nil {
2024-02-18 10:42:21 +00:00
err := json.Unmarshal([]byte(cmd.val), &cmd.expanded)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return "", err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
return cmd.expanded, nil
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONCmd) readReply(rd *proto.Reader) error {
2024-02-18 10:42:21 +00:00
// nil response from JSON.(M)GET (cmd.baseCmd.err will be "redis: nil")
2024-02-18 10:42:21 +00:00
if cmd.baseCmd.Err() == Nil {
2024-02-18 10:42:21 +00:00
cmd.val = ""
2024-02-18 10:42:21 +00:00
return Nil
2024-02-18 10:42:21 +00:00
}
if readType, err := rd.PeekReplyType(); err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
} else if readType == proto.RespArray {
size, err := rd.ReadArrayLen()
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
expanded := make([]interface{}, size)
for i := 0; i < size; i++ {
2024-02-18 10:42:21 +00:00
if expanded[i], err = rd.ReadReply(); err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd.expanded = expanded
} else {
2024-02-18 10:42:21 +00:00
if str, err := rd.ReadString(); err != nil && err != Nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
} else if str == "" || err == Nil {
2024-02-18 10:42:21 +00:00
cmd.val = ""
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
cmd.val = str
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
return nil
2024-02-18 10:42:21 +00:00
}
// -------------------------------------------
type JSONSliceCmd struct {
baseCmd
2024-02-18 10:42:21 +00:00
val []interface{}
}
func NewJSONSliceCmd(ctx context.Context, args ...interface{}) *JSONSliceCmd {
2024-02-18 10:42:21 +00:00
return &JSONSliceCmd{
2024-02-18 10:42:21 +00:00
baseCmd: baseCmd{
ctx: ctx,
2024-02-18 10:42:21 +00:00
args: args,
},
}
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONSliceCmd) String() string {
2024-02-18 10:42:21 +00:00
return cmdString(cmd, cmd.val)
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONSliceCmd) SetVal(val []interface{}) {
2024-02-18 10:42:21 +00:00
cmd.val = val
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONSliceCmd) Val() []interface{} {
2024-02-18 10:42:21 +00:00
return cmd.val
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONSliceCmd) Result() ([]interface{}, error) {
2024-02-18 10:42:21 +00:00
return cmd.val, cmd.err
2024-02-18 10:42:21 +00:00
}
func (cmd *JSONSliceCmd) readReply(rd *proto.Reader) error {
2024-02-18 10:42:21 +00:00
if cmd.baseCmd.Err() == Nil {
2024-02-18 10:42:21 +00:00
cmd.val = nil
2024-02-18 10:42:21 +00:00
return Nil
2024-02-18 10:42:21 +00:00
}
if readType, err := rd.PeekReplyType(); err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
} else if readType == proto.RespArray {
2024-02-18 10:42:21 +00:00
response, err := rd.ReadReply()
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
cmd.val = response.([]interface{})
2024-02-18 10:42:21 +00:00
}
} else {
2024-02-18 10:42:21 +00:00
n, err := rd.ReadArrayLen()
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd.val = make([]interface{}, n)
2024-02-18 10:42:21 +00:00
for i := 0; i < len(cmd.val); i++ {
2024-02-18 10:42:21 +00:00
switch s, err := rd.ReadString(); {
2024-02-18 10:42:21 +00:00
case err == Nil:
2024-02-18 10:42:21 +00:00
cmd.val[i] = ""
2024-02-18 10:42:21 +00:00
case err != nil:
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
default:
2024-02-18 10:42:21 +00:00
cmd.val[i] = s
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
/*******************************************************************************
2024-02-18 10:42:21 +00:00
*
2024-02-18 10:42:21 +00:00
* IntPointerSliceCmd
2024-02-18 10:42:21 +00:00
* used to represent a RedisJSON response where the result is either an integer or nil
2024-02-18 10:42:21 +00:00
*
2024-02-18 10:42:21 +00:00
*******************************************************************************/
type IntPointerSliceCmd struct {
baseCmd
2024-02-18 10:42:21 +00:00
val []*int64
}
// NewIntPointerSliceCmd initialises an IntPointerSliceCmd
2024-02-18 10:42:21 +00:00
func NewIntPointerSliceCmd(ctx context.Context, args ...interface{}) *IntPointerSliceCmd {
2024-02-18 10:42:21 +00:00
return &IntPointerSliceCmd{
2024-02-18 10:42:21 +00:00
baseCmd: baseCmd{
ctx: ctx,
2024-02-18 10:42:21 +00:00
args: args,
},
}
2024-02-18 10:42:21 +00:00
}
func (cmd *IntPointerSliceCmd) String() string {
2024-02-18 10:42:21 +00:00
return cmdString(cmd, cmd.val)
2024-02-18 10:42:21 +00:00
}
func (cmd *IntPointerSliceCmd) SetVal(val []*int64) {
2024-02-18 10:42:21 +00:00
cmd.val = val
2024-02-18 10:42:21 +00:00
}
func (cmd *IntPointerSliceCmd) Val() []*int64 {
2024-02-18 10:42:21 +00:00
return cmd.val
2024-02-18 10:42:21 +00:00
}
func (cmd *IntPointerSliceCmd) Result() ([]*int64, error) {
2024-02-18 10:42:21 +00:00
return cmd.val, cmd.err
2024-02-18 10:42:21 +00:00
}
func (cmd *IntPointerSliceCmd) readReply(rd *proto.Reader) error {
2024-02-18 10:42:21 +00:00
n, err := rd.ReadArrayLen()
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd.val = make([]*int64, n)
for i := 0; i < len(cmd.val); i++ {
2024-02-18 10:42:21 +00:00
val, err := rd.ReadInt()
2024-02-18 10:42:21 +00:00
if err != nil && err != Nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
} else if err != Nil {
2024-02-18 10:42:21 +00:00
cmd.val[i] = &val
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
return nil
2024-02-18 10:42:21 +00:00
}
//------------------------------------------------------------------------------
// JSONArrAppend adds the provided JSON values to the end of the array at the given path.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.arrappend
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONArrAppend(ctx context.Context, key, path string, values ...interface{}) *IntSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.ARRAPPEND", key, path}
2024-02-18 10:42:21 +00:00
args = append(args, values...)
2024-02-18 10:42:21 +00:00
cmd := NewIntSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONArrIndex searches for the first occurrence of the provided JSON value in the array at the given path.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.arrindex
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONArrIndex(ctx context.Context, key, path string, value ...interface{}) *IntSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.ARRINDEX", key, path}
2024-02-18 10:42:21 +00:00
args = append(args, value...)
2024-02-18 10:42:21 +00:00
cmd := NewIntSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONArrIndexWithArgs searches for the first occurrence of a JSON value in an array while allowing the start and
2024-02-18 10:42:21 +00:00
// stop options to be provided.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.arrindex
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONArrIndexWithArgs(ctx context.Context, key, path string, options *JSONArrIndexArgs, value ...interface{}) *IntSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.ARRINDEX", key, path}
2024-02-18 10:42:21 +00:00
args = append(args, value...)
if options != nil {
2024-02-18 10:42:21 +00:00
args = append(args, options.Start)
2024-02-18 10:42:21 +00:00
if options.Stop != nil {
2024-02-18 10:42:21 +00:00
args = append(args, *options.Stop)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewIntSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONArrInsert inserts the JSON values into the array at the specified path before the index (shifts to the right).
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.arrinsert
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONArrInsert(ctx context.Context, key, path string, index int64, values ...interface{}) *IntSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.ARRINSERT", key, path, index}
2024-02-18 10:42:21 +00:00
args = append(args, values...)
2024-02-18 10:42:21 +00:00
cmd := NewIntSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONArrLen reports the length of the JSON array at the specified path in the given key.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.arrlen
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONArrLen(ctx context.Context, key, path string) *IntSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.ARRLEN", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewIntSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONArrPop removes and returns an element from the specified index in the array.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.arrpop
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONArrPop(ctx context.Context, key, path string, index int) *StringSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.ARRPOP", key, path, index}
2024-02-18 10:42:21 +00:00
cmd := NewStringSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONArrTrim trims an array to contain only the specified inclusive range of elements.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.arrtrim
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONArrTrim(ctx context.Context, key, path string) *IntSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.ARRTRIM", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewIntSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONArrTrimWithArgs trims an array to contain only the specified inclusive range of elements.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.arrtrim
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONArrTrimWithArgs(ctx context.Context, key, path string, options *JSONArrTrimArgs) *IntSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.ARRTRIM", key, path}
if options != nil {
2024-02-18 10:42:21 +00:00
args = append(args, options.Start)
if options.Stop != nil {
2024-02-18 10:42:21 +00:00
args = append(args, *options.Stop)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewIntSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONClear clears container values (arrays/objects) and sets numeric values to 0.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.clear
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONClear(ctx context.Context, key, path string) *IntCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.CLEAR", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONDebugMemory reports a value's memory usage in bytes (unimplemented)
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.debug-memory
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONDebugMemory(ctx context.Context, key, path string) *IntCmd {
2024-02-18 10:42:21 +00:00
panic("not implemented")
2024-02-18 10:42:21 +00:00
}
// JSONDel deletes a value.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.del
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONDel(ctx context.Context, key, path string) *IntCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.DEL", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONForget deletes a value.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.forget
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONForget(ctx context.Context, key, path string) *IntCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.FORGET", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewIntCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONGet returns the value at path in JSON serialized form. JSON.GET returns an
2024-02-18 10:42:21 +00:00
// array of strings. This function parses out the wrapping array but leaves the
2024-02-18 10:42:21 +00:00
// internal strings unprocessed by default (see Val())
2024-02-18 10:42:21 +00:00
// For more information - https://redis.io/commands/json.get/
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONGet(ctx context.Context, key string, paths ...string) *JSONCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, len(paths)+2)
2024-02-18 10:42:21 +00:00
args[0] = "JSON.GET"
2024-02-18 10:42:21 +00:00
args[1] = key
2024-02-18 10:42:21 +00:00
for n, path := range paths {
2024-02-18 10:42:21 +00:00
args[n+2] = path
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := newJSONCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
type JSONGetArgs struct {
Indent string
2024-02-18 10:42:21 +00:00
Newline string
Space string
2024-02-18 10:42:21 +00:00
}
// JSONGetWithArgs - Retrieves the value of a key from a JSON document.
2024-02-18 10:42:21 +00:00
// This function also allows for specifying additional options such as:
2024-02-18 10:42:21 +00:00
// Indention, NewLine and Space
2024-02-18 10:42:21 +00:00
// For more information - https://redis.io/commands/json.get/
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONGetWithArgs(ctx context.Context, key string, options *JSONGetArgs, paths ...string) *JSONCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.GET", key}
2024-02-18 10:42:21 +00:00
if options != nil {
2024-02-18 10:42:21 +00:00
if options.Indent != "" {
2024-02-18 10:42:21 +00:00
args = append(args, "INDENT", options.Indent)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if options.Newline != "" {
2024-02-18 10:42:21 +00:00
args = append(args, "NEWLINE", options.Newline)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if options.Space != "" {
2024-02-18 10:42:21 +00:00
args = append(args, "SPACE", options.Space)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
for _, path := range paths {
2024-02-18 10:42:21 +00:00
args = append(args, path)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := newJSONCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONMerge merges a given JSON value into matching paths.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.merge
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONMerge(ctx context.Context, key, path string, value string) *StatusCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.MERGE", key, path, value}
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONMGet returns the values at the specified path from multiple key arguments.
2024-02-18 10:42:21 +00:00
// Note - the arguments are reversed when compared with `JSON.MGET` as we want
2024-02-18 10:42:21 +00:00
// to follow the pattern of having the last argument be variable.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.mget
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONMGet(ctx context.Context, path string, keys ...string) *JSONSliceCmd {
2024-02-18 10:42:21 +00:00
args := make([]interface{}, len(keys)+1)
2024-02-18 10:42:21 +00:00
args[0] = "JSON.MGET"
2024-02-18 10:42:21 +00:00
for n, key := range keys {
2024-02-18 10:42:21 +00:00
args[n+1] = key
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
args = append(args, path)
2024-02-18 10:42:21 +00:00
cmd := NewJSONSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONMSetArgs sets or updates one or more JSON values according to the specified key-path-value triplets.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.mset
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONMSetArgs(ctx context.Context, docs []JSONSetArgs) *StatusCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.MSET"}
2024-02-18 10:42:21 +00:00
for _, doc := range docs {
2024-02-18 10:42:21 +00:00
args = append(args, doc.Key, doc.Path, doc.Value)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
func (c cmdable) JSONMSet(ctx context.Context, params ...interface{}) *StatusCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.MSET"}
2024-02-18 10:42:21 +00:00
args = append(args, params...)
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONNumIncrBy increments the number value stored at the specified path by the provided number.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.numincreby
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONNumIncrBy(ctx context.Context, key, path string, value float64) *JSONCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.NUMINCRBY", key, path, value}
2024-02-18 10:42:21 +00:00
cmd := newJSONCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONObjKeys returns the keys in the object that's referenced by the specified path.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.objkeys
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONObjKeys(ctx context.Context, key, path string) *SliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.OBJKEYS", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONObjLen reports the number of keys in the JSON object at the specified path in the given key.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.objlen
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONObjLen(ctx context.Context, key, path string) *IntPointerSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.OBJLEN", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewIntPointerSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONSet sets the JSON value at the given path in the given key. The value must be something that
2024-02-18 10:42:21 +00:00
// can be marshaled to JSON (using encoding/JSON) unless the argument is a string or a []byte when we assume that
2024-02-18 10:42:21 +00:00
// it can be passed directly as JSON.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.set
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONSet(ctx context.Context, key, path string, value interface{}) *StatusCmd {
2024-02-18 10:42:21 +00:00
return c.JSONSetMode(ctx, key, path, value, "")
2024-02-18 10:42:21 +00:00
}
// JSONSetMode sets the JSON value at the given path in the given key and allows the mode to be set
2024-02-18 10:42:21 +00:00
// (the mode value must be "XX" or "NX"). The value must be something that can be marshaled to JSON (using encoding/JSON) unless
2024-02-18 10:42:21 +00:00
// the argument is a string or []byte when we assume that it can be passed directly as JSON.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.set
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONSetMode(ctx context.Context, key, path string, value interface{}, mode string) *StatusCmd {
2024-02-18 10:42:21 +00:00
var bytes []byte
2024-02-18 10:42:21 +00:00
var err error
2024-02-18 10:42:21 +00:00
switch v := value.(type) {
2024-02-18 10:42:21 +00:00
case string:
2024-02-18 10:42:21 +00:00
bytes = []byte(v)
2024-02-18 10:42:21 +00:00
case []byte:
2024-02-18 10:42:21 +00:00
bytes = v
2024-02-18 10:42:21 +00:00
default:
2024-02-18 10:42:21 +00:00
bytes, err = json.Marshal(v)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.SET", key, path, util.BytesToString(bytes)}
2024-02-18 10:42:21 +00:00
if mode != "" {
2024-02-18 10:42:21 +00:00
switch strings.ToUpper(mode) {
2024-02-18 10:42:21 +00:00
case "XX", "NX":
2024-02-18 10:42:21 +00:00
args = append(args, strings.ToUpper(mode))
default:
2024-02-18 10:42:21 +00:00
panic("redis: JSON.SET mode must be NX or XX")
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
cmd := NewStatusCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
cmd.SetErr(err)
2024-02-18 10:42:21 +00:00
} else {
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONStrAppend appends the JSON-string values to the string at the specified path.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.strappend
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONStrAppend(ctx context.Context, key, path, value string) *IntPointerSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.STRAPPEND", key, path, value}
2024-02-18 10:42:21 +00:00
cmd := NewIntPointerSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONStrLen reports the length of the JSON String at the specified path in the given key.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.strlen
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONStrLen(ctx context.Context, key, path string) *IntPointerSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.STRLEN", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewIntPointerSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONToggle toggles a Boolean value stored at the specified path.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.toggle
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONToggle(ctx context.Context, key, path string) *IntPointerSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.TOGGLE", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewIntPointerSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}
// JSONType reports the type of JSON value at the specified path.
2024-02-18 10:42:21 +00:00
// For more information, see https://redis.io/commands/json.type
2024-02-18 10:42:21 +00:00
func (c cmdable) JSONType(ctx context.Context, key, path string) *JSONSliceCmd {
2024-02-18 10:42:21 +00:00
args := []interface{}{"JSON.TYPE", key, path}
2024-02-18 10:42:21 +00:00
cmd := NewJSONSliceCmd(ctx, args...)
2024-02-18 10:42:21 +00:00
_ = c(ctx, cmd)
2024-02-18 10:42:21 +00:00
return cmd
2024-02-18 10:42:21 +00:00
}