2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 11:27:17 +08:00

feat: 初步完成redis操作方法

This commit is contained in:
耗子
2024-11-11 02:22:23 +08:00
parent 5fba45e3a4
commit 6f0f4c69ef
9 changed files with 365 additions and 10 deletions

View File

@@ -21,7 +21,7 @@ type Postgres struct {
port uint
}
func NewPostgres(username, password, address, hbaFile string, port uint) (*Postgres, error) {
func NewPostgres(username, password, address string, port uint, hbaFile string) (*Postgres, error) {
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=postgres sslmode=disable", address, port, username, password)
if password == "" {
dsn = fmt.Sprintf("host=%s port=%d user=%s dbname=postgres sslmode=disable", address, port, username)

View File

@@ -1,9 +1,23 @@
package db
import (
"encoding/json"
"fmt"
"time"
"github.com/gomodule/redigo/redis"
)
type RedisKV struct {
Key string `json:"key"`
Value string `json:"value"`
Type string `json:"type"`
Size int64 `json:"size"`
Length int64 `json:"length"`
TTL int64 `json:"ttl"`
UpdatedAt time.Time `json:"updated_at"`
}
type Redis struct {
conn redis.Conn
username string
@@ -29,6 +43,129 @@ func (r *Redis) Close() error {
return r.conn.Close()
}
func (r *Redis) Do(command string, args ...any) (any, error) {
func (r *Redis) Exec(command string, args ...any) (any, error) {
return r.conn.Do(command, args...)
}
func (r *Redis) Database() (int, error) {
return redis.Int(r.conn.Do("CONFIG", "GET", "databases"))
}
func (r *Redis) Select(db int) error {
_, err := r.conn.Do("SELECT", db)
return err
}
func (r *Redis) Size() (int, error) {
return redis.Int(r.conn.Do("DBSIZE"))
}
func (r *Redis) Data(page, pageSize int) ([]RedisKV, error) {
result := make([]RedisKV, 0)
cursor := 0
var keys []string
for {
values, err := redis.Values(r.conn.Do("SCAN", cursor, "COUNT", 100))
if err != nil {
return nil, fmt.Errorf("failed to SCAN: %v", err)
}
var batch []string
_, err = redis.Scan(values, &cursor, &batch)
if err != nil {
return nil, fmt.Errorf("failed to parse SCAN result: %v", err)
}
keys = append(keys, batch...)
if cursor == 0 {
break
}
}
start := (page - 1) * pageSize
end := start + pageSize
if start >= len(keys) {
return []RedisKV{}, nil
}
if end > len(keys) {
end = len(keys)
}
paged := keys[start:end]
for _, key := range paged {
kv := RedisKV{
Key: key,
}
keyType, err := redis.String(r.conn.Do("TYPE", key))
if err != nil {
continue
}
kv.Type = keyType
ttl, err := redis.Int64(r.conn.Do("TTL", key))
if err == nil {
kv.TTL = ttl
}
idleTime, err := redis.Int64(r.conn.Do("OBJECT", "IDLETIME", key))
if err == nil {
kv.UpdatedAt = time.Now().Add(-time.Duration(idleTime) * time.Second)
} else {
kv.UpdatedAt = time.Now()
}
memory, err := redis.Int64(r.conn.Do("MEMORY", "USAGE", key))
if err == nil {
kv.Size = memory
}
var value any
switch keyType {
case "string":
if value, err = redis.String(r.conn.Do("GET", key)); err == nil {
kv.Length = int64(len(value.(string)))
}
case "list":
if value, err = redis.Strings(r.conn.Do("LRANGE", key, 0, -1)); err == nil {
kv.Length, _ = redis.Int64(r.conn.Do("LLEN", key))
}
case "set":
if value, err = redis.Strings(r.conn.Do("SMEMBERS", key)); err == nil {
kv.Length, _ = redis.Int64(r.conn.Do("SCARD", key))
}
case "zset":
if members, err := redis.Strings(r.conn.Do("ZRANGE", key, 0, -1, "WITHSCORES")); err == nil {
kv.Length, _ = redis.Int64(r.conn.Do("ZCARD", key))
zsetMap := make(map[string]string)
for i := 0; i < len(members); i += 2 {
zsetMap[members[i]] = members[i+1]
}
value = zsetMap
}
case "hash":
if value, err = redis.StringMap(r.conn.Do("HGETALL", key)); err == nil {
kv.Length, _ = redis.Int64(r.conn.Do("HLEN", key))
}
default:
continue
}
if err != nil {
continue
}
if kv.Length > 500 {
value = fmt.Sprintf("data is too long, can't display")
}
if str, ok := value.(string); ok {
kv.Value = str
} else {
encoded, err := json.Marshal(value)
if err != nil {
continue
}
kv.Value = string(encoded)
}
result = append(result, kv)
}
return result, nil
}