mirror of
https://github.com/hanzokv/go.git
synced 2026-09-24 00:31:51 +00:00
KV lives in its own org now, like hanzokms / hanzos3 / hanzo-ds. The repo moved hanzoai/kv-go -> hanzokv/go, so the module path follows: a Go module path must match where the repo actually is, or the proxy cannot resolve it. The name is `go`, not `kv-go`, following the hanzo-ds convention — that org holds go, mock, native, sqlbuilder, sqlparser, each named for its language or concern with the ORG supplying the product noun. Repeating "kv" inside a repo that already lives under hanzokv is the compound-word habit we are dropping. 349 occurrences across 188 files: the root module, all four extra/* modules, every example module, imports throughout the tree, and the docs. Builds clean. The package is still `package redis` and the extra dirs are still named redis*. That rename is deliberately NOT bundled here: it is 5,771 occurrences, it breaks all 11 consumers at once, and a large share are WIRE CONTRACTS rather than branding — the redis:// scheme parser, the "redis: nil" error string, RESP command names. Renaming those breaks protocol compatibility with the Valkey server. It needs the same our-vocabulary-vs-the-wire split the argo sweep used, as its own change. GitHub keeps the old path redirecting, and versions already published under github.com/hanzoai/kv-go/v9 stay resolvable, so nothing breaks the moment this lands. Consumers move on their own schedule.
210 lines
4.5 KiB
Go
210 lines
4.5 KiB
Go
package redis
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/hanzokv/go/v9/internal/routing"
|
|
)
|
|
|
|
type (
|
|
module = string
|
|
commandName = string
|
|
)
|
|
|
|
var defaultPolicies = map[module]map[commandName]*routing.CommandPolicy{
|
|
"ft": {
|
|
"create": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"search": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"aggregate": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"dictadd": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"dictdump": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"dictdel": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"suglen": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultHashSlot,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"cursor": {
|
|
Request: routing.ReqSpecial,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"sugadd": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultHashSlot,
|
|
},
|
|
"sugget": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultHashSlot,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"sugdel": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultHashSlot,
|
|
},
|
|
"spellcheck": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"explain": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"explaincli": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"aliasadd": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"aliasupdate": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"aliasdel": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"info": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"tagvals": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"syndump": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"synupdate": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"profile": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
Tips: map[string]string{
|
|
routing.ReadOnlyCMD: "",
|
|
},
|
|
},
|
|
"alter": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"dropindex": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
"drop": {
|
|
Request: routing.ReqDefault,
|
|
Response: routing.RespDefaultKeyless,
|
|
},
|
|
},
|
|
}
|
|
|
|
type CommandInfoResolveFunc func(ctx context.Context, cmd Cmder) *routing.CommandPolicy
|
|
|
|
type commandInfoResolver struct {
|
|
resolveFunc CommandInfoResolveFunc
|
|
fallBackResolver *commandInfoResolver
|
|
}
|
|
|
|
func NewCommandInfoResolver(resolveFunc CommandInfoResolveFunc) *commandInfoResolver {
|
|
return &commandInfoResolver{
|
|
resolveFunc: resolveFunc,
|
|
}
|
|
}
|
|
|
|
func NewDefaultCommandPolicyResolver() *commandInfoResolver {
|
|
return NewCommandInfoResolver(func(ctx context.Context, cmd Cmder) *routing.CommandPolicy {
|
|
module := "core"
|
|
command := cmd.Name()
|
|
cmdParts := strings.Split(command, ".")
|
|
if len(cmdParts) == 2 {
|
|
module = cmdParts[0]
|
|
command = cmdParts[1]
|
|
}
|
|
|
|
if policy, ok := defaultPolicies[module][command]; ok {
|
|
return policy
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (r *commandInfoResolver) GetCommandPolicy(ctx context.Context, cmd Cmder) *routing.CommandPolicy {
|
|
if r.resolveFunc == nil {
|
|
return nil
|
|
}
|
|
|
|
policy := r.resolveFunc(ctx, cmd)
|
|
if policy != nil {
|
|
return policy
|
|
}
|
|
|
|
if r.fallBackResolver != nil {
|
|
return r.fallBackResolver.GetCommandPolicy(ctx, cmd)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *commandInfoResolver) SetFallbackResolver(fallbackResolver *commandInfoResolver) {
|
|
r.fallBackResolver = fallbackResolver
|
|
}
|