From 48eb99e68fed260b0522f613af2689ba7ef3fa0d Mon Sep 17 00:00:00 2001 From: Florent Messa Date: Thu, 29 Dec 2022 16:02:50 +0100 Subject: [PATCH 1/2] ref: upgrade to latest go-redis --- go.mod | 6 +- go.sum | 116 +++++++++++++++++++++++++----- kvstores.go | 33 ++++----- kvstores_test.go | 62 ++++++++-------- memory.go | 55 ++++++++------- redis.go | 180 +++++++++++++++++++++++------------------------ redis_test.go | 8 ++- 7 files changed, 272 insertions(+), 188 deletions(-) diff --git a/go.mod b/go.mod index 013b2f5..6424004 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,7 @@ module github.com/ulule/gokvstores go 1.13 require ( - github.com/onsi/ginkgo v1.10.1 // indirect - github.com/onsi/gomega v1.7.0 // indirect + github.com/go-redis/redis/v8 v8.11.5 github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/stretchr/testify v1.4.0 - gopkg.in/redis.v5 v5.2.9 + github.com/stretchr/testify v1.5.1 ) diff --git a/go.sum b/go.sum index 11eafd4..383ee05 100644 --- a/go.sum +++ b/go.sum @@ -1,39 +1,117 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/redis.v5 v5.2.9 h1:MNZYOLPomQzZMfpN3ZtD1uyJ2IDonTTlxYiV/pEApiw= -gopkg.in/redis.v5 v5.2.9/go.mod h1:6gtv0/+A4iM08kdRfocWYB3bLX2tebpNtfKlFT6H4mY= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/kvstores.go b/kvstores.go index bc92ed4..218575b 100644 --- a/kvstores.go +++ b/kvstores.go @@ -1,6 +1,7 @@ package gokvstores import ( + "context" "sort" "time" ) @@ -8,53 +9,53 @@ import ( // KVStore is the KV store interface. type KVStore interface { // Get returns value for the given key. - Get(key string) (interface{}, error) + Get(ctx context.Context, key string) (interface{}, error) // MGet returns map of key, value for a list of keys. - MGet(keys []string) (map[string]interface{}, error) + MGet(ctx context.Context, keys []string) (map[string]interface{}, error) // Set sets value for the given key. - Set(key string, value interface{}) error + Set(ctx context.Context, key string, value interface{}) error // SetWithExpiration sets the value for the given key for a specified duration. - SetWithExpiration(key string, value interface{}, expiration time.Duration) error + SetWithExpiration(ctx context.Context, key string, value interface{}, expiration time.Duration) error // GetMap returns map for the given key. - GetMap(key string) (map[string]interface{}, error) + GetMap(ctx context.Context, key string) (map[string]interface{}, error) // GetMaps returns maps for the given keys. - GetMaps(keys []string) (map[string]map[string]interface{}, error) + GetMaps(ctx context.Context, keys []string) (map[string]map[string]interface{}, error) // SetMap sets map for the given key. - SetMap(key string, value map[string]interface{}) error + SetMap(ctx context.Context, key string, value map[string]interface{}) error // SetMaps sets the given maps. - SetMaps(maps map[string]map[string]interface{}) error + SetMaps(ctx context.Context, maps map[string]map[string]interface{}) error // DeleteMap removes the specified fields from the map stored at key. - DeleteMap(key string, fields ...string) error + DeleteMap(ctx context.Context, key string, fields ...string) error // GetSlice returns slice for the given key. - GetSlice(key string) ([]interface{}, error) + GetSlice(ctx context.Context, key string) ([]interface{}, error) // SetSlice sets slice for the given key. - SetSlice(key string, value []interface{}) error + SetSlice(ctx context.Context, key string, value []interface{}) error // AppendSlice appends values to an existing slice. // If key does not exist, creates slice. - AppendSlice(key string, values ...interface{}) error + AppendSlice(ctx context.Context, key string, values ...interface{}) error // Exists checks if the given key exists. - Exists(key string) (bool, error) + Exists(ctx context.Context, keys ...string) (bool, error) // Delete deletes the given key. - Delete(key string) error + Delete(ctx context.Context, key string) error // Flush flushes the store. - Flush() error + Flush(ctx context.Context) error // Return all keys matching pattern - Keys(pattern string) ([]interface{}, error) + Keys(ctx context.Context, pattern string) ([]interface{}, error) // Close closes the connection to the store. Close() error diff --git a/kvstores_test.go b/kvstores_test.go index 26ecf47..b6358e2 100644 --- a/kvstores_test.go +++ b/kvstores_test.go @@ -1,6 +1,7 @@ package gokvstores import ( + "context" "sort" "testing" "time" @@ -10,8 +11,9 @@ import ( func testStore(t *testing.T, store KVStore) { is := assert.New(t) + ctx := context.Background() - err := store.Flush() + err := store.Flush(ctx) is.NoError(err) itemResults := map[string]interface{}{ @@ -23,18 +25,18 @@ func testStore(t *testing.T, store KVStore) { for key, expected := range itemResults { // Set - err = store.Set(key, expected) + err = store.Set(ctx, key, expected) is.NoError(err) // Get - v, err := store.Get(key) + v, err := store.Get(ctx, key) is.NoError(err) val, ok := v.(string) is.True(ok) is.Equal(expected, val) - exists, err := store.Exists(key) + exists, err := store.Exists(ctx, key) is.NoError(err) is.True(exists) @@ -42,7 +44,7 @@ func testStore(t *testing.T, store KVStore) { keys := []string{"key1", "key2", "key3"} - mResults, err := store.MGet(keys) + mResults, err := store.MGet(ctx, keys) for key, result := range mResults { val, ok := result.(string) @@ -53,13 +55,13 @@ func testStore(t *testing.T, store KVStore) { for key := range itemResults { // Delete - err = store.Delete(key) + err = store.Delete(ctx, key) is.NoError(err) - v, _ := store.Get(key) + v, _ := store.Get(ctx, key) is.Nil(v) - exists, err := store.Exists(key) + exists, err := store.Exists(ctx, key) is.NoError(err) is.False(exists) } @@ -73,18 +75,18 @@ func testStore(t *testing.T, store KVStore) { } for key, expected := range mapResults { - err = store.SetMap(key, expected) + err = store.SetMap(ctx, key, expected) is.NoError(err) - v, err := store.GetMap(key) + v, err := store.GetMap(ctx, key) is.Equal(expected, v) - exists, err := store.Exists(key) + exists, err := store.Exists(ctx, key) is.NoError(err) is.True(exists) } - results, err := store.GetMaps(keys) + results, err := store.GetMaps(ctx, keys) is.NoError(err) for key, result := range results { @@ -92,23 +94,23 @@ func testStore(t *testing.T, store KVStore) { } for key := range mapResults { - err = store.Delete(key) + err = store.Delete(ctx, key) is.NoError(err) - v, _ := store.GetMap(key) + v, _ := store.GetMap(ctx, key) is.Nil(v) - exists, err := store.Exists(key) + exists, err := store.Exists(ctx, key) is.NoError(err) is.False(exists) } - is.NoError(store.SetMaps(mapResults)) - results, err = store.GetMaps(keys) + is.NoError(store.SetMaps(ctx, mapResults)) + results, err = store.GetMaps(ctx, keys) is.NoError(err) for key, result := range results { is.Equal(result, mapResults[key]) - is.NoError(store.Delete(key)) + is.NoError(store.Delete(ctx, key)) } // Slices @@ -120,26 +122,26 @@ func testStore(t *testing.T, store KVStore) { } for key, expected := range sliceResults { - err = store.SetSlice(key, expected) + err = store.SetSlice(ctx, key, expected) is.NoError(err) expectedStrings, err := stringSlice(expected) is.NoError(err) - v, err := store.GetSlice(key) + v, err := store.GetSlice(ctx, key) is.NoError(err) strings, err := stringSlice(v) is.NoError(err) is.Equal(expectedStrings, strings) - exists, err := store.Exists(key) + exists, err := store.Exists(ctx, key) is.NoError(err) is.True(exists) - err = store.AppendSlice(key, "append1", "append2") + err = store.AppendSlice(ctx, key, "append1", "append2") is.NoError(err) - v, err = store.GetSlice(key) + v, err = store.GetSlice(ctx, key) is.NoError(err) expectedStrings = append(expectedStrings, []string{"append1", "append2"}...) @@ -148,13 +150,13 @@ func testStore(t *testing.T, store KVStore) { is.NoError(err) is.Equal(expectedStrings, values) - err = store.Delete(key) + err = store.Delete(ctx, key) is.NoError(err) - v, _ = store.GetSlice(key) + v, _ = store.GetSlice(ctx, key) is.Nil(v) - exists, err = store.Exists(key) + exists, err = store.Exists(ctx, key) is.NoError(err) is.False(exists) @@ -162,10 +164,10 @@ func testStore(t *testing.T, store KVStore) { // Test set with duration expiration := 1 - err = store.SetWithExpiration("foo", "bar", time.Duration(expiration)*time.Second) + err = store.SetWithExpiration(ctx, "foo", "bar", time.Duration(expiration)*time.Second) is.NoError(err) - v, err := store.Get("foo") + v, err := store.Get(ctx, "foo") is.NoError(err) val, ok := v.(string) is.True(ok) @@ -173,10 +175,10 @@ func testStore(t *testing.T, store KVStore) { time.Sleep(time.Duration(expiration) * time.Second) - v, _ = store.Get("foo") + v, _ = store.Get(ctx, "foo") is.Nil(v) - exists, err := store.Exists("foo") + exists, err := store.Exists(ctx, "foo") is.NoError(err) is.False(exists) diff --git a/memory.go b/memory.go index e714767..2a04408 100644 --- a/memory.go +++ b/memory.go @@ -1,6 +1,7 @@ package gokvstores import ( + "context" "time" "github.com/patrickmn/go-cache" @@ -14,35 +15,35 @@ type MemoryStore struct { } // Get returns item from the cache. -func (c *MemoryStore) Get(key string) (interface{}, error) { +func (c *MemoryStore) Get(ctx context.Context, key string) (interface{}, error) { item, _ := c.cache.Get(key) return item, nil } // MGet returns map of key, value for a list of keys. -func (c *MemoryStore) MGet(keys []string) (map[string]interface{}, error) { +func (c *MemoryStore) MGet(ctx context.Context, keys []string) (map[string]interface{}, error) { results := make(map[string]interface{}, len(keys)) for _, key := range keys { - item, _ := c.Get(key) + item, _ := c.Get(ctx, key) results[key] = item } return results, nil } // Set sets value in the cache. -func (c *MemoryStore) Set(key string, value interface{}) error { +func (c *MemoryStore) Set(ctx context.Context, key string, value interface{}) error { c.cache.Set(key, value, c.expiration) return nil } // SetWithExpiration sets the value for the given key for a specified duration. -func (c *MemoryStore) SetWithExpiration(key string, value interface{}, expiration time.Duration) error { +func (c *MemoryStore) SetWithExpiration(ctx context.Context, key string, value interface{}, expiration time.Duration) error { c.cache.Set(key, value, expiration) return nil } // GetMap returns map for the given key. -func (c *MemoryStore) GetMap(key string) (map[string]interface{}, error) { +func (c *MemoryStore) GetMap(ctx context.Context, key string) (map[string]interface{}, error) { if v, found := c.cache.Get(key); found { return v.(map[string]interface{}), nil } @@ -50,10 +51,10 @@ func (c *MemoryStore) GetMap(key string) (map[string]interface{}, error) { } // GetMaps returns maps for the given keys. -func (c *MemoryStore) GetMaps(keys []string) (map[string]map[string]interface{}, error) { +func (c *MemoryStore) GetMaps(ctx context.Context, keys []string) (map[string]map[string]interface{}, error) { values := make(map[string]map[string]interface{}, len(keys)) for _, v := range keys { - value, _ := c.GetMap(v) + value, _ := c.GetMap(ctx, v) if value != nil { values[v] = value } @@ -63,22 +64,22 @@ func (c *MemoryStore) GetMaps(keys []string) (map[string]map[string]interface{}, } // SetMap sets a map for the given key. -func (c *MemoryStore) SetMap(key string, value map[string]interface{}) error { +func (c *MemoryStore) SetMap(ctx context.Context, key string, value map[string]interface{}) error { c.cache.Set(key, value, c.expiration) return nil } // SetMaps sets the given maps. -func (c *MemoryStore) SetMaps(maps map[string]map[string]interface{}) error { +func (c *MemoryStore) SetMaps(ctx context.Context, maps map[string]map[string]interface{}) error { for k, v := range maps { - c.SetMap(k, v) + c.SetMap(ctx, k, v) } return nil } // DeleteMap removes the specified fields from the map stored at key. -func (c *MemoryStore) DeleteMap(key string, fields ...string) error { - m, err := c.GetMap(key) +func (c *MemoryStore) DeleteMap(ctx context.Context, key string, fields ...string) error { + m, err := c.GetMap(ctx, key) if err != nil { return err } @@ -87,11 +88,11 @@ func (c *MemoryStore) DeleteMap(key string, fields ...string) error { delete(m, field) } - return c.SetMap(key, m) + return c.SetMap(ctx, key, m) } // GetSlice returns slice for the given key. -func (c *MemoryStore) GetSlice(key string) ([]interface{}, error) { +func (c *MemoryStore) GetSlice(ctx context.Context, key string) ([]interface{}, error) { if v, found := c.cache.Get(key); found { return v.([]interface{}), nil } @@ -99,20 +100,20 @@ func (c *MemoryStore) GetSlice(key string) ([]interface{}, error) { } // SetSlice sets slice for the given key. -func (c *MemoryStore) SetSlice(key string, value []interface{}) error { +func (c *MemoryStore) SetSlice(ctx context.Context, key string, value []interface{}) error { c.cache.Set(key, value, c.expiration) return nil } // AppendSlice appends values to the given slice. -func (c *MemoryStore) AppendSlice(key string, values ...interface{}) error { - items, err := c.GetSlice(key) +func (c *MemoryStore) AppendSlice(ctx context.Context, key string, values ...interface{}) error { + items, err := c.GetSlice(ctx, key) if err != nil { return err } if items == nil { - return c.SetSlice(key, values) + return c.SetSlice(ctx, key, values) } for _, item := range values { @@ -128,28 +129,30 @@ func (c *MemoryStore) Close() error { } // Flush removes all items from the cache. -func (c *MemoryStore) Flush() error { +func (c *MemoryStore) Flush(ctx context.Context) error { c.cache.Flush() return nil } // Delete deletes the given key. -func (c *MemoryStore) Delete(key string) error { +func (c *MemoryStore) Delete(ctx context.Context, key string) error { c.cache.Delete(key) return nil } // Keys returns all keys matching pattern -func (c *MemoryStore) Keys(pattern string) ([]interface{}, error) { +func (c *MemoryStore) Keys(ctx context.Context, pattern string) ([]interface{}, error) { return nil, nil } // Exists checks if the given key exists. -func (c *MemoryStore) Exists(key string) (bool, error) { - if _, exists := c.cache.Get(key); exists { - return true, nil +func (c *MemoryStore) Exists(ctx context.Context, keys ...string) (bool, error) { + for i := range keys { + if _, exists := c.cache.Get(keys[i]); !exists { + return false, nil + } } - return false, nil + return true, nil } // NewMemoryStore returns in-memory KVStore. diff --git a/redis.go b/redis.go index d316c6f..9b1ed49 100644 --- a/redis.go +++ b/redis.go @@ -1,11 +1,12 @@ package gokvstores import ( + "context" "fmt" "net" "time" - redis "gopkg.in/redis.v5" + redis "github.com/go-redis/redis/v8" ) // ---------------------------------------------------------------------------- @@ -14,34 +15,34 @@ import ( // RedisClient is an interface thats allows to use Redis cluster or a redis single client seamlessly. type RedisClient interface { - Ping() *redis.StatusCmd - Exists(key string) *redis.BoolCmd - Del(keys ...string) *redis.IntCmd - FlushDb() *redis.StatusCmd + Ping(ctx context.Context) *redis.StatusCmd + Exists(ctx context.Context, keys ...string) *redis.IntCmd + Del(ctx context.Context, keys ...string) *redis.IntCmd + FlushDB(ctx context.Context) *redis.StatusCmd Close() error - Process(cmd redis.Cmder) error - Get(key string) *redis.StringCmd - Set(key string, value interface{}, expiration time.Duration) *redis.StatusCmd - MGet(keys ...string) *redis.SliceCmd - HDel(key string, fields ...string) *redis.IntCmd - HGetAll(key string) *redis.StringStringMapCmd - HMSet(key string, fields map[string]string) *redis.StatusCmd - SMembers(key string) *redis.StringSliceCmd - SAdd(key string, members ...interface{}) *redis.IntCmd - Keys(pattern string) *redis.StringSliceCmd - Pipeline() *redis.Pipeline + Process(ctx context.Context, cmd redis.Cmder) error + Get(ctx context.Context, key string) *redis.StringCmd + Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd + MGet(ctx context.Context, keys ...string) *redis.SliceCmd + HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd + HGetAll(ctx context.Context, key string) *redis.StringStringMapCmd + HMSet(ctx context.Context, key string, values ...interface{}) *redis.BoolCmd + SMembers(ctx context.Context, key string) *redis.StringSliceCmd + SAdd(ctx context.Context, key string, members ...interface{}) *redis.IntCmd + Keys(ctx context.Context, pattern string) *redis.StringSliceCmd + Pipeline() redis.Pipeliner } // RedisPipeline is a struct which contains an opend redis pipeline transaction type RedisPipeline struct { - pipeline *redis.Pipeline + pipeline redis.Pipeliner } // RedisClientOptions are Redis client options. type RedisClientOptions struct { Network string Addr string - Dialer func() (net.Conn, error) + Dialer func(ctx context.Context, network string, addr string) (net.Conn, error) Password string DB int MaxRetries int @@ -82,10 +83,10 @@ type RedisStore struct { } // Get returns value for the given key. -func (r *RedisStore) Get(key string) (interface{}, error) { - cmd := redis.NewCmd("get", key) +func (r *RedisStore) Get(ctx context.Context, key string) (interface{}, error) { + cmd := redis.NewCmd(ctx, "get", key) - if err := r.client.Process(cmd); err != nil { + if err := r.client.Process(ctx, cmd); err != nil { if err == redis.Nil { return nil, nil } @@ -97,8 +98,8 @@ func (r *RedisStore) Get(key string) (interface{}, error) { } // MGet returns map of key, value for a list of keys. -func (r *RedisStore) MGet(keys []string) (map[string]interface{}, error) { - values, err := r.client.MGet(keys...).Result() +func (r *RedisStore) MGet(ctx context.Context, keys []string) (map[string]interface{}, error) { + values, err := r.client.MGet(ctx, keys...).Result() newValues := make(map[string]interface{}, len(keys)) @@ -114,18 +115,18 @@ func (r *RedisStore) MGet(keys []string) (map[string]interface{}, error) { } // Set sets the value for the given key. -func (r *RedisStore) Set(key string, value interface{}) error { - return r.client.Set(key, value, r.expiration).Err() +func (r *RedisStore) Set(ctx context.Context, key string, value interface{}) error { + return r.client.Set(ctx, key, value, r.expiration).Err() } // SetWithExpiration sets the value for the given key. -func (r *RedisStore) SetWithExpiration(key string, value interface{}, expiration time.Duration) error { - return r.client.Set(key, value, expiration).Err() +func (r *RedisStore) SetWithExpiration(ctx context.Context, key string, value interface{}, expiration time.Duration) error { + return r.client.Set(ctx, key, value, expiration).Err() } // GetMap returns map for the given key. -func (r *RedisStore) GetMap(key string) (map[string]interface{}, error) { - values, err := r.client.HGetAll(key).Result() +func (r *RedisStore) GetMap(ctx context.Context, key string) (map[string]interface{}, error) { + values, err := r.client.HGetAll(ctx, key).Result() if err != nil { return nil, err } @@ -143,7 +144,7 @@ func (r *RedisStore) GetMap(key string) (map[string]interface{}, error) { } // SetMap sets map for the given key. -func (r *RedisStore) SetMap(key string, values map[string]interface{}) error { +func (r *RedisStore) SetMap(ctx context.Context, key string, values map[string]interface{}) error { newValues := make(map[string]string, len(values)) for k, v := range values { @@ -155,17 +156,17 @@ func (r *RedisStore) SetMap(key string, values map[string]interface{}) error { } } - return r.client.HMSet(key, newValues).Err() + return r.client.HMSet(ctx, key, newValues).Err() } // DeleteMap removes the specified fields from the map stored at key. -func (r *RedisStore) DeleteMap(key string, fields ...string) error { - return r.client.HDel(key, fields...).Err() +func (r *RedisStore) DeleteMap(ctx context.Context, key string, fields ...string) error { + return r.client.HDel(ctx, key, fields...).Err() } // GetSlice returns slice for the given key. -func (r *RedisStore) GetSlice(key string) ([]interface{}, error) { - values, err := r.client.SMembers(key).Result() +func (r *RedisStore) GetSlice(ctx context.Context, key string) ([]interface{}, error) { + values, err := r.client.SMembers(ctx, key).Result() if err != nil { return nil, err } @@ -183,10 +184,10 @@ func (r *RedisStore) GetSlice(key string) ([]interface{}, error) { } // SetSlice sets map for the given key. -func (r *RedisStore) SetSlice(key string, values []interface{}) error { +func (r *RedisStore) SetSlice(ctx context.Context, key string, values []interface{}) error { for _, v := range values { if v != nil { - if err := r.client.SAdd(key, v).Err(); err != nil { + if err := r.client.SAdd(ctx, key, v).Err(); err != nil { return err } } @@ -196,24 +197,24 @@ func (r *RedisStore) SetSlice(key string, values []interface{}) error { } // AppendSlice appends values to the given slice. -func (r *RedisStore) AppendSlice(key string, values ...interface{}) error { - return r.SetSlice(key, values) +func (r *RedisStore) AppendSlice(ctx context.Context, key string, values ...interface{}) error { + return r.SetSlice(ctx, key, values) } // Exists checks key existence. -func (r *RedisStore) Exists(key string) (bool, error) { - cmd := r.client.Exists(key) - return cmd.Val(), cmd.Err() +func (r *RedisStore) Exists(ctx context.Context, keys ...string) (bool, error) { + cmd := r.client.Exists(ctx, keys...) + return cmd.Val() > 0, cmd.Err() } // Delete deletes key. -func (r *RedisStore) Delete(key string) error { - return r.client.Del(key).Err() +func (r *RedisStore) Delete(ctx context.Context, key string) error { + return r.client.Del(ctx, key).Err() } // Keys returns all keys matching pattern. -func (r *RedisStore) Keys(pattern string) ([]interface{}, error) { - values, err := r.client.Keys(pattern).Result() +func (r *RedisStore) Keys(ctx context.Context, pattern string) ([]interface{}, error) { + values, err := r.client.Keys(ctx, pattern).Result() if len(values) == 0 { return nil, err @@ -229,8 +230,8 @@ func (r *RedisStore) Keys(pattern string) ([]interface{}, error) { } // Flush flushes the current database. -func (r *RedisStore) Flush() error { - return r.client.FlushDb().Err() +func (r *RedisStore) Flush(ctx context.Context) error { + return r.client.FlushDB(ctx).Err() } // Close closes the client connection. @@ -239,7 +240,7 @@ func (r *RedisStore) Close() error { } // NewRedisClientStore returns Redis client instance of KVStore. -func NewRedisClientStore(options *RedisClientOptions, expiration time.Duration) (KVStore, error) { +func NewRedisClientStore(ctx context.Context, options *RedisClientOptions, expiration time.Duration) (KVStore, error) { opts := &redis.Options{ Network: options.Network, Addr: options.Addr, @@ -254,12 +255,11 @@ func NewRedisClientStore(options *RedisClientOptions, expiration time.Duration) PoolTimeout: options.PoolTimeout, IdleTimeout: options.IdleTimeout, IdleCheckFrequency: options.IdleCheckFrequency, - ReadOnly: options.ReadOnly, } client := redis.NewClient(opts) - if err := client.Ping().Err(); err != nil { + if err := client.Ping(ctx).Err(); err != nil { return nil, err } @@ -270,7 +270,7 @@ func NewRedisClientStore(options *RedisClientOptions, expiration time.Duration) } // NewRedisClusterStore returns Redis cluster client instance of KVStore. -func NewRedisClusterStore(options *RedisClusterOptions, expiration time.Duration) (KVStore, error) { +func NewRedisClusterStore(ctx context.Context, options *RedisClusterOptions, expiration time.Duration) (KVStore, error) { opts := &redis.ClusterOptions{ Addrs: options.Addrs, MaxRedirects: options.MaxRedirects, @@ -288,7 +288,7 @@ func NewRedisClusterStore(options *RedisClusterOptions, expiration time.Duration client := redis.NewClusterClient(opts) - if err := client.Ping().Err(); err != nil { + if err := client.Ping(ctx).Err(); err != nil { return nil, err } @@ -299,7 +299,7 @@ func NewRedisClusterStore(options *RedisClusterOptions, expiration time.Duration } // Pipeline uses pipeline as a Redis client to execute multiple calls at once -func (r *RedisStore) Pipeline(f func(r *RedisStore) error) ([]redis.Cmder, error) { +func (r *RedisStore) Pipeline(ctx context.Context, f func(r *RedisStore) error) ([]redis.Cmder, error) { pipe := r.client.Pipeline() redisPipeline := RedisPipeline{ @@ -316,15 +316,15 @@ func (r *RedisStore) Pipeline(f func(r *RedisStore) error) ([]redis.Cmder, error return nil, err } - cmds, err := pipe.Exec() + cmds, err := pipe.Exec(ctx) return cmds, err } // GetMaps returns maps for the given keys. -func (r *RedisStore) GetMaps(keys []string) (map[string]map[string]interface{}, error) { - commands, err := r.Pipeline(func(r *RedisStore) error { +func (r *RedisStore) GetMaps(ctx context.Context, keys []string) (map[string]map[string]interface{}, error) { + commands, err := r.Pipeline(ctx, func(r *RedisStore) error { for _, key := range keys { - r.client.HGetAll(key) + r.client.HGetAll(ctx, key) } return nil @@ -354,10 +354,10 @@ func (r *RedisStore) GetMaps(keys []string) (map[string]map[string]interface{}, } // SetMaps sets the given maps. -func (r *RedisStore) SetMaps(maps map[string]map[string]interface{}) error { - _, err := r.Pipeline(func(r *RedisStore) error { +func (r *RedisStore) SetMaps(ctx context.Context, maps map[string]map[string]interface{}) error { + _, err := r.Pipeline(ctx, func(r *RedisStore) error { for k, v := range maps { - r.SetMap(k, v) + r.SetMap(ctx, k, v) } return nil @@ -366,28 +366,28 @@ func (r *RedisStore) SetMaps(maps map[string]map[string]interface{}) error { } // Pipeline returns Redis pipeline -func (r RedisPipeline) Pipeline() *redis.Pipeline { +func (r RedisPipeline) Pipeline() redis.Pipeliner { return r.pipeline } // Ping implements RedisClient Ping for pipeline -func (r RedisPipeline) Ping() *redis.StatusCmd { - return r.pipeline.Ping() +func (r RedisPipeline) Ping(ctx context.Context) *redis.StatusCmd { + return r.pipeline.Ping(ctx) } // Exists implements RedisClient Exists for pipeline -func (r RedisPipeline) Exists(key string) *redis.BoolCmd { - return r.pipeline.Exists(key) +func (r RedisPipeline) Exists(ctx context.Context, keys ...string) *redis.IntCmd { + return r.pipeline.Exists(ctx, keys...) } // Del implements RedisClient Del for pipeline -func (r RedisPipeline) Del(keys ...string) *redis.IntCmd { - return r.pipeline.Del(keys...) +func (r RedisPipeline) Del(ctx context.Context, keys ...string) *redis.IntCmd { + return r.pipeline.Del(ctx, keys...) } // FlushDb implements RedisClient FlushDb for pipeline -func (r RedisPipeline) FlushDb() *redis.StatusCmd { - return r.pipeline.FlushDb() +func (r RedisPipeline) FlushDB(ctx context.Context) *redis.StatusCmd { + return r.pipeline.FlushDB(ctx) } // Close implements RedisClient Close for pipeline @@ -396,51 +396,51 @@ func (r RedisPipeline) Close() error { } // Process implements RedisClient Process for pipeline -func (r RedisPipeline) Process(cmd redis.Cmder) error { - return r.pipeline.Process(cmd) +func (r RedisPipeline) Process(ctx context.Context, cmd redis.Cmder) error { + return r.pipeline.Process(ctx, cmd) } // Get implements RedisClient Get for pipeline -func (r RedisPipeline) Get(key string) *redis.StringCmd { - return r.pipeline.Get(key) +func (r RedisPipeline) Get(ctx context.Context, key string) *redis.StringCmd { + return r.pipeline.Get(ctx, key) } // MGet implements RedisClient MGet for pipeline -func (r RedisPipeline) MGet(keys ...string) *redis.SliceCmd { - return r.pipeline.MGet(keys...) +func (r RedisPipeline) MGet(ctx context.Context, keys ...string) *redis.SliceCmd { + return r.pipeline.MGet(ctx, keys...) } // Set implements RedisClient Set for pipeline -func (r RedisPipeline) Set(key string, value interface{}, expiration time.Duration) *redis.StatusCmd { - return r.pipeline.Set(key, value, expiration) +func (r RedisPipeline) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd { + return r.pipeline.Set(ctx, key, value, expiration) } // HDel implements RedisClient HDel for pipeline -func (r RedisPipeline) HDel(key string, fields ...string) *redis.IntCmd { - return r.pipeline.HDel(key, fields...) +func (r RedisPipeline) HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd { + return r.pipeline.HDel(ctx, key, fields...) } // HGetAll implements RedisClient HGetAll for pipeline -func (r RedisPipeline) HGetAll(key string) *redis.StringStringMapCmd { - return r.pipeline.HGetAll(key) +func (r RedisPipeline) HGetAll(ctx context.Context, key string) *redis.StringStringMapCmd { + return r.pipeline.HGetAll(ctx, key) } // HMSet implements RedisClient HMSet for pipeline -func (r RedisPipeline) HMSet(key string, fields map[string]string) *redis.StatusCmd { - return r.pipeline.HMSet(key, fields) +func (r RedisPipeline) HMSet(ctx context.Context, key string, values ...interface{}) *redis.BoolCmd { + return r.pipeline.HMSet(ctx, key, values...) } // SMembers implements RedisClient SMembers for pipeline -func (r RedisPipeline) SMembers(key string) *redis.StringSliceCmd { - return r.pipeline.SMembers(key) +func (r RedisPipeline) SMembers(ctx context.Context, key string) *redis.StringSliceCmd { + return r.pipeline.SMembers(ctx, key) } // SAdd implements RedisClient SAdd for pipeline -func (r RedisPipeline) SAdd(key string, members ...interface{}) *redis.IntCmd { - return r.pipeline.SAdd(key, members...) +func (r RedisPipeline) SAdd(ctx context.Context, key string, members ...interface{}) *redis.IntCmd { + return r.pipeline.SAdd(ctx, key, members...) } // Keys implements RedisClient Keys for pipeline -func (r RedisPipeline) Keys(pattern string) *redis.StringSliceCmd { - return r.pipeline.Keys(pattern) +func (r RedisPipeline) Keys(ctx context.Context, pattern string) *redis.StringSliceCmd { + return r.pipeline.Keys(ctx, pattern) } diff --git a/redis_test.go b/redis_test.go index dcae9da..dc32cf4 100644 --- a/redis_test.go +++ b/redis_test.go @@ -1,6 +1,7 @@ package gokvstores import ( + "context" "sort" "testing" "time" @@ -9,7 +10,8 @@ import ( ) func TestRedisStore(t *testing.T) { - store, err := NewRedisClientStore(&RedisClientOptions{ + ctx := context.Background() + store, err := NewRedisClientStore(ctx, &RedisClientOptions{ Addr: "localhost:6379", Password: "", DB: 0, @@ -29,11 +31,11 @@ func TestRedisStore(t *testing.T) { expectedStrings := []string{"order1", "order2", "order3"} for key, expected := range mapResults { - err = store.SetMap(key, expected) + err = store.SetMap(ctx, key, expected) is.NoError(err) } - values, err := store.Keys("order*") + values, err := store.Keys(ctx, "order*") is.NoError(err) sort.Strings(expectedStrings) From 3bd12fb72ebe66299f3d7e954abcc1c751b8f54b Mon Sep 17 00:00:00 2001 From: Florent Messa Date: Thu, 29 Dec 2022 16:11:09 +0100 Subject: [PATCH 2/2] fix: compatibility for DummyStore --- dummy.go | 41 ++++++++++++++++++++++++----------------- memory.go | 2 ++ redis.go | 2 ++ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/dummy.go b/dummy.go index 934902e..ac5bf81 100644 --- a/dummy.go +++ b/dummy.go @@ -1,84 +1,89 @@ package gokvstores -import "time" +import ( + "context" + "time" +) // DummyStore is a noop store (caching disabled). type DummyStore struct{} // Get returns value for the given key. -func (DummyStore) Get(key string) (interface{}, error) { +func (DummyStore) Get(ctx context.Context, key string) (interface{}, error) { return nil, nil } // MGet returns map of key, value for a list of keys. -func (DummyStore) MGet(keys []string) (map[string]interface{}, error) { +func (DummyStore) MGet(ctx context.Context, keys []string) (map[string]interface{}, error) { return nil, nil } // Set sets value for the given key. -func (DummyStore) Set(key string, value interface{}) error { +func (DummyStore) Set(ctx context.Context, key string, value interface{}) error { return nil } // SetWithExpiration sets the value for the given key for a specified duration. -func (DummyStore) SetWithExpiration(key string, value interface{}, expiration time.Duration) error { +func (DummyStore) SetWithExpiration(ctx context.Context, key string, value interface{}, expiration time.Duration) error { return nil } // GetMap returns map for the given key. -func (DummyStore) GetMap(key string) (map[string]interface{}, error) { +func (DummyStore) GetMap(ctx context.Context, key string) (map[string]interface{}, error) { return nil, nil } // GetMaps returns maps for the given keys. -func (DummyStore) GetMaps(keys []string) (map[string]map[string]interface{}, error) { +func (DummyStore) GetMaps(ctx context.Context, keys []string) (map[string]map[string]interface{}, error) { return nil, nil } // SetMap sets map for the given key. -func (DummyStore) SetMap(key string, value map[string]interface{}) error { +func (DummyStore) SetMap(ctx context.Context, key string, value map[string]interface{}) error { return nil } // SetMaps sets the given maps. -func (DummyStore) SetMaps(maps map[string]map[string]interface{}) error { return nil } +func (DummyStore) SetMaps(ctx context.Context, maps map[string]map[string]interface{}) error { + return nil +} // DeleteMap removes the specified fields from the map stored at key. -func (DummyStore) DeleteMap(key string, fields ...string) error { return nil } +func (DummyStore) DeleteMap(ctx context.Context, key string, fields ...string) error { return nil } // GetSlice returns slice for the given key. -func (DummyStore) GetSlice(key string) ([]interface{}, error) { +func (DummyStore) GetSlice(ctx context.Context, key string) ([]interface{}, error) { return nil, nil } // SetSlice sets slice for the given key. -func (DummyStore) SetSlice(key string, value []interface{}) error { +func (DummyStore) SetSlice(ctx context.Context, key string, value []interface{}) error { return nil } // AppendSlice appends values to an existing slice. // If key does not exist, creates slice. -func (DummyStore) AppendSlice(key string, values ...interface{}) error { +func (DummyStore) AppendSlice(ctx context.Context, key string, values ...interface{}) error { return nil } // Exists checks if the given key exists. -func (DummyStore) Exists(key string) (bool, error) { +func (DummyStore) Exists(ctx context.Context, keys ...string) (bool, error) { return false, nil } // Delete deletes the given key. -func (DummyStore) Delete(key string) error { +func (DummyStore) Delete(ctx context.Context, key string) error { return nil } // Keys returns all keys matching pattern -func (DummyStore) Keys(pattern string) ([]interface{}, error) { +func (DummyStore) Keys(ctx context.Context, pattern string) ([]interface{}, error) { return nil, nil } // Flush flushes the store. -func (DummyStore) Flush() error { +func (DummyStore) Flush(ctx context.Context) error { return nil } @@ -86,3 +91,5 @@ func (DummyStore) Flush() error { func (DummyStore) Close() error { return nil } + +var _ KVStore = &DummyStore{} diff --git a/memory.go b/memory.go index 2a04408..8687f49 100644 --- a/memory.go +++ b/memory.go @@ -163,3 +163,5 @@ func NewMemoryStore(expiration time.Duration, cleanupInterval time.Duration) (KV cleanupInterval: cleanupInterval, }, nil } + +var _ KVStore = &MemoryStore{} diff --git a/redis.go b/redis.go index 9b1ed49..35f34ad 100644 --- a/redis.go +++ b/redis.go @@ -444,3 +444,5 @@ func (r RedisPipeline) SAdd(ctx context.Context, key string, members ...interfac func (r RedisPipeline) Keys(ctx context.Context, pattern string) *redis.StringSliceCmd { return r.pipeline.Keys(ctx, pattern) } + +var _ KVStore = &RedisStore{}