feat: add flush db operation
This commit is contained in:
parent
67666f4edf
commit
9b9d0e3c7c
|
@ -1521,6 +1521,45 @@ func (c *connectionService) DeleteKey(connName string, db int, k any, async bool
|
|||
return
|
||||
}
|
||||
|
||||
// FlushDB flush database
|
||||
func (c *connectionService) FlushDB(connName string, db int, async bool) (resp types.JSResp) {
|
||||
item, err := c.getRedisClient(connName, db)
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
|
||||
flush := func(ctx context.Context, cli redis.UniversalClient) {
|
||||
cli.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
|
||||
pipe.Select(ctx, db)
|
||||
if async {
|
||||
pipe.FlushDBAsync(ctx)
|
||||
} else {
|
||||
pipe.FlushDB(ctx)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
client, ctx := item.client, item.ctx
|
||||
if cluster, ok := client.(*redis.ClusterClient); ok {
|
||||
// cluster mode
|
||||
err = cluster.ForEachMaster(ctx, func(ctx context.Context, cli *redis.Client) error {
|
||||
flush(ctx, cli)
|
||||
return nil
|
||||
})
|
||||
} else {
|
||||
flush(ctx, client)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
resp.Msg = err.Error()
|
||||
return
|
||||
}
|
||||
resp.Success = true
|
||||
return
|
||||
}
|
||||
|
||||
// RenameKey rename key
|
||||
func (c *connectionService) RenameKey(connName string, db int, key, newKey string) (resp types.JSResp) {
|
||||
item, err := c.getRedisClient(connName, db)
|
||||
|
|
|
@ -99,7 +99,7 @@ func (l *LogHook) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.Proc
|
|||
err := next(ctx, cmds)
|
||||
cost := time.Since(t).Milliseconds()
|
||||
b := make([]byte, 0, 64)
|
||||
for _, cmd := range cmds {
|
||||
for i, cmd := range cmds {
|
||||
log.Println("pipeline: ", cmd)
|
||||
if l.cmdExec != nil {
|
||||
for i, arg := range cmd.Args() {
|
||||
|
@ -108,9 +108,11 @@ func (l *LogHook) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.Proc
|
|||
}
|
||||
b = appendArg(b, arg)
|
||||
}
|
||||
if i != len(cmds) {
|
||||
b = append(b, '\n')
|
||||
}
|
||||
}
|
||||
}
|
||||
if l.cmdExec != nil {
|
||||
l.cmdExec(string(b), cost)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import KeyFilterDialog from './components/dialogs/KeyFilterDialog.vue'
|
|||
import { WindowSetDarkTheme, WindowSetLightTheme } from 'wailsjs/runtime/runtime.js'
|
||||
import { darkThemeOverrides, themeOverrides } from '@/utils/theme.js'
|
||||
import AboutDialog from '@/components/dialogs/AboutDialog.vue'
|
||||
import FlushDbDialog from '@/components/dialogs/FlushDbDialog.vue'
|
||||
|
||||
hljs.registerLanguage('json', json)
|
||||
hljs.registerLanguage('plaintext', plaintext)
|
||||
|
@ -73,6 +74,7 @@ watch(
|
|||
<add-fields-dialog />
|
||||
<rename-key-dialog />
|
||||
<delete-key-dialog />
|
||||
<flush-db-dialog />
|
||||
<set-ttl-dialog />
|
||||
<preferences-dialog />
|
||||
<about-dialog />
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script setup>
|
||||
import { computed, nextTick, reactive, ref } from 'vue'
|
||||
import { computed, h, nextTick, reactive, ref } from 'vue'
|
||||
import IconButton from '@/components/common/IconButton.vue'
|
||||
import Refresh from '@/components/icons/Refresh.vue'
|
||||
import useConnectionStore from 'stores/connections.js'
|
||||
import { map, uniqBy } from 'lodash'
|
||||
import { map, size, split, uniqBy } from 'lodash'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Delete from '@/components/icons/Delete.vue'
|
||||
import dayjs from 'dayjs'
|
||||
|
@ -132,6 +132,17 @@ defineExpose({
|
|||
filter(value, row) {
|
||||
return value === '' || !!~row.cmd.indexOf(value.toString())
|
||||
},
|
||||
render({ cmd }, index) {
|
||||
const cmdList = split(cmd, '\n')
|
||||
if (size(cmdList) > 1) {
|
||||
return h(
|
||||
'div',
|
||||
null,
|
||||
map(cmdList, (c) => h('div', null, c)),
|
||||
)
|
||||
}
|
||||
return cmd
|
||||
},
|
||||
},
|
||||
{
|
||||
title: $t('log.cost_time'),
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<script setup>
|
||||
import { reactive, watch } from 'vue'
|
||||
import useDialog from 'stores/dialog'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import useConnectionStore from 'stores/connections.js'
|
||||
|
||||
const flushForm = reactive({
|
||||
server: '',
|
||||
db: 0,
|
||||
key: '',
|
||||
async: false,
|
||||
confirm: false,
|
||||
})
|
||||
|
||||
const dialogStore = useDialog()
|
||||
const connectionStore = useConnectionStore()
|
||||
watch(
|
||||
() => dialogStore.flushDBDialogVisible,
|
||||
(visible) => {
|
||||
if (visible) {
|
||||
const { server, db } = dialogStore.flushDBParam
|
||||
flushForm.server = server
|
||||
flushForm.db = db
|
||||
flushForm.async = true
|
||||
flushForm.confirm = false
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const i18n = useI18n()
|
||||
const onConfirmFlush = async () => {
|
||||
try {
|
||||
const { server, db, async } = flushForm
|
||||
const success = await connectionStore.flushDatabase(server, db, async)
|
||||
if (success) {
|
||||
$message.success(i18n.t('dialogue.handle_succ'))
|
||||
}
|
||||
} catch (e) {
|
||||
$message.error(e.message)
|
||||
}
|
||||
dialogStore.closeFlushDBDialog()
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
dialogStore.closeFlushDBDialog()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-modal
|
||||
v-model:show="dialogStore.flushDBDialogVisible"
|
||||
:closable="false"
|
||||
:close-on-esc="false"
|
||||
:mask-closable="false"
|
||||
:show-icon="false"
|
||||
:title="$t('interface.flush_db')"
|
||||
preset="dialog"
|
||||
transform-origin="center">
|
||||
<n-form :model="flushForm" :show-require-mark="false" label-placement="top">
|
||||
<n-form-item :label="$t('dialogue.key.server')">
|
||||
<n-input :value="flushForm.server" readonly />
|
||||
</n-form-item>
|
||||
<n-form-item :label="$t('dialogue.key.db_index')">
|
||||
<n-input :value="flushForm.db.toString()" readonly />
|
||||
</n-form-item>
|
||||
<n-form-item :label="$t('dialogue.key.async_delete')" required>
|
||||
<n-checkbox v-model:checked="flushForm.async">{{ $t('dialogue.key.async_delete_title') }}</n-checkbox>
|
||||
</n-form-item>
|
||||
<n-form-item :label="$t('common.warning')" required>
|
||||
<n-checkbox v-model:checked="flushForm.confirm">
|
||||
<span style="color: red; font-weight: bold">{{ $t('dialogue.key.confirm_flush') }}</span>
|
||||
</n-checkbox>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
|
||||
<template #action>
|
||||
<n-button :focusable="false" @click="onClose">{{ $t('common.cancel') }}</n-button>
|
||||
<n-button :disabled="!!!flushForm.confirm" :focusable="false" type="primary" @click="onConfirmFlush">
|
||||
{{ $t('dialogue.key.confirm_flush_db') }}
|
||||
</n-button>
|
||||
</template>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -10,7 +10,7 @@ const props = defineProps({
|
|||
},
|
||||
strokeColor: {
|
||||
type: String,
|
||||
default: '#FFF',
|
||||
default: 'currentColor',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -117,8 +117,8 @@ const menuOptions = {
|
|||
key: 'd1',
|
||||
},
|
||||
{
|
||||
key: 'key_remove',
|
||||
label: i18n.t('interface.batch_delete'),
|
||||
key: 'db_flush',
|
||||
label: i18n.t('interface.flush_db'),
|
||||
icon: renderIcon(Delete),
|
||||
},
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ const menuOptions = {
|
|||
},
|
||||
{
|
||||
key: 'key_remove',
|
||||
label: i18n.t('interface.batch_delete'),
|
||||
label: i18n.t('interface.batch_delete_key'),
|
||||
icon: renderIcon(Delete),
|
||||
},
|
||||
],
|
||||
|
@ -260,7 +260,7 @@ const handleSelectContextMenu = (key) => {
|
|||
connectionStore.closeDatabase(props.server, db)
|
||||
break
|
||||
case 'db_flush':
|
||||
dialogStore.openDeleteKeyDialog(props.server, db, '*')
|
||||
dialogStore.openFlushDBDialog(props.server, db)
|
||||
break
|
||||
case 'db_newkey':
|
||||
case 'key_newkey':
|
||||
|
@ -548,7 +548,7 @@ const getDatabaseMenu = (opened, loading, end) => {
|
|||
onClick: () => handleSelectContextMenu('db_loadall'),
|
||||
}),
|
||||
h(IconButton, {
|
||||
tTooltip: 'interface.batch_delete',
|
||||
tTooltip: 'interface.flush_db',
|
||||
icon: Delete,
|
||||
disabled: loading === true,
|
||||
onClick: () => handleSelectContextMenu('db_flush'),
|
||||
|
@ -585,7 +585,7 @@ const getLayerMenu = () => {
|
|||
onClick: () => handleSelectContextMenu('key_newkey'),
|
||||
}),
|
||||
h(IconButton, {
|
||||
tTooltip: 'interface.batch_delete',
|
||||
tTooltip: 'interface.batch_delete_key',
|
||||
icon: Delete,
|
||||
onClick: () => handleSelectContextMenu('key_remove'),
|
||||
}),
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"rename_key": "Rename Key",
|
||||
"delete_key": "Delete Key",
|
||||
"batch_delete_key": "Batch Delete Keys",
|
||||
"flush_db": "Flush Database",
|
||||
"copy_value": "Copy Value",
|
||||
"edit_value": "Edit Value",
|
||||
"save_update": "Save Update",
|
||||
|
@ -82,7 +83,6 @@
|
|||
"decode_with": "Decode / Decompression",
|
||||
"reload": "Reload",
|
||||
"open_connection": "Open Connection",
|
||||
"batch_delete": "Batch Delete",
|
||||
"copy_path": "Copy Path",
|
||||
"copy_key": "Copy Key",
|
||||
"binary_key": "Binary Key Name",
|
||||
|
@ -214,14 +214,16 @@
|
|||
"new": "New Key",
|
||||
"new_name": "New Key Name",
|
||||
"persist_key": "Persist Key",
|
||||
"server": "Belong",
|
||||
"server": "Connection",
|
||||
"db_index": "Database Index",
|
||||
"key_expression": "Key Expression",
|
||||
"affected_key": "Affected Keys",
|
||||
"show_affected_key": "Show Affected Keys",
|
||||
"confirm_delete_key": "Confirm Delete {num} Key(s)",
|
||||
"async_delete": "Asynchronously Execute",
|
||||
"async_delete_title": "Do not waiting for the operation's result"
|
||||
"async_delete_title": "Do not waiting for the operation's result",
|
||||
"confirm_flush": "I know what I'm doing!",
|
||||
"confirm_flush_db": "Confirm Flush Database"
|
||||
},
|
||||
"field": {
|
||||
"new": "Add New Field",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"rename_key": "重命名键",
|
||||
"delete_key": "删除键",
|
||||
"batch_delete_key": "批量删除键",
|
||||
"flush_db": "清空数据库",
|
||||
"copy_value": "复制值",
|
||||
"edit_value": "修改值",
|
||||
"save_update": "保存修改",
|
||||
|
@ -82,7 +83,6 @@
|
|||
"decode_with": "解码/解压方式",
|
||||
"reload": "重新载入",
|
||||
"open_connection": "打开连接",
|
||||
"batch_delete": "批量删除键",
|
||||
"copy_path": "复制路径",
|
||||
"copy_key": "复制键名",
|
||||
"binary_key": "二进制键名",
|
||||
|
@ -220,7 +220,9 @@
|
|||
"show_affected_key": "查看受影响的键名",
|
||||
"confirm_delete_key": "确认删除{num}个键",
|
||||
"async_delete": "异步执行",
|
||||
"async_delete_title": "不等待操作结果"
|
||||
"async_delete_title": "不等待操作结果",
|
||||
"confirm_flush": "我知道我正在执行的操作!",
|
||||
"confirm_flush_db": "确认清空数据库"
|
||||
},
|
||||
"field": {
|
||||
"new": "添加新字段",
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
DeleteConnection,
|
||||
DeleteGroup,
|
||||
DeleteKey,
|
||||
FlushDB,
|
||||
GetCmdHistory,
|
||||
GetConnection,
|
||||
GetKeyValue,
|
||||
|
@ -1666,6 +1667,30 @@ const useConnectionStore = defineStore('connections', {
|
|||
return false
|
||||
},
|
||||
|
||||
/**
|
||||
* flush database
|
||||
* @param connName
|
||||
* @param db
|
||||
* @param async
|
||||
* @return {Promise<boolean>}
|
||||
*/
|
||||
async flushDatabase(connName, db, async) {
|
||||
try {
|
||||
const { success = false } = await FlushDB(connName, db, async)
|
||||
|
||||
if (success === true) {
|
||||
// update tree view data
|
||||
this._deleteKeyNode(connName, db)
|
||||
// set tab content empty
|
||||
const tab = useTabStore()
|
||||
tab.emptyTab(connName)
|
||||
return true
|
||||
}
|
||||
} finally {
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
/**
|
||||
* rename key
|
||||
* @param {string} connName
|
||||
|
|
|
@ -63,6 +63,12 @@ const useDialogStore = defineStore('dialog', {
|
|||
},
|
||||
deleteKeyDialogVisible: false,
|
||||
|
||||
flushDBParam: {
|
||||
server: '',
|
||||
db: 0,
|
||||
},
|
||||
flushDBDialogVisible: false,
|
||||
|
||||
selectTTL: -1,
|
||||
ttlDialogVisible: false,
|
||||
|
||||
|
@ -164,6 +170,15 @@ const useDialogStore = defineStore('dialog', {
|
|||
this.deleteKeyDialogVisible = false
|
||||
},
|
||||
|
||||
openFlushDBDialog(server, db) {
|
||||
this.flushDBParam.server = server
|
||||
this.flushDBParam.db = db
|
||||
this.flushDBDialogVisible = true
|
||||
},
|
||||
closeFlushDBDialog() {
|
||||
this.flushDBDialogVisible = false
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} prefix
|
||||
|
|
Loading…
Reference in New Issue