Compare commits
5 Commits
97f6ded7e0
...
44f8581a41
Author | SHA1 | Date |
---|---|---|
tiny-craft | 44f8581a41 | |
tiny-craft | 76734989d5 | |
tiny-craft | a4412d21d4 | |
tiny-craft | a6645e3340 | |
tiny-craft | ca663d8a55 |
|
@ -327,7 +327,7 @@ func (c *connectionService) OpenConnection(name string) (resp types.JSResp) {
|
||||||
// get connection config
|
// get connection config
|
||||||
selConn := c.conns.GetConnection(name)
|
selConn := c.conns.GetConnection(name)
|
||||||
|
|
||||||
totaldb := 16
|
var totaldb int
|
||||||
if selConn.DBFilterType == "" || selConn.DBFilterType == "none" {
|
if selConn.DBFilterType == "" || selConn.DBFilterType == "none" {
|
||||||
// get total databases
|
// get total databases
|
||||||
if config, err := rdb.ConfigGet(ctx, "databases").Result(); err == nil {
|
if config, err := rdb.ConfigGet(ctx, "databases").Result(); err == nil {
|
||||||
|
@ -343,9 +343,23 @@ func (c *connectionService) OpenConnection(name string) (resp types.JSResp) {
|
||||||
resp.Msg = "get server info fail:" + err.Error()
|
resp.Msg = "get server info fail:" + err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Parse all db, response content like below
|
// parse all db, response content like below
|
||||||
var dbs []types.ConnectionDB
|
var dbs []types.ConnectionDB
|
||||||
info := c.parseInfo(res)
|
info := c.parseInfo(res)
|
||||||
|
if totaldb <= 0 {
|
||||||
|
// cannot retrieve the database count by "CONFIG GET databases", try to get max index from keyspace
|
||||||
|
keyspace := info["Keyspace"]
|
||||||
|
var db, maxDB int
|
||||||
|
for dbName := range keyspace {
|
||||||
|
if db, err = strconv.Atoi(strings.TrimLeft(dbName, "db")); err == nil {
|
||||||
|
if maxDB < db {
|
||||||
|
maxDB = db
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totaldb = maxDB + 1
|
||||||
|
}
|
||||||
|
|
||||||
queryDB := func(idx int) types.ConnectionDB {
|
queryDB := func(idx int) types.ConnectionDB {
|
||||||
dbName := "db" + strconv.Itoa(idx)
|
dbName := "db" + strconv.Itoa(idx)
|
||||||
dbInfoStr := info["Keyspace"][dbName]
|
dbInfoStr := info["Keyspace"][dbName]
|
||||||
|
@ -531,7 +545,7 @@ func (c *connectionService) ScanKeys(connName string, db int, match, keyType str
|
||||||
|
|
||||||
filterType := len(keyType) > 0
|
filterType := len(keyType) > 0
|
||||||
|
|
||||||
var keys []string
|
var keys []any
|
||||||
//keys := map[string]keyItem{}
|
//keys := map[string]keyItem{}
|
||||||
var cursor uint64
|
var cursor uint64
|
||||||
for {
|
for {
|
||||||
|
@ -545,7 +559,9 @@ func (c *connectionService) ScanKeys(connName string, db int, match, keyType str
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
keys = append(keys, loadedKey...)
|
for _, k := range loadedKey {
|
||||||
|
keys = append(keys, strutil.EncodeRedisKey(k))
|
||||||
|
}
|
||||||
//for _, k := range loadedKey {
|
//for _, k := range loadedKey {
|
||||||
// //t, _ := rdb.Type(ctx, k).Result()
|
// //t, _ := rdb.Type(ctx, k).Result()
|
||||||
// keys[k] = keyItem{Type: "t"}
|
// keys[k] = keyItem{Type: "t"}
|
||||||
|
@ -565,13 +581,14 @@ func (c *connectionService) ScanKeys(connName string, db int, match, keyType str
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKeyValue get value by key
|
// GetKeyValue get value by key
|
||||||
func (c *connectionService) GetKeyValue(connName string, db int, key, viewAs string) (resp types.JSResp) {
|
func (c *connectionService) GetKeyValue(connName string, db int, k any, viewAs string) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
var keyType string
|
var keyType string
|
||||||
var dur time.Duration
|
var dur time.Duration
|
||||||
keyType, err = rdb.Type(ctx, key).Result()
|
keyType, err = rdb.Type(ctx, key).Result()
|
||||||
|
@ -703,13 +720,14 @@ func (c *connectionService) GetKeyValue(connName string, db int, key, viewAs str
|
||||||
|
|
||||||
// SetKeyValue set value by key
|
// SetKeyValue set value by key
|
||||||
// @param ttl <= 0 means keep current ttl
|
// @param ttl <= 0 means keep current ttl
|
||||||
func (c *connectionService) SetKeyValue(connName string, db int, key, keyType string, value any, ttl int64, viewAs string) (resp types.JSResp) {
|
func (c *connectionService) SetKeyValue(connName string, db int, k any, keyType string, value any, ttl int64, viewAs string) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
var expiration time.Duration
|
var expiration time.Duration
|
||||||
if ttl < 0 {
|
if ttl < 0 {
|
||||||
if expiration, err = rdb.PTTL(ctx, key).Result(); err != nil {
|
if expiration, err = rdb.PTTL(ctx, key).Result(); err != nil {
|
||||||
|
@ -825,13 +843,14 @@ func (c *connectionService) SetKeyValue(connName string, db int, key, keyType st
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHashValue set hash field
|
// SetHashValue set hash field
|
||||||
func (c *connectionService) SetHashValue(connName string, db int, key, field, newField, value string) (resp types.JSResp) {
|
func (c *connectionService) SetHashValue(connName string, db int, k any, field, newField, value string) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
var removedField []string
|
var removedField []string
|
||||||
updatedField := map[string]string{}
|
updatedField := map[string]string{}
|
||||||
if len(field) <= 0 {
|
if len(field) <= 0 {
|
||||||
|
@ -870,13 +889,14 @@ func (c *connectionService) SetHashValue(connName string, db int, key, field, ne
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddHashField add or update hash field
|
// AddHashField add or update hash field
|
||||||
func (c *connectionService) AddHashField(connName string, db int, key string, action int, fieldItems []any) (resp types.JSResp) {
|
func (c *connectionService) AddHashField(connName string, db int, k any, action int, fieldItems []any) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
updated := map[string]any{}
|
updated := map[string]any{}
|
||||||
switch action {
|
switch action {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -915,13 +935,14 @@ func (c *connectionService) AddHashField(connName string, db int, key string, ac
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddListItem add item to list or remove from it
|
// AddListItem add item to list or remove from it
|
||||||
func (c *connectionService) AddListItem(connName string, db int, key string, action int, items []any) (resp types.JSResp) {
|
func (c *connectionService) AddListItem(connName string, db int, k any, action int, items []any) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
var leftPush, rightPush []any
|
var leftPush, rightPush []any
|
||||||
switch action {
|
switch action {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -947,13 +968,14 @@ func (c *connectionService) AddListItem(connName string, db int, key string, act
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetListItem update or remove list item by index
|
// SetListItem update or remove list item by index
|
||||||
func (c *connectionService) SetListItem(connName string, db int, key string, index int64, value string) (resp types.JSResp) {
|
func (c *connectionService) SetListItem(connName string, db int, k any, index int64, value string) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
var removed []int64
|
var removed []int64
|
||||||
updated := map[int64]string{}
|
updated := map[int64]string{}
|
||||||
if len(value) <= 0 {
|
if len(value) <= 0 {
|
||||||
|
@ -989,13 +1011,14 @@ func (c *connectionService) SetListItem(connName string, db int, key string, ind
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSetItem add members to set or remove from set
|
// SetSetItem add members to set or remove from set
|
||||||
func (c *connectionService) SetSetItem(connName string, db int, key string, remove bool, members []any) (resp types.JSResp) {
|
func (c *connectionService) SetSetItem(connName string, db int, k any, remove bool, members []any) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
if remove {
|
if remove {
|
||||||
_, err = rdb.SRem(ctx, key, members...).Result()
|
_, err = rdb.SRem(ctx, key, members...).Result()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1011,13 +1034,14 @@ func (c *connectionService) SetSetItem(connName string, db int, key string, remo
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSetItem replace member of set
|
// UpdateSetItem replace member of set
|
||||||
func (c *connectionService) UpdateSetItem(connName string, db int, key, value, newValue string) (resp types.JSResp) {
|
func (c *connectionService) UpdateSetItem(connName string, db int, k any, value, newValue string) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
_, _ = rdb.SRem(ctx, key, value).Result()
|
_, _ = rdb.SRem(ctx, key, value).Result()
|
||||||
_, err = rdb.SAdd(ctx, key, newValue).Result()
|
_, err = rdb.SAdd(ctx, key, newValue).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1030,13 +1054,14 @@ func (c *connectionService) UpdateSetItem(connName string, db int, key, value, n
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateZSetValue update value of sorted set member
|
// UpdateZSetValue update value of sorted set member
|
||||||
func (c *connectionService) UpdateZSetValue(connName string, db int, key, value, newValue string, score float64) (resp types.JSResp) {
|
func (c *connectionService) UpdateZSetValue(connName string, db int, k any, value, newValue string, score float64) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
updated := map[string]any{}
|
updated := map[string]any{}
|
||||||
var removed []string
|
var removed []string
|
||||||
if len(newValue) <= 0 {
|
if len(newValue) <= 0 {
|
||||||
|
@ -1080,13 +1105,14 @@ func (c *connectionService) UpdateZSetValue(connName string, db int, key, value,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddZSetValue add item to sorted set
|
// AddZSetValue add item to sorted set
|
||||||
func (c *connectionService) AddZSetValue(connName string, db int, key string, action int, valueScore map[string]float64) (resp types.JSResp) {
|
func (c *connectionService) AddZSetValue(connName string, db int, k any, action int, valueScore map[string]float64) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
members := maputil.ToSlice(valueScore, func(k string) redis.Z {
|
members := maputil.ToSlice(valueScore, func(k string) redis.Z {
|
||||||
return redis.Z{
|
return redis.Z{
|
||||||
Score: valueScore[k],
|
Score: valueScore[k],
|
||||||
|
@ -1112,13 +1138,14 @@ func (c *connectionService) AddZSetValue(connName string, db int, key string, ac
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddStreamValue add stream field
|
// AddStreamValue add stream field
|
||||||
func (c *connectionService) AddStreamValue(connName string, db int, key, ID string, fieldItems []any) (resp types.JSResp) {
|
func (c *connectionService) AddStreamValue(connName string, db int, k any, ID string, fieldItems []any) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
_, err = rdb.XAdd(ctx, &redis.XAddArgs{
|
_, err = rdb.XAdd(ctx, &redis.XAddArgs{
|
||||||
Stream: key,
|
Stream: key,
|
||||||
ID: ID,
|
ID: ID,
|
||||||
|
@ -1134,26 +1161,28 @@ func (c *connectionService) AddStreamValue(connName string, db int, key, ID stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveStreamValues remove stream values by id
|
// RemoveStreamValues remove stream values by id
|
||||||
func (c *connectionService) RemoveStreamValues(connName string, db int, key string, IDs []string) (resp types.JSResp) {
|
func (c *connectionService) RemoveStreamValues(connName string, db int, k any, IDs []string) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
_, err = rdb.XDel(ctx, key, IDs...).Result()
|
_, err = rdb.XDel(ctx, key, IDs...).Result()
|
||||||
resp.Success = true
|
resp.Success = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetKeyTTL set ttl of key
|
// SetKeyTTL set ttl of key
|
||||||
func (c *connectionService) SetKeyTTL(connName string, db int, key string, ttl int64) (resp types.JSResp) {
|
func (c *connectionService) SetKeyTTL(connName string, db int, k any, ttl int64) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
var expiration time.Duration
|
var expiration time.Duration
|
||||||
if ttl < 0 {
|
if ttl < 0 {
|
||||||
if err = rdb.Persist(ctx, key).Err(); err != nil {
|
if err = rdb.Persist(ctx, key).Err(); err != nil {
|
||||||
|
@ -1173,14 +1202,15 @@ func (c *connectionService) SetKeyTTL(connName string, db int, key string, ttl i
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteKey remove redis key
|
// DeleteKey remove redis key
|
||||||
func (c *connectionService) DeleteKey(connName string, db int, key string) (resp types.JSResp) {
|
func (c *connectionService) DeleteKey(connName string, db int, k any) (resp types.JSResp) {
|
||||||
rdb, ctx, err := c.getRedisClient(connName, db)
|
rdb, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var deletedKeys []string
|
|
||||||
|
|
||||||
|
key := strutil.DecodeRedisKey(k)
|
||||||
|
var deletedKeys []string
|
||||||
if strings.HasSuffix(key, "*") {
|
if strings.HasSuffix(key, "*") {
|
||||||
// delete by prefix
|
// delete by prefix
|
||||||
var cursor uint64
|
var cursor uint64
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package strutil
|
||||||
|
|
||||||
|
import "unicode/utf8"
|
||||||
|
|
||||||
|
func containsBinary(str string) bool {
|
||||||
|
//buf := []byte(str)
|
||||||
|
//size := 0
|
||||||
|
//for start := 0; start < len(buf); start += size {
|
||||||
|
// var r rune
|
||||||
|
// if r, size = utf8.DecodeRune(buf[start:]); r == utf8.RuneError {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
if !utf8.ValidString(str) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
|
@ -54,7 +54,7 @@ func ConvertTo(str, targetType string) (value, resultType string) {
|
||||||
return
|
return
|
||||||
|
|
||||||
case types.HEX:
|
case types.HEX:
|
||||||
if hexStr, ok := decodeHex(str); ok {
|
if hexStr, ok := decodeToHex(str); ok {
|
||||||
value = hexStr
|
value = hexStr
|
||||||
} else {
|
} else {
|
||||||
value = str
|
value = str
|
||||||
|
@ -161,8 +161,8 @@ func autoToType(str string) (value, resultType string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isBinary(str) {
|
if containsBinary(str) {
|
||||||
if value, ok = decodeHex(str); ok {
|
if value, ok = decodeToHex(str); ok {
|
||||||
resultType = types.HEX
|
resultType = types.HEX
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -174,24 +174,12 @@ func autoToType(str string) (value, resultType string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func isBinary(str string) bool {
|
|
||||||
for _, s := range str {
|
|
||||||
if s < 0x20 || s > 0x7E {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeJson(str string) (string, bool) {
|
func decodeJson(str string) (string, bool) {
|
||||||
var data any
|
|
||||||
if (strings.HasPrefix(str, "{") && strings.HasSuffix(str, "}")) ||
|
if (strings.HasPrefix(str, "{") && strings.HasSuffix(str, "}")) ||
|
||||||
(strings.HasPrefix(str, "[") && strings.HasSuffix(str, "]")) {
|
(strings.HasPrefix(str, "[") && strings.HasSuffix(str, "]")) {
|
||||||
if err := json.Unmarshal([]byte(str), &data); err == nil {
|
var out bytes.Buffer
|
||||||
var jsonByte []byte
|
if err := json.Indent(&out, []byte(str), "", " "); err == nil {
|
||||||
if jsonByte, err = json.MarshalIndent(data, "", " "); err == nil {
|
return out.String(), true
|
||||||
return string(jsonByte), true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return str, false
|
return str, false
|
||||||
|
@ -212,7 +200,7 @@ func decodeBinary(str string) (string, bool) {
|
||||||
return binary.String(), true
|
return binary.String(), true
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeHex(str string) (string, bool) {
|
func decodeToHex(str string) (string, bool) {
|
||||||
decodeStr := hex.EncodeToString([]byte(str))
|
decodeStr := hex.EncodeToString([]byte(str))
|
||||||
var resultStr strings.Builder
|
var resultStr strings.Builder
|
||||||
for i := 0; i < len(decodeStr); i += 2 {
|
for i := 0; i < len(decodeStr); i += 2 {
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package strutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
sliceutil "tinyrdm/backend/utils/slice"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EncodeRedisKey encode the redis key to integer array
|
||||||
|
// if key contains binary which could not display on ui, convert the key to char array
|
||||||
|
func EncodeRedisKey(key string) any {
|
||||||
|
if containsBinary(key) {
|
||||||
|
b := []byte(key)
|
||||||
|
arr := make([]int, len(b))
|
||||||
|
for i, bb := range b {
|
||||||
|
arr[i] = int(bb)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeRedisKey decode redis key to readable string
|
||||||
|
func DecodeRedisKey(key any) string {
|
||||||
|
switch key.(type) {
|
||||||
|
case string:
|
||||||
|
return key.(string)
|
||||||
|
|
||||||
|
case []any:
|
||||||
|
arr := key.([]any)
|
||||||
|
bytes := sliceutil.Map(arr, func(i int) byte {
|
||||||
|
if c, ok := AnyToInt(arr[i]); ok {
|
||||||
|
return byte(c)
|
||||||
|
}
|
||||||
|
return '0'
|
||||||
|
})
|
||||||
|
return string(bytes)
|
||||||
|
|
||||||
|
case []int:
|
||||||
|
arr := key.([]int)
|
||||||
|
b := make([]byte, len(arr))
|
||||||
|
for i, bb := range arr {
|
||||||
|
b[i] = byte(bb)
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// AnyToInt convert any value to int
|
||||||
|
func AnyToInt(val any) (int, bool) {
|
||||||
|
switch val.(type) {
|
||||||
|
case string:
|
||||||
|
num, err := strconv.Atoi(val.(string))
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
return num, true
|
||||||
|
case float64:
|
||||||
|
return int(val.(float64)), true
|
||||||
|
case float32:
|
||||||
|
return int(val.(float32)), true
|
||||||
|
case int64:
|
||||||
|
return int(val.(int64)), true
|
||||||
|
case int32:
|
||||||
|
return int(val.(int32)), true
|
||||||
|
case int:
|
||||||
|
return val.(int), true
|
||||||
|
case bool:
|
||||||
|
if val.(bool) {
|
||||||
|
return 1, true
|
||||||
|
} else {
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { typesBgColor, typesColor, validType } from '@/consts/support_redis_type.js'
|
import { typesBgColor, typesColor, validType } from '@/consts/support_redis_type.js'
|
||||||
|
import Binary from '@/components/icons/Binary.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: {
|
type: {
|
||||||
|
@ -10,6 +11,7 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
default: 'STRING',
|
default: 'STRING',
|
||||||
},
|
},
|
||||||
|
binaryKey: Boolean,
|
||||||
bordered: Boolean,
|
bordered: Boolean,
|
||||||
size: String,
|
size: String,
|
||||||
})
|
})
|
||||||
|
@ -31,6 +33,9 @@ const backgroundColor = computed(() => {
|
||||||
:size="props.size"
|
:size="props.size"
|
||||||
strong>
|
strong>
|
||||||
{{ props.type }}
|
{{ props.type }}
|
||||||
|
<template #icon>
|
||||||
|
<n-icon v-if="binaryKey" :component="Binary" size="18" />
|
||||||
|
</template>
|
||||||
</n-tag>
|
</n-tag>
|
||||||
<!-- <div class="redis-type-tag flex-box-h" :style="{backgroundColor: backgroundColor}">{{ props.type }}</div>-->
|
<!-- <div class="redis-type-tag flex-box-h" :style="{backgroundColor: backgroundColor}">{{ props.type }}</div>-->
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -165,6 +165,7 @@ const tabContent = computed(() => {
|
||||||
type: toUpper(tab.type),
|
type: toUpper(tab.type),
|
||||||
db: tab.db,
|
db: tab.db,
|
||||||
keyPath: tab.key,
|
keyPath: tab.key,
|
||||||
|
keyCode: tab.keyCode,
|
||||||
ttl: tab.ttl,
|
ttl: tab.ttl,
|
||||||
value: tab.value,
|
value: tab.value,
|
||||||
size: tab.size || 0,
|
size: tab.size || 0,
|
||||||
|
@ -217,6 +218,7 @@ const onReloadKey = async () => {
|
||||||
v-else
|
v-else
|
||||||
:db="tabContent.db"
|
:db="tabContent.db"
|
||||||
:key-path="tabContent.keyPath"
|
:key-path="tabContent.keyPath"
|
||||||
|
:key-code="tabContent.keyCode"
|
||||||
:name="tabContent.name"
|
:name="tabContent.name"
|
||||||
:ttl="tabContent.ttl"
|
:ttl="tabContent.ttl"
|
||||||
:value="tabContent.value"
|
:value="tabContent.value"
|
||||||
|
|
|
@ -11,6 +11,8 @@ import IconButton from '@/components/common/IconButton.vue'
|
||||||
import useConnectionStore from 'stores/connections.js'
|
import useConnectionStore from 'stores/connections.js'
|
||||||
import Copy from '@/components/icons/Copy.vue'
|
import Copy from '@/components/icons/Copy.vue'
|
||||||
import { ClipboardSetText } from 'wailsjs/runtime/runtime.js'
|
import { ClipboardSetText } from 'wailsjs/runtime/runtime.js'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
server: String,
|
server: String,
|
||||||
|
@ -23,6 +25,10 @@ const props = defineProps({
|
||||||
default: 'STRING',
|
default: 'STRING',
|
||||||
},
|
},
|
||||||
keyPath: String,
|
keyPath: String,
|
||||||
|
keyCode: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
ttl: {
|
ttl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1,
|
default: -1,
|
||||||
|
@ -33,8 +39,20 @@ const dialogStore = useDialog()
|
||||||
const connectionStore = useConnectionStore()
|
const connectionStore = useConnectionStore()
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
|
|
||||||
|
const binaryKey = computed(() => {
|
||||||
|
return !!props.keyCode
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ComputedRef<string|number[]>}
|
||||||
|
*/
|
||||||
|
const keyName = computed(() => {
|
||||||
|
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||||
|
})
|
||||||
|
|
||||||
const onReloadKey = () => {
|
const onReloadKey = () => {
|
||||||
connectionStore.loadKeyValue(props.server, props.db, props.keyPath)
|
connectionStore.loadKeyValue(props.server, props.db, keyName.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onCopyKey = () => {
|
const onCopyKey = () => {
|
||||||
|
@ -49,9 +67,17 @@ const onCopyKey = () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onRenameKey = () => {
|
||||||
|
if (binaryKey.value) {
|
||||||
|
$message.error(i18n.t('dialogue.rename_binary_key_fail'))
|
||||||
|
} else {
|
||||||
|
dialogStore.openRenameKeyDialog(props.server, props.db, props.keyPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const onDeleteKey = () => {
|
const onDeleteKey = () => {
|
||||||
$dialog.warning(i18n.t('dialogue.remove_tip', { name: props.keyPath }), () => {
|
$dialog.warning(i18n.t('dialogue.remove_tip', { name: props.keyPath }), () => {
|
||||||
connectionStore.deleteKey(props.server, props.db, props.keyPath).then((success) => {
|
connectionStore.deleteKey(props.server, props.db, keyName.value).then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
$message.success(i18n.t('dialogue.delete_key_succ', { key: props.keyPath }))
|
$message.success(i18n.t('dialogue.delete_key_succ', { key: props.keyPath }))
|
||||||
}
|
}
|
||||||
|
@ -63,7 +89,7 @@ const onDeleteKey = () => {
|
||||||
<template>
|
<template>
|
||||||
<div class="content-toolbar flex-box-h">
|
<div class="content-toolbar flex-box-h">
|
||||||
<n-input-group>
|
<n-input-group>
|
||||||
<redis-type-tag :type="props.keyType" size="large" />
|
<redis-type-tag :type="props.keyType" :binary-key="binaryKey" size="large" />
|
||||||
<n-input v-model:value="props.keyPath">
|
<n-input v-model:value="props.keyPath">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<icon-button :icon="Refresh" size="18" t-tooltip="interface.reload" @click="onReloadKey" />
|
<icon-button :icon="Refresh" size="18" t-tooltip="interface.reload" @click="onReloadKey" />
|
||||||
|
@ -86,18 +112,13 @@ const onDeleteKey = () => {
|
||||||
</template>
|
</template>
|
||||||
TTL
|
TTL
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
<icon-button
|
<icon-button :icon="Edit" border size="18" t-tooltip="interface.rename_key" @click="onRenameKey" />
|
||||||
:icon="Edit"
|
|
||||||
border
|
|
||||||
size="18"
|
|
||||||
t-tooltip="interface.rename_key"
|
|
||||||
@click="dialogStore.openRenameKeyDialog(props.server, props.db, props.keyPath)" />
|
|
||||||
</n-button-group>
|
</n-button-group>
|
||||||
<n-tooltip>
|
<n-tooltip>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-button>
|
<n-button :focusable="false" @click="onDeleteKey">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon :component="Delete" size="18" @click="onDeleteKey" />
|
<n-icon :component="Delete" size="18" />
|
||||||
</template>
|
</template>
|
||||||
</n-button>
|
</n-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -8,12 +8,17 @@ import { types, types as redisTypes } from '@/consts/support_redis_type.js'
|
||||||
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
||||||
import useDialogStore from 'stores/dialog.js'
|
import useDialogStore from 'stores/dialog.js'
|
||||||
import useConnectionStore from 'stores/connections.js'
|
import useConnectionStore from 'stores/connections.js'
|
||||||
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
name: String,
|
name: String,
|
||||||
db: Number,
|
db: Number,
|
||||||
keyPath: String,
|
keyPath: String,
|
||||||
|
keyCode: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
ttl: {
|
ttl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1,
|
default: -1,
|
||||||
|
@ -22,6 +27,14 @@ const props = defineProps({
|
||||||
size: Number,
|
size: Number,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ComputedRef<string|number[]>}
|
||||||
|
*/
|
||||||
|
const keyName = computed(() => {
|
||||||
|
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||||
|
})
|
||||||
|
|
||||||
const filterOption = [
|
const filterOption = [
|
||||||
{
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
|
@ -119,11 +132,11 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.removeHashField(
|
const { success, msg } = await connectionStore.removeHashField(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
row.key,
|
row.key,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.key }))
|
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.key }))
|
||||||
// update display value
|
// update display value
|
||||||
// if (!isEmpty(removed)) {
|
// if (!isEmpty(removed)) {
|
||||||
|
@ -143,13 +156,13 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.setHash(
|
const { success, msg } = await connectionStore.setHash(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
row.key,
|
row.key,
|
||||||
currentEditRow.value.key,
|
currentEditRow.value.key,
|
||||||
currentEditRow.value.value,
|
currentEditRow.value.value,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.save_value_succ'))
|
$message.success(i18n.t('dialogue.save_value_succ'))
|
||||||
// update display value
|
// update display value
|
||||||
// if (!isEmpty(updated)) {
|
// if (!isEmpty(updated)) {
|
||||||
|
@ -198,7 +211,7 @@ const tableData = computed(() => {
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
const onAddRow = () => {
|
const onAddRow = () => {
|
||||||
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, types.HASH)
|
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, props.keyCode, types.HASH)
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterValue = ref('')
|
const filterValue = ref('')
|
||||||
|
@ -240,7 +253,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-wrapper flex-box-v">
|
<div class="content-wrapper flex-box-v">
|
||||||
<content-toolbar :db="props.db" :key-path="props.keyPath" :key-type="keyType" :server="props.name" :ttl="ttl" />
|
<content-toolbar
|
||||||
|
:db="props.db"
|
||||||
|
:key-path="props.keyPath"
|
||||||
|
:key-code="props.keyCode"
|
||||||
|
:key-type="keyType"
|
||||||
|
:server="props.name"
|
||||||
|
:ttl="ttl" />
|
||||||
<div class="tb2 flex-box-h">
|
<div class="tb2 flex-box-h">
|
||||||
<div class="flex-box-h">
|
<div class="flex-box-h">
|
||||||
<n-input-group>
|
<n-input-group>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n'
|
||||||
import ContentToolbar from './ContentToolbar.vue'
|
import ContentToolbar from './ContentToolbar.vue'
|
||||||
import AddLink from '@/components/icons/AddLink.vue'
|
import AddLink from '@/components/icons/AddLink.vue'
|
||||||
import { NButton, NCode, NIcon, NInput } from 'naive-ui'
|
import { NButton, NCode, NIcon, NInput } from 'naive-ui'
|
||||||
import { size } from 'lodash'
|
import { isEmpty, size } from 'lodash'
|
||||||
import { types, types as redisTypes } from '@/consts/support_redis_type.js'
|
import { types, types as redisTypes } from '@/consts/support_redis_type.js'
|
||||||
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
||||||
import useDialogStore from 'stores/dialog.js'
|
import useDialogStore from 'stores/dialog.js'
|
||||||
|
@ -15,6 +15,10 @@ const props = defineProps({
|
||||||
name: String,
|
name: String,
|
||||||
db: Number,
|
db: Number,
|
||||||
keyPath: String,
|
keyPath: String,
|
||||||
|
keyCode: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
ttl: {
|
ttl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1,
|
default: -1,
|
||||||
|
@ -23,6 +27,14 @@ const props = defineProps({
|
||||||
size: Number,
|
size: Number,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ComputedRef<string|number[]>}
|
||||||
|
*/
|
||||||
|
const keyName = computed(() => {
|
||||||
|
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||||
|
})
|
||||||
|
|
||||||
const connectionStore = useConnectionStore()
|
const connectionStore = useConnectionStore()
|
||||||
const dialogStore = useDialogStore()
|
const dialogStore = useDialogStore()
|
||||||
const keyType = redisTypes.LIST
|
const keyType = redisTypes.LIST
|
||||||
|
@ -56,6 +68,7 @@ const valueColumn = reactive({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const actionColumn = {
|
const actionColumn = {
|
||||||
key: 'action',
|
key: 'action',
|
||||||
title: i18n.t('interface.action'),
|
title: i18n.t('interface.action'),
|
||||||
|
@ -76,11 +89,11 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.removeListItem(
|
const { success, msg } = await connectionStore.removeListItem(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
row.no - 1,
|
row.no - 1,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.delete_key_succ', { key: '#' + row.no }))
|
$message.success(i18n.t('dialogue.delete_key_succ', { key: '#' + row.no }))
|
||||||
// update display value
|
// update display value
|
||||||
// if (!isEmpty(removed)) {
|
// if (!isEmpty(removed)) {
|
||||||
|
@ -98,12 +111,12 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.updateListItem(
|
const { success, msg } = await connectionStore.updateListItem(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
currentEditRow.value.no - 1,
|
currentEditRow.value.no - 1,
|
||||||
currentEditRow.value.value,
|
currentEditRow.value.value,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.save_value_succ'))
|
$message.success(i18n.t('dialogue.save_value_succ'))
|
||||||
// update display value
|
// update display value
|
||||||
// if (!isEmpty(updated)) {
|
// if (!isEmpty(updated)) {
|
||||||
|
@ -153,7 +166,7 @@ const tableData = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const onAddValue = (value) => {
|
const onAddValue = (value) => {
|
||||||
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, types.LIST)
|
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, props.keyCode, types.LIST)
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterValue = ref('')
|
const filterValue = ref('')
|
||||||
|
@ -172,7 +185,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-wrapper flex-box-v">
|
<div class="content-wrapper flex-box-v">
|
||||||
<content-toolbar :db="props.db" :key-path="props.keyPath" :key-type="keyType" :server="props.name" :ttl="ttl" />
|
<content-toolbar
|
||||||
|
:db="props.db"
|
||||||
|
:key-path="props.keyPath"
|
||||||
|
:key-code="props.keyCode"
|
||||||
|
:key-type="keyType"
|
||||||
|
:server="props.name"
|
||||||
|
:ttl="ttl" />
|
||||||
<div class="tb2 flex-box-h">
|
<div class="tb2 flex-box-h">
|
||||||
<div class="flex-box-h">
|
<div class="flex-box-h">
|
||||||
<n-input
|
<n-input
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n'
|
||||||
import ContentToolbar from './ContentToolbar.vue'
|
import ContentToolbar from './ContentToolbar.vue'
|
||||||
import AddLink from '@/components/icons/AddLink.vue'
|
import AddLink from '@/components/icons/AddLink.vue'
|
||||||
import { NButton, NCode, NIcon, NInput } from 'naive-ui'
|
import { NButton, NCode, NIcon, NInput } from 'naive-ui'
|
||||||
import { size } from 'lodash'
|
import { isEmpty, size } from 'lodash'
|
||||||
import useDialogStore from 'stores/dialog.js'
|
import useDialogStore from 'stores/dialog.js'
|
||||||
import { types, types as redisTypes } from '@/consts/support_redis_type.js'
|
import { types, types as redisTypes } from '@/consts/support_redis_type.js'
|
||||||
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
||||||
|
@ -15,6 +15,10 @@ const props = defineProps({
|
||||||
name: String,
|
name: String,
|
||||||
db: Number,
|
db: Number,
|
||||||
keyPath: String,
|
keyPath: String,
|
||||||
|
keyCode: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
ttl: {
|
ttl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1,
|
default: -1,
|
||||||
|
@ -23,6 +27,14 @@ const props = defineProps({
|
||||||
size: Number,
|
size: Number,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ComputedRef<string|number[]>}
|
||||||
|
*/
|
||||||
|
const keyName = computed(() => {
|
||||||
|
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||||
|
})
|
||||||
|
|
||||||
const connectionStore = useConnectionStore()
|
const connectionStore = useConnectionStore()
|
||||||
const dialogStore = useDialogStore()
|
const dialogStore = useDialogStore()
|
||||||
const keyType = redisTypes.SET
|
const keyType = redisTypes.SET
|
||||||
|
@ -78,11 +90,11 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.removeSetItem(
|
const { success, msg } = await connectionStore.removeSetItem(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
row.value,
|
row.value,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.value }))
|
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.value }))
|
||||||
// update display value
|
// update display value
|
||||||
// props.value.splice(row.no - 1, 1)
|
// props.value.splice(row.no - 1, 1)
|
||||||
|
@ -98,12 +110,12 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.updateSetItem(
|
const { success, msg } = await connectionStore.updateSetItem(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
row.value,
|
row.value,
|
||||||
currentEditRow.value.value,
|
currentEditRow.value.value,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.save_value_succ'))
|
$message.success(i18n.t('dialogue.save_value_succ'))
|
||||||
// update display value
|
// update display value
|
||||||
// props.value[row.no - 1] = currentEditRow.value.value
|
// props.value[row.no - 1] = currentEditRow.value.value
|
||||||
|
@ -149,7 +161,7 @@ const tableData = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const onAddValue = (value) => {
|
const onAddValue = (value) => {
|
||||||
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, types.SET)
|
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, props.keyCode, types.SET)
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterValue = ref('')
|
const filterValue = ref('')
|
||||||
|
@ -168,7 +180,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-wrapper flex-box-v">
|
<div class="content-wrapper flex-box-v">
|
||||||
<content-toolbar :db="props.db" :key-path="props.keyPath" :key-type="keyType" :server="props.name" :ttl="ttl" />
|
<content-toolbar
|
||||||
|
:db="props.db"
|
||||||
|
:key-path="props.keyPath"
|
||||||
|
:key-code="props.keyCode"
|
||||||
|
:key-type="keyType"
|
||||||
|
:server="props.name"
|
||||||
|
:ttl="ttl" />
|
||||||
<div class="tb2 flex-box-h">
|
<div class="tb2 flex-box-h">
|
||||||
<div class="flex-box-h">
|
<div class="flex-box-h">
|
||||||
<n-input
|
<n-input
|
||||||
|
|
|
@ -8,13 +8,17 @@ import { types, types as redisTypes } from '@/consts/support_redis_type.js'
|
||||||
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
||||||
import useDialogStore from 'stores/dialog.js'
|
import useDialogStore from 'stores/dialog.js'
|
||||||
import useConnectionStore from 'stores/connections.js'
|
import useConnectionStore from 'stores/connections.js'
|
||||||
import { includes, keys, some, values } from 'lodash'
|
import { includes, isEmpty, keys, some, values } from 'lodash'
|
||||||
|
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
name: String,
|
name: String,
|
||||||
db: Number,
|
db: Number,
|
||||||
keyPath: String,
|
keyPath: String,
|
||||||
|
keyCode: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
ttl: {
|
ttl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1,
|
default: -1,
|
||||||
|
@ -23,6 +27,14 @@ const props = defineProps({
|
||||||
size: Number,
|
size: Number,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ComputedRef<string|number[]>}
|
||||||
|
*/
|
||||||
|
const keyName = computed(() => {
|
||||||
|
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||||
|
})
|
||||||
|
|
||||||
const filterOption = [
|
const filterOption = [
|
||||||
{
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
|
@ -86,11 +98,11 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.removeStreamValues(
|
const { success, msg } = await connectionStore.removeStreamValues(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
row.id,
|
row.id,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.id }))
|
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.id }))
|
||||||
// update display value
|
// update display value
|
||||||
// if (!isEmpty(removed)) {
|
// if (!isEmpty(removed)) {
|
||||||
|
@ -122,7 +134,7 @@ const tableData = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const onAddRow = () => {
|
const onAddRow = () => {
|
||||||
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, types.STREAM)
|
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, props.keyCode, types.STREAM)
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterValue = ref('')
|
const filterValue = ref('')
|
||||||
|
@ -153,7 +165,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-wrapper flex-box-v">
|
<div class="content-wrapper flex-box-v">
|
||||||
<content-toolbar :db="props.db" :key-path="props.keyPath" :key-type="keyType" :server="props.name" :ttl="ttl" />
|
<content-toolbar
|
||||||
|
:db="props.db"
|
||||||
|
:key-path="props.keyPath"
|
||||||
|
:key-code="props.keyCode"
|
||||||
|
:key-type="keyType"
|
||||||
|
:server="props.name"
|
||||||
|
:ttl="ttl" />
|
||||||
<div class="tb2 flex-box-h">
|
<div class="tb2 flex-box-h">
|
||||||
<div class="flex-box-h">
|
<div class="flex-box-h">
|
||||||
<n-input-group>
|
<n-input-group>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Close from '@/components/icons/Close.vue'
|
||||||
import Edit from '@/components/icons/Edit.vue'
|
import Edit from '@/components/icons/Edit.vue'
|
||||||
import { types as redisTypes } from '@/consts/support_redis_type.js'
|
import { types as redisTypes } from '@/consts/support_redis_type.js'
|
||||||
import { ClipboardSetText } from 'wailsjs/runtime/runtime.js'
|
import { ClipboardSetText } from 'wailsjs/runtime/runtime.js'
|
||||||
import { map, toLower } from 'lodash'
|
import { isEmpty, map, toLower } from 'lodash'
|
||||||
import useConnectionStore from 'stores/connections.js'
|
import useConnectionStore from 'stores/connections.js'
|
||||||
|
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
|
@ -20,6 +20,10 @@ const props = defineProps({
|
||||||
name: String,
|
name: String,
|
||||||
db: Number,
|
db: Number,
|
||||||
keyPath: String,
|
keyPath: String,
|
||||||
|
keyCode: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
ttl: {
|
ttl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1,
|
default: -1,
|
||||||
|
@ -32,6 +36,14 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ComputedRef<string|number[]>}
|
||||||
|
*/
|
||||||
|
const keyName = computed(() => {
|
||||||
|
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||||
|
})
|
||||||
|
|
||||||
const viewOption = computed(() =>
|
const viewOption = computed(() =>
|
||||||
map(types, (t) => {
|
map(types, (t) => {
|
||||||
return {
|
return {
|
||||||
|
@ -76,7 +88,7 @@ const viewLanguage = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const onViewTypeUpdate = (viewType) => {
|
const onViewTypeUpdate = (viewType) => {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath, viewType)
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value, viewType)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,14 +128,14 @@ const onSaveValue = async () => {
|
||||||
const { success, msg } = await connectionStore.setKey(
|
const { success, msg } = await connectionStore.setKey(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
toLower(keyType),
|
toLower(keyType),
|
||||||
editValue.value,
|
editValue.value,
|
||||||
-1,
|
-1,
|
||||||
props.viewAs,
|
props.viewAs,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
await connectionStore.loadKeyValue(props.name, props.db, props.keyPath)
|
await connectionStore.loadKeyValue(props.name, props.db, keyName.value)
|
||||||
$message.success(i18n.t('dialogue.save_value_succ'))
|
$message.success(i18n.t('dialogue.save_value_succ'))
|
||||||
} else {
|
} else {
|
||||||
$message.error(msg)
|
$message.error(msg)
|
||||||
|
@ -139,13 +151,19 @@ const onSaveValue = async () => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-wrapper flex-box-v">
|
<div class="content-wrapper flex-box-v">
|
||||||
<content-toolbar :db="props.db" :key-path="keyPath" :key-type="keyType" :server="props.name" :ttl="ttl" />
|
<content-toolbar
|
||||||
|
:db="props.db"
|
||||||
|
:key-path="keyPath"
|
||||||
|
:key-code="keyCode"
|
||||||
|
:key-type="keyType"
|
||||||
|
:server="props.name"
|
||||||
|
:ttl="ttl" />
|
||||||
<div class="tb2 flex-box-h">
|
<div class="tb2 flex-box-h">
|
||||||
<n-text>{{ $t('interface.view_as') }}</n-text>
|
<n-text>{{ $t('interface.view_as') }}</n-text>
|
||||||
<n-select
|
<n-select
|
||||||
:value="props.viewAs"
|
:value="props.viewAs"
|
||||||
:options="viewOption"
|
:options="viewOption"
|
||||||
style="width: 200px"
|
style="width: 160px"
|
||||||
filterable
|
filterable
|
||||||
@update:value="onViewTypeUpdate" />
|
@update:value="onViewTypeUpdate" />
|
||||||
<div class="flex-item-expand"></div>
|
<div class="flex-item-expand"></div>
|
||||||
|
|
|
@ -15,6 +15,10 @@ const props = defineProps({
|
||||||
name: String,
|
name: String,
|
||||||
db: Number,
|
db: Number,
|
||||||
keyPath: String,
|
keyPath: String,
|
||||||
|
keyCode: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
ttl: {
|
ttl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1,
|
default: -1,
|
||||||
|
@ -23,6 +27,14 @@ const props = defineProps({
|
||||||
size: Number,
|
size: Number,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {ComputedRef<string|number[]>}
|
||||||
|
*/
|
||||||
|
const keyName = computed(() => {
|
||||||
|
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||||
|
})
|
||||||
|
|
||||||
const filterOption = [
|
const filterOption = [
|
||||||
{
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
|
@ -149,11 +161,11 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.removeZSetItem(
|
const { success, msg } = await connectionStore.removeZSetItem(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
row.value,
|
row.value,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.value }))
|
$message.success(i18n.t('dialogue.delete_key_succ', { key: row.value }))
|
||||||
} else {
|
} else {
|
||||||
$message.error(msg)
|
$message.error(msg)
|
||||||
|
@ -172,13 +184,13 @@ const actionColumn = {
|
||||||
const { success, msg } = await connectionStore.updateZSetItem(
|
const { success, msg } = await connectionStore.updateZSetItem(
|
||||||
props.name,
|
props.name,
|
||||||
props.db,
|
props.db,
|
||||||
props.keyPath,
|
keyName.value,
|
||||||
row.value,
|
row.value,
|
||||||
newValue,
|
newValue,
|
||||||
currentEditRow.value.score,
|
currentEditRow.value.score,
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
connectionStore.loadKeyValue(props.name, props.db, props.keyPath).then((r) => {})
|
connectionStore.loadKeyValue(props.name, props.db, keyName.value).then((r) => {})
|
||||||
$message.success(i18n.t('dialogue.save_value_succ'))
|
$message.success(i18n.t('dialogue.save_value_succ'))
|
||||||
} else {
|
} else {
|
||||||
$message.error(msg)
|
$message.error(msg)
|
||||||
|
@ -222,7 +234,7 @@ const tableData = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const onAddRow = () => {
|
const onAddRow = () => {
|
||||||
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, types.ZSET)
|
dialogStore.openAddFieldsDialog(props.name, props.db, props.keyPath, props.keyCode, types.ZSET)
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterValue = ref('')
|
const filterValue = ref('')
|
||||||
|
@ -266,7 +278,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="content-wrapper flex-box-v">
|
<div class="content-wrapper flex-box-v">
|
||||||
<content-toolbar :db="props.db" :key-path="props.keyPath" :key-type="keyType" :server="props.name" :ttl="ttl" />
|
<content-toolbar
|
||||||
|
:db="props.db"
|
||||||
|
:key-path="props.keyPath"
|
||||||
|
:key-code="props.keyCode"
|
||||||
|
:key-type="keyType"
|
||||||
|
:server="props.name"
|
||||||
|
:ttl="ttl" />
|
||||||
<div class="tb2 flex-box-h">
|
<div class="tb2 flex-box-h">
|
||||||
<div class="flex-box-h">
|
<div class="flex-box-h">
|
||||||
<n-input-group>
|
<n-input-group>
|
||||||
|
|
|
@ -10,13 +10,14 @@ import AddHashValue from '@/components/new_value/AddHashValue.vue'
|
||||||
import AddZSetValue from '@/components/new_value/AddZSetValue.vue'
|
import AddZSetValue from '@/components/new_value/AddZSetValue.vue'
|
||||||
import useConnectionStore from 'stores/connections.js'
|
import useConnectionStore from 'stores/connections.js'
|
||||||
import NewStreamValue from '@/components/new_value/NewStreamValue.vue'
|
import NewStreamValue from '@/components/new_value/NewStreamValue.vue'
|
||||||
import { size, slice } from 'lodash'
|
import { isEmpty, size, slice } from 'lodash'
|
||||||
|
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
const newForm = reactive({
|
const newForm = reactive({
|
||||||
server: '',
|
server: '',
|
||||||
db: 0,
|
db: 0,
|
||||||
key: '',
|
key: '',
|
||||||
|
keyCode: null,
|
||||||
type: '',
|
type: '',
|
||||||
opType: 0,
|
opType: 0,
|
||||||
value: null,
|
value: null,
|
||||||
|
@ -65,10 +66,11 @@ watch(
|
||||||
() => dialogStore.addFieldsDialogVisible,
|
() => dialogStore.addFieldsDialogVisible,
|
||||||
(visible) => {
|
(visible) => {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
const { server, db, key, type } = dialogStore.addFieldParam
|
const { server, db, key, keyCode, type } = dialogStore.addFieldParam
|
||||||
newForm.server = server
|
newForm.server = server
|
||||||
newForm.db = db
|
newForm.db = db
|
||||||
newForm.key = key
|
newForm.key = key
|
||||||
|
newForm.keyCode = keyCode
|
||||||
newForm.type = type
|
newForm.type = type
|
||||||
newForm.opType = 0
|
newForm.opType = 0
|
||||||
newForm.value = null
|
newForm.value = null
|
||||||
|
@ -79,24 +81,25 @@ watch(
|
||||||
const connectionStore = useConnectionStore()
|
const connectionStore = useConnectionStore()
|
||||||
const onAdd = async () => {
|
const onAdd = async () => {
|
||||||
try {
|
try {
|
||||||
const { server, db, key, type } = newForm
|
const { server, db, key, keyCode, type } = newForm
|
||||||
let { value } = newForm
|
let { value } = newForm
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = defaultValue[type]
|
value = defaultValue[type]
|
||||||
}
|
}
|
||||||
|
const keyName = isEmpty(keyCode) ? key : keyCode
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case types.LIST:
|
case types.LIST:
|
||||||
{
|
{
|
||||||
let data
|
let data
|
||||||
if (newForm.opType === 1) {
|
if (newForm.opType === 1) {
|
||||||
data = await connectionStore.prependListItem(server, db, key, value)
|
data = await connectionStore.prependListItem(server, db, keyName, value)
|
||||||
} else {
|
} else {
|
||||||
data = await connectionStore.appendListItem(server, db, key, value)
|
data = await connectionStore.appendListItem(server, db, keyName, value)
|
||||||
}
|
}
|
||||||
const { success, msg } = data
|
const { success, msg } = data
|
||||||
if (success) {
|
if (success) {
|
||||||
if (newForm.reload) {
|
if (newForm.reload) {
|
||||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||||
}
|
}
|
||||||
$message.success(i18n.t('dialogue.handle_succ'))
|
$message.success(i18n.t('dialogue.handle_succ'))
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,10 +110,16 @@ const onAdd = async () => {
|
||||||
|
|
||||||
case types.HASH:
|
case types.HASH:
|
||||||
{
|
{
|
||||||
const { success, msg } = await connectionStore.addHashField(server, db, key, newForm.opType, value)
|
const { success, msg } = await connectionStore.addHashField(
|
||||||
|
server,
|
||||||
|
db,
|
||||||
|
keyName,
|
||||||
|
newForm.opType,
|
||||||
|
value,
|
||||||
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
if (newForm.reload) {
|
if (newForm.reload) {
|
||||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||||
}
|
}
|
||||||
$message.success(i18n.t('dialogue.handle_succ'))
|
$message.success(i18n.t('dialogue.handle_succ'))
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,10 +130,10 @@ const onAdd = async () => {
|
||||||
|
|
||||||
case types.SET:
|
case types.SET:
|
||||||
{
|
{
|
||||||
const { success, msg } = await connectionStore.addSetItem(server, db, key, value)
|
const { success, msg } = await connectionStore.addSetItem(server, db, keyName, value)
|
||||||
if (success) {
|
if (success) {
|
||||||
if (newForm.reload) {
|
if (newForm.reload) {
|
||||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||||
}
|
}
|
||||||
$message.success(i18n.t('dialogue.handle_succ'))
|
$message.success(i18n.t('dialogue.handle_succ'))
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,10 +144,16 @@ const onAdd = async () => {
|
||||||
|
|
||||||
case types.ZSET:
|
case types.ZSET:
|
||||||
{
|
{
|
||||||
const { success, msg } = await connectionStore.addZSetItem(server, db, key, newForm.opType, value)
|
const { success, msg } = await connectionStore.addZSetItem(
|
||||||
|
server,
|
||||||
|
db,
|
||||||
|
keyName,
|
||||||
|
newForm.opType,
|
||||||
|
value,
|
||||||
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
if (newForm.reload) {
|
if (newForm.reload) {
|
||||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||||
}
|
}
|
||||||
$message.success(i18n.t('dialogue.handle_succ'))
|
$message.success(i18n.t('dialogue.handle_succ'))
|
||||||
} else {
|
} else {
|
||||||
|
@ -153,13 +168,13 @@ const onAdd = async () => {
|
||||||
const { success, msg } = await connectionStore.addStreamValue(
|
const { success, msg } = await connectionStore.addStreamValue(
|
||||||
server,
|
server,
|
||||||
db,
|
db,
|
||||||
key,
|
keyName,
|
||||||
value[0],
|
value[0],
|
||||||
slice(value, 1),
|
slice(value, 1),
|
||||||
)
|
)
|
||||||
if (success) {
|
if (success) {
|
||||||
if (newForm.reload) {
|
if (newForm.reload) {
|
||||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||||
}
|
}
|
||||||
$message.success(i18n.t('dialogue.handle_succ'))
|
$message.success(i18n.t('dialogue.handle_succ'))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,8 +3,14 @@ import { reactive, ref, watch } from 'vue'
|
||||||
import useDialog from 'stores/dialog'
|
import useDialog from 'stores/dialog'
|
||||||
import useTabStore from 'stores/tab.js'
|
import useTabStore from 'stores/tab.js'
|
||||||
import useConnectionStore from 'stores/connections.js'
|
import useConnectionStore from 'stores/connections.js'
|
||||||
|
import Binary from '@/components/icons/Binary.vue'
|
||||||
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
const ttlForm = reactive({
|
const ttlForm = reactive({
|
||||||
|
server: '',
|
||||||
|
db: 0,
|
||||||
|
key: '',
|
||||||
|
keyCode: null,
|
||||||
ttl: -1,
|
ttl: -1,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -12,9 +18,6 @@ const dialogStore = useDialog()
|
||||||
const connectionStore = useConnectionStore()
|
const connectionStore = useConnectionStore()
|
||||||
const tabStore = useTabStore()
|
const tabStore = useTabStore()
|
||||||
|
|
||||||
const currentServer = ref('')
|
|
||||||
const currentKey = ref('')
|
|
||||||
const currentDB = ref(0)
|
|
||||||
watch(
|
watch(
|
||||||
() => dialogStore.ttlDialogVisible,
|
() => dialogStore.ttlDialogVisible,
|
||||||
(visible) => {
|
(visible) => {
|
||||||
|
@ -22,15 +25,15 @@ watch(
|
||||||
// get ttl from current tab
|
// get ttl from current tab
|
||||||
const tab = tabStore.currentTab
|
const tab = tabStore.currentTab
|
||||||
if (tab != null) {
|
if (tab != null) {
|
||||||
|
ttlForm.server = tab.name
|
||||||
|
ttlForm.db = tab.db
|
||||||
ttlForm.key = tab.key
|
ttlForm.key = tab.key
|
||||||
|
ttlForm.keyCode = tab.keyCode
|
||||||
if (tab.ttl < 0) {
|
if (tab.ttl < 0) {
|
||||||
// forever
|
// forever
|
||||||
} else {
|
} else {
|
||||||
ttlForm.ttl = tab.ttl
|
ttlForm.ttl = tab.ttl
|
||||||
}
|
}
|
||||||
currentServer.value = tab.name
|
|
||||||
currentDB.value = tab.db
|
|
||||||
currentKey.value = tab.key
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -46,16 +49,18 @@ const onConfirm = async () => {
|
||||||
if (tab == null) {
|
if (tab == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const success = await connectionStore.setTTL(tab.name, tab.db, tab.key, ttlForm.ttl)
|
const key = isEmpty(ttlForm.keyCode) ? ttlForm.key : ttlForm.keyCode
|
||||||
|
const success = await connectionStore.setTTL(tab.name, tab.db, key, ttlForm.ttl)
|
||||||
if (success) {
|
if (success) {
|
||||||
tabStore.updateTTL({
|
tabStore.updateTTL({
|
||||||
server: currentServer.value,
|
server: ttlForm.server,
|
||||||
db: currentDB.value,
|
db: ttlForm.db,
|
||||||
key: currentKey.value,
|
key: ttlForm.key,
|
||||||
ttl: ttlForm.ttl,
|
ttl: ttlForm.ttl,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
$message.error(e.message || 'set ttl fail')
|
||||||
} finally {
|
} finally {
|
||||||
dialogStore.closeTTLDialog()
|
dialogStore.closeTTLDialog()
|
||||||
}
|
}
|
||||||
|
@ -74,7 +79,11 @@ const onConfirm = async () => {
|
||||||
transform-origin="center">
|
transform-origin="center">
|
||||||
<n-form :model="ttlForm" :show-require-mark="false" label-placement="top">
|
<n-form :model="ttlForm" :show-require-mark="false" label-placement="top">
|
||||||
<n-form-item :label="$t('common.key')">
|
<n-form-item :label="$t('common.key')">
|
||||||
<n-input :value="currentKey" readonly />
|
<n-input :value="ttlForm.key" readonly>
|
||||||
|
<template #prefix>
|
||||||
|
<n-icon v-if="!!ttlForm.keyCode" :component="Binary" size="20" />
|
||||||
|
</template>
|
||||||
|
</n-input>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item :label="$t('interface.ttl')" required>
|
<n-form-item :label="$t('interface.ttl')" required>
|
||||||
<n-input-number
|
<n-input-number
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round">
|
||||||
|
<rect x="14" y="14" width="4" height="6" rx="2" />
|
||||||
|
<rect x="6" y="4" width="4" height="6" rx="2" />
|
||||||
|
<path d="M6 20h4" />
|
||||||
|
<path d="M14 10h4" />
|
||||||
|
<path d="M6 14h2v6" />
|
||||||
|
<path d="M14 4h2v6" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -3,6 +3,7 @@ import { computed, h, nextTick, onMounted, reactive, ref } from 'vue'
|
||||||
import { ConnectionType } from '@/consts/connection_type.js'
|
import { ConnectionType } from '@/consts/connection_type.js'
|
||||||
import { NIcon, NSpace, NTag } from 'naive-ui'
|
import { NIcon, NSpace, NTag } from 'naive-ui'
|
||||||
import Key from '@/components/icons/Key.vue'
|
import Key from '@/components/icons/Key.vue'
|
||||||
|
import Binary from '@/components/icons/Binary.vue'
|
||||||
import ToggleDb from '@/components/icons/ToggleDb.vue'
|
import ToggleDb from '@/components/icons/ToggleDb.vue'
|
||||||
import { find, get, includes, indexOf, isEmpty, pull, remove, size } from 'lodash'
|
import { find, get, includes, indexOf, isEmpty, pull, remove, size } from 'lodash'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
@ -223,7 +224,9 @@ const handleSelectContextMenu = (key) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const node = connectionStore.getNode(selectedKey)
|
const node = connectionStore.getNode(selectedKey)
|
||||||
const { db, key: nodeKey, redisKey } = node || {}
|
const { db, key: nodeKey } = node || {}
|
||||||
|
const redisKey = node.redisKeyCode || node.redisKey
|
||||||
|
const redisKeyName = !!node.redisKeyCode ? node.label : redisKey
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'server_info':
|
case 'server_info':
|
||||||
tabStore.setSelectedKeys(props.server)
|
tabStore.setSelectedKeys(props.server)
|
||||||
|
@ -267,10 +270,10 @@ const handleSelectContextMenu = (key) => {
|
||||||
dialogStore.openDeleteKeyDialog(props.server, db, isEmpty(redisKey) ? '*' : redisKey + ':*')
|
dialogStore.openDeleteKeyDialog(props.server, db, isEmpty(redisKey) ? '*' : redisKey + ':*')
|
||||||
break
|
break
|
||||||
case 'value_remove':
|
case 'value_remove':
|
||||||
$dialog.warning(i18n.t('dialogue.remove_tip', { name: redisKey }), () => {
|
$dialog.warning(i18n.t('dialogue.remove_tip', { name: redisKeyName }), () => {
|
||||||
connectionStore.deleteKey(props.server, db, redisKey).then((success) => {
|
connectionStore.deleteKey(props.server, db, redisKey).then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
$message.success(i18n.t('dialogue.delete_key_succ', { key: redisKey }))
|
$message.success(i18n.t('dialogue.delete_key_succ', { key: redisKeyName }))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -327,7 +330,8 @@ const onUpdateSelectedKeys = (keys, options) => {
|
||||||
// prevent load duplicate key
|
// prevent load duplicate key
|
||||||
for (const node of options) {
|
for (const node of options) {
|
||||||
if (node.type === ConnectionType.RedisValue) {
|
if (node.type === ConnectionType.RedisValue) {
|
||||||
const { key, db, redisKey } = node
|
const { key, db } = node
|
||||||
|
const redisKey = node.redisKeyCode || node.redisKey
|
||||||
if (!includes(selectedKeys.value, key)) {
|
if (!includes(selectedKeys.value, key)) {
|
||||||
connectionStore.loadKeyValue(props.server, db, redisKey)
|
connectionStore.loadKeyValue(props.server, db, redisKey)
|
||||||
}
|
}
|
||||||
|
@ -373,7 +377,7 @@ const renderPrefix = ({ option }) => {
|
||||||
NIcon,
|
NIcon,
|
||||||
{ size: 20 },
|
{ size: 20 },
|
||||||
{
|
{
|
||||||
default: () => h(Key),
|
default: () => h(!!option.redisKeyCode ? Binary : Key),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
"batch_delete": "Batch Delete",
|
"batch_delete": "Batch Delete",
|
||||||
"copy_path": "Copy Path",
|
"copy_path": "Copy Path",
|
||||||
"copy_key": "Copy Key",
|
"copy_key": "Copy Key",
|
||||||
|
"binary_key": "Binary Key Name",
|
||||||
"remove_key": "Remove Key",
|
"remove_key": "Remove Key",
|
||||||
"new_key": "Add New Key",
|
"new_key": "Add New Key",
|
||||||
"nonexist_tab_content": "Selected key does not exist. Please retry",
|
"nonexist_tab_content": "Selected key does not exist. Please retry",
|
||||||
|
@ -105,6 +106,7 @@
|
||||||
"delete_key_succ": "\"{key}\" has been deleted",
|
"delete_key_succ": "\"{key}\" has been deleted",
|
||||||
"save_value_succ": "Value Saved !",
|
"save_value_succ": "Value Saved !",
|
||||||
"copy_succ": "Value Copied !",
|
"copy_succ": "Value Copied !",
|
||||||
|
"rename_binary_key_fail": "Rename binary key name is unsupported",
|
||||||
"handle_succ": "Success!",
|
"handle_succ": "Success!",
|
||||||
"reload_succ": "Reloaded!",
|
"reload_succ": "Reloaded!",
|
||||||
"field_required": "This item should not be blank",
|
"field_required": "This item should not be blank",
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
"batch_delete": "批量删除键",
|
"batch_delete": "批量删除键",
|
||||||
"copy_path": "复制路径",
|
"copy_path": "复制路径",
|
||||||
"copy_key": "复制键名",
|
"copy_key": "复制键名",
|
||||||
|
"binary_key": "二进制键名",
|
||||||
"remove_key": "删除键",
|
"remove_key": "删除键",
|
||||||
"new_key": "添加新键",
|
"new_key": "添加新键",
|
||||||
"nonexist_tab_content": "所选键不存在,请尝试刷新重试",
|
"nonexist_tab_content": "所选键不存在,请尝试刷新重试",
|
||||||
|
@ -105,6 +106,7 @@
|
||||||
"delete_key_succ": "{key} 已被删除",
|
"delete_key_succ": "{key} 已被删除",
|
||||||
"save_value_succ": "已保存值",
|
"save_value_succ": "已保存值",
|
||||||
"copy_succ": "已复制到剪切板",
|
"copy_succ": "已复制到剪切板",
|
||||||
|
"rename_binary_key_fail": "不支持重命名二进制键名",
|
||||||
"handle_succ": "操作成功",
|
"handle_succ": "操作成功",
|
||||||
"reload_succ": "已重新载入",
|
"reload_succ": "已重新载入",
|
||||||
"field_required": "此项不能为空",
|
"field_required": "此项不能为空",
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
get,
|
get,
|
||||||
isEmpty,
|
isEmpty,
|
||||||
join,
|
join,
|
||||||
|
map,
|
||||||
remove,
|
remove,
|
||||||
size,
|
size,
|
||||||
slice,
|
slice,
|
||||||
|
@ -49,6 +50,7 @@ import {
|
||||||
import { ConnectionType } from '@/consts/connection_type.js'
|
import { ConnectionType } from '@/consts/connection_type.js'
|
||||||
import useTabStore from './tab.js'
|
import useTabStore from './tab.js'
|
||||||
import { types } from '@/consts/support_redis_type.js'
|
import { types } from '@/consts/support_redis_type.js'
|
||||||
|
import { decodeRedisKey, nativeRedisKey } from '@/utils/key_convert.js'
|
||||||
|
|
||||||
const useConnectionStore = defineStore('connections', {
|
const useConnectionStore = defineStore('connections', {
|
||||||
/**
|
/**
|
||||||
|
@ -68,6 +70,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @property {number} type
|
* @property {number} type
|
||||||
* @property {number} [db] - database index, type == ConnectionType.RedisDB only
|
* @property {number} [db] - database index, type == ConnectionType.RedisDB only
|
||||||
* @property {string} [redisKey] - redis key, type == ConnectionType.RedisKey || type == ConnectionType.RedisValue only
|
* @property {string} [redisKey] - redis key, type == ConnectionType.RedisKey || type == ConnectionType.RedisValue only
|
||||||
|
* @property {string} [redisKeyCode] - redis key char code array, optional for redis key which contains binary data
|
||||||
* @property {number} [keys] - children key count
|
* @property {number} [keys] - children key count
|
||||||
* @property {boolean} [isLeaf]
|
* @property {boolean} [isLeaf]
|
||||||
* @property {boolean} [opened] - redis db is opened, type == ConnectionType.RedisDB only
|
* @property {boolean} [opened] - redis db is opened, type == ConnectionType.RedisDB only
|
||||||
|
@ -529,11 +532,10 @@ const useConnectionStore = defineStore('connections', {
|
||||||
selDB.opened = true
|
selDB.opened = true
|
||||||
if (isEmpty(keys)) {
|
if (isEmpty(keys)) {
|
||||||
selDB.children = []
|
selDB.children = []
|
||||||
return
|
} else {
|
||||||
|
// append db node to current connection's children
|
||||||
|
this._addKeyNodes(connName, db, keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
// append db node to current connection's children
|
|
||||||
this._addKeyNodes(connName, db, keys)
|
|
||||||
this._tidyNode(connName, db)
|
this._tidyNode(connName, db)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -592,7 +594,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* load redis key
|
* load redis key
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} [key] when key is null or blank, update tab to display normal content (blank content or server status)
|
* @param {string|number[]} [key] when key is null or blank, update tab to display normal content (blank content or server status)
|
||||||
* @param {string} [viewType]
|
* @param {string} [viewType]
|
||||||
*/
|
*/
|
||||||
async loadKeyValue(server, db, key, viewType) {
|
async loadKeyValue(server, db, key, viewType) {
|
||||||
|
@ -602,12 +604,15 @@ const useConnectionStore = defineStore('connections', {
|
||||||
const { data, success, msg } = await GetKeyValue(server, db, key, viewType)
|
const { data, success, msg } = await GetKeyValue(server, db, key, viewType)
|
||||||
if (success) {
|
if (success) {
|
||||||
const { type, ttl, value, size, viewAs } = data
|
const { type, ttl, value, size, viewAs } = data
|
||||||
|
const k = decodeRedisKey(key)
|
||||||
|
const binaryKey = k !== key
|
||||||
tab.upsertTab({
|
tab.upsertTab({
|
||||||
server,
|
server,
|
||||||
db,
|
db,
|
||||||
type,
|
type,
|
||||||
ttl,
|
ttl,
|
||||||
key,
|
keyCode: binaryKey ? key : undefined,
|
||||||
|
key: k,
|
||||||
value,
|
value,
|
||||||
size,
|
size,
|
||||||
viewAs,
|
viewAs,
|
||||||
|
@ -629,6 +634,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
type: 'none',
|
type: 'none',
|
||||||
ttl: -1,
|
ttl: -1,
|
||||||
key: null,
|
key: null,
|
||||||
|
keyCode: null,
|
||||||
value: null,
|
value: null,
|
||||||
size: 0,
|
size: 0,
|
||||||
})
|
})
|
||||||
|
@ -713,7 +719,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* remove keys in db
|
* remove keys in db
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string[]} keys
|
* @param {Array<string|number[]>} keys
|
||||||
* @param {boolean} [sortInsert]
|
* @param {boolean} [sortInsert]
|
||||||
* @return {{success: boolean, newKey: number, newLayer: number, replaceKey: number}}
|
* @return {{success: boolean, newKey: number, newLayer: number, replaceKey: number}}
|
||||||
* @private
|
* @private
|
||||||
|
@ -735,7 +741,9 @@ const useConnectionStore = defineStore('connections', {
|
||||||
const nodeMap = this._getNodeMap(connName, db)
|
const nodeMap = this._getNodeMap(connName, db)
|
||||||
const rootChildren = selDB.children
|
const rootChildren = selDB.children
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
const keyParts = split(key, separator)
|
const k = decodeRedisKey(key)
|
||||||
|
const binaryKey = k !== key
|
||||||
|
const keyParts = binaryKey ? [nativeRedisKey(key)] : split(k, separator)
|
||||||
const len = size(keyParts)
|
const len = size(keyParts)
|
||||||
const lastIdx = len - 1
|
const lastIdx = len - 1
|
||||||
let handlePath = ''
|
let handlePath = ''
|
||||||
|
@ -776,10 +784,11 @@ const useConnectionStore = defineStore('connections', {
|
||||||
const replaceKey = nodeMap.has(nodeKey)
|
const replaceKey = nodeMap.has(nodeKey)
|
||||||
const selectedNode = {
|
const selectedNode = {
|
||||||
key: `${connName}/db${db}#${nodeKey}`,
|
key: `${connName}/db${db}#${nodeKey}`,
|
||||||
label: keyParts[i],
|
label: binaryKey ? k : keyParts[i],
|
||||||
db,
|
db,
|
||||||
keys: 0,
|
keys: 0,
|
||||||
redisKey: handlePath,
|
redisKey: handlePath,
|
||||||
|
redisKeyCode: binaryKey ? key : undefined,
|
||||||
type: ConnectionType.RedisValue,
|
type: ConnectionType.RedisValue,
|
||||||
isLeaf: true,
|
isLeaf: true,
|
||||||
}
|
}
|
||||||
|
@ -864,7 +873,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sort all node item's children and calculate keys count
|
* sort all node item's children and calculate keys count
|
||||||
* @param node
|
* @param {DatabaseItem} node
|
||||||
* @param {boolean} skipSort skip sorting children
|
* @param {boolean} skipSort skip sorting children
|
||||||
* @returns {boolean} return whether key count changed
|
* @returns {boolean} return whether key count changed
|
||||||
* @private
|
* @private
|
||||||
|
@ -881,7 +890,12 @@ const useConnectionStore = defineStore('connections', {
|
||||||
count += elem.keys
|
count += elem.keys
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
count += 1
|
if (node.type === ConnectionType.RedisValue) {
|
||||||
|
count += 1
|
||||||
|
} else {
|
||||||
|
// no children in db node or layer node, set count to 0
|
||||||
|
count = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (node.keys !== count) {
|
if (node.keys !== count) {
|
||||||
node.keys = count
|
node.keys = count
|
||||||
|
@ -926,7 +940,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* set redis key
|
* set redis key
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {string} keyType
|
* @param {string} keyType
|
||||||
* @param {any} value
|
* @param {any} value
|
||||||
* @param {number} ttl
|
* @param {number} ttl
|
||||||
|
@ -959,7 +973,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* when both field and newField are set, and field !== newField, delete field and add newField
|
* when both field and newField are set, and field !== newField, delete field and add newField
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {string} field
|
* @param {string} field
|
||||||
* @param {string} newField
|
* @param {string} newField
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
|
@ -983,7 +997,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* insert or update hash field item
|
* insert or update hash field item
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {number }action 0:ignore duplicated fields 1:overwrite duplicated fields
|
* @param {number }action 0:ignore duplicated fields 1:overwrite duplicated fields
|
||||||
* @param {string[]} fieldItems field1, value1, filed2, value2...
|
* @param {string[]} fieldItems field1, value1, filed2, value2...
|
||||||
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
||||||
|
@ -1028,7 +1042,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* insert list item
|
* insert list item
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {int} action 0: push to head, 1: push to tail
|
* @param {int} action 0: push to head, 1: push to tail
|
||||||
* @param {string[]}values
|
* @param {string[]}values
|
||||||
* @returns {Promise<*|{msg, success: boolean}>}
|
* @returns {Promise<*|{msg, success: boolean}>}
|
||||||
|
@ -1089,7 +1103,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* update value of list item by index
|
* update value of list item by index
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {number} index
|
* @param {number} index
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
||||||
|
@ -1112,7 +1126,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* remove list item
|
* remove list item
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {number} index
|
* @param {number} index
|
||||||
* @returns {Promise<{[msg]: string, success: boolean, [removed]: string[]}>}
|
* @returns {Promise<{[msg]: string, success: boolean, [removed]: string[]}>}
|
||||||
*/
|
*/
|
||||||
|
@ -1134,7 +1148,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* add item to set
|
* add item to set
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number} key
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @returns {Promise<{[msg]: string, success: boolean}>}
|
* @returns {Promise<{[msg]: string, success: boolean}>}
|
||||||
*/
|
*/
|
||||||
|
@ -1155,7 +1169,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* update value of set item
|
* update value of set item
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @param {string} newValue
|
* @param {string} newValue
|
||||||
* @returns {Promise<{[msg]: string, success: boolean}>}
|
* @returns {Promise<{[msg]: string, success: boolean}>}
|
||||||
|
@ -1175,10 +1189,10 @@ const useConnectionStore = defineStore('connections', {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove item from set
|
* remove item from set
|
||||||
* @param connName
|
* @param {string} connName
|
||||||
* @param db
|
* @param {number} db
|
||||||
* @param key
|
* @param {string|number[]} key
|
||||||
* @param value
|
* @param {string} value
|
||||||
* @returns {Promise<{[msg]: string, success: boolean}>}
|
* @returns {Promise<{[msg]: string, success: boolean}>}
|
||||||
*/
|
*/
|
||||||
async removeSetItem(connName, db, key, value) {
|
async removeSetItem(connName, db, key, value) {
|
||||||
|
@ -1198,7 +1212,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* add item to sorted set
|
* add item to sorted set
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {number} action
|
* @param {number} action
|
||||||
* @param {Object.<string, number>} vs value: score
|
* @param {Object.<string, number>} vs value: score
|
||||||
* @returns {Promise<{[msg]: string, success: boolean}>}
|
* @returns {Promise<{[msg]: string, success: boolean}>}
|
||||||
|
@ -1220,7 +1234,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* update item of sorted set
|
* update item of sorted set
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @param {string} newValue
|
* @param {string} newValue
|
||||||
* @param {number} score
|
* @param {number} score
|
||||||
|
@ -1244,7 +1258,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* remove item from sorted set
|
* remove item from sorted set
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param key
|
* @param {string|number[]} key
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @returns {Promise<{[msg]: string, success: boolean, [removed]: []}>}
|
* @returns {Promise<{[msg]: string, success: boolean, [removed]: []}>}
|
||||||
*/
|
*/
|
||||||
|
@ -1266,7 +1280,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* insert new stream field item
|
* insert new stream field item
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
* @param {string[]} values field1, value1, filed2, value2...
|
* @param {string[]} values field1, value1, filed2, value2...
|
||||||
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
||||||
|
@ -1289,7 +1303,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* remove stream field
|
* remove stream field
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {string[]|string} ids
|
* @param {string[]|string} ids
|
||||||
* @returns {Promise<{[msg]: {}, success: boolean, [removed]: string[]}>}
|
* @returns {Promise<{[msg]: {}, success: boolean, [removed]: string[]}>}
|
||||||
*/
|
*/
|
||||||
|
@ -1427,7 +1441,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* delete redis key
|
* delete redis key
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {boolean} [soft] do not try to remove from redis if true, just remove from tree data
|
* @param {boolean} [soft] do not try to remove from redis if true, just remove from tree data
|
||||||
* @returns {Promise<boolean>}
|
* @returns {Promise<boolean>}
|
||||||
*/
|
*/
|
||||||
|
@ -1437,9 +1451,10 @@ const useConnectionStore = defineStore('connections', {
|
||||||
await DeleteKey(connName, db, key)
|
await DeleteKey(connName, db, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const k = nativeRedisKey(key)
|
||||||
// update tree view data
|
// update tree view data
|
||||||
this._deleteKeyNode(connName, db, key)
|
this._deleteKeyNode(connName, db, k)
|
||||||
this._tidyNode(connName, db, key, true)
|
this._tidyNode(connName, db, k, true)
|
||||||
|
|
||||||
// set tab content empty
|
// set tab content empty
|
||||||
const tab = useTabStore()
|
const tab = useTabStore()
|
||||||
|
|
|
@ -45,6 +45,7 @@ const useDialogStore = defineStore('dialog', {
|
||||||
server: '',
|
server: '',
|
||||||
db: 0,
|
db: 0,
|
||||||
key: '',
|
key: '',
|
||||||
|
keyCode: null,
|
||||||
type: null,
|
type: null,
|
||||||
},
|
},
|
||||||
addFieldsDialogVisible: false,
|
addFieldsDialogVisible: false,
|
||||||
|
@ -185,12 +186,14 @@ const useDialogStore = defineStore('dialog', {
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
|
* @param {number[]|null} keyCode
|
||||||
* @param {string} type
|
* @param {string} type
|
||||||
*/
|
*/
|
||||||
openAddFieldsDialog(server, db, key, type) {
|
openAddFieldsDialog(server, db, key, keyCode, type) {
|
||||||
this.addFieldParam.server = server
|
this.addFieldParam.server = server
|
||||||
this.addFieldParam.db = db
|
this.addFieldParam.db = db
|
||||||
this.addFieldParam.key = key
|
this.addFieldParam.key = key
|
||||||
|
this.addFieldParam.keyCode = keyCode
|
||||||
this.addFieldParam.type = type
|
this.addFieldParam.type = type
|
||||||
this.addFieldsDialogVisible = true
|
this.addFieldsDialogVisible = true
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,6 +14,7 @@ const useTabStore = defineStore('tab', {
|
||||||
* @property {string} [server] server name
|
* @property {string} [server] server name
|
||||||
* @property {int} [db] database index
|
* @property {int} [db] database index
|
||||||
* @property {string} [key] current key name
|
* @property {string} [key] current key name
|
||||||
|
* @property {number[]|null|undefined} [keyCode] current key name as char array
|
||||||
* @property {int} [ttl] ttl of current key
|
* @property {int} [ttl] ttl of current key
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -83,11 +84,12 @@ const useTabStore = defineStore('tab', {
|
||||||
* @param {number} [type]
|
* @param {number} [type]
|
||||||
* @param {number} [ttl]
|
* @param {number} [ttl]
|
||||||
* @param {string} [key]
|
* @param {string} [key]
|
||||||
|
* @param {string} [keyCode]
|
||||||
* @param {number} [size]
|
* @param {number} [size]
|
||||||
* @param {*} [value]
|
* @param {*} [value]
|
||||||
* @param {string} [viewAs]
|
* @param {string} [viewAs]
|
||||||
*/
|
*/
|
||||||
upsertTab({ server, db, type, ttl, key, size, value, viewAs }) {
|
upsertTab({ server, db, type, ttl, key, keyCode, size, value, viewAs }) {
|
||||||
let tabIndex = findIndex(this.tabList, { name: server })
|
let tabIndex = findIndex(this.tabList, { name: server })
|
||||||
if (tabIndex === -1) {
|
if (tabIndex === -1) {
|
||||||
this.tabList.push({
|
this.tabList.push({
|
||||||
|
@ -97,6 +99,7 @@ const useTabStore = defineStore('tab', {
|
||||||
type,
|
type,
|
||||||
ttl,
|
ttl,
|
||||||
key,
|
key,
|
||||||
|
keyCode,
|
||||||
size,
|
size,
|
||||||
value,
|
value,
|
||||||
viewAs,
|
viewAs,
|
||||||
|
@ -112,6 +115,7 @@ const useTabStore = defineStore('tab', {
|
||||||
tab.type = type
|
tab.type = type
|
||||||
tab.ttl = ttl
|
tab.ttl = ttl
|
||||||
tab.key = key
|
tab.key = key
|
||||||
|
tab.keyCode = keyCode
|
||||||
tab.size = size
|
tab.size = size
|
||||||
tab.value = value
|
tab.value = value
|
||||||
tab.viewAs = viewAs
|
tab.viewAs = viewAs
|
||||||
|
@ -123,7 +127,7 @@ const useTabStore = defineStore('tab', {
|
||||||
* update ttl by tag
|
* update ttl by tag
|
||||||
* @param {string} server
|
* @param {string} server
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string|number[]} key
|
||||||
* @param {number} ttl
|
* @param {number} ttl
|
||||||
*/
|
*/
|
||||||
updateTTL({ server, db, key, ttl }) {
|
updateTTL({ server, db, key, ttl }) {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { join, map } from 'lodash'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* converted binary data in strings to hex format
|
||||||
|
* @param {string|number[]} key
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
export function decodeRedisKey(key) {
|
||||||
|
if (key instanceof Array) {
|
||||||
|
// char array, convert to hex string
|
||||||
|
return join(
|
||||||
|
map(key, (k) => {
|
||||||
|
if (k >= 32 && k <= 126) {
|
||||||
|
return String.fromCharCode(k)
|
||||||
|
}
|
||||||
|
return '\\x' + k.toString(16).toUpperCase().padStart(2, '0')
|
||||||
|
}),
|
||||||
|
'',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert char code array to string
|
||||||
|
* @param {string|number[]} key
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
export function nativeRedisKey(key) {
|
||||||
|
if (key instanceof Array) {
|
||||||
|
return map(key, (c) => String.fromCharCode(c)).join('')
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
"info": {
|
"info": {
|
||||||
"companyName": "Tiny Craft",
|
"companyName": "Tiny Craft",
|
||||||
"productName": "Tiny RDM",
|
"productName": "Tiny RDM",
|
||||||
"productVersion": "0.9.0",
|
"productVersion": "1.0.0",
|
||||||
"copyright": "Copyright © 2023",
|
"copyright": "Copyright © 2023",
|
||||||
"comments": "Tiny Redis Desktop Manager"
|
"comments": "Tiny Redis Desktop Manager"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue