Package Database KV:

- Driver: add instance to compare keys
- Driver: add optionnal function to search keys with a pattern of keys
- Driver: add fakefunction search based on compare & list to replace a dedicated search function
- Table: add function search function

Other:
- Bump dependencies
This commit is contained in:
Nicolas JUHEL
2025-05-19 09:46:30 +02:00
parent 4a37d3db6a
commit 0f4ac42db9
8 changed files with 190 additions and 78 deletions

View File

@@ -0,0 +1,49 @@
package kvdriver
type CompareEqual[K comparable] func(ref, part K) bool
type CompareContains[K comparable] func(ref, part K) bool
type CompareEmpty[K comparable] func(part K) bool
type Compare[K comparable] interface {
IsEqual(ref, part K) bool
IsContains(ref, part K) bool
IsEmpty(part K) bool
}
func NewCompare[K comparable](eq CompareEqual[K], cn CompareContains[K], em CompareEmpty[K]) Compare[K] {
return &cmp[K]{
feq: eq,
fcn: cn,
fem: em,
}
}
type cmp[K comparable] struct {
feq CompareEqual[K]
fcn CompareContains[K]
fem CompareEmpty[K]
}
func (o *cmp[K]) IsEqual(ref, part K) bool {
if o == nil || o.feq == nil {
return false
}
return o.feq(ref, part)
}
func (o *cmp[K]) IsContains(ref, part K) bool {
if o == nil || o.fcn == nil {
return false
}
return o.fcn(ref, part)
}
func (o *cmp[K]) IsEmpty(part K) bool {
if o == nil || o.fem == nil {
return false
}
return o.fem(part)
}

View File

@@ -37,6 +37,8 @@ const pkgName = "golib/database/kvdriver"
const (
ErrorParamEmpty liberr.CodeError = iota + liberr.MinPkgDatabaseKVDrv
ErrorBadInstance
ErrorCompareFunctionEqual
ErrorCompareFunctionContain
ErrorGetFunction
ErrorSetFunction
ErrorDelFunction
@@ -59,6 +61,10 @@ func getMessage(code liberr.CodeError) (message string) {
return "given parameters is empty"
case ErrorBadInstance:
return "bad instance of " + pkgName
case ErrorCompareFunctionEqual:
return "missing comparable equal function of " + pkgName
case ErrorCompareFunctionContain:
return "missing comparable contain function of " + pkgName
case ErrorGetFunction:
return "missing get function of " + pkgName
case ErrorSetFunction:

View File

@@ -34,25 +34,34 @@ type FuncNew[K comparable, M any] func() libkvt.KVDriver[K, M]
type FuncGet[K comparable, M any] func(key K) (M, error)
type FuncSet[K comparable, M any] func(key K, model M) error
type FuncDel[K comparable] func(key K) error
type FuncList[K comparable, M any] func() ([]K, error)
type FuncList[K comparable] func() ([]K, error)
type FuncSearch[K comparable] func(prefix K) ([]K, error)
type FuncWalk[K comparable, M any] func(fct libkvt.FctWalk[K, M]) error
type drv[K comparable, M any] struct {
FctNew FuncNew[K, M]
FctGet FuncGet[K, M]
FctSet FuncSet[K, M]
FctDel FuncDel[K]
FctList FuncList[K, M]
FctWalk FuncWalk[K, M] // optional
cmp Compare[K]
fctNew FuncNew[K, M]
fctGet FuncGet[K, M]
fctSet FuncSet[K, M]
fctDel FuncDel[K]
fctLst FuncList[K]
fctSch FuncSearch[K] // optional
fctWlk FuncWalk[K, M] // optional
}
func New[K comparable, M any](fn FuncNew[K, M], fg FuncGet[K, M], fs FuncSet[K, M], fd FuncDel[K], fl FuncList[K, M], fw FuncWalk[K, M]) libkvt.KVDriver[K, M] {
func New[K comparable, M any](cmp Compare[K], fn FuncNew[K, M], fg FuncGet[K, M], fs FuncSet[K, M], fd FuncDel[K], fl FuncList[K], fh FuncSearch[K], fw FuncWalk[K, M]) libkvt.KVDriver[K, M] {
return &drv[K, M]{
FctNew: fn,
FctGet: fg,
FctSet: fs,
FctDel: fd,
FctList: fl,
FctWalk: fw,
cmp: cmp, // compare instance
fctNew: fn,
fctGet: fg,
fctSet: fs,
fctDel: fd,
fctLst: fl,
fctSch: fh, // optional
fctWlk: fw, // optional
}
}

View File

@@ -31,27 +31,29 @@ import (
)
func (o *drv[K, M]) New() libkvt.KVDriver[K, M] {
if o.FctNew != nil {
return o.FctNew()
if o.fctNew != nil {
return o.fctNew()
}
return &drv[K, M]{
FctNew: o.FctNew,
FctGet: o.FctGet,
FctSet: o.FctSet,
FctDel: o.FctDel,
FctList: o.FctList,
FctWalk: o.FctWalk,
cmp: o.cmp,
fctNew: o.fctNew,
fctGet: o.fctGet,
fctSet: o.fctSet,
fctDel: o.fctDel,
fctLst: o.fctLst,
fctSch: o.fctSch,
fctWlk: o.fctWlk,
}
}
func (o *drv[K, M]) Get(key K, model *M) error {
if o == nil {
return ErrorBadInstance.Error(nil)
} else if o.FctGet == nil {
} else if o.fctGet == nil {
return ErrorGetFunction.Error(nil)
} else {
m, e := o.FctGet(key)
m, e := o.fctGet(key)
*model = m
return e
}
@@ -60,30 +62,44 @@ func (o *drv[K, M]) Get(key K, model *M) error {
func (o *drv[K, M]) Set(key K, model M) error {
if o == nil {
return ErrorBadInstance.Error(nil)
} else if o.FctSet == nil {
} else if o.fctSet == nil {
return ErrorSetFunction.Error(nil)
} else {
return o.FctSet(key, model)
return o.fctSet(key, model)
}
}
func (o *drv[K, M]) Del(key K) error {
if o == nil {
return ErrorBadInstance.Error(nil)
} else if o.FctDel == nil {
} else if o.fctDel == nil {
return ErrorSetFunction.Error(nil)
} else {
return o.FctDel(key)
return o.fctDel(key)
}
}
func (o *drv[K, M]) List() ([]K, error) {
if o == nil {
return nil, ErrorBadInstance.Error(nil)
} else if o.FctList == nil {
} else if o.fctLst == nil {
return nil, ErrorListFunction.Error(nil)
} else {
return o.FctList()
return o.fctLst()
}
}
func (o *drv[K, M]) Search(pattern K) ([]K, error) {
if o == nil {
return nil, ErrorBadInstance.Error(nil)
} else if o.cmp == nil {
return nil, ErrorBadInstance.Error(nil)
} else if o.cmp.IsEmpty(pattern) {
return o.List()
} else if o.fctSch != nil {
return o.fctSch(pattern)
} else {
return o.fakeSrch(pattern)
}
}
@@ -92,10 +108,24 @@ func (o *drv[K, M]) Walk(fct libkvt.FctWalk[K, M]) error {
return ErrorBadInstance.Error(nil)
} else if fct == nil {
return ErrorFunctionParams.Error(nil)
} else if o.FctWalk == nil {
} else if o.fctWlk == nil {
return o.fakeWalk(fct)
} else {
return o.FctWalk(fct)
return o.fctWlk(fct)
}
}
func (o *drv[K, M]) fakeSrch(pattern K) ([]K, error) {
if l, e := o.List(); e != nil {
return nil, e
} else {
var res = make([]K, 0)
for _, k := range l {
if o.cmp.IsContains(k, pattern) {
res = append(res, k)
}
}
return res, nil
}
}

View File

@@ -35,18 +35,6 @@ type tbl[K comparable, M any] struct {
d libkvt.KVDriver[K, M]
}
func (o *tbl[K, M]) getDriver() libkvt.KVDriver[K, M] {
if o == nil {
return nil
}
if o.d == nil {
return nil
} else {
return o.d
}
}
func (o *tbl[K, M]) Get(key K) (libkvt.KVItem[K, M], error) {
if drv := o.getDriver(); drv == nil {
return nil, ErrorBadDriver.Error(nil)
@@ -65,18 +53,6 @@ func (o *tbl[K, M]) Del(key K) error {
}
}
func (o *tbl[K, M]) Walk(fct libkvt.FuncWalk[K, M]) error {
if drv := o.getDriver(); drv == nil {
return ErrorBadDriver.Error(nil)
} else {
return drv.Walk(func(key K, model M) bool {
kvi := libkvs.New[K, M](drv.New(), key)
kvi.Set(model)
return fct(kvi)
})
}
}
func (o *tbl[K, M]) List() ([]libkvt.KVItem[K, M], error) {
var res = make([]libkvt.KVItem[K, M], 0)
@@ -92,3 +68,43 @@ func (o *tbl[K, M]) List() ([]libkvt.KVItem[K, M], error) {
return res, nil
}
}
func (o *tbl[K, M]) Search(pattern K) ([]libkvt.KVItem[K, M], error) {
var res = make([]libkvt.KVItem[K, M], 0)
if drv := o.getDriver(); drv == nil {
return nil, ErrorBadDriver.Error(nil)
} else if l, e := drv.Search(pattern); e != nil {
return nil, e
} else {
for _, k := range l {
res = append(res, libkvs.New[K, M](drv.New(), k))
}
return res, nil
}
}
func (o *tbl[K, M]) Walk(fct libkvt.FuncWalk[K, M]) error {
if drv := o.getDriver(); drv == nil {
return ErrorBadDriver.Error(nil)
} else {
return drv.Walk(func(key K, model M) bool {
kvi := libkvs.New[K, M](drv.New(), key)
kvi.Set(model)
return fct(kvi)
})
}
}
func (o *tbl[K, M]) getDriver() libkvt.KVDriver[K, M] {
if o == nil {
return nil
}
if o.d == nil {
return nil
} else {
return o.d
}
}

View File

@@ -34,5 +34,6 @@ type KVDriver[K comparable, M any] interface {
Set(key K, model M) error
Del(key K) error
List() ([]K, error)
Search(pattern K) ([]K, error)
Walk(fct FctWalk[K, M]) error
}

View File

@@ -32,5 +32,6 @@ type KVTable[K comparable, M any] interface {
Get(key K) (KVItem[K, M], error)
Del(key K) error
List() ([]KVItem[K, M], error)
Search(pattern K) ([]KVItem[K, M], error)
Walk(fct FuncWalk[K, M]) error
}

44
go.mod
View File

@@ -5,12 +5,12 @@ go 1.24
toolchain go1.24.1
require (
github.com/aws/aws-sdk-go v1.55.6
github.com/aws/aws-sdk-go v1.55.7
github.com/aws/aws-sdk-go-v2 v1.36.3
github.com/aws/aws-sdk-go-v2/config v1.29.13
github.com/aws/aws-sdk-go-v2/credentials v1.17.66
github.com/aws/aws-sdk-go-v2/service/iam v1.41.1
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.1
github.com/aws/aws-sdk-go-v2/config v1.29.14
github.com/aws/aws-sdk-go-v2/credentials v1.17.67
github.com/aws/aws-sdk-go-v2/service/iam v1.42.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.3
github.com/aws/smithy-go v1.22.3
github.com/bits-and-blooms/bitset v1.22.0
github.com/c-bata/go-prompt v0.2.6
@@ -19,7 +19,7 @@ require (
github.com/fsnotify/fsnotify v1.9.0
github.com/fxamacker/cbor/v2 v2.8.0
github.com/gin-gonic/gin v1.10.0
github.com/go-ldap/ldap/v3 v3.4.10
github.com/go-ldap/ldap/v3 v3.4.11
github.com/go-playground/validator/v10 v10.26.0
github.com/go-viper/mapstructure/v2 v2.2.1
github.com/google/go-github/v33 v33.0.0
@@ -32,9 +32,9 @@ require (
github.com/mattn/go-colorable v0.1.14
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.5.0
github.com/nats-io/jwt/v2 v2.7.3
github.com/nats-io/nats-server/v2 v2.11.1
github.com/nats-io/nats.go v1.41.1
github.com/nats-io/jwt/v2 v2.7.4
github.com/nats-io/nats-server/v2 v2.11.3
github.com/nats-io/nats.go v1.42.0
github.com/onsi/ginkgo/v2 v2.23.4
github.com/onsi/gomega v1.37.0
github.com/pelletier/go-toml v1.9.5
@@ -48,21 +48,21 @@ require (
github.com/spf13/viper v1.20.1
github.com/ugorji/go/codec v1.2.12
github.com/ulikunitz/xz v0.5.12
github.com/vbauerster/mpb/v8 v8.9.3
github.com/vbauerster/mpb/v8 v8.10.1
github.com/xanzy/go-gitlab v0.115.0
github.com/xhit/go-simple-mail v2.2.2+incompatible
golang.org/x/net v0.39.0
golang.org/x/oauth2 v0.29.0
golang.org/x/sync v0.13.0
golang.org/x/sys v0.32.0
golang.org/x/term v0.31.0
golang.org/x/net v0.40.0
golang.org/x/oauth2 v0.30.0
golang.org/x/sync v0.14.0
golang.org/x/sys v0.33.0
golang.org/x/term v0.32.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/clickhouse v0.6.1
gorm.io/driver/mysql v1.5.7
gorm.io/driver/postgres v1.5.11
gorm.io/driver/sqlite v1.5.7
gorm.io/driver/sqlserver v1.5.4
gorm.io/gorm v1.25.12
gorm.io/gorm v1.26.1
)
require (
@@ -85,12 +85,12 @@ require (
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.18 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.13.2 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect
@@ -98,7 +98,7 @@ require (
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.7.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
@@ -145,7 +145,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nats-io/nkeys v0.4.10 // indirect
github.com/nats-io/nkeys v0.4.11 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/paulmach/orb v0.11.1 // indirect
@@ -174,8 +174,8 @@ require (
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.16.0 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.32.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect