feat: add sync/async delete key option to delete key dialog
This commit is contained in:
parent
4a0807e463
commit
d61eb1323f
|
@ -1330,7 +1330,7 @@ func (c *connectionService) SetKeyTTL(connName string, db int, k any, ttl int64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteKey remove redis key
|
// DeleteKey remove redis key
|
||||||
func (c *connectionService) DeleteKey(connName string, db int, k any) (resp types.JSResp) {
|
func (c *connectionService) DeleteKey(connName string, db int, k any, async bool) (resp types.JSResp) {
|
||||||
client, ctx, err := c.getRedisClient(connName, db)
|
client, ctx, err := c.getRedisClient(connName, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
|
@ -1344,10 +1344,15 @@ func (c *connectionService) DeleteKey(connName string, db int, k any) (resp type
|
||||||
var mutex sync.Mutex
|
var mutex sync.Mutex
|
||||||
del := func(ctx context.Context, cli redis.UniversalClient) error {
|
del := func(ctx context.Context, cli redis.UniversalClient) error {
|
||||||
iter := cli.Scan(ctx, 0, key, 10000).Iterator()
|
iter := cli.Scan(ctx, 0, key, 10000).Iterator()
|
||||||
|
var fn func(c context.Context, ks ...string) *redis.IntCmd
|
||||||
|
if async {
|
||||||
|
fn = cli.Unlink
|
||||||
|
} else {
|
||||||
|
fn = cli.Del
|
||||||
|
}
|
||||||
for iter.Next(ctx) {
|
for iter.Next(ctx) {
|
||||||
subKey := iter.Val()
|
subKey := iter.Val()
|
||||||
if err = cli.Unlink(ctx, subKey).Err(); err != nil {
|
if err = fn(ctx, subKey).Err(); err != nil {
|
||||||
log.Println("unlink error", err.Error())
|
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
|
@ -1373,10 +1378,16 @@ func (c *connectionService) DeleteKey(connName string, db int, k any) (resp type
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// delete key only
|
// delete key only
|
||||||
_, err = client.Del(ctx, key).Result()
|
if async {
|
||||||
if err != nil {
|
if _, err = client.Unlink(ctx, key).Result(); err != nil {
|
||||||
resp.Msg = err.Error()
|
resp.Msg = err.Error()
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err = client.Del(ctx, key).Result(); err != nil {
|
||||||
|
resp.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
deletedKeys = append(deletedKeys, key)
|
deletedKeys = append(deletedKeys, key)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ const deleteForm = reactive({
|
||||||
showAffected: false,
|
showAffected: false,
|
||||||
loadingAffected: false,
|
loadingAffected: false,
|
||||||
affectedKeys: [],
|
affectedKeys: [],
|
||||||
|
async: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const dialogStore = useDialog()
|
const dialogStore = useDialog()
|
||||||
|
@ -27,6 +28,7 @@ watch(
|
||||||
deleteForm.showAffected = false
|
deleteForm.showAffected = false
|
||||||
deleteForm.loadingAffected = false
|
deleteForm.loadingAffected = false
|
||||||
deleteForm.affectedKeys = []
|
deleteForm.affectedKeys = []
|
||||||
|
deleteForm.async = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -50,8 +52,8 @@ const resetAffected = () => {
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
const onConfirmDelete = async () => {
|
const onConfirmDelete = async () => {
|
||||||
try {
|
try {
|
||||||
const { server, db, key } = deleteForm
|
const { server, db, key, async } = deleteForm
|
||||||
const success = await connectionStore.deleteKeyPrefix(server, db, key)
|
const success = await connectionStore.deleteKeyPrefix(server, db, key, async)
|
||||||
if (success) {
|
if (success) {
|
||||||
$message.success(i18n.t('dialogue.handle_succ'))
|
$message.success(i18n.t('dialogue.handle_succ'))
|
||||||
}
|
}
|
||||||
|
@ -86,6 +88,9 @@ const onClose = () => {
|
||||||
<n-form-item :label="$t('dialogue.key.key_expression')" required>
|
<n-form-item :label="$t('dialogue.key.key_expression')" required>
|
||||||
<n-input v-model:value="deleteForm.key" placeholder="" @input="resetAffected" />
|
<n-input v-model:value="deleteForm.key" placeholder="" @input="resetAffected" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
<n-form-item :label="$t('dialogue.key.async_delete')" required>
|
||||||
|
<n-checkbox v-model:checked="deleteForm.async">{{ $t('dialogue.key.async_delete_title') }}</n-checkbox>
|
||||||
|
</n-form-item>
|
||||||
<n-card v-if="deleteForm.showAffected" :title="$t('dialogue.key.affected_key')" size="small">
|
<n-card v-if="deleteForm.showAffected" :title="$t('dialogue.key.affected_key')" size="small">
|
||||||
<n-skeleton v-if="deleteForm.loadingAffected" :repeat="10" text />
|
<n-skeleton v-if="deleteForm.loadingAffected" :repeat="10" text />
|
||||||
<n-log
|
<n-log
|
||||||
|
|
|
@ -199,7 +199,9 @@
|
||||||
"key_expression": "Key Expression",
|
"key_expression": "Key Expression",
|
||||||
"affected_key": "Affected Keys",
|
"affected_key": "Affected Keys",
|
||||||
"show_affected_key": "Show Affected Keys",
|
"show_affected_key": "Show Affected Keys",
|
||||||
"confirm_delete_key": "Confirm Delete {num} Keys"
|
"confirm_delete_key": "Confirm Delete {num} Key(s)",
|
||||||
|
"async_delete": "Asynchronously Execute",
|
||||||
|
"async_delete_title": "Do not waiting for the operation's result"
|
||||||
},
|
},
|
||||||
"field": {
|
"field": {
|
||||||
"new": "Add New Field",
|
"new": "Add New Field",
|
||||||
|
|
|
@ -198,7 +198,9 @@
|
||||||
"key_expression": "键名表达式",
|
"key_expression": "键名表达式",
|
||||||
"affected_key": "受影响的键名",
|
"affected_key": "受影响的键名",
|
||||||
"show_affected_key": "查看受影响的键名",
|
"show_affected_key": "查看受影响的键名",
|
||||||
"confirm_delete_key": "确认删除{num}个键"
|
"confirm_delete_key": "确认删除{num}个键",
|
||||||
|
"async_delete": "异步执行",
|
||||||
|
"async_delete_title": "不等待操作结果"
|
||||||
},
|
},
|
||||||
"field": {
|
"field": {
|
||||||
"new": "添加新字段",
|
"new": "添加新字段",
|
||||||
|
|
|
@ -1479,12 +1479,13 @@ const useConnectionStore = defineStore('connections', {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete keys with prefix
|
* delete keys with prefix
|
||||||
* @param connName
|
* @param {string} connName
|
||||||
* @param db
|
* @param {number} db
|
||||||
* @param prefix
|
* @param {string} prefix
|
||||||
|
* @param {boolean} async
|
||||||
* @returns {Promise<boolean>}
|
* @returns {Promise<boolean>}
|
||||||
*/
|
*/
|
||||||
async deleteKeyPrefix(connName, db, prefix) {
|
async deleteKeyPrefix(connName, db, prefix, async) {
|
||||||
if (isEmpty(prefix)) {
|
if (isEmpty(prefix)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -1492,7 +1493,7 @@ const useConnectionStore = defineStore('connections', {
|
||||||
if (!endsWith(prefix, '*')) {
|
if (!endsWith(prefix, '*')) {
|
||||||
prefix += '*'
|
prefix += '*'
|
||||||
}
|
}
|
||||||
const { data, success, msg } = await DeleteKey(connName, db, prefix)
|
const { data, success, msg } = await DeleteKey(connName, db, prefix, async)
|
||||||
if (success) {
|
if (success) {
|
||||||
// const { deleted: keys = [] } = data
|
// const { deleted: keys = [] } = data
|
||||||
// for (const key of keys) {
|
// for (const key of keys) {
|
||||||
|
|
Loading…
Reference in New Issue