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
|
||||
selConn := c.conns.GetConnection(name)
|
||||
|
||||
totaldb := 16
|
||||
var totaldb int
|
||||
if selConn.DBFilterType == "" || selConn.DBFilterType == "none" {
|
||||
// get total databases
|
||||
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()
|
||||
return
|
||||
}
|
||||
// Parse all db, response content like below
|
||||
// parse all db, response content like below
|
||||
var dbs []types.ConnectionDB
|
||||
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 {
|
||||
dbName := "db" + strconv.Itoa(idx)
|
||||
dbInfoStr := info["Keyspace"][dbName]
|
||||
|
@ -531,7 +545,7 @@ func (c *connectionService) ScanKeys(connName string, db int, match, keyType str
|
|||
|
||||
filterType := len(keyType) > 0
|
||||
|
||||
var keys []string
|
||||
var keys []any
|
||||
//keys := map[string]keyItem{}
|
||||
var cursor uint64
|
||||
for {
|
||||
|
@ -545,7 +559,9 @@ func (c *connectionService) ScanKeys(connName string, db int, match, keyType str
|
|||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
keys = append(keys, loadedKey...)
|
||||
for _, k := range loadedKey {
|
||||
keys = append(keys, strutil.EncodeRedisKey(k))
|
||||
}
|
||||
//for _, k := range loadedKey {
|
||||
// //t, _ := rdb.Type(ctx, k).Result()
|
||||
// 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
|
||||
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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
var keyType string
|
||||
var dur time.Duration
|
||||
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
|
||||
// @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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
var expiration time.Duration
|
||||
if ttl < 0 {
|
||||
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
|
||||
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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
var removedField []string
|
||||
updatedField := map[string]string{}
|
||||
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
|
||||
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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
updated := map[string]any{}
|
||||
switch action {
|
||||
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
|
||||
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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
var leftPush, rightPush []any
|
||||
switch action {
|
||||
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
|
||||
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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
var removed []int64
|
||||
updated := map[int64]string{}
|
||||
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
|
||||
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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
if remove {
|
||||
_, err = rdb.SRem(ctx, key, members...).Result()
|
||||
} else {
|
||||
|
@ -1011,13 +1034,14 @@ func (c *connectionService) SetSetItem(connName string, db int, key string, remo
|
|||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
_, _ = rdb.SRem(ctx, key, value).Result()
|
||||
_, err = rdb.SAdd(ctx, key, newValue).Result()
|
||||
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
|
||||
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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
updated := map[string]any{}
|
||||
var removed []string
|
||||
if len(newValue) <= 0 {
|
||||
|
@ -1080,13 +1105,14 @@ func (c *connectionService) UpdateZSetValue(connName string, db int, key, value,
|
|||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
members := maputil.ToSlice(valueScore, func(k string) redis.Z {
|
||||
return redis.Z{
|
||||
Score: valueScore[k],
|
||||
|
@ -1112,13 +1138,14 @@ func (c *connectionService) AddZSetValue(connName string, db int, key string, ac
|
|||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
_, err = rdb.XAdd(ctx, &redis.XAddArgs{
|
||||
Stream: key,
|
||||
ID: ID,
|
||||
|
@ -1134,26 +1161,28 @@ func (c *connectionService) AddStreamValue(connName string, db int, key, ID stri
|
|||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
_, err = rdb.XDel(ctx, key, IDs...).Result()
|
||||
resp.Success = true
|
||||
return
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
var expiration time.Duration
|
||||
if ttl < 0 {
|
||||
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
|
||||
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)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
var deletedKeys []string
|
||||
|
||||
key := strutil.DecodeRedisKey(k)
|
||||
var deletedKeys []string
|
||||
if strings.HasSuffix(key, "*") {
|
||||
// delete by prefix
|
||||
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
|
||||
|
||||
case types.HEX:
|
||||
if hexStr, ok := decodeHex(str); ok {
|
||||
if hexStr, ok := decodeToHex(str); ok {
|
||||
value = hexStr
|
||||
} else {
|
||||
value = str
|
||||
|
@ -161,8 +161,8 @@ func autoToType(str string) (value, resultType string) {
|
|||
return
|
||||
}
|
||||
|
||||
if isBinary(str) {
|
||||
if value, ok = decodeHex(str); ok {
|
||||
if containsBinary(str) {
|
||||
if value, ok = decodeToHex(str); ok {
|
||||
resultType = types.HEX
|
||||
return
|
||||
}
|
||||
|
@ -174,24 +174,12 @@ func autoToType(str string) (value, resultType string) {
|
|||
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) {
|
||||
var data any
|
||||
if (strings.HasPrefix(str, "{") && strings.HasSuffix(str, "}")) ||
|
||||
(strings.HasPrefix(str, "[") && strings.HasSuffix(str, "]")) {
|
||||
if err := json.Unmarshal([]byte(str), &data); err == nil {
|
||||
var jsonByte []byte
|
||||
if jsonByte, err = json.MarshalIndent(data, "", " "); err == nil {
|
||||
return string(jsonByte), true
|
||||
}
|
||||
var out bytes.Buffer
|
||||
if err := json.Indent(&out, []byte(str), "", " "); err == nil {
|
||||
return out.String(), true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
|
@ -212,7 +200,7 @@ func decodeBinary(str string) (string, bool) {
|
|||
return binary.String(), true
|
||||
}
|
||||
|
||||
func decodeHex(str string) (string, bool) {
|
||||
func decodeToHex(str string) (string, bool) {
|
||||
decodeStr := hex.EncodeToString([]byte(str))
|
||||
var resultStr strings.Builder
|
||||
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>
|
||||
import { computed } from 'vue'
|
||||
import { typesBgColor, typesColor, validType } from '@/consts/support_redis_type.js'
|
||||
import Binary from '@/components/icons/Binary.vue'
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
|
@ -10,6 +11,7 @@ const props = defineProps({
|
|||
},
|
||||
default: 'STRING',
|
||||
},
|
||||
binaryKey: Boolean,
|
||||
bordered: Boolean,
|
||||
size: String,
|
||||
})
|
||||
|
@ -31,6 +33,9 @@ const backgroundColor = computed(() => {
|
|||
:size="props.size"
|
||||
strong>
|
||||
{{ props.type }}
|
||||
<template #icon>
|
||||
<n-icon v-if="binaryKey" :component="Binary" size="18" />
|
||||
</template>
|
||||
</n-tag>
|
||||
<!-- <div class="redis-type-tag flex-box-h" :style="{backgroundColor: backgroundColor}">{{ props.type }}</div>-->
|
||||
</template>
|
||||
|
|
|
@ -165,6 +165,7 @@ const tabContent = computed(() => {
|
|||
type: toUpper(tab.type),
|
||||
db: tab.db,
|
||||
keyPath: tab.key,
|
||||
keyCode: tab.keyCode,
|
||||
ttl: tab.ttl,
|
||||
value: tab.value,
|
||||
size: tab.size || 0,
|
||||
|
@ -217,6 +218,7 @@ const onReloadKey = async () => {
|
|||
v-else
|
||||
:db="tabContent.db"
|
||||
:key-path="tabContent.keyPath"
|
||||
:key-code="tabContent.keyCode"
|
||||
:name="tabContent.name"
|
||||
:ttl="tabContent.ttl"
|
||||
:value="tabContent.value"
|
||||
|
|
|
@ -11,6 +11,8 @@ import IconButton from '@/components/common/IconButton.vue'
|
|||
import useConnectionStore from 'stores/connections.js'
|
||||
import Copy from '@/components/icons/Copy.vue'
|
||||
import { ClipboardSetText } from 'wailsjs/runtime/runtime.js'
|
||||
import { computed } from 'vue'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
const props = defineProps({
|
||||
server: String,
|
||||
|
@ -23,6 +25,10 @@ const props = defineProps({
|
|||
default: 'STRING',
|
||||
},
|
||||
keyPath: String,
|
||||
keyCode: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
ttl: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
|
@ -33,8 +39,20 @@ const dialogStore = useDialog()
|
|||
const connectionStore = useConnectionStore()
|
||||
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 = () => {
|
||||
connectionStore.loadKeyValue(props.server, props.db, props.keyPath)
|
||||
connectionStore.loadKeyValue(props.server, props.db, keyName.value)
|
||||
}
|
||||
|
||||
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 = () => {
|
||||
$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) {
|
||||
$message.success(i18n.t('dialogue.delete_key_succ', { key: props.keyPath }))
|
||||
}
|
||||
|
@ -63,7 +89,7 @@ const onDeleteKey = () => {
|
|||
<template>
|
||||
<div class="content-toolbar flex-box-h">
|
||||
<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">
|
||||
<template #suffix>
|
||||
<icon-button :icon="Refresh" size="18" t-tooltip="interface.reload" @click="onReloadKey" />
|
||||
|
@ -86,18 +112,13 @@ const onDeleteKey = () => {
|
|||
</template>
|
||||
TTL
|
||||
</n-tooltip>
|
||||
<icon-button
|
||||
:icon="Edit"
|
||||
border
|
||||
size="18"
|
||||
t-tooltip="interface.rename_key"
|
||||
@click="dialogStore.openRenameKeyDialog(props.server, props.db, props.keyPath)" />
|
||||
<icon-button :icon="Edit" border size="18" t-tooltip="interface.rename_key" @click="onRenameKey" />
|
||||
</n-button-group>
|
||||
<n-tooltip>
|
||||
<template #trigger>
|
||||
<n-button>
|
||||
<n-button :focusable="false" @click="onDeleteKey">
|
||||
<template #icon>
|
||||
<n-icon :component="Delete" size="18" @click="onDeleteKey" />
|
||||
<n-icon :component="Delete" size="18" />
|
||||
</template>
|
||||
</n-button>
|
||||
</template>
|
||||
|
|
|
@ -8,12 +8,17 @@ import { types, types as redisTypes } from '@/consts/support_redis_type.js'
|
|||
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
||||
import useDialogStore from 'stores/dialog.js'
|
||||
import useConnectionStore from 'stores/connections.js'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
const i18n = useI18n()
|
||||
const props = defineProps({
|
||||
name: String,
|
||||
db: Number,
|
||||
keyPath: String,
|
||||
keyCode: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
ttl: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
|
@ -22,6 +27,14 @@ const props = defineProps({
|
|||
size: Number,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {ComputedRef<string|number[]>}
|
||||
*/
|
||||
const keyName = computed(() => {
|
||||
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||
})
|
||||
|
||||
const filterOption = [
|
||||
{
|
||||
value: 1,
|
||||
|
@ -119,11 +132,11 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.removeHashField(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
row.key,
|
||||
)
|
||||
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 }))
|
||||
// update display value
|
||||
// if (!isEmpty(removed)) {
|
||||
|
@ -143,13 +156,13 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.setHash(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
row.key,
|
||||
currentEditRow.value.key,
|
||||
currentEditRow.value.value,
|
||||
)
|
||||
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'))
|
||||
// update display value
|
||||
// if (!isEmpty(updated)) {
|
||||
|
@ -198,7 +211,7 @@ const tableData = computed(() => {
|
|||
return data
|
||||
})
|
||||
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('')
|
||||
|
@ -240,7 +253,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
|
||||
<template>
|
||||
<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="flex-box-h">
|
||||
<n-input-group>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n'
|
|||
import ContentToolbar from './ContentToolbar.vue'
|
||||
import AddLink from '@/components/icons/AddLink.vue'
|
||||
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 EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
||||
import useDialogStore from 'stores/dialog.js'
|
||||
|
@ -15,6 +15,10 @@ const props = defineProps({
|
|||
name: String,
|
||||
db: Number,
|
||||
keyPath: String,
|
||||
keyCode: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
ttl: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
|
@ -23,6 +27,14 @@ const props = defineProps({
|
|||
size: Number,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {ComputedRef<string|number[]>}
|
||||
*/
|
||||
const keyName = computed(() => {
|
||||
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||
})
|
||||
|
||||
const connectionStore = useConnectionStore()
|
||||
const dialogStore = useDialogStore()
|
||||
const keyType = redisTypes.LIST
|
||||
|
@ -56,6 +68,7 @@ const valueColumn = reactive({
|
|||
}
|
||||
},
|
||||
})
|
||||
|
||||
const actionColumn = {
|
||||
key: 'action',
|
||||
title: i18n.t('interface.action'),
|
||||
|
@ -76,11 +89,11 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.removeListItem(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
row.no - 1,
|
||||
)
|
||||
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 }))
|
||||
// update display value
|
||||
// if (!isEmpty(removed)) {
|
||||
|
@ -98,12 +111,12 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.updateListItem(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
currentEditRow.value.no - 1,
|
||||
currentEditRow.value.value,
|
||||
)
|
||||
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'))
|
||||
// update display value
|
||||
// if (!isEmpty(updated)) {
|
||||
|
@ -153,7 +166,7 @@ const tableData = computed(() => {
|
|||
})
|
||||
|
||||
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('')
|
||||
|
@ -172,7 +185,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
|
||||
<template>
|
||||
<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="flex-box-h">
|
||||
<n-input
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n'
|
|||
import ContentToolbar from './ContentToolbar.vue'
|
||||
import AddLink from '@/components/icons/AddLink.vue'
|
||||
import { NButton, NCode, NIcon, NInput } from 'naive-ui'
|
||||
import { size } from 'lodash'
|
||||
import { isEmpty, size } from 'lodash'
|
||||
import useDialogStore from 'stores/dialog.js'
|
||||
import { types, types as redisTypes } from '@/consts/support_redis_type.js'
|
||||
import EditableTableColumn from '@/components/common/EditableTableColumn.vue'
|
||||
|
@ -15,6 +15,10 @@ const props = defineProps({
|
|||
name: String,
|
||||
db: Number,
|
||||
keyPath: String,
|
||||
keyCode: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
ttl: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
|
@ -23,6 +27,14 @@ const props = defineProps({
|
|||
size: Number,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {ComputedRef<string|number[]>}
|
||||
*/
|
||||
const keyName = computed(() => {
|
||||
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||
})
|
||||
|
||||
const connectionStore = useConnectionStore()
|
||||
const dialogStore = useDialogStore()
|
||||
const keyType = redisTypes.SET
|
||||
|
@ -78,11 +90,11 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.removeSetItem(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
row.value,
|
||||
)
|
||||
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 }))
|
||||
// update display value
|
||||
// props.value.splice(row.no - 1, 1)
|
||||
|
@ -98,12 +110,12 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.updateSetItem(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
row.value,
|
||||
currentEditRow.value.value,
|
||||
)
|
||||
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'))
|
||||
// update display value
|
||||
// props.value[row.no - 1] = currentEditRow.value.value
|
||||
|
@ -149,7 +161,7 @@ const tableData = computed(() => {
|
|||
})
|
||||
|
||||
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('')
|
||||
|
@ -168,7 +180,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
|
||||
<template>
|
||||
<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="flex-box-h">
|
||||
<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 useDialogStore from 'stores/dialog.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 props = defineProps({
|
||||
name: String,
|
||||
db: Number,
|
||||
keyPath: String,
|
||||
keyCode: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
ttl: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
|
@ -23,6 +27,14 @@ const props = defineProps({
|
|||
size: Number,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {ComputedRef<string|number[]>}
|
||||
*/
|
||||
const keyName = computed(() => {
|
||||
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||
})
|
||||
|
||||
const filterOption = [
|
||||
{
|
||||
value: 1,
|
||||
|
@ -86,11 +98,11 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.removeStreamValues(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
row.id,
|
||||
)
|
||||
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 }))
|
||||
// update display value
|
||||
// if (!isEmpty(removed)) {
|
||||
|
@ -122,7 +134,7 @@ const tableData = computed(() => {
|
|||
})
|
||||
|
||||
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('')
|
||||
|
@ -153,7 +165,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
|
||||
<template>
|
||||
<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="flex-box-h">
|
||||
<n-input-group>
|
||||
|
|
|
@ -10,7 +10,7 @@ import Close from '@/components/icons/Close.vue'
|
|||
import Edit from '@/components/icons/Edit.vue'
|
||||
import { types as redisTypes } from '@/consts/support_redis_type.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'
|
||||
|
||||
const i18n = useI18n()
|
||||
|
@ -20,6 +20,10 @@ const props = defineProps({
|
|||
name: String,
|
||||
db: Number,
|
||||
keyPath: String,
|
||||
keyCode: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
ttl: {
|
||||
type: Number,
|
||||
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(() =>
|
||||
map(types, (t) => {
|
||||
return {
|
||||
|
@ -76,7 +88,7 @@ const viewLanguage = computed(() => {
|
|||
})
|
||||
|
||||
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(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
toLower(keyType),
|
||||
editValue.value,
|
||||
-1,
|
||||
props.viewAs,
|
||||
)
|
||||
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'))
|
||||
} else {
|
||||
$message.error(msg)
|
||||
|
@ -139,13 +151,19 @@ const onSaveValue = async () => {
|
|||
|
||||
<template>
|
||||
<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">
|
||||
<n-text>{{ $t('interface.view_as') }}</n-text>
|
||||
<n-select
|
||||
:value="props.viewAs"
|
||||
:options="viewOption"
|
||||
style="width: 200px"
|
||||
style="width: 160px"
|
||||
filterable
|
||||
@update:value="onViewTypeUpdate" />
|
||||
<div class="flex-item-expand"></div>
|
||||
|
|
|
@ -15,6 +15,10 @@ const props = defineProps({
|
|||
name: String,
|
||||
db: Number,
|
||||
keyPath: String,
|
||||
keyCode: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
ttl: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
|
@ -23,6 +27,14 @@ const props = defineProps({
|
|||
size: Number,
|
||||
})
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {ComputedRef<string|number[]>}
|
||||
*/
|
||||
const keyName = computed(() => {
|
||||
return !isEmpty(props.keyCode) ? props.keyCode : props.keyPath
|
||||
})
|
||||
|
||||
const filterOption = [
|
||||
{
|
||||
value: 1,
|
||||
|
@ -149,11 +161,11 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.removeZSetItem(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
row.value,
|
||||
)
|
||||
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 }))
|
||||
} else {
|
||||
$message.error(msg)
|
||||
|
@ -172,13 +184,13 @@ const actionColumn = {
|
|||
const { success, msg } = await connectionStore.updateZSetItem(
|
||||
props.name,
|
||||
props.db,
|
||||
props.keyPath,
|
||||
keyName.value,
|
||||
row.value,
|
||||
newValue,
|
||||
currentEditRow.value.score,
|
||||
)
|
||||
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'))
|
||||
} else {
|
||||
$message.error(msg)
|
||||
|
@ -222,7 +234,7 @@ const tableData = computed(() => {
|
|||
})
|
||||
|
||||
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('')
|
||||
|
@ -266,7 +278,13 @@ const onUpdateFilter = (filters, sourceColumn) => {
|
|||
|
||||
<template>
|
||||
<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="flex-box-h">
|
||||
<n-input-group>
|
||||
|
|
|
@ -10,13 +10,14 @@ import AddHashValue from '@/components/new_value/AddHashValue.vue'
|
|||
import AddZSetValue from '@/components/new_value/AddZSetValue.vue'
|
||||
import useConnectionStore from 'stores/connections.js'
|
||||
import NewStreamValue from '@/components/new_value/NewStreamValue.vue'
|
||||
import { size, slice } from 'lodash'
|
||||
import { isEmpty, size, slice } from 'lodash'
|
||||
|
||||
const i18n = useI18n()
|
||||
const newForm = reactive({
|
||||
server: '',
|
||||
db: 0,
|
||||
key: '',
|
||||
keyCode: null,
|
||||
type: '',
|
||||
opType: 0,
|
||||
value: null,
|
||||
|
@ -65,10 +66,11 @@ watch(
|
|||
() => dialogStore.addFieldsDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
const { server, db, key, type } = dialogStore.addFieldParam
|
||||
const { server, db, key, keyCode, type } = dialogStore.addFieldParam
|
||||
newForm.server = server
|
||||
newForm.db = db
|
||||
newForm.key = key
|
||||
newForm.keyCode = keyCode
|
||||
newForm.type = type
|
||||
newForm.opType = 0
|
||||
newForm.value = null
|
||||
|
@ -79,24 +81,25 @@ watch(
|
|||
const connectionStore = useConnectionStore()
|
||||
const onAdd = async () => {
|
||||
try {
|
||||
const { server, db, key, type } = newForm
|
||||
const { server, db, key, keyCode, type } = newForm
|
||||
let { value } = newForm
|
||||
if (value == null) {
|
||||
value = defaultValue[type]
|
||||
}
|
||||
const keyName = isEmpty(keyCode) ? key : keyCode
|
||||
switch (type) {
|
||||
case types.LIST:
|
||||
{
|
||||
let data
|
||||
if (newForm.opType === 1) {
|
||||
data = await connectionStore.prependListItem(server, db, key, value)
|
||||
data = await connectionStore.prependListItem(server, db, keyName, value)
|
||||
} else {
|
||||
data = await connectionStore.appendListItem(server, db, key, value)
|
||||
data = await connectionStore.appendListItem(server, db, keyName, value)
|
||||
}
|
||||
const { success, msg } = data
|
||||
if (success) {
|
||||
if (newForm.reload) {
|
||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
||||
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||
}
|
||||
$message.success(i18n.t('dialogue.handle_succ'))
|
||||
} else {
|
||||
|
@ -107,10 +110,16 @@ const onAdd = async () => {
|
|||
|
||||
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 (newForm.reload) {
|
||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
||||
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||
}
|
||||
$message.success(i18n.t('dialogue.handle_succ'))
|
||||
} else {
|
||||
|
@ -121,10 +130,10 @@ const onAdd = async () => {
|
|||
|
||||
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 (newForm.reload) {
|
||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
||||
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||
}
|
||||
$message.success(i18n.t('dialogue.handle_succ'))
|
||||
} else {
|
||||
|
@ -135,10 +144,16 @@ const onAdd = async () => {
|
|||
|
||||
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 (newForm.reload) {
|
||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
||||
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||
}
|
||||
$message.success(i18n.t('dialogue.handle_succ'))
|
||||
} else {
|
||||
|
@ -153,13 +168,13 @@ const onAdd = async () => {
|
|||
const { success, msg } = await connectionStore.addStreamValue(
|
||||
server,
|
||||
db,
|
||||
key,
|
||||
keyName,
|
||||
value[0],
|
||||
slice(value, 1),
|
||||
)
|
||||
if (success) {
|
||||
if (newForm.reload) {
|
||||
connectionStore.loadKeyValue(server, db, key).then(() => {})
|
||||
connectionStore.loadKeyValue(server, db, keyName).then(() => {})
|
||||
}
|
||||
$message.success(i18n.t('dialogue.handle_succ'))
|
||||
} else {
|
||||
|
|
|
@ -3,8 +3,14 @@ import { reactive, ref, watch } from 'vue'
|
|||
import useDialog from 'stores/dialog'
|
||||
import useTabStore from 'stores/tab.js'
|
||||
import useConnectionStore from 'stores/connections.js'
|
||||
import Binary from '@/components/icons/Binary.vue'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
const ttlForm = reactive({
|
||||
server: '',
|
||||
db: 0,
|
||||
key: '',
|
||||
keyCode: null,
|
||||
ttl: -1,
|
||||
})
|
||||
|
||||
|
@ -12,9 +18,6 @@ const dialogStore = useDialog()
|
|||
const connectionStore = useConnectionStore()
|
||||
const tabStore = useTabStore()
|
||||
|
||||
const currentServer = ref('')
|
||||
const currentKey = ref('')
|
||||
const currentDB = ref(0)
|
||||
watch(
|
||||
() => dialogStore.ttlDialogVisible,
|
||||
(visible) => {
|
||||
|
@ -22,15 +25,15 @@ watch(
|
|||
// get ttl from current tab
|
||||
const tab = tabStore.currentTab
|
||||
if (tab != null) {
|
||||
ttlForm.server = tab.name
|
||||
ttlForm.db = tab.db
|
||||
ttlForm.key = tab.key
|
||||
ttlForm.keyCode = tab.keyCode
|
||||
if (tab.ttl < 0) {
|
||||
// forever
|
||||
} else {
|
||||
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) {
|
||||
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) {
|
||||
tabStore.updateTTL({
|
||||
server: currentServer.value,
|
||||
db: currentDB.value,
|
||||
key: currentKey.value,
|
||||
server: ttlForm.server,
|
||||
db: ttlForm.db,
|
||||
key: ttlForm.key,
|
||||
ttl: ttlForm.ttl,
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
$message.error(e.message || 'set ttl fail')
|
||||
} finally {
|
||||
dialogStore.closeTTLDialog()
|
||||
}
|
||||
|
@ -74,7 +79,11 @@ const onConfirm = async () => {
|
|||
transform-origin="center">
|
||||
<n-form :model="ttlForm" :show-require-mark="false" label-placement="top">
|
||||
<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 :label="$t('interface.ttl')" required>
|
||||
<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 { NIcon, NSpace, NTag } from 'naive-ui'
|
||||
import Key from '@/components/icons/Key.vue'
|
||||
import Binary from '@/components/icons/Binary.vue'
|
||||
import ToggleDb from '@/components/icons/ToggleDb.vue'
|
||||
import { find, get, includes, indexOf, isEmpty, pull, remove, size } from 'lodash'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
@ -223,7 +224,9 @@ const handleSelectContextMenu = (key) => {
|
|||
return
|
||||
}
|
||||
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) {
|
||||
case 'server_info':
|
||||
tabStore.setSelectedKeys(props.server)
|
||||
|
@ -267,10 +270,10 @@ const handleSelectContextMenu = (key) => {
|
|||
dialogStore.openDeleteKeyDialog(props.server, db, isEmpty(redisKey) ? '*' : redisKey + ':*')
|
||||
break
|
||||
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) => {
|
||||
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
|
||||
for (const node of options) {
|
||||
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)) {
|
||||
connectionStore.loadKeyValue(props.server, db, redisKey)
|
||||
}
|
||||
|
@ -373,7 +377,7 @@ const renderPrefix = ({ option }) => {
|
|||
NIcon,
|
||||
{ size: 20 },
|
||||
{
|
||||
default: () => h(Key),
|
||||
default: () => h(!!option.redisKeyCode ? Binary : Key),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
"batch_delete": "Batch Delete",
|
||||
"copy_path": "Copy Path",
|
||||
"copy_key": "Copy Key",
|
||||
"binary_key": "Binary Key Name",
|
||||
"remove_key": "Remove Key",
|
||||
"new_key": "Add New Key",
|
||||
"nonexist_tab_content": "Selected key does not exist. Please retry",
|
||||
|
@ -105,6 +106,7 @@
|
|||
"delete_key_succ": "\"{key}\" has been deleted",
|
||||
"save_value_succ": "Value Saved !",
|
||||
"copy_succ": "Value Copied !",
|
||||
"rename_binary_key_fail": "Rename binary key name is unsupported",
|
||||
"handle_succ": "Success!",
|
||||
"reload_succ": "Reloaded!",
|
||||
"field_required": "This item should not be blank",
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
"batch_delete": "批量删除键",
|
||||
"copy_path": "复制路径",
|
||||
"copy_key": "复制键名",
|
||||
"binary_key": "二进制键名",
|
||||
"remove_key": "删除键",
|
||||
"new_key": "添加新键",
|
||||
"nonexist_tab_content": "所选键不存在,请尝试刷新重试",
|
||||
|
@ -105,6 +106,7 @@
|
|||
"delete_key_succ": "{key} 已被删除",
|
||||
"save_value_succ": "已保存值",
|
||||
"copy_succ": "已复制到剪切板",
|
||||
"rename_binary_key_fail": "不支持重命名二进制键名",
|
||||
"handle_succ": "操作成功",
|
||||
"reload_succ": "已重新载入",
|
||||
"field_required": "此项不能为空",
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
get,
|
||||
isEmpty,
|
||||
join,
|
||||
map,
|
||||
remove,
|
||||
size,
|
||||
slice,
|
||||
|
@ -49,6 +50,7 @@ import {
|
|||
import { ConnectionType } from '@/consts/connection_type.js'
|
||||
import useTabStore from './tab.js'
|
||||
import { types } from '@/consts/support_redis_type.js'
|
||||
import { decodeRedisKey, nativeRedisKey } from '@/utils/key_convert.js'
|
||||
|
||||
const useConnectionStore = defineStore('connections', {
|
||||
/**
|
||||
|
@ -68,6 +70,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* @property {number} type
|
||||
* @property {number} [db] - database index, type == ConnectionType.RedisDB 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 {boolean} [isLeaf]
|
||||
* @property {boolean} [opened] - redis db is opened, type == ConnectionType.RedisDB only
|
||||
|
@ -529,11 +532,10 @@ const useConnectionStore = defineStore('connections', {
|
|||
selDB.opened = true
|
||||
if (isEmpty(keys)) {
|
||||
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)
|
||||
},
|
||||
|
||||
|
@ -592,7 +594,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* load redis key
|
||||
* @param {string} server
|
||||
* @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]
|
||||
*/
|
||||
async loadKeyValue(server, db, key, viewType) {
|
||||
|
@ -602,12 +604,15 @@ const useConnectionStore = defineStore('connections', {
|
|||
const { data, success, msg } = await GetKeyValue(server, db, key, viewType)
|
||||
if (success) {
|
||||
const { type, ttl, value, size, viewAs } = data
|
||||
const k = decodeRedisKey(key)
|
||||
const binaryKey = k !== key
|
||||
tab.upsertTab({
|
||||
server,
|
||||
db,
|
||||
type,
|
||||
ttl,
|
||||
key,
|
||||
keyCode: binaryKey ? key : undefined,
|
||||
key: k,
|
||||
value,
|
||||
size,
|
||||
viewAs,
|
||||
|
@ -629,6 +634,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
type: 'none',
|
||||
ttl: -1,
|
||||
key: null,
|
||||
keyCode: null,
|
||||
value: null,
|
||||
size: 0,
|
||||
})
|
||||
|
@ -713,7 +719,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* remove keys in db
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string[]} keys
|
||||
* @param {Array<string|number[]>} keys
|
||||
* @param {boolean} [sortInsert]
|
||||
* @return {{success: boolean, newKey: number, newLayer: number, replaceKey: number}}
|
||||
* @private
|
||||
|
@ -735,7 +741,9 @@ const useConnectionStore = defineStore('connections', {
|
|||
const nodeMap = this._getNodeMap(connName, db)
|
||||
const rootChildren = selDB.children
|
||||
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 lastIdx = len - 1
|
||||
let handlePath = ''
|
||||
|
@ -776,10 +784,11 @@ const useConnectionStore = defineStore('connections', {
|
|||
const replaceKey = nodeMap.has(nodeKey)
|
||||
const selectedNode = {
|
||||
key: `${connName}/db${db}#${nodeKey}`,
|
||||
label: keyParts[i],
|
||||
label: binaryKey ? k : keyParts[i],
|
||||
db,
|
||||
keys: 0,
|
||||
redisKey: handlePath,
|
||||
redisKeyCode: binaryKey ? key : undefined,
|
||||
type: ConnectionType.RedisValue,
|
||||
isLeaf: true,
|
||||
}
|
||||
|
@ -864,7 +873,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
|
||||
/**
|
||||
* sort all node item's children and calculate keys count
|
||||
* @param node
|
||||
* @param {DatabaseItem} node
|
||||
* @param {boolean} skipSort skip sorting children
|
||||
* @returns {boolean} return whether key count changed
|
||||
* @private
|
||||
|
@ -881,7 +890,12 @@ const useConnectionStore = defineStore('connections', {
|
|||
count += elem.keys
|
||||
}
|
||||
} 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) {
|
||||
node.keys = count
|
||||
|
@ -926,7 +940,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* set redis key
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {string} keyType
|
||||
* @param {any} value
|
||||
* @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
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {string} field
|
||||
* @param {string} newField
|
||||
* @param {string} value
|
||||
|
@ -983,7 +997,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* insert or update hash field item
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {number }action 0:ignore duplicated fields 1:overwrite duplicated fields
|
||||
* @param {string[]} fieldItems field1, value1, filed2, value2...
|
||||
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
||||
|
@ -1028,7 +1042,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* insert list item
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {int} action 0: push to head, 1: push to tail
|
||||
* @param {string[]}values
|
||||
* @returns {Promise<*|{msg, success: boolean}>}
|
||||
|
@ -1089,7 +1103,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* update value of list item by index
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {number} index
|
||||
* @param {string} value
|
||||
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
||||
|
@ -1112,7 +1126,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* remove list item
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {number} index
|
||||
* @returns {Promise<{[msg]: string, success: boolean, [removed]: string[]}>}
|
||||
*/
|
||||
|
@ -1134,7 +1148,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* add item to set
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number} key
|
||||
* @param {string} value
|
||||
* @returns {Promise<{[msg]: string, success: boolean}>}
|
||||
*/
|
||||
|
@ -1155,7 +1169,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* update value of set item
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {string} value
|
||||
* @param {string} newValue
|
||||
* @returns {Promise<{[msg]: string, success: boolean}>}
|
||||
|
@ -1175,10 +1189,10 @@ const useConnectionStore = defineStore('connections', {
|
|||
|
||||
/**
|
||||
* remove item from set
|
||||
* @param connName
|
||||
* @param db
|
||||
* @param key
|
||||
* @param value
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string|number[]} key
|
||||
* @param {string} value
|
||||
* @returns {Promise<{[msg]: string, success: boolean}>}
|
||||
*/
|
||||
async removeSetItem(connName, db, key, value) {
|
||||
|
@ -1198,7 +1212,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* add item to sorted set
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {number} action
|
||||
* @param {Object.<string, number>} vs value: score
|
||||
* @returns {Promise<{[msg]: string, success: boolean}>}
|
||||
|
@ -1220,7 +1234,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* update item of sorted set
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {string} value
|
||||
* @param {string} newValue
|
||||
* @param {number} score
|
||||
|
@ -1244,7 +1258,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* remove item from sorted set
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param key
|
||||
* @param {string|number[]} key
|
||||
* @param {string} value
|
||||
* @returns {Promise<{[msg]: string, success: boolean, [removed]: []}>}
|
||||
*/
|
||||
|
@ -1266,7 +1280,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* insert new stream field item
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {string} id
|
||||
* @param {string[]} values field1, value1, filed2, value2...
|
||||
* @returns {Promise<{[msg]: string, success: boolean, [updated]: {}}>}
|
||||
|
@ -1289,7 +1303,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* remove stream field
|
||||
* @param {string} connName
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {string[]|string} ids
|
||||
* @returns {Promise<{[msg]: {}, success: boolean, [removed]: string[]}>}
|
||||
*/
|
||||
|
@ -1427,7 +1441,7 @@ const useConnectionStore = defineStore('connections', {
|
|||
* delete redis key
|
||||
* @param {string} connName
|
||||
* @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
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
|
@ -1437,9 +1451,10 @@ const useConnectionStore = defineStore('connections', {
|
|||
await DeleteKey(connName, db, key)
|
||||
}
|
||||
|
||||
const k = nativeRedisKey(key)
|
||||
// update tree view data
|
||||
this._deleteKeyNode(connName, db, key)
|
||||
this._tidyNode(connName, db, key, true)
|
||||
this._deleteKeyNode(connName, db, k)
|
||||
this._tidyNode(connName, db, k, true)
|
||||
|
||||
// set tab content empty
|
||||
const tab = useTabStore()
|
||||
|
|
|
@ -45,6 +45,7 @@ const useDialogStore = defineStore('dialog', {
|
|||
server: '',
|
||||
db: 0,
|
||||
key: '',
|
||||
keyCode: null,
|
||||
type: null,
|
||||
},
|
||||
addFieldsDialogVisible: false,
|
||||
|
@ -185,12 +186,14 @@ const useDialogStore = defineStore('dialog', {
|
|||
* @param {string} server
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {number[]|null} keyCode
|
||||
* @param {string} type
|
||||
*/
|
||||
openAddFieldsDialog(server, db, key, type) {
|
||||
openAddFieldsDialog(server, db, key, keyCode, type) {
|
||||
this.addFieldParam.server = server
|
||||
this.addFieldParam.db = db
|
||||
this.addFieldParam.key = key
|
||||
this.addFieldParam.keyCode = keyCode
|
||||
this.addFieldParam.type = type
|
||||
this.addFieldsDialogVisible = true
|
||||
},
|
||||
|
|
|
@ -14,6 +14,7 @@ const useTabStore = defineStore('tab', {
|
|||
* @property {string} [server] server name
|
||||
* @property {int} [db] database index
|
||||
* @property {string} [key] current key name
|
||||
* @property {number[]|null|undefined} [keyCode] current key name as char array
|
||||
* @property {int} [ttl] ttl of current key
|
||||
*/
|
||||
|
||||
|
@ -83,11 +84,12 @@ const useTabStore = defineStore('tab', {
|
|||
* @param {number} [type]
|
||||
* @param {number} [ttl]
|
||||
* @param {string} [key]
|
||||
* @param {string} [keyCode]
|
||||
* @param {number} [size]
|
||||
* @param {*} [value]
|
||||
* @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 })
|
||||
if (tabIndex === -1) {
|
||||
this.tabList.push({
|
||||
|
@ -97,6 +99,7 @@ const useTabStore = defineStore('tab', {
|
|||
type,
|
||||
ttl,
|
||||
key,
|
||||
keyCode,
|
||||
size,
|
||||
value,
|
||||
viewAs,
|
||||
|
@ -112,6 +115,7 @@ const useTabStore = defineStore('tab', {
|
|||
tab.type = type
|
||||
tab.ttl = ttl
|
||||
tab.key = key
|
||||
tab.keyCode = keyCode
|
||||
tab.size = size
|
||||
tab.value = value
|
||||
tab.viewAs = viewAs
|
||||
|
@ -123,7 +127,7 @@ const useTabStore = defineStore('tab', {
|
|||
* update ttl by tag
|
||||
* @param {string} server
|
||||
* @param {number} db
|
||||
* @param {string} key
|
||||
* @param {string|number[]} key
|
||||
* @param {number} 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": {
|
||||
"companyName": "Tiny Craft",
|
||||
"productName": "Tiny RDM",
|
||||
"productVersion": "0.9.0",
|
||||
"productVersion": "1.0.0",
|
||||
"copyright": "Copyright © 2023",
|
||||
"comments": "Tiny Redis Desktop Manager"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue