mirror of
https://github.com/gofiber/storage.git
synced 2025-10-04 08:16:36 +08:00
🎑 update sqlite3
This commit is contained in:
11
go.mod
11
go.mod
@@ -3,15 +3,8 @@ module github.com/gofiber/storage
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.35.19 // indirect
|
||||
github.com/go-redis/redis/v8 v8.3.3
|
||||
github.com/gofiber/fiber/v2 v2.1.2
|
||||
github.com/gofiber/utils v0.0.10
|
||||
github.com/golang/snappy v0.0.2 // indirect
|
||||
github.com/gomodule/redigo v1.8.2
|
||||
github.com/klauspost/compress v1.11.2 // indirect
|
||||
github.com/gofiber/utils v0.1.0
|
||||
github.com/mattn/go-sqlite3 v1.14.4
|
||||
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
32
go.sum
@@ -1,9 +1,6 @@
|
||||
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/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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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.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/gofiber/fiber/v2 v2.1.2 h1:b4rpt9xtj7LxT1Vp3yR76LOfs6ZzPJybbNMjjpn+fos=
|
||||
github.com/gofiber/fiber/v2 v2.1.2/go.mod h1:jMNH7iuOJ1AGdoJrx1OwaZIX7SOrQUtJi9R35QWhi4s=
|
||||
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/gofiber/utils v0.1.0 h1:NvW+7gf1CCKp1cOMxXijjYJseQt3Y0RXa8YKm65Z0fE=
|
||||
github.com/gofiber/utils v0.1.0/go.mod h1:pacRFtghAE3UoknMOUiXh2Io/nLWSUHtQCi/3QASsOc=
|
||||
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.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/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
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.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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/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.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
|
||||
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.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
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/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/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/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
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/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.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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
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/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
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-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
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-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-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-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/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
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-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-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-20180909124046-d0be0721c37e/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-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-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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
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-20190329151228-23e29df326fe/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/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.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.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
|
@@ -13,7 +13,16 @@ var ConfigDefault = Config{
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cfg.GCInterval = ConfigDefault.GCInterval
|
||||
}
|
||||
|
@@ -13,7 +13,16 @@ var ConfigDefault = Config{
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cfg.GCInterval = ConfigDefault.GCInterval
|
||||
}
|
||||
|
@@ -20,12 +20,7 @@ type entry struct {
|
||||
// New creates a new memory storage
|
||||
func New(config ...Config) *Storage {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = configDefault(config[0])
|
||||
}
|
||||
cfg := configDefault(config...)
|
||||
|
||||
// Create storage
|
||||
store := &Storage{
|
||||
|
@@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/gofiber/utils"
|
||||
)
|
||||
|
||||
func Test_Set(t *testing.T) {
|
||||
|
@@ -60,7 +60,16 @@ var ConfigDefault = Config{
|
||||
}
|
||||
|
||||
// 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 == "" {
|
||||
cfg.URI = ConfigDefault.URI
|
||||
}
|
||||
|
@@ -26,12 +26,7 @@ type MongoStorage struct {
|
||||
// New creates a new MongoDB storage
|
||||
func New(config ...Config) *Storage {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = configDefault(config[0])
|
||||
}
|
||||
cfg := configDefault(config...)
|
||||
|
||||
// Set mongo options
|
||||
opt := options.Client()
|
||||
|
@@ -13,7 +13,16 @@ var ConfigDefault = Config{
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cfg.GCInterval = ConfigDefault.GCInterval
|
||||
}
|
||||
|
@@ -12,12 +12,7 @@ type Storage struct {
|
||||
// New creates a new storage
|
||||
func New(config ...Config) *Storage {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = configDefault(config[0])
|
||||
}
|
||||
cfg := configDefault(config...)
|
||||
|
||||
// Create storage
|
||||
store := &Storage{
|
||||
|
@@ -13,7 +13,16 @@ var ConfigDefault = Config{
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cfg.GCInterval = ConfigDefault.GCInterval
|
||||
}
|
||||
|
@@ -12,12 +12,7 @@ type Storage struct {
|
||||
// New creates a new storage
|
||||
func New(config ...Config) *Storage {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = configDefault(config[0])
|
||||
}
|
||||
cfg := configDefault(config...)
|
||||
|
||||
// Create storage
|
||||
store := &Storage{
|
||||
|
@@ -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.
|
@@ -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
|
||||
}
|
@@ -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)
|
||||
}
|
||||
|
||||
}
|
@@ -108,7 +108,16 @@ var ConfigDefault = Config{
|
||||
}
|
||||
|
||||
// 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 == "" {
|
||||
cfg.Addr = ConfigDefault.Addr
|
||||
}
|
||||
|
@@ -15,12 +15,7 @@ type Storage struct {
|
||||
// New creates a new redis storage
|
||||
func New(config ...Config) *Storage {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = configDefault(config[0])
|
||||
}
|
||||
cfg := configDefault(config...)
|
||||
|
||||
// Create new redis client
|
||||
db := redis.NewClient(&redis.Options{
|
||||
|
@@ -4,20 +4,77 @@ import "time"
|
||||
|
||||
// Config defines the config for storage.
|
||||
type Config struct {
|
||||
// Time before deleting expired keys
|
||||
//
|
||||
// Default is 10 * time.Second
|
||||
GCInterval time.Duration
|
||||
|
||||
// DB file path
|
||||
//
|
||||
// Default is "./fiber.sqlite3"
|
||||
FilePath string
|
||||
|
||||
// DB table name
|
||||
//
|
||||
// Default is "fiber"
|
||||
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
|
||||
var ConfigDefault = Config{
|
||||
GCInterval: 10 * time.Second,
|
||||
FilePath: "./db.sqlite3",
|
||||
FilePath: "./fiber.sqlite3",
|
||||
TableName: "fiber",
|
||||
DropTable: false,
|
||||
MaxOpenConns: 100,
|
||||
MaxIdleConns: 100,
|
||||
ConnMaxLifetime: 1 * time.Second,
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cfg.GCInterval = ConfigDefault.GCInterval
|
||||
}
|
||||
@@ -27,5 +84,14 @@ func configDefault(cfg Config) Config {
|
||||
if cfg.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
|
||||
}
|
||||
|
@@ -2,10 +2,13 @@ package sqlite3
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/utils"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
// Storage interface that is implemented by storage providers
|
||||
@@ -13,66 +16,85 @@ type Storage struct {
|
||||
db *sql.DB
|
||||
gcInterval time.Duration
|
||||
|
||||
selectQuery string
|
||||
insertQuery string
|
||||
deleteQuery string
|
||||
clearQuery string
|
||||
gcQuery string
|
||||
sqlSelect string
|
||||
sqlInsert string
|
||||
sqlDelete string
|
||||
sqlClear string
|
||||
sqlGC string
|
||||
}
|
||||
|
||||
var (
|
||||
migrateQuery = `
|
||||
CREATE TABLE IF NOT EXISTS %s (
|
||||
id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT '',
|
||||
key TEXT NOT NULL,
|
||||
dropQuery = `DROP TABLE IF EXISTS %s;`
|
||||
initQuery = []string{
|
||||
`CREATE TABLE IF NOT EXISTS %s (
|
||||
key VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT '',
|
||||
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
|
||||
func New(config ...Config) *Storage {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// 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),
|
||||
}
|
||||
cfg := configDefault(config...)
|
||||
|
||||
// Create db
|
||||
db, err := sql.Open("sqlite3", cfg.FilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store.db = db
|
||||
|
||||
// Migrate db
|
||||
_, err = store.db.Exec(fmt.Sprintf(migrateQuery, cfg.TableName))
|
||||
if err != nil {
|
||||
// Set database options
|
||||
db.SetMaxOpenConns(cfg.MaxOpenConns)
|
||||
db.SetMaxIdleConns(cfg.MaxIdleConns)
|
||||
db.SetConnMaxLifetime(cfg.ConnMaxLifetime)
|
||||
|
||||
// Ping database
|
||||
if err := db.Ping(); err != nil {
|
||||
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
|
||||
go store.gc()
|
||||
|
||||
return store
|
||||
}
|
||||
|
||||
var noRows = errors.New("sql: no rows in result set")
|
||||
|
||||
// Get value by key
|
||||
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
|
||||
var (
|
||||
@@ -80,8 +102,11 @@ func (s *Storage) Get(key string) ([]byte, error) {
|
||||
exp int64 = 0
|
||||
)
|
||||
if err := row.Scan(&data, &exp); err != nil {
|
||||
if err != noRows {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// If the expiration time has already passed, then return nil
|
||||
if time.Now().After(time.Unix(exp, 0)) {
|
||||
@@ -93,19 +118,19 @@ func (s *Storage) Get(key string) ([]byte, error) {
|
||||
|
||||
// Set key with value
|
||||
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
|
||||
}
|
||||
|
||||
// Delete entry by key
|
||||
func (s *Storage) Delete(key string) error {
|
||||
_, err := s.db.Exec(s.deleteQuery, key)
|
||||
_, err := s.db.Exec(s.sqlDelete, key)
|
||||
return err
|
||||
}
|
||||
|
||||
// Clear all entries, including unexpired
|
||||
func (s *Storage) Clear() error {
|
||||
_, err := s.db.Exec(s.clearQuery)
|
||||
_, err := s.db.Exec(s.sqlClear)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -114,7 +139,7 @@ func (s *Storage) gc() {
|
||||
tick := time.NewTicker(s.gcInterval)
|
||||
for {
|
||||
<-tick.C
|
||||
if _, err := s.db.Exec(s.gcQuery); err != nil {
|
||||
if _, err := s.db.Exec(s.sqlGC); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@@ -4,23 +4,18 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/gofiber/utils"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func getConfig() Config {
|
||||
cfg := configDefault(Config{})
|
||||
cfg.FilePath = ":memory:"
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func Test_New(t *testing.T) {
|
||||
New()
|
||||
}
|
||||
|
||||
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))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
@@ -30,12 +25,14 @@ func Test_Get_Set(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))
|
||||
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, true, b == nil)
|
||||
}
|
||||
|
Reference in New Issue
Block a user