feat: add delete key dialog and logic
refactor: tidy function of connection store
This commit is contained in:
parent
d7955702f8
commit
1841ccf3d3
|
@ -107,9 +107,9 @@ func (c *connectionService) SaveConnection(name string, param types.ConnectionCo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveConnection remove connection by name
|
// DeleteConnection remove connection by name
|
||||||
func (c *connectionService) RemoveConnection(name string) (resp types.JSResp) {
|
func (c *connectionService) DeleteConnection(name string) (resp types.JSResp) {
|
||||||
err := c.conns.RemoveConnection(name)
|
err := c.conns.DeleteConnection(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
|
@ -151,9 +151,9 @@ func (c *connectionService) RenameGroup(name, newName string) (resp types.JSResp
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveGroup remove group by name
|
// DeleteGroup remove group by name
|
||||||
func (c *connectionService) RemoveGroup(name string, includeConn bool) (resp types.JSResp) {
|
func (c *connectionService) DeleteGroup(name string, includeConn bool) (resp types.JSResp) {
|
||||||
err := c.conns.RemoveGroup(name, includeConn)
|
err := c.conns.DeleteGroup(name, includeConn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
|
@ -318,12 +318,8 @@ func (c *connectionService) ScanKeys(connName string, db int, prefix string) (re
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasSuffix(prefix, "*") {
|
var keys []string
|
||||||
prefix += ":*"
|
//keys := map[string]keyItem{}
|
||||||
}
|
|
||||||
|
|
||||||
//var keys []string
|
|
||||||
keys := map[string]keyItem{}
|
|
||||||
var cursor uint64
|
var cursor uint64
|
||||||
for {
|
for {
|
||||||
var loadedKey []string
|
var loadedKey []string
|
||||||
|
@ -332,11 +328,11 @@ func (c *connectionService) ScanKeys(connName string, db int, prefix string) (re
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//c.updateDBKey(connName, db, loadedKey)
|
keys = append(keys, loadedKey...)
|
||||||
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"}
|
||||||
}
|
//}
|
||||||
//keys = append(keys, loadedKey...)
|
//keys = append(keys, loadedKey...)
|
||||||
// no more loadedKey
|
// no more loadedKey
|
||||||
if cursor == 0 {
|
if cursor == 0 {
|
||||||
|
@ -873,15 +869,15 @@ func (c *connectionService) SetKeyTTL(connName string, db int, key string, ttl i
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveKey remove redis key
|
// DeleteKey remove redis key
|
||||||
func (c *connectionService) RemoveKey(connName string, db int, key string) (resp types.JSResp) {
|
func (c *connectionService) DeleteKey(connName string, db int, keys []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
|
||||||
}
|
}
|
||||||
|
|
||||||
rmCount, err := rdb.Del(ctx, key).Result()
|
rmCount, err := rdb.Del(ctx, keys...).Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
|
|
|
@ -210,8 +210,8 @@ func (c *ConnectionsStorage) UpdateConnection(name string, param types.Connectio
|
||||||
return c.saveConnections(conns)
|
return c.saveConnections(conns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveConnection remove special connection
|
// DeleteConnection remove special connection
|
||||||
func (c *ConnectionsStorage) RemoveConnection(name string) error {
|
func (c *ConnectionsStorage) DeleteConnection(name string) error {
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
defer c.mutex.Unlock()
|
defer c.mutex.Unlock()
|
||||||
|
|
||||||
|
@ -328,8 +328,8 @@ func (c *ConnectionsStorage) RenameGroup(name, newName string) error {
|
||||||
return c.saveConnections(conns)
|
return c.saveConnections(conns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveGroup remove special group, include all connections under it
|
// DeleteGroup remove special group, include all connections under it
|
||||||
func (c *ConnectionsStorage) RemoveGroup(group string, includeConnection bool) error {
|
func (c *ConnectionsStorage) DeleteGroup(group string, includeConnection bool) error {
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
defer c.mutex.Unlock()
|
defer c.mutex.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import plaintext from 'highlight.js/lib/languages/plaintext'
|
||||||
import AddFieldsDialog from './components/dialogs/AddFieldsDialog.vue'
|
import AddFieldsDialog from './components/dialogs/AddFieldsDialog.vue'
|
||||||
import AppContent from './AppContent.vue'
|
import AppContent from './AppContent.vue'
|
||||||
import GroupDialog from './components/dialogs/GroupDialog.vue'
|
import GroupDialog from './components/dialogs/GroupDialog.vue'
|
||||||
|
import DeleteKeyDialog from './components/dialogs/DeleteKeyDialog.vue'
|
||||||
|
|
||||||
hljs.registerLanguage('json', json)
|
hljs.registerLanguage('json', json)
|
||||||
hljs.registerLanguage('plaintext', plaintext)
|
hljs.registerLanguage('plaintext', plaintext)
|
||||||
|
@ -46,6 +47,7 @@ const themeOverrides = {
|
||||||
<new-key-dialog />
|
<new-key-dialog />
|
||||||
<add-fields-dialog />
|
<add-fields-dialog />
|
||||||
<rename-key-dialog />
|
<rename-key-dialog />
|
||||||
|
<delete-key-dialog />
|
||||||
<set-ttl-dialog />
|
<set-ttl-dialog />
|
||||||
<preferences-dialog />
|
<preferences-dialog />
|
||||||
</n-dialog-provider>
|
</n-dialog-provider>
|
||||||
|
|
|
@ -41,7 +41,7 @@ const onReloadKey = () => {
|
||||||
const confirmDialog = useConfirmDialog()
|
const confirmDialog = useConfirmDialog()
|
||||||
const onDeleteKey = () => {
|
const onDeleteKey = () => {
|
||||||
confirmDialog.warning(i18n.t('remove_tip', { name: props.keyPath }), () => {
|
confirmDialog.warning(i18n.t('remove_tip', { name: props.keyPath }), () => {
|
||||||
connectionStore.removeKey(props.server, props.db, props.keyPath).then((success) => {
|
connectionStore.deleteKey(props.server, props.db, props.keyPath).then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
message.success(i18n.t('delete_key_succ', { key: props.keyPath }))
|
message.success(i18n.t('delete_key_succ', { key: props.keyPath }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
<script setup>
|
||||||
|
import { reactive, watch } from 'vue'
|
||||||
|
import useDialog from '../../stores/dialog'
|
||||||
|
import { useMessage } from 'naive-ui'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import useConnectionStore from '../../stores/connections.js'
|
||||||
|
import { isEmpty, size } from 'lodash'
|
||||||
|
|
||||||
|
const deleteForm = reactive({
|
||||||
|
server: '',
|
||||||
|
db: 0,
|
||||||
|
key: '',
|
||||||
|
showAffected: false,
|
||||||
|
loadingAffected: false,
|
||||||
|
affectedKeys: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
const dialogStore = useDialog()
|
||||||
|
const connectionStore = useConnectionStore()
|
||||||
|
watch(
|
||||||
|
() => dialogStore.deleteKeyDialogVisible,
|
||||||
|
(visible) => {
|
||||||
|
if (visible) {
|
||||||
|
const { server, db, key } = dialogStore.deleteKeyParam
|
||||||
|
deleteForm.server = server
|
||||||
|
deleteForm.db = db
|
||||||
|
deleteForm.key = key
|
||||||
|
deleteForm.showAffected = false
|
||||||
|
deleteForm.loadingAffected = false
|
||||||
|
deleteForm.affectedKeys = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const scanAffectedKey = async () => {
|
||||||
|
try {
|
||||||
|
deleteForm.loadingAffected = true
|
||||||
|
const { keys = [] } = await connectionStore.scanKeys(deleteForm.server, deleteForm.db, deleteForm.key)
|
||||||
|
deleteForm.affectedKeys = keys || []
|
||||||
|
deleteForm.showAffected = true
|
||||||
|
} finally {
|
||||||
|
deleteForm.loadingAffected = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetAffected = () => {
|
||||||
|
deleteForm.showAffected = false
|
||||||
|
deleteForm.affectedKeys = []
|
||||||
|
}
|
||||||
|
|
||||||
|
const i18n = useI18n()
|
||||||
|
const message = useMessage()
|
||||||
|
const onConfirmDelete = async () => {
|
||||||
|
try {
|
||||||
|
const { server, db, key } = deleteForm
|
||||||
|
const success = await connectionStore.deleteKeys(server, db, key, deleteForm.affectedKeys)
|
||||||
|
if (success) {
|
||||||
|
message.success(i18n.t('handle_succ'))
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
message.error(e.message)
|
||||||
|
}
|
||||||
|
dialogStore.closeDeleteKeyDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
dialogStore.closeDeleteKeyDialog()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<n-modal
|
||||||
|
v-model:show="dialogStore.deleteKeyDialogVisible"
|
||||||
|
:closable="false"
|
||||||
|
:close-on-esc="false"
|
||||||
|
:mask-closable="false"
|
||||||
|
:show-icon="false"
|
||||||
|
:title="$t('batch_delete_key')"
|
||||||
|
preset="dialog"
|
||||||
|
transform-origin="center"
|
||||||
|
>
|
||||||
|
<n-form
|
||||||
|
:model="deleteForm"
|
||||||
|
:show-require-mark="false"
|
||||||
|
label-align="right"
|
||||||
|
label-placement="left"
|
||||||
|
label-width="auto"
|
||||||
|
>
|
||||||
|
<n-form-item :label="$t('server')">
|
||||||
|
<n-input :value="deleteForm.server" readonly />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item :label="$t('db_index')">
|
||||||
|
<n-input :value="deleteForm.db.toString()" readonly />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item :label="$t('key_expression')" required>
|
||||||
|
<n-input v-model:value="deleteForm.key" placeholder="" @input="resetAffected" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-card v-if="deleteForm.showAffected" :title="$t('affected_key')" size="small">
|
||||||
|
<n-skeleton v-if="deleteForm.loadingAffected" text :repeat="10" />
|
||||||
|
<n-log
|
||||||
|
v-else
|
||||||
|
:rows="10"
|
||||||
|
:line-height="1.5"
|
||||||
|
:lines="deleteForm.affectedKeys"
|
||||||
|
style="user-select: text; cursor: text"
|
||||||
|
/>
|
||||||
|
</n-card>
|
||||||
|
</n-form>
|
||||||
|
|
||||||
|
<template #action>
|
||||||
|
<div class="flex-item n-dialog__action">
|
||||||
|
<n-button @click="onClose">{{ $t('cancel') }}</n-button>
|
||||||
|
<n-button v-if="!deleteForm.showAffected" type="primary" @click="scanAffectedKey">
|
||||||
|
{{ $t('show_affected_key') }}
|
||||||
|
</n-button>
|
||||||
|
<n-button v-else type="error" :disabled="isEmpty(deleteForm.affectedKeys)" @click="onConfirmDelete">
|
||||||
|
{{ $t('confirm_delete_key', { num: size(deleteForm.affectedKeys) }) }}
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</n-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -36,7 +36,7 @@ const dbOptions = computed(() =>
|
||||||
)
|
)
|
||||||
const newFormRef = ref(null)
|
const newFormRef = ref(null)
|
||||||
|
|
||||||
const formLabelWidth = '60px'
|
const formLabelWidth = '100px'
|
||||||
const options = computed(() => {
|
const options = computed(() => {
|
||||||
return Object.keys(types).map((t) => ({
|
return Object.keys(types).map((t) => ({
|
||||||
value: t,
|
value: t,
|
||||||
|
@ -125,7 +125,7 @@ const onClose = () => {
|
||||||
<n-form-item :label="$t('key')" path="key" required>
|
<n-form-item :label="$t('key')" path="key" required>
|
||||||
<n-input v-model:value="newForm.key" placeholder="" />
|
<n-input v-model:value="newForm.key" placeholder="" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="DB" path="db" required>
|
<n-form-item :label="$t('db_index')" path="db" required>
|
||||||
<n-select v-model:value="newForm.db" :options="dbOptions" />
|
<n-select v-model:value="newForm.db" :options="dbOptions" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item :label="$t('type')" path="type" required>
|
<n-form-item :label="$t('type')" path="type" required>
|
||||||
|
|
|
@ -38,7 +38,7 @@ const message = useMessage()
|
||||||
const onDeleteKey = () => {
|
const onDeleteKey = () => {
|
||||||
const { server, db, key } = currentSelect.value
|
const { server, db, key } = currentSelect.value
|
||||||
confirmDialog.warning(i18n.t('remove_tip', { name: key }), () => {
|
confirmDialog.warning(i18n.t('remove_tip', { name: key }), () => {
|
||||||
connectionStore.removeKey(server, db, key).then((success) => {
|
connectionStore.deleteKey(server, db, key).then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
message.success(i18n.t('delete_key_succ', { key }))
|
message.success(i18n.t('delete_key_succ', { key }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,22 +278,24 @@ const handleSelectContextMenu = (key) => {
|
||||||
nextTick().then(() => expandKey(nodeKey))
|
nextTick().then(() => expandKey(nodeKey))
|
||||||
break
|
break
|
||||||
case 'db_reload':
|
case 'db_reload':
|
||||||
connectionStore.scanKeys(name, db)
|
connectionStore.reopenDatabase(name, db)
|
||||||
break
|
break
|
||||||
case 'db_newkey':
|
case 'db_newkey':
|
||||||
case 'key_newkey':
|
case 'key_newkey':
|
||||||
dialogStore.openNewKeyDialog(redisKey, name, db)
|
dialogStore.openNewKeyDialog(redisKey, name, db)
|
||||||
break
|
break
|
||||||
case 'key_reload':
|
case 'key_reload':
|
||||||
connectionStore.scanKeys(name, db, redisKey)
|
connectionStore.loadKeys(name, db, redisKey)
|
||||||
break
|
break
|
||||||
case 'value_reload':
|
case 'value_reload':
|
||||||
connectionStore.loadKeyValue(name, db, redisKey)
|
connectionStore.loadKeyValue(name, db, redisKey)
|
||||||
break
|
break
|
||||||
case 'key_remove':
|
case 'key_remove':
|
||||||
|
dialogStore.openDeleteKeyDialog(name, db, redisKey + ':*')
|
||||||
|
break
|
||||||
case 'value_remove':
|
case 'value_remove':
|
||||||
confirmDialog.warning(i18n.t('remove_tip', { name: redisKey }), () => {
|
confirmDialog.warning(i18n.t('remove_tip', { name: redisKey }), () => {
|
||||||
connectionStore.removeKey(name, db, redisKey).then((success) => {
|
connectionStore.deleteKey(name, db, redisKey).then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
message.success(i18n.t('delete_key_succ', { key: redisKey }))
|
message.success(i18n.t('delete_key_succ', { key: redisKey }))
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ const openConnection = async (name) => {
|
||||||
const dialog = useDialog()
|
const dialog = useDialog()
|
||||||
const removeConnection = (name) => {
|
const removeConnection = (name) => {
|
||||||
confirmDialog.warning(i18n.t('remove_tip', { type: i18n.t('conn_name'), name }), async () => {
|
confirmDialog.warning(i18n.t('remove_tip', { type: i18n.t('conn_name'), name }), async () => {
|
||||||
connectionStore.removeConnection(name).then(({ success, msg }) => {
|
connectionStore.deleteConnection(name).then(({ success, msg }) => {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
message.error(msg)
|
message.error(msg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
"forever": "Forever",
|
"forever": "Forever",
|
||||||
"rename_key": "Rename Key",
|
"rename_key": "Rename Key",
|
||||||
"delete_key": "Delete Key",
|
"delete_key": "Delete Key",
|
||||||
|
"batch_delete_key": "Batch Delete Key",
|
||||||
|
"db_index": "Database Index",
|
||||||
|
"key_expression": "Key Expression",
|
||||||
|
"affected_key": "Affected Key",
|
||||||
|
"show_affected_key": "Show Affected Key",
|
||||||
|
"confirm_delete_key": "Confirm Delete {num}",
|
||||||
"delete_key_succ": "\"{key}\" has been deleted",
|
"delete_key_succ": "\"{key}\" has been deleted",
|
||||||
"copy_value": "Copy Value",
|
"copy_value": "Copy Value",
|
||||||
"edit_value": "Edit Value",
|
"edit_value": "Edit Value",
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
"forever": "永久",
|
"forever": "永久",
|
||||||
"rename_key": "重命名键",
|
"rename_key": "重命名键",
|
||||||
"delete_key": "删除键",
|
"delete_key": "删除键",
|
||||||
|
"batch_delete_key": "批量删除键",
|
||||||
|
"db_index": "数据库编号",
|
||||||
|
"key_expression": "键名表达式",
|
||||||
|
"affected_key": "受影响的键名",
|
||||||
|
"show_affected_key": "查看受影响的键名",
|
||||||
|
"confirm_delete_key": "确认删除{num}个键",
|
||||||
"delete_key_succ": "{key} 已被删除",
|
"delete_key_succ": "{key} 已被删除",
|
||||||
"copy_value": "复制值",
|
"copy_value": "复制值",
|
||||||
"edit_value": "修改值",
|
"edit_value": "修改值",
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { findIndex, get, isEmpty, last, map, remove, size, sortedIndexBy, split, uniq } from 'lodash'
|
import { endsWith, findIndex, get, isEmpty, last, remove, size, sortedIndexBy, split, uniq } from 'lodash'
|
||||||
import {
|
import {
|
||||||
AddHashField,
|
AddHashField,
|
||||||
AddListItem,
|
AddListItem,
|
||||||
AddZSetValue,
|
AddZSetValue,
|
||||||
CloseConnection,
|
CloseConnection,
|
||||||
CreateGroup,
|
CreateGroup,
|
||||||
|
DeleteConnection,
|
||||||
|
DeleteGroup,
|
||||||
|
DeleteKey,
|
||||||
GetConnection,
|
GetConnection,
|
||||||
GetKeyValue,
|
GetKeyValue,
|
||||||
ListConnection,
|
ListConnection,
|
||||||
OpenConnection,
|
OpenConnection,
|
||||||
OpenDatabase,
|
OpenDatabase,
|
||||||
RemoveConnection,
|
|
||||||
RemoveGroup,
|
|
||||||
RemoveKey,
|
|
||||||
RenameGroup,
|
RenameGroup,
|
||||||
RenameKey,
|
RenameKey,
|
||||||
SaveConnection,
|
SaveConnection,
|
||||||
|
@ -29,6 +29,7 @@ import {
|
||||||
} from '../../wailsjs/go/services/connectionService.js'
|
} from '../../wailsjs/go/services/connectionService.js'
|
||||||
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 { nextTick } from 'vue'
|
||||||
|
|
||||||
const separator = ':'
|
const separator = ':'
|
||||||
|
|
||||||
|
@ -313,10 +314,10 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @param name
|
* @param name
|
||||||
* @returns {Promise<{success: boolean, [msg]: string}>}
|
* @returns {Promise<{success: boolean, [msg]: string}>}
|
||||||
*/
|
*/
|
||||||
async removeConnection(name) {
|
async deleteConnection(name) {
|
||||||
// close connection first
|
// close connection first
|
||||||
await this.closeConnection(name)
|
await this.closeConnection(name)
|
||||||
const { success, msg } = await RemoveConnection(name)
|
const { success, msg } = await DeleteConnection(name)
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return { success: false, msg }
|
return { success: false, msg }
|
||||||
}
|
}
|
||||||
|
@ -357,13 +358,13 @@ const useConnectionStore = defineStore('connections', {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove group by name
|
* delete group by name
|
||||||
* @param {string} name
|
* @param {string} name
|
||||||
* @param {boolean} [includeConn]
|
* @param {boolean} [includeConn]
|
||||||
* @returns {Promise<{success: boolean, [msg]: string}>}
|
* @returns {Promise<{success: boolean, [msg]: string}>}
|
||||||
*/
|
*/
|
||||||
async deleteGroup(name, includeConn) {
|
async deleteGroup(name, includeConn) {
|
||||||
const { success, msg } = await RemoveGroup(name, includeConn === true)
|
const { success, msg } = await DeleteGroup(name, includeConn === true)
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return { success: false, msg }
|
return { success: false, msg }
|
||||||
}
|
}
|
||||||
|
@ -394,6 +395,18 @@ const useConnectionStore = defineStore('connections', {
|
||||||
this._updateNodeChildren(connName, db, keys)
|
this._updateNodeChildren(connName, db, keys)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reopen database
|
||||||
|
* @param connName
|
||||||
|
* @param db
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async reopenDatabase(connName, db) {
|
||||||
|
const dbs = this.databases[connName]
|
||||||
|
dbs[db].children = undefined
|
||||||
|
dbs[db].isLeaf = false
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load redis key
|
* load redis key
|
||||||
* @param server
|
* @param server
|
||||||
|
@ -426,40 +439,78 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} [prefix] full reload database if prefix is null
|
* @param {string} [prefix] full reload database if prefix is null
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<{keys: string[]}>}
|
||||||
*/
|
*/
|
||||||
async scanKeys(connName, db, prefix) {
|
async scanKeys(connName, db, prefix) {
|
||||||
const { data, success, msg } = await ScanKeys(connName, db, prefix || '*')
|
const { data, success, msg } = await ScanKeys(connName, db, prefix || '*')
|
||||||
if (!success) {
|
if (!success) {
|
||||||
throw new Error(msg)
|
throw new Error(msg)
|
||||||
}
|
}
|
||||||
|
const { keys = [] } = data
|
||||||
|
return { keys, success }
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load keys with prefix
|
||||||
|
* @param {string} connName
|
||||||
|
* @param {number} db
|
||||||
|
* @param {string} [prefix]
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async loadKeys(connName, db, prefix) {
|
||||||
|
let scanPrefix = prefix
|
||||||
|
if (isEmpty(scanPrefix)) {
|
||||||
|
scanPrefix = '*'
|
||||||
|
} else {
|
||||||
|
if (!endsWith(prefix, separator + '*')) {
|
||||||
|
scanPrefix = prefix + separator + '*'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const { keys, success } = await this.scanKeys(connName, db, scanPrefix)
|
||||||
|
if (!success) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// remove current keys below prefix
|
// remove current keys below prefix
|
||||||
|
this._deleteKeyNodes(connName, db, prefix)
|
||||||
|
this._updateNodeChildren(connName, db, keys)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove key with prefix
|
||||||
|
* @param {string} connName
|
||||||
|
* @param {number} db
|
||||||
|
* @param {string} prefix
|
||||||
|
* @returns {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_deleteKeyNodes(connName, db, prefix) {
|
||||||
const dbs = this.databases[connName]
|
const dbs = this.databases[connName]
|
||||||
let node = dbs[db]
|
let node = dbs[db]
|
||||||
if (!isEmpty(prefix)) {
|
const prefixPart = split(prefix, separator)
|
||||||
const prefixPart = split(prefix, separator)
|
const partLen = size(prefixPart)
|
||||||
for (const key of prefixPart) {
|
for (let i = 0; i < partLen; i++) {
|
||||||
const idx = findIndex(node.children, { label: key })
|
let idx = findIndex(node.children, { label: prefixPart[i] })
|
||||||
if (idx === -1) {
|
if (idx === -1) {
|
||||||
node = null
|
node = null
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if (i === partLen - 1) {
|
||||||
|
// remove last part from parent
|
||||||
|
node.children.splice(idx, 1)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
node = node.children[idx]
|
node = node.children[idx]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node != null) {
|
return false
|
||||||
node.children = []
|
|
||||||
}
|
|
||||||
|
|
||||||
const { keys = [] } = data
|
|
||||||
this._updateNodeChildren(connName, db, keys)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove keys in db
|
* remove keys in db
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {Object.<string, {}>[]} keys
|
* @param {string[]} keys
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_updateNodeChildren(connName, db, keys) {
|
_updateNodeChildren(connName, db, keys) {
|
||||||
|
@ -495,7 +546,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
dbs[db].children = []
|
dbs[db].children = []
|
||||||
}
|
}
|
||||||
const keyStruct = dbs[db].children
|
const keyStruct = dbs[db].children
|
||||||
for (const key in keys) {
|
for (const key of keys) {
|
||||||
const keyPart = split(key, separator)
|
const keyPart = split(key, separator)
|
||||||
// const prefixLen = size(keyPart) - 1
|
// const prefixLen = size(keyPart) - 1
|
||||||
const len = size(keyPart)
|
const len = size(keyPart)
|
||||||
|
@ -1010,7 +1061,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_removeKey(connName, db, key) {
|
_deleteKeyNode(connName, db, key) {
|
||||||
const dbs = this.databases[connName]
|
const dbs = this.databases[connName]
|
||||||
const dbDetail = get(dbs, db, {})
|
const dbDetail = get(dbs, db, {})
|
||||||
|
|
||||||
|
@ -1078,18 +1129,18 @@ const useConnectionStore = defineStore('connections', {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove redis key
|
* delete redis key
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
* @param {number} db
|
* @param {number} db
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
* @returns {Promise<boolean>}
|
* @returns {Promise<boolean>}
|
||||||
*/
|
*/
|
||||||
async removeKey(connName, db, key) {
|
async deleteKey(connName, db, key) {
|
||||||
try {
|
try {
|
||||||
const { data, success, msg } = await RemoveKey(connName, db, key)
|
const { data, success, msg } = await DeleteKey(connName, db, [key])
|
||||||
if (success) {
|
if (success) {
|
||||||
// update tree view data
|
// update tree view data
|
||||||
this._removeKey(connName, db, key)
|
this._deleteKeyNode(connName, db, key)
|
||||||
|
|
||||||
// set tab content empty
|
// set tab content empty
|
||||||
const tab = useTabStore()
|
const tab = useTabStore()
|
||||||
|
@ -1101,6 +1152,32 @@ const useConnectionStore = defineStore('connections', {
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete keys with prefix
|
||||||
|
* @param connName
|
||||||
|
* @param db
|
||||||
|
* @param prefix
|
||||||
|
* @param keys
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
async deleteKeys(connName, db, prefix, keys) {
|
||||||
|
if (isEmpty(keys)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const { success, msg } = await DeleteKey(connName, db, keys)
|
||||||
|
if (success) {
|
||||||
|
for (const key of keys) {
|
||||||
|
await this.deleteKey(connName, db, key)
|
||||||
|
await nextTick()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rename key
|
* rename key
|
||||||
* @param {string} connName
|
* @param {string} connName
|
||||||
|
@ -1113,7 +1190,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
const { success = false, msg } = await RenameKey(connName, db, key, newKey)
|
const { success = false, msg } = await RenameKey(connName, db, key, newKey)
|
||||||
if (success) {
|
if (success) {
|
||||||
// delete old key and add new key struct
|
// delete old key and add new key struct
|
||||||
this._removeKey(connName, db, key)
|
this._deleteKeyNode(connName, db, key)
|
||||||
this._addKey(connName, db, newKey)
|
this._addKey(connName, db, newKey)
|
||||||
return { success: true }
|
return { success: true }
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -36,6 +36,13 @@ const useDialogStore = defineStore('dialog', {
|
||||||
},
|
},
|
||||||
renameDialogVisible: false,
|
renameDialogVisible: false,
|
||||||
|
|
||||||
|
deleteKeyParam: {
|
||||||
|
server: '',
|
||||||
|
db: 0,
|
||||||
|
key: '',
|
||||||
|
},
|
||||||
|
deleteKeyDialogVisible: false,
|
||||||
|
|
||||||
selectTTL: -1,
|
selectTTL: -1,
|
||||||
ttlDialogVisible: false,
|
ttlDialogVisible: false,
|
||||||
|
|
||||||
|
@ -92,6 +99,16 @@ const useDialogStore = defineStore('dialog', {
|
||||||
this.renameDialogVisible = false
|
this.renameDialogVisible = false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openDeleteKeyDialog(server, db, key) {
|
||||||
|
this.deleteKeyParam.server = server
|
||||||
|
this.deleteKeyParam.db = db
|
||||||
|
this.deleteKeyParam.key = key
|
||||||
|
this.deleteKeyDialogVisible = true
|
||||||
|
},
|
||||||
|
closeDeleteKeyDialog() {
|
||||||
|
this.deleteKeyDialogVisible = false
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} prefix
|
* @param {string} prefix
|
||||||
|
|
Loading…
Reference in New Issue