From 5b84fa59f6c88d47d76b34589a0d6412905ac892 Mon Sep 17 00:00:00 2001 From: Lykin <137850705+tiny-craft@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:15:02 +0800 Subject: [PATCH] perf: set value support format viewing #65 --- backend/services/browser_service.go | 81 +++--- backend/types/js_resp.go | 21 +- backend/types/redis_wrapper.go | 16 ++ backend/utils/string/convert.go | 53 ++-- .../content_value/ContentValueHash.vue | 1 - .../content_value/ContentValueList.vue | 14 +- .../content_value/ContentValueSet.vue | 231 ++++++++++++------ .../content_value/ContentValueWrapper.vue | 46 ++-- frontend/src/stores/browser.js | 25 +- frontend/src/utils/discrete.js | 3 + 10 files changed, 309 insertions(+), 182 deletions(-) diff --git a/backend/services/browser_service.go b/backend/services/browser_service.go index 07857a8..dd2aa82 100644 --- a/backend/services/browser_service.go +++ b/backend/services/browser_service.go @@ -580,6 +580,11 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS resp.Msg = "key not exists" return } + var doConvert bool + if (len(param.Decode) > 0 && param.Decode != types.DECODE_NONE) || + (len(param.Format) > 0 && param.Format != types.FORMAT_RAW) { + doConvert = true + } var data types.KeyDetail //var cursor uint64 @@ -636,14 +641,15 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS loadListHandle := func() ([]types.ListEntryItem, bool, error) { var loadVal []string var cursor uint64 + var subErr error if param.Full { // load all cursor = 0 - loadVal, err = client.LRange(ctx, key, 0, -1).Result() + loadVal, subErr = client.LRange(ctx, key, 0, -1).Result() } else { cursor, _ = getEntryCursor() scanSize := int64(Preferences().GetScanSize()) - loadVal, err = client.LRange(ctx, key, int64(cursor), int64(cursor)+scanSize-1).Result() + loadVal, subErr = client.LRange(ctx, key, int64(cursor), int64(cursor)+scanSize-1).Result() cursor = cursor + uint64(scanSize) if len(loadVal) < int(scanSize) { cursor = 0 @@ -652,12 +658,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS setEntryCursor(cursor) items := make([]types.ListEntryItem, len(loadVal)) - doConvert := len(param.Decode) > 0 && len(param.Format) > 0 for i, val := range loadVal { - items[i] = types.ListEntryItem{ - Value: val, - DisplayValue: "", - } items[i].Value = val if doConvert { if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val { @@ -665,8 +666,8 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS } } } - if err != nil { - return items, false, err + if subErr != nil { + return items, false, subErr } return items, cursor == 0, nil } @@ -685,14 +686,14 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS items := make([]types.HashEntryItem, 0, scanSize) var loadedVal []string var cursor uint64 - doConvert := len(param.Decode) > 0 && len(param.Format) > 0 + var subErr error if param.Full { // load all cursor = 0 for { - loadedVal, cursor, err = client.HScan(ctx, key, cursor, "*", scanSize).Result() - if err != nil { - return nil, false, err + loadedVal, cursor, subErr = client.HScan(ctx, key, cursor, "*", scanSize).Result() + if subErr != nil { + return nil, false, subErr } for i := 0; i < len(loadedVal); i += 2 { items = append(items, types.HashEntryItem{ @@ -711,9 +712,9 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS } } else { cursor, _ = getEntryCursor() - loadedVal, cursor, err = client.HScan(ctx, key, cursor, matchPattern, scanSize).Result() - if err != nil { - return nil, false, err + loadedVal, cursor, subErr = client.HScan(ctx, key, cursor, matchPattern, scanSize).Result() + if subErr != nil { + return nil, false, subErr } for i := 0; i < len(loadedVal); i += 2 { items = append(items, types.HashEntryItem{ @@ -739,30 +740,39 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS } case "set": - loadSetHandle := func() ([]string, bool, error) { - var items []string + loadSetHandle := func() ([]types.SetEntryItem, bool, error) { + var items []types.SetEntryItem var cursor uint64 + var subErr error scanSize := int64(Preferences().GetScanSize()) var loadedKey []string if param.Full { // load all cursor = 0 for { - loadedKey, cursor, err = client.SScan(ctx, key, cursor, param.MatchPattern, scanSize).Result() - if err != nil { - return items, false, err + loadedKey, cursor, subErr = client.SScan(ctx, key, cursor, param.MatchPattern, scanSize).Result() + if subErr != nil { + return items, false, subErr } - items = append(items, loadedKey...) if cursor == 0 { break } } } else { cursor, _ = getEntryCursor() - loadedKey, cursor, err = client.SScan(ctx, key, cursor, param.MatchPattern, scanSize).Result() - items = append(items, loadedKey...) + loadedKey, cursor, subErr = client.SScan(ctx, key, cursor, param.MatchPattern, scanSize).Result() } setEntryCursor(cursor) + + items = make([]types.SetEntryItem, len(loadedKey)) + for i, val := range loadedKey { + items[i].Value = val + if doConvert { + if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val { + items[i].DisplayValue = dv + } + } + } return items, cursor == 0, nil } @@ -1245,23 +1255,36 @@ func (b *browserService) SetSetItem(connName string, db int, k any, remove bool, } // UpdateSetItem replace member of set -func (b *browserService) UpdateSetItem(connName string, db int, k any, value, newValue string) (resp types.JSResp) { - item, err := b.getRedisClient(connName, db) +func (b *browserService) UpdateSetItem(param types.SetSetParam) (resp types.JSResp) { + item, err := b.getRedisClient(param.Server, param.DB) if err != nil { resp.Msg = err.Error() return } client, ctx := item.client, item.ctx - key := strutil.DecodeRedisKey(k) - _, _ = client.SRem(ctx, key, value).Result() - _, err = client.SAdd(ctx, key, newValue).Result() + key := strutil.DecodeRedisKey(param.Key) + // remove old value + str := strutil.DecodeRedisKey(param.Value) + _, _ = client.SRem(ctx, key, str).Result() + + // insert new value + str = strutil.DecodeRedisKey(param.NewValue) + var saveStr string + if saveStr, err = strutil.SaveAs(str, param.Format, param.Decode); err != nil { + resp.Msg = fmt.Sprintf(`save to type "%s" fail: %s`, param.Format, err.Error()) + return + } + _, err = client.SAdd(ctx, key, saveStr).Result() if err != nil { resp.Msg = err.Error() return } resp.Success = true + resp.Data = map[string]any{ + "added": saveStr, + } return } diff --git a/backend/types/js_resp.go b/backend/types/js_resp.go index 7559fbd..89b5fa1 100644 --- a/backend/types/js_resp.go +++ b/backend/types/js_resp.go @@ -30,17 +30,6 @@ type KeyDetailParam struct { Full bool `json:"full"` } -type ListEntryItem struct { - Value any `json:"v"` - DisplayValue string `json:"dv,omitempty"` -} - -type HashEntryItem struct { - Key string `json:"k"` - Value any `json:"v"` - DisplayValue string `json:"dv,omitempty"` -} - type KeyDetail struct { Value any `json:"value"` Length int64 `json:"length,omitempty"` @@ -80,3 +69,13 @@ type SetHashParam struct { Format string `json:"format,omitempty"` Decode string `json:"decode,omitempty"` } + +type SetSetParam struct { + Server string `json:"server"` + DB int `json:"db"` + Key any `json:"key"` + Value any `json:"value"` + NewValue any `json:"newValue"` + Format string `json:"format,omitempty"` + Decode string `json:"decode,omitempty"` +} diff --git a/backend/types/redis_wrapper.go b/backend/types/redis_wrapper.go index 1419136..f830aab 100644 --- a/backend/types/redis_wrapper.go +++ b/backend/types/redis_wrapper.go @@ -1,5 +1,21 @@ package types +type ListEntryItem struct { + Value any `json:"v"` + DisplayValue string `json:"dv,omitempty"` +} + +type HashEntryItem struct { + Key string `json:"k"` + Value any `json:"v"` + DisplayValue string `json:"dv,omitempty"` +} + +type SetEntryItem struct { + Value any `json:"v"` + DisplayValue string `json:"dv,omitempty"` +} + type ZSetItem struct { Value string `json:"value"` Score float64 `json:"score"` diff --git a/backend/utils/string/convert.go b/backend/utils/string/convert.go index 67fa749..8b82e53 100644 --- a/backend/utils/string/convert.go +++ b/backend/utils/string/convert.go @@ -106,31 +106,34 @@ func decodeWith(str, decodeType string) (value, resultDecode string) { // if no decode is possible, it will return the origin string value and "none" decode type func autoDecode(str string) (value, resultDecode string) { if len(str) > 0 { - var ok bool - if value, ok = decodeBase64(str); ok { - resultDecode = types.DECODE_BASE64 - return - } + // pure digit content may incorrect regard as some encoded type, skip decode + if match, _ := regexp.MatchString(`^\d+$`, str); !match { + var ok bool + if value, ok = decodeBase64(str); ok { + resultDecode = types.DECODE_BASE64 + return + } - if value, ok = decodeGZip(str); ok { - resultDecode = types.DECODE_GZIP - return - } + if value, ok = decodeGZip(str); ok { + resultDecode = types.DECODE_GZIP + return + } - // FIXME: skip decompress with deflate due to incorrect format checking - //if value, ok = decodeDeflate(str); ok { - // resultDecode = types.DECODE_DEFLATE - // return - //} + // FIXME: skip decompress with deflate due to incorrect format checking + //if value, ok = decodeDeflate(str); ok { + // resultDecode = types.DECODE_DEFLATE + // return + //} - if value, ok = decodeZStd(str); ok { - resultDecode = types.DECODE_ZSTD - return - } + if value, ok = decodeZStd(str); ok { + resultDecode = types.DECODE_ZSTD + return + } - if value, ok = decodeBrotli(str); ok { - resultDecode = types.DECODE_BROTLI - return + if value, ok = decodeBrotli(str); ok { + resultDecode = types.DECODE_BROTLI + return + } } } @@ -215,11 +218,9 @@ func decodeJson(str string) (string, bool) { } func decodeBase64(str string) (string, bool) { - if match, _ := regexp.MatchString(`^\d+$`, str); !match { - if decodedStr, err := base64.StdEncoding.DecodeString(str); err == nil { - if s := string(decodedStr); !containsBinary(s) { - return s, true - } + if decodedStr, err := base64.StdEncoding.DecodeString(str); err == nil { + if s := string(decodedStr); !containsBinary(s) { + return s, true } } return str, false diff --git a/frontend/src/components/content_value/ContentValueHash.vue b/frontend/src/components/content_value/ContentValueHash.vue index 320924c..94fab1e 100644 --- a/frontend/src/components/content_value/ContentValueHash.vue +++ b/frontend/src/components/content_value/ContentValueHash.vue @@ -373,7 +373,6 @@ defineExpose({