feat: support create connection by redis url string #127

This commit is contained in:
Lykin 2024-01-25 17:48:27 +08:00
parent f3a43c8083
commit 4032c80add
5 changed files with 96 additions and 1 deletions

View File

@ -15,6 +15,7 @@ import (
"net"
"os"
"path"
"strconv"
"strings"
"sync"
"time"
@ -512,3 +513,36 @@ func (c *connectionService) ImportConnections() (resp types.JSResp) {
resp.Success = true
return
}
// ParseConnectURL parse connection url string
func (c *connectionService) ParseConnectURL(url string) (resp types.JSResp) {
urlOpt, err := redis.ParseURL(url)
if err != nil {
resp.Msg = err.Error()
return
}
addrPart := strings.Split(urlOpt.Addr, ":")
addr := addrPart[0]
port := 6379
if len(addrPart) > 1 {
port, _ = strconv.Atoi(addrPart[1])
}
resp.Success = true
resp.Data = struct {
Addr string `json:"addr"`
Port int `json:"port"`
Username string `json:"username"`
Password string `json:"password"`
ConnTimeout int64 `json:"connTimeout"`
ExecTimeout int64 `json:"execTimeout"`
}{
Addr: addr,
Port: port,
Username: urlOpt.Username,
Password: urlOpt.Password,
ConnTimeout: int64(urlOpt.DialTimeout.Seconds()),
ExecTimeout: int64(urlOpt.ReadTimeout.Seconds()),
}
return
}

View File

@ -267,6 +267,29 @@ const onTestConnection = async () => {
const onClose = () => {
dialogStore.closeConnDialog()
}
const pasteFromClipboard = async () => {
// url example:
// redis://user:password@localhost:6789/3?dial_timeout=3&db=1&read_timeout=6s&max_retries=2
let opt = {}
try {
opt = await connectionStore.parseUrlFromClipboard()
} catch (e) {
$message.error(i18n.t('dialogue.connection.parse_fail', { reason: e.message }))
return
}
generalForm.value.name = generalForm.value.addr = opt.addr
generalForm.value.port = opt.port
generalForm.value.username = opt.username
generalForm.value.password = opt.password
if (opt.connTimeout > 0) {
generalForm.value.connTimeout = opt.connTimeout
}
if (opt.execTimeout > 0) {
generalForm.value.execTimeout = opt.execTimeout
}
$message.success(i18n.t('dialogue.connection.parse_pass', { url: opt.url }))
}
</script>
<template>
@ -685,6 +708,9 @@ const onClose = () => {
</n-button>
</div>
<div class="flex-item n-dialog__action">
<n-button :disabled="closingConnection" :focusable="false" @click="pasteFromClipboard">
{{ $t('dialogue.connection.parse_url_clipboard') }}
</n-button>
<n-button :disabled="closingConnection" :focusable="false" @click="onClose">
{{ $t('common.cancel') }}
</n-button>

View File

@ -187,6 +187,9 @@
"test": "Test Connection",
"test_succ": "Successful connection to redis-server",
"test_fail": "Fail Connection",
"parse_url_clipboard": "Parse URL from Clipboard",
"parse_pass": "Redis URL Parsed {url}",
"parse_fail": "Parse Redis URL failed: {reason}",
"advn": {
"title": "Advanced",
"filter": "Default Key Filter Pattern",

View File

@ -187,6 +187,9 @@
"test": "测试连接",
"test_succ": "成功连接到Redis服务器",
"test_fail": "连接失败",
"parse_url_clipboard": "解析剪切板中的URL",
"parse_pass": "解析Redis URL完成: {url}",
"parse_fail": "解析Redis URL失败: {reason}",
"advn": {
"title": "高级配置",
"filter": "默认键过滤表达式",

View File

@ -1,5 +1,5 @@
import { defineStore } from 'pinia'
import { get, isEmpty, uniq } from 'lodash'
import { get, isEmpty, isObject, uniq } from 'lodash'
import {
CreateGroup,
DeleteConnection,
@ -8,6 +8,7 @@ import {
GetConnection,
ImportConnections,
ListConnection,
ParseConnectURL,
RenameGroup,
SaveConnection,
SaveLastDB,
@ -18,6 +19,7 @@ import { ConnectionType } from '@/consts/connection_type.js'
import { KeyViewType } from '@/consts/key_view_type.js'
import useBrowserStore from 'stores/browser.js'
import { i18nGlobal } from '@/utils/i18n.js'
import { ClipboardGetText } from 'wailsjs/runtime/runtime.js'
const useConnectionStore = defineStore('connections', {
/**
@ -404,6 +406,10 @@ const useConnectionStore = defineStore('connections', {
return { success: true }
},
/**
* export connections to zip
* @return {Promise<void>}
*/
async exportConnections() {
const {
success,
@ -420,6 +426,10 @@ const useConnectionStore = defineStore('connections', {
$message.success(i18nGlobal.t('dialogue.handle_succ'))
},
/**
* import connections from zip
* @return {Promise<void>}
*/
async importConnections() {
const { success, msg } = await ImportConnections()
if (!success) {
@ -431,6 +441,25 @@ const useConnectionStore = defineStore('connections', {
$message.success(i18nGlobal.t('dialogue.handle_succ'))
},
/**
* parse redis url from text in clipboard
* @return {Promise<{}>}
*/
async parseUrlFromClipboard() {
const urlString = await ClipboardGetText()
if (isEmpty(urlString)) {
throw new Error('no text in clipboard')
}
const { success, msg, data } = await ParseConnectURL(urlString)
if (!success || !isObject(data)) {
throw new Error(msg || 'unknown')
}
data.url = urlString
return data
},
},
})