From 2c787c406796fcc861e454b3d5beee84a05e9411 Mon Sep 17 00:00:00 2001 From: helei Date: Thu, 28 May 2026 14:55:20 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E8=A1=A5=E5=85=85redis=20=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: helei --- db/localredis/unimplemented.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/db/localredis/unimplemented.go b/db/localredis/unimplemented.go index 5cfa71a..47a89b9 100644 --- a/db/localredis/unimplemented.go +++ b/db/localredis/unimplemented.go @@ -2994,3 +2994,21 @@ func (l *LocalCache) SetIFDNEGet(ctx context.Context, key string, value interfac func (l *LocalCache) VRange(ctx context.Context, key string, start string, end string, count int64) *redis.StringSliceCmd { return nil } + +func (l *LocalCache) ReplicaOf(ctx context.Context, host string, port string) *redis.StatusCmd { + return nil +} + +func (l *LocalCache) XCfgSet(ctx context.Context, a *redis.XCfgSetArgs) *redis.StatusCmd { + return nil +} +func (l *LocalCache) VSimWithArgsWithAttribs(ctx context.Context, key string, val redis.Vector, args *redis.VSimArgs) *redis.VectorAttribSliceCmd { + return nil +} +func (l *LocalCache) VSimWithArgsWithScoresWithAttribs(ctx context.Context, key string, val redis.Vector, args *redis.VSimArgs) *redis.VectorScoreAttribSliceCmd { + return nil +} + +func (l *LocalCache) VIsMember(ctx context.Context, key string, element string) *redis.BoolCmd { + return nil +} From ea2e17fb90d9bf928183b18c2dde719c971286f5 Mon Sep 17 00:00:00 2001 From: helei Date: Thu, 28 May 2026 20:29:35 +0800 Subject: [PATCH 02/13] =?UTF-8?q?Bool=20=E6=96=B0=E5=A2=9EPTR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: helei --- dataType/bool.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dataType/bool.go b/dataType/bool.go index 902c555..89ff61d 100644 --- a/dataType/bool.go +++ b/dataType/bool.go @@ -130,3 +130,7 @@ func (b *Bool) GobDecode(data []byte) error { b.bool = data[0] != 0 return nil } + +func (b Bool) ToPtr() *Bool { + return &b +} From 5bd1153103d7d2251c9f1387333a7f92fddb8af7 Mon Sep 17 00:00:00 2001 From: helei Date: Mon, 1 Jun 2026 10:20:58 +0800 Subject: [PATCH 03/13] =?UTF-8?q?CustomTime=20=E6=96=B0=E5=A2=9EUnmarshalP?= =?UTF-8?q?aram?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: helei --- dataType/date.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dataType/date.go b/dataType/date.go index 094f0d4..462ec82 100644 --- a/dataType/date.go +++ b/dataType/date.go @@ -155,6 +155,20 @@ func (c *CustomTime) UnmarshalJSON(b []byte) (err error) { return err } +// UnmarshalParam 从 query string 参数解析 +func (c *CustomTime) UnmarshalParam(param string) error { + if param == "" { + return nil + } + tf := formatter.FormatRule[time.Time]{FormatType: "output_date"} + _t, err := tf.Format(param) + if err != nil { + return err + } + c.Time = _t + return nil +} + // noinspection all func (c CustomTime) ToPtr() *CustomTime { return &c From 16b4d22df578793cee6496010ac14146c573241c Mon Sep 17 00:00:00 2001 From: helei Date: Tue, 2 Jun 2026 17:59:42 +0800 Subject: [PATCH 04/13] =?UTF-8?q?refactor:=20=E7=AE=80=E5=8C=96=20CustomDa?= =?UTF-8?q?te/CustomTime=20=E7=9A=84=20Scan=20=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除对 sql.NullTime 的依赖,改用 timeFormat.Format 统一解析。 新增 nil 值处理,避免空指针问题。 Co-Authored-By: Claude Opus 4.7 --- dataType/date.go | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/dataType/date.go b/dataType/date.go index 462ec82..a2703e7 100644 --- a/dataType/date.go +++ b/dataType/date.go @@ -1,7 +1,6 @@ package dataType import ( - "database/sql" "database/sql/driver" "strings" "time" @@ -13,6 +12,16 @@ import ( "helay.net/go/utils/v3/tools" ) +var timeFormat = formatter.FormatRule[time.Time]{ + FormatType: "output_date", + InputRules: []string{ + "timestamp", + "2006-01-02", + "2006-01-02 15", + "2006-01-02 15:04", + }, +} + type CustomDate struct { time.Time } @@ -23,10 +32,15 @@ func (c CustomDate) String() string { } // noinspection all -func (c *CustomDate) Scan(value interface{}) (err error) { - nullTime := &sql.NullTime{} - err = nullTime.Scan(value) - c.Time = nullTime.Time +func (c *CustomDate) Scan(value any) (err error) { + if value == nil { + return nil + } + t, err := timeFormat.Format(value) + if err != nil { + return err + } + c.Time = t return } @@ -70,8 +84,7 @@ func (c *CustomDate) UnmarshalJSON(b []byte) (err error) { //*this = CustomTime{} return nil } - tf := formatter.FormatRule[time.Time]{FormatType: "output_date"} - _t, err := tf.Format(s) + _t, err := timeFormat.Format(s) if err != nil { return err } @@ -98,9 +111,14 @@ func (c CustomTime) String() string { // noinspection all func (c *CustomTime) Scan(value interface{}) (err error) { - nullTime := &sql.NullTime{} - err = nullTime.Scan(value) - c.Time = nullTime.Time + if value == nil { + return nil + } + t, err := timeFormat.Format(value) + if err != nil { + return err + } + c.Time = t return } From 01233d566b5e374bb91c0d1df4e5dae73393c0ad Mon Sep 17 00:00:00 2001 From: helei Date: Tue, 2 Jun 2026 18:00:26 +0800 Subject: [PATCH 05/13] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20dateObjectFor?= =?UTF-8?q?mat=20=E4=B8=AD=20Any2string=20=E8=B0=83=E7=94=A8=E6=97=B6?= =?UTF-8?q?=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 仅在 time.Time 类型断言失败时才进行字符串转换 Co-Authored-By: Claude Opus 4.7 --- rule-engine/formatter/format.rule.date.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rule-engine/formatter/format.rule.date.go b/rule-engine/formatter/format.rule.date.go index 8875d16..774843a 100644 --- a/rule-engine/formatter/format.rule.date.go +++ b/rule-engine/formatter/format.rule.date.go @@ -51,10 +51,11 @@ func (f FormatRule[T]) dateObjectFormat(_src any) (any, error) { t time.Time err error ok bool - src = tools.Any2string(_src) + src string ) // 首先尝试使用 https://github.com/araddon/dateparse 库 if t, ok = _src.(time.Time); !ok { + src = tools.Any2string(_src) t, err = dateparse.ParseLocal(src) } if err == nil { From 9eed0b80969c9b26e32da45a3813eb8d40319bef Mon Sep 17 00:00:00 2001 From: helei Date: Wed, 3 Jun 2026 17:39:06 +0800 Subject: [PATCH 06/13] =?UTF-8?q?refactor:=20=E5=B0=86=20JSONMap=20?= =?UTF-8?q?=E4=BB=8E=20map=20=E7=B1=BB=E5=9E=8B=E5=88=AB=E5=90=8D=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=20struct?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 JSONMap 从 type JSONMap map[string]any 改为 struct 类型, 以支持更灵活的类型行为控制。新增 Add/Get/Remove 方法。 Co-Authored-By: Claude Opus 4.7 --- dataType/json_map.go | 72 ++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/dataType/json_map.go b/dataType/json_map.go index 0842a86..9188afa 100644 --- a/dataType/json_map.go +++ b/dataType/json_map.go @@ -5,6 +5,7 @@ import ( "context" "database/sql/driver" "encoding/json" + "errors" "gorm.io/gorm" "gorm.io/gorm/clause" @@ -13,48 +14,32 @@ import ( // JSONMap defined JSON data type, need to implements driver.Valuer, sql.Scanner interface // noinspection all -type JSONMap map[string]any +type JSONMap struct { + data map[string]any +} // Value return json value, implement driver.Valuer interface // noinspection all func (m JSONMap) Value() (driver.Value, error) { - return DriverValueWithJson(m) + return DriverValueWithJson(m.data) } // Scan scan value into Jsonb, implements sql.Scanner interface // noinspection all func (m *JSONMap) Scan(val any) error { - return DriverScanWithJson(val, m) // 这里暂时先用这个版本 - //if val == nil { - // *m = make(JSONMap) - // return nil - //} - //var ba []byte - //switch v := val.(type) { - //case []byte: - // ba = v - //case string: - // ba = []byte(v) - //default: - // return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", val)) - //} - //t := map[string]any{} - //rd := bytes.NewReader(ba) - //decoder := json.NewDecoder(rd) - //decoder.UseNumber() - //err := decoder.Decode(&t) - //*m = t - //return err + if m == nil { + return errors.New("JSONMap is nil") + } + return DriverScanWithJson(val, &m.data) // 这里暂时先用这个版本 } // MarshalJSON to output non base64 encoded []byte // noinspection all func (m JSONMap) MarshalJSON() ([]byte, error) { - if m == nil { + if m.data == nil { return []byte("null"), nil } - t := (map[string]any)(m) - return json.Marshal(t) + return json.Marshal(m.data) } // UnmarshalJSON to deserialize []byte @@ -64,10 +49,7 @@ func (m *JSONMap) UnmarshalJSON(b []byte) error { rd := bytes.NewReader(b) decoder := json.NewDecoder(rd) decoder.UseNumber() - t := map[string]any{} - err := decoder.Decode(&t) - *m = t - return err + return decoder.Decode(&m.data) } // GormDataType gorm common data type @@ -83,7 +65,33 @@ func (JSONMap) GormDBDataType(db *gorm.DB, field *schema.Field) string { } // noinspection all -func (jm JSONMap) GormValue(_ context.Context, db *gorm.DB) clause.Expr { - data, _ := jm.MarshalJSON() +func (m JSONMap) GormValue(_ context.Context, db *gorm.DB) clause.Expr { + data, _ := m.MarshalJSON() return MapGormValue(string(data), db) } + +func (m *JSONMap) Add(k string, v any) { + if m == nil { + return + } + if m.data == nil { + m.data = make(map[string]any) + } + m.data[k] = v +} + +func (m *JSONMap) Get(k string) (any, bool) { + if m == nil || m.data == nil { + return nil, false + } + v, ok := m.data[k] + return v, ok +} + +func (m *JSONMap) Remove(k string) { + if m == nil || m.data == nil { + return + } + + delete(m.data, k) +} From 96c65341880521f677e9570cf1cd3dc74e44abcd Mon Sep 17 00:00:00 2001 From: helei Date: Tue, 9 Jun 2026 14:53:31 +0800 Subject: [PATCH 07/13] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20GenericStrin?= =?UTF-8?q?gHasher=20=E5=92=8C=20JSONMap=20=E6=9E=84=E9=80=A0=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 (1M context) --- dataType/json_map.go | 4 ++++ safe/types.go | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/dataType/json_map.go b/dataType/json_map.go index 9188afa..98fb7f1 100644 --- a/dataType/json_map.go +++ b/dataType/json_map.go @@ -18,6 +18,10 @@ type JSONMap struct { data map[string]any } +func NewJSONMap(data map[string]any) JSONMap { + return JSONMap{data: data} +} + // Value return json value, implement driver.Valuer interface // noinspection all func (m JSONMap) Value() (driver.Value, error) { diff --git a/safe/types.go b/safe/types.go index 34a002f..392661d 100644 --- a/safe/types.go +++ b/safe/types.go @@ -1,6 +1,7 @@ package safe import ( + "fmt" "time" "unsafe" @@ -28,6 +29,11 @@ type OnExpired[K comparable] func(key []K) // 过期回调 type Hasher[K comparable] interface { Hash(K) uint64 } +type GenericStringHasher[T fmt.Stringer] struct{} + +func (h GenericStringHasher[T]) Hash(k T) uint64 { + return xxhash.Sum64String(k.String()) +} // IntegerHasher 整数哈希器 type IntegerHasher[T constraints.Integer] struct{} From e67170530343817b2dad15fdf5bc59008b1495a5 Mon Sep 17 00:00:00 2001 From: helei Date: Tue, 16 Jun 2026 15:11:05 +0800 Subject: [PATCH 08/13] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20ToStrings=20?= =?UTF-8?q?=E6=B3=9B=E5=9E=8B=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将实现 fmt.Stringer 的切片转换为 []string。 Co-Authored-By: Claude Opus 4.7 (1M context) --- tools/array.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/array.go b/tools/array.go index 87e44cd..f3a8f46 100644 --- a/tools/array.go +++ b/tools/array.go @@ -373,6 +373,16 @@ func AnySlice2StrSlice(slice []any) []string { return out } +// ToStrings 将实现了 fmt.Stringer 接口的元素切片转换为字符串切片 +// slice: 任意实现了 String() string 的元素类型切片 +func ToStrings[T fmt.Stringer](slice []T) []string { + out := make([]string, len(slice)) + for i, v := range slice { + out[i] = v.String() + } + return out +} + // AnySlice2Str 将任意切片转成字符串 func AnySlice2Str(slice []any, _sep ...string) string { var builder strings.Builder From 1d8b588da2eda087b06557cf5e34baa45a74d50b Mon Sep 17 00:00:00 2001 From: helei Date: Wed, 17 Jun 2026 11:02:23 +0800 Subject: [PATCH 09/13] =?UTF-8?q?feat:=20JSONMap=20=E6=B7=BB=E5=8A=A0=20To?= =?UTF-8?q?Map=20=E6=96=B9=E6=B3=95=E8=BF=94=E5=9B=9E=E5=86=85=E9=83=A8=20?= =?UTF-8?q?map?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 (1M context) --- dataType/json_map.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dataType/json_map.go b/dataType/json_map.go index 98fb7f1..679aa89 100644 --- a/dataType/json_map.go +++ b/dataType/json_map.go @@ -99,3 +99,7 @@ func (m *JSONMap) Remove(k string) { delete(m.data, k) } + +func (m *JSONMap) ToMap() map[string]any { + return m.data +} From 33a7cdfd606c9090700c4a986bf3c12d8c89da13 Mon Sep 17 00:00:00 2001 From: helei Date: Wed, 17 Jun 2026 17:43:07 +0800 Subject: [PATCH 10/13] =?UTF-8?q?feat:=20=E4=B8=BA=20Byte=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=B7=BB=E5=8A=A0=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为 dataType.Byte 添加 ToInt、ToInt64、ToUint64、ToFloat64、ToString、ToBool、ToInt32、ToInt16、ToByte 方法 Co-Authored-By: Claude Opus 4.8 (1M context) --- dataType/int.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/dataType/int.go b/dataType/int.go index 99d5b7b..2e57a3b 100644 --- a/dataType/int.go +++ b/dataType/int.go @@ -47,6 +47,42 @@ func (Byte) GormDBDataType(db *gorm.DB, field *schema.Field) string { return "int" } +func (b Byte) ToInt() int { + return int(b) +} + +func (b Byte) ToInt64() int64 { + return int64(b) +} + +func (b Byte) ToUint64() uint64 { + return uint64(b) +} + +func (b Byte) ToFloat64() float64 { + return float64(b) +} + +func (b Byte) ToString() string { + return fmt.Sprintf("%d", b) +} + +func (b Byte) ToBool() bool { + return b != 0 +} + +func (b Byte) ToInt32() int32 { + return int32(b) +} + +func (b Byte) ToInt16() int16 { + return int16(b) +} + +func (b Byte) ToByte() byte { + return byte(b) +} + type Uint64 struct { uint64 } From 72e28d50c840a70879b72202e70e0b719397d6c8 Mon Sep 17 00:00:00 2001 From: helei Date: Thu, 18 Jun 2026 15:10:14 +0800 Subject: [PATCH 11/13] =?UTF-8?q?feat:=20EmailSender=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=20EnableExternalTo=20=E5=AD=97=E6=AE=B5=E5=92=8C=20Clone=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- net/email/email.go | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/net/email/email.go b/net/email/email.go index 84e7ffa..920fa58 100644 --- a/net/email/email.go +++ b/net/email/email.go @@ -10,15 +10,35 @@ import ( ) type EmailSender struct { - SmtpSenderMail string `json:"smtp_sender_mail" yaml:"smtp_sender_mail"` - SmtpSenderAlias string `json:"smtp_sender_alias" yaml:"smtp_sender_alias"` - SmtpSenderTo []string `json:"smtp_sender_to" yaml:"smtp_sender_to"` - SmtpSenderAddr string `json:"smtp_sender_addr" yaml:"smtp_sender_addr"` - SmtpSenderPort int `json:"smtp_sender_port" yaml:"smtp_sender_port"` - Account string `json:"account" yaml:"account"` - Password string `json:"password" yaml:"password"` - Proxy cfg_proxy.Proxy `json:"proxy" yaml:"proxy"` - TLS *cfg_tls.TLS `json:"tls" yaml:"tls"` + SmtpSenderMail string `json:"smtp_sender_mail" yaml:"smtp_sender_mail"` + SmtpSenderAlias string `json:"smtp_sender_alias" yaml:"smtp_sender_alias"` + EnableExternalTo bool `json:"enable_external_to" yaml:"enable_external_to"` // 是否启用外部邮件接收人,可用在调用层,是否决定重写 SmtpSenderTo + SmtpSenderTo []string `json:"smtp_sender_to" yaml:"smtp_sender_to"` + SmtpSenderAddr string `json:"smtp_sender_addr" yaml:"smtp_sender_addr"` + SmtpSenderPort int `json:"smtp_sender_port" yaml:"smtp_sender_port"` + Account string `json:"account" yaml:"account"` + Password string `json:"password" yaml:"password"` + + Proxy cfg_proxy.Proxy `json:"proxy" yaml:"proxy"` + TLS *cfg_tls.TLS `json:"tls" yaml:"tls"` +} + +func (e *EmailSender) Clone(dst []string) *EmailSender { + out := &EmailSender{ + SmtpSenderMail: e.SmtpSenderMail, + SmtpSenderAlias: e.SmtpSenderAlias, + SmtpSenderTo: e.SmtpSenderTo, + SmtpSenderPort: e.SmtpSenderPort, + SmtpSenderAddr: e.SmtpSenderAddr, + Account: e.Account, + Password: e.Password, + Proxy: e.Proxy, + TLS: e.TLS, + } + if len(dst) > 0 { + out.SmtpSenderTo = dst + } + return out } func (e *EmailSender) NewDialer() (*gomail.Dialer, error) { From 89a1bde7a68ebc97ba117a13a31414d94cb07f5f Mon Sep 17 00:00:00 2001 From: helei Date: Fri, 26 Jun 2026 15:35:50 +0800 Subject: [PATCH 12/13] =?UTF-8?q?chore:=20=E5=8D=87=E7=BA=A7=20go.mod=20?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - go 1.25.0 -> 1.26 - 升级多个依赖包到最新稳定版本(sarama、elasticsearch、pgx、minio、quic-go、go-redis、etcd、gorm 等) - 移除部分已不再需要的间接依赖(dgryski/go-rendezvous、eapache/queue、go-ini/ini、hashicorp/errwrap、hashicorp/go-multierror、go.yaml.in/yaml/v2、google.golang.org/genproto) - 新增 gorilla/websocket 间接依赖 Co-Authored-By: Claude Opus 4.8 (1M context) --- go.mod | 92 +++++++++++++++++++++++++++------------------------------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/go.mod b/go.mod index 6f686c6..cf9983d 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,14 @@ module helay.net/go/utils/v3 -go 1.25.0 +go 1.26 require ( - github.com/IBM/sarama v1.48.0 + github.com/IBM/sarama v1.50.3 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/cespare/xxhash/v2 v2.3.0 github.com/colinmarc/hdfs/v2 v2.4.0 github.com/dchest/captcha v1.1.0 - github.com/elastic/go-elasticsearch/v8 v8.19.5 + github.com/elastic/go-elasticsearch/v8 v8.19.6 github.com/gin-gonic/gin v1.12.0 github.com/go-playground/form/v4 v4.3.0 github.com/go-sql-driver/mysql v1.10.0 @@ -21,65 +21,65 @@ require ( github.com/gorilla/handlers v1.5.2 github.com/gorilla/schema v1.4.1 github.com/helays/gomail/v2 v2.0.3 - github.com/jackc/pgx/v5 v5.9.2 - github.com/jlaffaye/ftp v0.2.0 + github.com/jackc/pgx/v5 v5.10.0 + github.com/jlaffaye/ftp v0.2.1 github.com/malfunkt/iprange v0.9.0 - github.com/minio/minio-go/v7 v7.1.0 + github.com/minio/minio-go/v7 v7.2.0 github.com/nacos-group/nacos-sdk-go/v2 v2.3.5 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/pkg/errors v0.9.1 github.com/pkg/sftp v1.13.10 - github.com/quic-go/quic-go v0.59.0 + github.com/quic-go/quic-go v0.60.0 github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 - github.com/redis/go-redis/v9 v9.19.0 + github.com/redis/go-redis/v9 v9.21.0 github.com/robfig/cron/v3 v3.0.1 github.com/sony/sonyflake/v2 v2.2.0 github.com/tjfoc/gmsm v1.4.1 github.com/vmihailenco/msgpack/v5 v5.4.1 github.com/xdg-go/scram v1.2.0 github.com/xuri/excelize/v2 v2.10.1 - go.etcd.io/etcd/client/v3 v3.6.10 + go.etcd.io/etcd/client/v3 v3.6.12 go.uber.org/zap v1.28.0 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba - golang.org/x/crypto v0.50.0 - golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f - golang.org/x/net v0.53.0 - golang.org/x/text v0.36.0 - gopkg.in/ini.v1 v1.67.1 + golang.org/x/crypto v0.53.0 + golang.org/x/exp v0.0.0-20260611194520-c48552f49976 + golang.org/x/net v0.56.0 + golang.org/x/text v0.38.0 + gopkg.in/ini.v1 v1.67.3 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.6.0 gorm.io/driver/postgres v1.6.0 gorm.io/driver/sqlite v1.6.0 - gorm.io/gorm v1.31.1 + gorm.io/gorm v1.31.2 ) require ( filippo.io/edwards25519 v1.2.0 // indirect - github.com/alibabacloud-go/alibabacloud-gateway-pop v0.1.3 // indirect + github.com/alibabacloud-go/alibabacloud-gateway-pop v0.1.4 // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect github.com/alibabacloud-go/darabonba-array v0.1.0 // indirect github.com/alibabacloud-go/darabonba-encode-util v0.0.2 // indirect github.com/alibabacloud-go/darabonba-map v0.0.2 // indirect - github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.15 // indirect + github.com/alibabacloud-go/darabonba-openapi/v2 v2.2.2 // indirect github.com/alibabacloud-go/darabonba-signature-util v0.0.7 // indirect github.com/alibabacloud-go/darabonba-string v1.0.2 // indirect github.com/alibabacloud-go/debug v1.0.1 // indirect github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect github.com/alibabacloud-go/kms-20160120/v3 v3.4.0 // indirect github.com/alibabacloud-go/openapi-util v0.1.2 // indirect - github.com/alibabacloud-go/tea v1.4.0 // indirect + github.com/alibabacloud-go/tea v1.5.2 // indirect github.com/alibabacloud-go/tea-utils/v2 v2.0.9 // indirect github.com/alibabacloud-go/tea-xml v1.1.3 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 // indirect github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1 // indirect github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.9 // indirect github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5 // indirect - github.com/aliyun/credentials-go v1.4.11 // indirect + github.com/aliyun/credentials-go v1.4.12 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/buger/jsonparser v1.1.1 // indirect + github.com/buger/jsonparser v1.2.0 // indirect github.com/bytedance/gopkg v0.1.4 // indirect - github.com/bytedance/sonic v1.15.1 // indirect + github.com/bytedance/sonic v1.15.2 // indirect github.com/bytedance/sonic/loader v0.5.1 // indirect github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/cloudwego/base64x v0.1.7 // indirect @@ -87,27 +87,23 @@ require ( github.com/coreos/go-systemd/v22 v22.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set v1.8.0 // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/eapache/go-resiliency v1.7.0 // indirect - github.com/eapache/queue v1.1.0 // indirect github.com/elastic/elastic-transport-go/v8 v8.11.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/felixge/httpsnoop v1.1.0 // indirect github.com/gabriel-vasile/mimetype v1.4.13 // indirect github.com/gin-contrib/sse v1.1.1 // indirect - github.com/go-ini/ini v1.67.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.30.2 // indirect + github.com/go-playground/validator/v10 v10.30.3 // indirect github.com/goccy/go-yaml v1.19.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.7.0-rc.1 // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect @@ -122,13 +118,13 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.5 // indirect + github.com/klauspost/compress v1.18.6 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/crc32 v1.3.0 // indirect github.com/kr/fs v0.1.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.22 // indirect - github.com/mattn/go-sqlite3 v1.14.44 // indirect + github.com/mattn/go-sqlite3 v1.14.47 // indirect github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -136,16 +132,16 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/orcaman/concurrent-map v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.3.0 // indirect + github.com/pelletier/go-toml/v2 v2.4.2 // indirect github.com/philhofer/fwd v1.2.0 // indirect - github.com/pierrec/lz4/v4 v4.1.26 // indirect + github.com/pierrec/lz4/v4 v4.1.27 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/common v0.69.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect github.com/quic-go/qpack v0.6.0 // indirect - github.com/richardlehane/mscfb v1.0.6 // indirect + github.com/richardlehane/mscfb v1.0.7 // indirect github.com/richardlehane/msoleps v1.0.6 // indirect github.com/rs/xid v1.6.0 // indirect github.com/tiendc/go-deepcopy v1.7.2 // indirect @@ -158,25 +154,23 @@ require ( github.com/xuri/efp v0.0.1 // indirect github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect - go.etcd.io/etcd/api/v3 v3.6.10 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.10 // indirect - go.mongodb.org/mongo-driver/v2 v2.6.0 // indirect + go.etcd.io/etcd/api/v3 v3.6.12 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.12 // indirect + go.mongodb.org/mongo-driver/v2 v2.7.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.43.0 // indirect - go.opentelemetry.io/otel/metric v1.43.0 // indirect - go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/arch v0.26.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.43.0 // indirect - golang.org/x/time v0.14.0 // indirect - google.golang.org/genproto v0.0.0-20260226221140-a57be14db171 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260427160629-7cedc36a6bc4 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 // indirect - google.golang.org/grpc v1.80.0 // indirect + golang.org/x/arch v0.28.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/time v0.15.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260622175928-b703f567277d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260622175928-b703f567277d // indirect + google.golang.org/grpc v1.81.1 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect From ef78367bcc416fb0a0aa029559d9222d19f0c1dd Mon Sep 17 00:00:00 2001 From: helei Date: Fri, 26 Jun 2026 15:37:23 +0800 Subject: [PATCH 13/13] =?UTF-8?q?feat:=20=E9=80=82=E9=85=8D=20go-redis=20v?= =?UTF-8?q?9.21.0=20=E6=96=B0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修正 VLinks/VLinksWithScores 返回类型(StringSliceSliceCmd / VectorScoreSliceCmd) - 新增 AR* 系列接口 stub(ARSet/ARGet/ARInsert/ARDel/ARLen/ARScan 等 28 个方法) - 新增 GetToBuffer/SetFromBuffer/JSONSetWithArgs/XNack/XAutoClaimWithDeleted 等接口 stub - 新增 IncrEXInt/IncrEXFloat 接口 stub 配套 go.mod 中 go-redis 升级到 v9.21.0 使用。 Co-Authored-By: Claude Opus 4.8 (1M context) --- db/localredis/unimplemented.go | 130 ++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) diff --git a/db/localredis/unimplemented.go b/db/localredis/unimplemented.go index 47a89b9..8501710 100644 --- a/db/localredis/unimplemented.go +++ b/db/localredis/unimplemented.go @@ -2721,13 +2721,13 @@ func (l *LocalCache) VInfo(ctx context.Context, key string) *redis.MapStringInte // VLinks // noinspection all -func (l *LocalCache) VLinks(ctx context.Context, key, element string) *redis.StringSliceCmd { +func (l *LocalCache) VLinks(ctx context.Context, key string, element string) *redis.StringSliceSliceCmd { return nil } // VLinksWithScores // noinspection all -func (l *LocalCache) VLinksWithScores(ctx context.Context, key, element string) *redis.VectorScoreSliceCmd { +func (l *LocalCache) VLinksWithScores(ctx context.Context, key, element string) *redis.VectorScoreSliceSliceCmd { return nil } @@ -3012,3 +3012,129 @@ func (l *LocalCache) VSimWithArgsWithScoresWithAttribs(ctx context.Context, key func (l *LocalCache) VIsMember(ctx context.Context, key string, element string) *redis.BoolCmd { return nil } + +func (l *LocalCache) ARSet(ctx context.Context, key string, index uint64, values ...string) *redis.IntCmd { + return nil +} +func (l *LocalCache) ARGet(ctx context.Context, key string, index uint64) *redis.StringCmd { + return nil +} +func (l *LocalCache) ARGetRange(ctx context.Context, key string, start uint64, end uint64) *redis.SliceCmd { + return nil +} + +func (l *LocalCache) ARMGet(ctx context.Context, key string, indexes ...uint64) *redis.SliceCmd { + return nil +} +func (l *LocalCache) ARMSet(ctx context.Context, key string, members ...redis.AREntry) *redis.IntCmd { + return nil +} +func (l *LocalCache) ARInsert(ctx context.Context, key string, values ...string) *redis.UintCmd { + return nil +} + +func (l *LocalCache) ARDel(ctx context.Context, key string, indexes ...uint64) *redis.IntCmd { + return nil +} +func (l *LocalCache) ARDelRange(ctx context.Context, key string, ranges ...redis.ARRange) *redis.UintCmd { + return nil +} +func (l *LocalCache) ARLen(ctx context.Context, key string) *redis.UintCmd { + return nil +} + +func (l *LocalCache) ARCount(ctx context.Context, key string) *redis.UintCmd { + return nil +} +func (l *LocalCache) ARNext(ctx context.Context, key string) *redis.UintCmd { + return nil +} +func (l *LocalCache) ARSeek(ctx context.Context, key string, index uint64) *redis.IntCmd { + return nil +} + +func (l *LocalCache) ARInfo(ctx context.Context, key string) *redis.MapStringInterfaceCmd { + return nil +} +func (l *LocalCache) ARInfoFull(ctx context.Context, key string) *redis.MapStringInterfaceCmd { + return nil +} +func (l *LocalCache) ARScan(ctx context.Context, key string, start uint64, end uint64, args *redis.ARScanArgs) *redis.AREntrySliceCmd { + return nil +} + +func (l *LocalCache) AROpSum(ctx context.Context, key string, start, end uint64) *redis.StringCmd { + return nil +} + +func (l *LocalCache) AROpMin(ctx context.Context, key string, start, end uint64) *redis.StringCmd { + return nil +} + +func (l *LocalCache) AROpMax(ctx context.Context, key string, start, end uint64) *redis.StringCmd { + return nil +} + +func (l *LocalCache) AROpAnd(ctx context.Context, key string, start, end uint64) *redis.IntCmd { + return nil +} + +func (l *LocalCache) AROpOr(ctx context.Context, key string, start, end uint64) *redis.IntCmd { + return nil +} + +func (l *LocalCache) AROpXor(ctx context.Context, key string, start, end uint64) *redis.IntCmd { + return nil +} + +func (l *LocalCache) AROpMatch(ctx context.Context, key string, start, end uint64, value string) *redis.IntCmd { + return nil +} + +func (l *LocalCache) AROpUsed(ctx context.Context, key string, start, end uint64) *redis.IntCmd { + return nil +} + +func (l *LocalCache) ARGrep(ctx context.Context, key string, start, end string, args *redis.ARGrepArgs) *redis.UintSliceCmd { + return nil +} + +func (l *LocalCache) ARGrepWithValues(ctx context.Context, key string, start, end string, args *redis.ARGrepArgs) *redis.AREntrySliceCmd { + return nil +} + +func (l *LocalCache) ARRing(ctx context.Context, key string, size uint64, values ...string) *redis.UintCmd { + return nil +} + +func (l *LocalCache) ARLastItems(ctx context.Context, key string, count uint64, rev bool) *redis.SliceCmd { + return nil +} + +func (l *LocalCache) GetToBuffer(ctx context.Context, key string, buf []byte) *redis.ZeroCopyStringCmd { + return nil +} + +func (l *LocalCache) IncrEXInt(ctx context.Context, key string, args redis.IncrEXIntArgs) *redis.IncrEXIntCmd { + return nil +} + +func (l *LocalCache) IncrEXFloat(ctx context.Context, key string, args redis.IncrEXFloatArgs) *redis.IncrEXFloatCmd { + return nil +} + +func (l *LocalCache) SetFromBuffer(ctx context.Context, key string, buf []byte) *redis.StatusCmd { + return nil +} + +func (l *LocalCache) XNack(ctx context.Context, a *redis.XNackArgs) *redis.IntCmd { + return nil +} + +func (l *LocalCache) XAutoClaimWithDeleted(ctx context.Context, a *redis.XAutoClaimArgs) *redis.XAutoClaimWithDeletedCmd { + return nil +} + +func (l *LocalCache) JSONSetWithArgs(ctx context.Context, key, path string, value interface{}, options *redis.JSONSetArgsOptions) *redis.StatusCmd { + return nil +}