🎑 update sqlite3

This commit is contained in:
Fenny
2020-11-01 10:52:23 +01:00
parent a7ba88a576
commit 127aa2a67d
20 changed files with 216 additions and 457 deletions

11
go.mod
View File

@@ -3,15 +3,8 @@ module github.com/gofiber/storage
go 1.14 go 1.14
require ( require (
github.com/aws/aws-sdk-go v1.35.19 // indirect
github.com/go-redis/redis/v8 v8.3.3 github.com/go-redis/redis/v8 v8.3.3
github.com/gofiber/fiber/v2 v2.1.2 github.com/gofiber/utils v0.1.0
github.com/gofiber/utils v0.0.10 github.com/mattn/go-sqlite3 v1.14.4
github.com/golang/snappy v0.0.2 // indirect
github.com/gomodule/redigo v1.8.2
github.com/klauspost/compress v1.11.2 // indirect
go.mongodb.org/mongo-driver v1.4.2 go.mongodb.org/mongo-driver v1.4.2
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect
golang.org/x/text v0.3.4 // indirect
) )

32
go.sum
View File

@@ -1,9 +1,6 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk= github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aws/aws-sdk-go v1.35.19 h1:vdIqQnOIqTNtvnOdt9r3Bf/FiCJ7KV/7O2BIj4TPx2w=
github.com/aws/aws-sdk-go v1.35.19/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
@@ -44,10 +41,8 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
github.com/gofiber/fiber/v2 v2.1.2 h1:b4rpt9xtj7LxT1Vp3yR76LOfs6ZzPJybbNMjjpn+fos= github.com/gofiber/utils v0.1.0 h1:NvW+7gf1CCKp1cOMxXijjYJseQt3Y0RXa8YKm65Z0fE=
github.com/gofiber/fiber/v2 v2.1.2/go.mod h1:jMNH7iuOJ1AGdoJrx1OwaZIX7SOrQUtJi9R35QWhi4s= github.com/gofiber/utils v0.1.0/go.mod h1:pacRFtghAE3UoknMOUiXh2Io/nLWSUHtQCi/3QASsOc=
github.com/gofiber/utils v0.0.10 h1:3Mr7X7JdCUo7CWf/i5sajSaDmArEDtti8bM1JUVso2U=
github.com/gofiber/utils v0.0.10/go.mod h1:9J5aHFUIjq0XfknT4+hdSMG6/jzfaAgCu4HEbWDeBlo=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 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.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@@ -58,10 +53,6 @@ github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 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.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.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -78,9 +69,8 @@ github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaR
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M= github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M=
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ=
github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@@ -90,6 +80,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/mattn/go-sqlite3 v1.14.4 h1:4rQjbDxdu9fSgI/r3KN72G3c2goxknAqHHgPWWs8UlI=
github.com/mattn/go-sqlite3 v1.14.4/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
@@ -120,15 +112,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
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/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo=
@@ -143,14 +130,11 @@ golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaE
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/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-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -159,8 +143,6 @@ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -174,7 +156,6 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 h1:/DtoiOYKoQCcIFXQjz07RnWNPRCbqmSXSpgEzhC9ZHM= golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 h1:/DtoiOYKoQCcIFXQjz07RnWNPRCbqmSXSpgEzhC9ZHM=
@@ -183,8 +164,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -206,7 +185,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= 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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
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.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=

View File

@@ -13,7 +13,16 @@ var ConfigDefault = Config{
} }
// Helper function to set default values // Helper function to set default values
func configDefault(cfg Config) Config { func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}
// Override default config
cfg := config[0]
// Set default values
if int(cfg.GCInterval) == 0 { if int(cfg.GCInterval) == 0 {
cfg.GCInterval = ConfigDefault.GCInterval cfg.GCInterval = ConfigDefault.GCInterval
} }

View File

@@ -13,7 +13,16 @@ var ConfigDefault = Config{
} }
// Helper function to set default values // Helper function to set default values
func configDefault(cfg Config) Config { func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}
// Override default config
cfg := config[0]
// Set default values
if int(cfg.GCInterval) == 0 { if int(cfg.GCInterval) == 0 {
cfg.GCInterval = ConfigDefault.GCInterval cfg.GCInterval = ConfigDefault.GCInterval
} }

View File

@@ -20,12 +20,7 @@ type entry struct {
// New creates a new memory storage // New creates a new memory storage
func New(config ...Config) *Storage { func New(config ...Config) *Storage {
// Set default config // Set default config
cfg := ConfigDefault cfg := configDefault(config...)
// Override config if provided
if len(config) > 0 {
cfg = configDefault(config[0])
}
// Create storage // Create storage
store := &Storage{ store := &Storage{

View File

@@ -4,7 +4,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/gofiber/fiber/v2/utils" "github.com/gofiber/utils"
) )
func Test_Set(t *testing.T) { func Test_Set(t *testing.T) {

View File

@@ -60,7 +60,16 @@ var ConfigDefault = Config{
} }
// Helper function to set default values // Helper function to set default values
func configDefault(cfg Config) Config { func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}
// Override default config
cfg := config[0]
// Set default values
if cfg.URI == "" { if cfg.URI == "" {
cfg.URI = ConfigDefault.URI cfg.URI = ConfigDefault.URI
} }

View File

@@ -26,12 +26,7 @@ type MongoStorage struct {
// New creates a new MongoDB storage // New creates a new MongoDB storage
func New(config ...Config) *Storage { func New(config ...Config) *Storage {
// Set default config // Set default config
cfg := ConfigDefault cfg := configDefault(config...)
// Override config if provided
if len(config) > 0 {
cfg = configDefault(config[0])
}
// Set mongo options // Set mongo options
opt := options.Client() opt := options.Client()

View File

@@ -13,7 +13,16 @@ var ConfigDefault = Config{
} }
// Helper function to set default values // Helper function to set default values
func configDefault(cfg Config) Config { func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}
// Override default config
cfg := config[0]
// Set default values
if int(cfg.GCInterval) == 0 { if int(cfg.GCInterval) == 0 {
cfg.GCInterval = ConfigDefault.GCInterval cfg.GCInterval = ConfigDefault.GCInterval
} }

View File

@@ -12,12 +12,7 @@ type Storage struct {
// New creates a new storage // New creates a new storage
func New(config ...Config) *Storage { func New(config ...Config) *Storage {
// Set default config // Set default config
cfg := ConfigDefault cfg := configDefault(config...)
// Override config if provided
if len(config) > 0 {
cfg = configDefault(config[0])
}
// Create storage // Create storage
store := &Storage{ store := &Storage{

View File

@@ -13,7 +13,16 @@ var ConfigDefault = Config{
} }
// Helper function to set default values // Helper function to set default values
func configDefault(cfg Config) Config { func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}
// Override default config
cfg := config[0]
// Set default values
if int(cfg.GCInterval) == 0 { if int(cfg.GCInterval) == 0 {
cfg.GCInterval = ConfigDefault.GCInterval cfg.GCInterval = ConfigDefault.GCInterval
} }

View File

@@ -12,12 +12,7 @@ type Storage struct {
// New creates a new storage // New creates a new storage
func New(config ...Config) *Storage { func New(config ...Config) *Storage {
// Set default config // Set default config
cfg := ConfigDefault cfg := configDefault(config...)
// Override config if provided
if len(config) > 0 {
cfg = configDefault(config[0])
}
// Create storage // Create storage
store := &Storage{ store := &Storage{

View File

@@ -1,20 +0,0 @@
# Redigo
A Redis storage driver using [gomodule/redigo](https://github.com/gomodule/redigo).
### Creation
To create a new instance of the Redis store, you must provide a dial function (which is used to create a new Redis pool) and a root Redis key to be used.
```go
// import "github.com/gomodule/redigo/redis"
store := redisStore.New(func() (redis.Conn, error) {
return redis.Dial("tcp", "127.0.0.1:6379")
}, "myRedisKey")
```
In this example, we're connectiong to a Redis server at `127.0.0.1:6379`, and prefixing all keys with `myRedisKey:`.
### Running tests/benchmarks
Tests and benchmarks for this package require a running Redis server, and assume you have one at `127.0.0.1:6379`. If needed, the dial function and/or address can be changed in the `getConn` and `redisLocation` variables, respectively.

View File

@@ -1,98 +0,0 @@
package redigo
import (
"time"
"github.com/gomodule/redigo/redis"
)
func New(dialFunc func() (redis.Conn, error), redisKey string) *RedisStore {
return &RedisStore{
connPool: redis.NewPool(dialFunc, 3),
redisKey: redisKey,
}
}
type RedisStore struct {
connPool *redis.Pool
redisKey string
}
func (rs RedisStore) Get(id string) ([]byte, error) {
redisConn := rs.connPool.Get()
defer redisConn.Close()
key := rs.redisKey + ":" + id
exists, err := redis.Bool(redisConn.Do("EXISTS", key))
if err != nil {
return nil, err
}
if !exists {
return nil, nil
}
return redis.Bytes(redisConn.Do("GET", key))
}
func (rs RedisStore) Set(id string, val []byte, expiration time.Duration) error {
redisConn := rs.connPool.Get()
defer redisConn.Close()
key := rs.redisKey + ":" + id
var err error
if expiration != 0 {
_, err = redisConn.Do("SET", key, val, "EX", expiration.Seconds())
} else {
_, err = redisConn.Do("SET", key, val)
}
return err
}
func (rs RedisStore) Clear() error {
redisConn := rs.connPool.Get()
defer redisConn.Close()
// The KEYS Redis command must NOT be used because of performance issues at high volumes.
// Instead, we use SCAN with a pattern and then delete each key individually using pipelining.
// Get all keys to delete.
pattern := rs.redisKey + ":*"
rresp, err := redis.MultiBulk(redisConn.Do("SCAN", "0", "MATCH", pattern))
if err != nil {
return err
}
keysToRemove, err := redis.Strings(rresp[1], err)
if err != nil {
return err
}
// Delete those keys through pipelining
for i, key := range keysToRemove {
// Flush every 5000 commands
if i%5000 == 0 {
err := redisConn.Flush()
if err != nil {
return err
}
}
_ = redisConn.Send("DEL", key)
}
// One final flush to send any remaining commands
return redisConn.Flush()
}
func (rs RedisStore) Delete(id string) error {
redisConn := rs.connPool.Get()
defer redisConn.Close()
key := rs.redisKey + ":" + id
_, err := redisConn.Do("DEL", key)
return err
}

View File

@@ -1,211 +0,0 @@
package redigo
import (
"fmt"
"os"
"testing"
"time"
"github.com/gofiber/utils"
"github.com/gomodule/redigo/redis"
)
// The tests here assume that you have a local Redis sever running on the default port.
// The Redis address can be changed using the redisLocation variable.
var (
uri = os.Getenv("REDIGO_URI")
getConn = func() (redis.Conn, error) {
return redis.Dial("tcp", uri)
}
)
func Test_Set(t *testing.T) {
if uri == "" {
t.Skip()
}
topLevelKey := "store"
store := New(getConn, topLevelKey)
key := "aaaa"
val := []byte("This is a value")
err := store.Set(key, val, 0)
utils.AssertEqual(t, nil, err)
key = fmt.Sprintf("%s:%s", topLevelKey, key)
redisConn, err := getConn()
defer redisConn.Close()
utils.AssertEqual(t, nil, err)
exists, err := redis.Bool(redisConn.Do("EXISTS", key))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, exists)
output, err := redis.Bytes(redisConn.Do("GET", key))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, val, output)
}
func Test_SetExpiry(t *testing.T) {
if uri == "" {
t.Skip()
}
topLevelKey := "store"
store := New(getConn, topLevelKey)
key := "aaaa"
val := []byte("This is a value")
expiry := time.Second * 60
err := store.Set(key, val, expiry)
utils.AssertEqual(t, nil, err)
key = fmt.Sprintf("%s:%s", topLevelKey, key)
redisConn, err := getConn()
defer redisConn.Close()
utils.AssertEqual(t, nil, err)
exists, err := redis.Bool(redisConn.Do("EXISTS", key))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, exists)
ttl, err := redis.Int64(redisConn.Do("TTL", key))
utils.AssertEqual(t, nil, err)
upperBound := int64(expiry.Seconds())
lowerBound := upperBound - 5
if !(ttl <= upperBound && ttl > lowerBound) {
t.Fatalf("Test_SetExpiry: expiry out of bounds (is %d, must be %d<x<=%d)", ttl, lowerBound, upperBound)
}
}
func Test_Get(t *testing.T) {
if uri == "" {
t.Skip()
}
topLevelKey := "store"
store := New(getConn, topLevelKey)
key := "aaaa"
val := []byte("This is a value")
redisConn, err := getConn()
defer redisConn.Close()
utils.AssertEqual(t, nil, err)
_, err = redisConn.Do("SET", fmt.Sprintf("%s:%s", topLevelKey, key), val)
utils.AssertEqual(t, nil, err)
output, err := store.Get(key)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, val, output)
}
func Test_Delete(t *testing.T) {
if uri == "" {
t.Skip()
}
topLevelKey := "store"
store := New(getConn, topLevelKey)
key := "aaaa"
formedKey := fmt.Sprintf("%s:%s", topLevelKey, key)
val := []byte("This is a value")
redisConn, err := getConn()
defer redisConn.Close()
utils.AssertEqual(t, nil, err)
_, err = redisConn.Do("SET", formedKey, val)
utils.AssertEqual(t, nil, err)
err = store.Delete(key)
utils.AssertEqual(t, nil, err)
exists, err := redis.Bool(redisConn.Do("EXISTS", formedKey))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, false, exists)
}
func Test_Clear(t *testing.T) {
if uri == "" {
t.Skip()
}
topLevelKey := "store"
store := New(getConn, topLevelKey)
key1 := "aaaa"
key2 := "bbbb"
formedKey1 := fmt.Sprintf("%s:%s", topLevelKey, key1)
formedKey2 := fmt.Sprintf("%s:%s", topLevelKey, key2)
val := []byte("This is a value")
redisConn, err := getConn()
defer redisConn.Close()
utils.AssertEqual(t, nil, err)
_, err = redisConn.Do("SET", formedKey1, val)
utils.AssertEqual(t, nil, err)
_, err = redisConn.Do("SET", formedKey2, val)
utils.AssertEqual(t, nil, err)
err = store.Clear()
utils.AssertEqual(t, nil, err)
exists, err := redis.Bool(redisConn.Do("EXISTS", formedKey1))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, false, exists)
exists, err = redis.Bool(redisConn.Do("EXISTS", formedKey2))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, false, exists)
}
func Benchmark_Set(b *testing.B) {
if uri == "" {
b.Skip()
}
topLevelKey := "store"
store := New(getConn, topLevelKey)
key := "aaaa"
val := []byte("This is a value")
expiry := time.Second * 60
b.ResetTimer()
for n := 0; n < b.N; n++ {
store.Set(key, val, expiry)
}
}
func Benchmark_Get(b *testing.B) {
if uri == "" {
b.Skip()
}
topLevelKey := "store"
store := New(getConn, topLevelKey)
key := "aaaa"
val := []byte("This is a value")
store.Set(key, val, 0)
b.ResetTimer()
for n := 0; n < b.N; n++ {
store.Get(key)
}
}

View File

@@ -108,7 +108,16 @@ var ConfigDefault = Config{
} }
// Helper function to set default values // Helper function to set default values
func configDefault(cfg Config) Config { func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}
// Override default config
cfg := config[0]
// Set default values
if cfg.Addr == "" { if cfg.Addr == "" {
cfg.Addr = ConfigDefault.Addr cfg.Addr = ConfigDefault.Addr
} }

View File

@@ -15,12 +15,7 @@ type Storage struct {
// New creates a new redis storage // New creates a new redis storage
func New(config ...Config) *Storage { func New(config ...Config) *Storage {
// Set default config // Set default config
cfg := ConfigDefault cfg := configDefault(config...)
// Override config if provided
if len(config) > 0 {
cfg = configDefault(config[0])
}
// Create new redis client // Create new redis client
db := redis.NewClient(&redis.Options{ db := redis.NewClient(&redis.Options{

View File

@@ -4,20 +4,77 @@ import "time"
// Config defines the config for storage. // Config defines the config for storage.
type Config struct { type Config struct {
// Time before deleting expired keys
//
// Default is 10 * time.Second
GCInterval time.Duration GCInterval time.Duration
// DB file path
//
// Default is "./fiber.sqlite3"
FilePath string FilePath string
// DB table name
//
// Default is "fiber"
TableName string TableName string
// When set to true, this will Drop any existing table with the same name
DropTable bool
// The maximum number of connections in the idle connection pool.
//
// If MaxOpenConns is greater than 0 but less than the new MaxIdleConns,
// then the new MaxIdleConns will be reduced to match the MaxOpenConns limit.
//
// If n < 0, no idle connections are retained.
//
// The default is 100.
MaxIdleConns int
// The maximum number of open connections to the database.
//
// If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than
// MaxIdleConns, then MaxIdleConns will be reduced to match the new
// MaxOpenConns limit.
//
// If n < 0, then there is no limit on the number of open connections.
//
// The default is 100.
MaxOpenConns int
// The maximum amount of time a connection may be reused.
//
// Expired connections may be closed lazily before reuse.
//
// If d < 0, connections are reused forever.
//
// The default is 1 * time.Second
ConnMaxLifetime time.Duration
} }
// ConfigDefault is the default config // ConfigDefault is the default config
var ConfigDefault = Config{ var ConfigDefault = Config{
GCInterval: 10 * time.Second, GCInterval: 10 * time.Second,
FilePath: "./db.sqlite3", FilePath: "./fiber.sqlite3",
TableName: "fiber", TableName: "fiber",
DropTable: false,
MaxOpenConns: 100,
MaxIdleConns: 100,
ConnMaxLifetime: 1 * time.Second,
} }
// Helper function to set default values // Helper function to set default values
func configDefault(cfg Config) Config { func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}
// Override default config
cfg := config[0]
// Set default values
if int(cfg.GCInterval) == 0 { if int(cfg.GCInterval) == 0 {
cfg.GCInterval = ConfigDefault.GCInterval cfg.GCInterval = ConfigDefault.GCInterval
} }
@@ -27,5 +84,14 @@ func configDefault(cfg Config) Config {
if cfg.TableName == "" { if cfg.TableName == "" {
cfg.TableName = ConfigDefault.TableName cfg.TableName = ConfigDefault.TableName
} }
if cfg.MaxOpenConns == 0 {
cfg.MaxOpenConns = ConfigDefault.MaxOpenConns
}
if cfg.MaxIdleConns == 0 {
cfg.MaxIdleConns = ConfigDefault.MaxIdleConns
}
if int(cfg.ConnMaxLifetime) == 0 {
cfg.ConnMaxLifetime = ConfigDefault.ConnMaxLifetime
}
return cfg return cfg
} }

View File

@@ -2,10 +2,13 @@ package sqlite3
import ( import (
"database/sql" "database/sql"
"errors"
"fmt" "fmt"
"time" "time"
"github.com/gofiber/utils" "github.com/gofiber/utils"
_ "github.com/mattn/go-sqlite3"
) )
// Storage interface that is implemented by storage providers // Storage interface that is implemented by storage providers
@@ -13,66 +16,85 @@ type Storage struct {
db *sql.DB db *sql.DB
gcInterval time.Duration gcInterval time.Duration
selectQuery string sqlSelect string
insertQuery string sqlInsert string
deleteQuery string sqlDelete string
clearQuery string sqlClear string
gcQuery string sqlGC string
} }
var ( var (
migrateQuery = ` dropQuery = `DROP TABLE IF EXISTS %s;`
CREATE TABLE IF NOT EXISTS %s ( initQuery = []string{
id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT '', `CREATE TABLE IF NOT EXISTS %s (
key TEXT NOT NULL, key VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT '',
data TEXT NOT NULL, data TEXT NOT NULL,
exp BIGINT NOT NULL exp BIGINT NOT NULL DEFAULT '0'
); );`,
` `CREATE INDEX IF NOT EXISTS exp ON %s (exp);`,
}
) )
// New creates a new storage // New creates a new storage
func New(config ...Config) *Storage { func New(config ...Config) *Storage {
// Set default config // Set default config
cfg := ConfigDefault cfg := configDefault(config...)
// Override config if provided
if len(config) > 0 {
cfg = configDefault(config[0])
}
// Create storage
store := &Storage{
gcInterval: cfg.GCInterval,
selectQuery: fmt.Sprintf(`SELECT data, exp FROM %s WHERE key=?;`, cfg.TableName),
insertQuery: fmt.Sprintf("INSERT INTO %s (key, data, exp) VALUES (?,?,?)", cfg.TableName),
deleteQuery: fmt.Sprintf("DELETE FROM %s WHERE key=?", cfg.TableName),
clearQuery: fmt.Sprintf("DELETE FROM %s;", cfg.TableName),
gcQuery: fmt.Sprintf("DELETE FROM %s WHERE exp <= ?", cfg.TableName),
}
// Create db // Create db
db, err := sql.Open("sqlite3", cfg.FilePath) db, err := sql.Open("sqlite3", cfg.FilePath)
if err != nil { if err != nil {
panic(err) panic(err)
} }
store.db = db
// Migrate db // Set database options
_, err = store.db.Exec(fmt.Sprintf(migrateQuery, cfg.TableName)) db.SetMaxOpenConns(cfg.MaxOpenConns)
if err != nil { db.SetMaxIdleConns(cfg.MaxIdleConns)
db.SetConnMaxLifetime(cfg.ConnMaxLifetime)
// Ping database
if err := db.Ping(); err != nil {
panic(err) panic(err)
} }
// Drop table if set to true
if cfg.DropTable {
if _, err = db.Exec(fmt.Sprintf(dropQuery, cfg.TableName)); err != nil {
_ = db.Close()
panic(err)
}
}
// Init database queries
for _, query := range initQuery {
if _, err := db.Exec(fmt.Sprintf(query, cfg.TableName)); err != nil {
_ = db.Close()
fmt.Println(fmt.Sprintf(query, cfg.TableName))
panic(err)
}
}
// Create storage
store := &Storage{
db: db,
gcInterval: cfg.GCInterval,
sqlSelect: fmt.Sprintf(`SELECT data, exp FROM %s WHERE key=?;`, cfg.TableName),
sqlInsert: fmt.Sprintf("INSERT INTO %s (key, data, exp) VALUES (?,?,?)", cfg.TableName),
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE key=?", cfg.TableName),
sqlClear: fmt.Sprintf("DELETE FROM %s;", cfg.TableName),
sqlGC: fmt.Sprintf("DELETE FROM %s WHERE exp <= ?", cfg.TableName),
}
// Start garbage collector // Start garbage collector
go store.gc() go store.gc()
return store return store
} }
var noRows = errors.New("sql: no rows in result set")
// Get value by key // Get value by key
func (s *Storage) Get(key string) ([]byte, error) { func (s *Storage) Get(key string) ([]byte, error) {
row := s.db.QueryRow(s.selectQuery, key) row := s.db.QueryRow(s.sqlSelect, key)
// Add db response to data // Add db response to data
var ( var (
@@ -80,8 +102,11 @@ func (s *Storage) Get(key string) ([]byte, error) {
exp int64 = 0 exp int64 = 0
) )
if err := row.Scan(&data, &exp); err != nil { if err := row.Scan(&data, &exp); err != nil {
if err != noRows {
return nil, err return nil, err
} }
return nil, nil
}
// If the expiration time has already passed, then return nil // If the expiration time has already passed, then return nil
if time.Now().After(time.Unix(exp, 0)) { if time.Now().After(time.Unix(exp, 0)) {
@@ -93,19 +118,19 @@ func (s *Storage) Get(key string) ([]byte, error) {
// Set key with value // Set key with value
func (s *Storage) Set(key string, val []byte, exp time.Duration) error { func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
_, err := s.db.Exec(s.insertQuery, key, utils.GetString(val), time.Now().Add(exp).Unix()) _, err := s.db.Exec(s.sqlInsert, key, utils.GetString(val), time.Now().Add(exp).Unix())
return err return err
} }
// Delete entry by key // Delete entry by key
func (s *Storage) Delete(key string) error { func (s *Storage) Delete(key string) error {
_, err := s.db.Exec(s.deleteQuery, key) _, err := s.db.Exec(s.sqlDelete, key)
return err return err
} }
// Clear all entries, including unexpired // Clear all entries, including unexpired
func (s *Storage) Clear() error { func (s *Storage) Clear() error {
_, err := s.db.Exec(s.clearQuery) _, err := s.db.Exec(s.sqlClear)
return err return err
} }
@@ -114,7 +139,7 @@ func (s *Storage) gc() {
tick := time.NewTicker(s.gcInterval) tick := time.NewTicker(s.gcInterval)
for { for {
<-tick.C <-tick.C
if _, err := s.db.Exec(s.gcQuery); err != nil { if _, err := s.db.Exec(s.sqlGC); err != nil {
panic(err) panic(err)
} }
} }

View File

@@ -4,23 +4,18 @@ import (
"testing" "testing"
"time" "time"
"github.com/gofiber/fiber/v2/utils" "github.com/gofiber/utils"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
) )
func getConfig() Config {
cfg := configDefault(Config{})
cfg.FilePath = ":memory:"
return cfg
}
func Test_New(t *testing.T) { func Test_New(t *testing.T) {
New() New()
} }
func Test_Get_Set(t *testing.T) { func Test_Get_Set(t *testing.T) {
s := New(getConfig()) s := New(Config{
FilePath: ":memory:",
})
err := s.Set("fiber-10k-stars?", []byte("yes!"), time.Duration(time.Hour*1)) err := s.Set("fiber-10k-stars?", []byte("yes!"), time.Duration(time.Hour*1))
utils.AssertEqual(t, nil, err) utils.AssertEqual(t, nil, err)
@@ -30,12 +25,14 @@ func Test_Get_Set(t *testing.T) {
} }
func Test_Expiration(t *testing.T) { func Test_Expiration(t *testing.T) {
s := New(getConfig()) s := New(Config{
FilePath: ":memory:",
})
err := s.Set("fiber-20k-stars?", []byte("yes!"), time.Duration(time.Nanosecond/2)) err := s.Set("fiber-20k-stars?", []byte("yes!"), time.Duration(time.Nanosecond/2))
utils.AssertEqual(t, nil, err) utils.AssertEqual(t, nil, err)
b, err := s.Get("fiber-20k-stars?") b, err := s.Get("fiber-220k-stars?")
utils.AssertEqual(t, nil, err) utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, b == nil) utils.AssertEqual(t, true, b == nil)
} }