mirror of
https://github.com/gofiber/storage.git
synced 2025-10-05 08:37:10 +08:00
📦 update mongodb
This commit is contained in:
18
.github/README.md
vendored
18
.github/README.md
vendored
@@ -1,17 +1 @@
|
|||||||
# 📦 Storage drivers for [Fiber](https://github.com/gofiber/fiber)
|
# redis
|
||||||
|
|
||||||
Premade storage drivers that implement [`fiber.Storage`](https://github.com/gofiber/fiber/blob/ba08653c92f86bc69956b23714f919b705d9381e/app.go#L39-L50), to be used with various Fiber middlewares.
|
|
||||||
|
|
||||||
## 📑 Contents
|
|
||||||
|
|
||||||
* [In-memory](/memory)
|
|
||||||
* [Memcached](/memcached)
|
|
||||||
* [MongoDB](/mongodb)
|
|
||||||
* [MySQL](/mysql)
|
|
||||||
* [Postgres](/postgres)
|
|
||||||
* [Redis](/redis)
|
|
||||||
* [SQLite3](/sqlite3)
|
|
||||||
|
|
||||||
## 🤔 Something missing?
|
|
||||||
|
|
||||||
If you've got a custom storage driver you made that's not listed here, why not submit a [PR](https://github.com/gofiber/storage/pulls) to add it?
|
|
||||||
|
28
.github/workflows/benchmark.yml
vendored
Normal file
28
.github/workflows/benchmark.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
on: [push]
|
||||||
|
name: Benchmark
|
||||||
|
jobs:
|
||||||
|
Compare:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Install Go
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: 1.15.x
|
||||||
|
- name: Fetch Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Run Benchmark
|
||||||
|
run: set -o pipefail; go test ./... -benchmem -run=^$ -bench . | tee output.txt
|
||||||
|
- name: Get Previous Benchmark Results
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ./cache
|
||||||
|
key: ${{ runner.os }}-benchmark
|
||||||
|
- name: Save Benchmark Results
|
||||||
|
uses: rhysd/github-action-benchmark@v1
|
||||||
|
with:
|
||||||
|
tool: 'go'
|
||||||
|
output-file-path: output.txt
|
||||||
|
github-token: ${{ secrets.BENCHMARK_TOKEN }}
|
||||||
|
fail-on-alert: true
|
||||||
|
comment-on-alert: true
|
||||||
|
auto-push: true
|
54
.github/workflows/codeql-analysis.yml
vendored
Normal file
54
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master, ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [master]
|
||||||
|
schedule:
|
||||||
|
- cron: '0 3 * * 6'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyse:
|
||||||
|
name: Analyse
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
# We must fetch at least the immediate parents so that if this is
|
||||||
|
# a pull request then we can checkout the head.
|
||||||
|
fetch-depth: 2
|
||||||
|
|
||||||
|
# If this run was triggered by a pull request event, then checkout
|
||||||
|
# the head of the pull request instead of the merge commit.
|
||||||
|
- run: git checkout HEAD^2
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v1
|
||||||
|
# Override language selection by uncommenting this and choosing your languages
|
||||||
|
with:
|
||||||
|
languages: go
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v1
|
12
.github/workflows/linter.yml
vendored
Normal file
12
.github/workflows/linter.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
on: [push, pull_request]
|
||||||
|
name: Linter
|
||||||
|
jobs:
|
||||||
|
Golint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Fetch Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Run Golint
|
||||||
|
uses: reviewdog/action-golangci-lint@v1
|
||||||
|
with:
|
||||||
|
golangci_lint_flags: "--tests=false"
|
12
.github/workflows/security.yml
vendored
Normal file
12
.github/workflows/security.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
on: [push, pull_request]
|
||||||
|
name: Security
|
||||||
|
jobs:
|
||||||
|
Gosec:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Fetch Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Run Gosec
|
||||||
|
uses: securego/gosec@master
|
||||||
|
with:
|
||||||
|
args: -exclude-dir=internal/*/ ./...
|
11
.github/workflows/snyk.yml
vendored
Normal file
11
.github/workflows/snyk.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
on: [push, pull_request_target]
|
||||||
|
name: Snyk security
|
||||||
|
jobs:
|
||||||
|
security:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Run Snyk to check for vulnerabilities
|
||||||
|
uses: snyk/actions/golang@master
|
||||||
|
env:
|
||||||
|
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
18
.github/workflows/test.yml
vendored
Normal file
18
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
on: [push, pull_request]
|
||||||
|
name: Test
|
||||||
|
jobs:
|
||||||
|
Build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go-version: [1.14.x, 1.15.x]
|
||||||
|
platform: [ubuntu-latest, windows-latest]
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
steps:
|
||||||
|
- name: Install Go
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: ${{ matrix.go-version }}
|
||||||
|
- name: Fetch Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Run Test
|
||||||
|
run: go test ./... -v -race
|
184
.gitignore
vendored
184
.gitignore
vendored
@@ -1,184 +0,0 @@
|
|||||||
|
|
||||||
# Created by https://www.toptal.com/developers/gitignore/api/windows,jetbrains+all,go,linux,macos
|
|
||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,jetbrains+all,go,linux,macos
|
|
||||||
|
|
||||||
### Go ###
|
|
||||||
# Binaries for programs and plugins
|
|
||||||
*.exe
|
|
||||||
*.exe~
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
|
||||||
*.test
|
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
|
||||||
*.out
|
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
|
||||||
# vendor/
|
|
||||||
|
|
||||||
### Go Patch ###
|
|
||||||
/vendor/
|
|
||||||
/Godeps/
|
|
||||||
|
|
||||||
### JetBrains+all ###
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
# *.iml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
||||||
### JetBrains+all Patch ###
|
|
||||||
# Ignores the whole .idea folder and all .iml files
|
|
||||||
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
|
|
||||||
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
|
|
||||||
|
|
||||||
*.iml
|
|
||||||
modules.xml
|
|
||||||
.idea/misc.xml
|
|
||||||
*.ipr
|
|
||||||
|
|
||||||
# Sonarlint plugin
|
|
||||||
.idea/sonarlint
|
|
||||||
|
|
||||||
### Linux ###
|
|
||||||
*~
|
|
||||||
|
|
||||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
|
||||||
.fuse_hidden*
|
|
||||||
|
|
||||||
# KDE directory preferences
|
|
||||||
.directory
|
|
||||||
|
|
||||||
# Linux trash folder which might appear on any partition or disk
|
|
||||||
.Trash-*
|
|
||||||
|
|
||||||
# .nfs files are created when an open file is removed but is still being accessed
|
|
||||||
.nfs*
|
|
||||||
|
|
||||||
### macOS ###
|
|
||||||
# General
|
|
||||||
.DS_Store
|
|
||||||
.AppleDouble
|
|
||||||
.LSOverride
|
|
||||||
|
|
||||||
# Icon must end with two \r
|
|
||||||
Icon
|
|
||||||
|
|
||||||
|
|
||||||
# Thumbnails
|
|
||||||
._*
|
|
||||||
|
|
||||||
# Files that might appear in the root of a volume
|
|
||||||
.DocumentRevisions-V100
|
|
||||||
.fseventsd
|
|
||||||
.Spotlight-V100
|
|
||||||
.TemporaryItems
|
|
||||||
.Trashes
|
|
||||||
.VolumeIcon.icns
|
|
||||||
.com.apple.timemachine.donotpresent
|
|
||||||
|
|
||||||
# Directories potentially created on remote AFP share
|
|
||||||
.AppleDB
|
|
||||||
.AppleDesktop
|
|
||||||
Network Trash Folder
|
|
||||||
Temporary Items
|
|
||||||
.apdisk
|
|
||||||
|
|
||||||
### Windows ###
|
|
||||||
# Windows thumbnail cache files
|
|
||||||
Thumbs.db
|
|
||||||
Thumbs.db:encryptable
|
|
||||||
ehthumbs.db
|
|
||||||
ehthumbs_vista.db
|
|
||||||
|
|
||||||
# Dump file
|
|
||||||
*.stackdump
|
|
||||||
|
|
||||||
# Folder config file
|
|
||||||
[Dd]esktop.ini
|
|
||||||
|
|
||||||
# Recycle Bin used on file shares
|
|
||||||
$RECYCLE.BIN/
|
|
||||||
|
|
||||||
# Windows Installer files
|
|
||||||
*.cab
|
|
||||||
*.msi
|
|
||||||
*.msix
|
|
||||||
*.msm
|
|
||||||
*.msp
|
|
||||||
|
|
||||||
# Windows shortcuts
|
|
||||||
*.lnk
|
|
||||||
|
|
@@ -16,26 +16,26 @@ type Config struct {
|
|||||||
var ConfigDefault = Config{}
|
var ConfigDefault = Config{}
|
||||||
|
|
||||||
// New creates a new storage
|
// New creates a new storage
|
||||||
func New(config ...Config) Storage {
|
func New(config ...Config) *Storage {
|
||||||
return Storage{}
|
return &Storage{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value by key
|
// Get value by key
|
||||||
func (store *Storage) Get(key string) ([]byte, error) {
|
func (s *Storage) Get(key string) ([]byte, error) {
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set key with value
|
// Set key with value
|
||||||
func (store *Storage) Set(key string, val []byte, exp time.Duration) error {
|
func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete key by key
|
// Delete key by key
|
||||||
func (store *Storage) Delete(key string) error {
|
func (s *Storage) Delete(key string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all keys
|
// Clear all keys
|
||||||
func (store *Storage) Clear() error {
|
func (s *Storage) Clear() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
72
mongodb/config.go
Normal file
72
mongodb/config.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package mongodb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||||
|
"go.mongodb.org/mongo-driver/event"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/readconcern"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/readpref"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/writeconcern"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config defines the config for storage.
|
||||||
|
type Config struct {
|
||||||
|
// Custom options
|
||||||
|
Addr string
|
||||||
|
Database string
|
||||||
|
Collection string
|
||||||
|
|
||||||
|
// https://pkg.go.dev/go.mongodb.org/mongo-driver@v1.4.2/mongo/options#ClientOptions
|
||||||
|
AppName string
|
||||||
|
Auth options.Credential
|
||||||
|
AutoEncryptionOptions *options.AutoEncryptionOptions
|
||||||
|
ConnectTimeout time.Duration
|
||||||
|
Compressors []string
|
||||||
|
Dialer options.ContextDialer
|
||||||
|
Direct bool
|
||||||
|
DisableOCSPEndpointCheck bool
|
||||||
|
HeartbeatInterval time.Duration
|
||||||
|
Hosts []string
|
||||||
|
LocalThreshold time.Duration
|
||||||
|
MaxConnIdleTime time.Duration
|
||||||
|
MaxPoolSize uint64
|
||||||
|
MinPoolSize uint64
|
||||||
|
PoolMonitor *event.PoolMonitor
|
||||||
|
Monitor *event.CommandMonitor
|
||||||
|
ReadConcern *readconcern.ReadConcern
|
||||||
|
ReadPreference *readpref.ReadPref
|
||||||
|
Registry *bsoncodec.Registry
|
||||||
|
ReplicaSet string
|
||||||
|
RetryReads bool
|
||||||
|
RetryWrites bool
|
||||||
|
ServerSelectionTimeout time.Duration
|
||||||
|
SocketTimeout time.Duration
|
||||||
|
TLSConfig *tls.Config
|
||||||
|
WriteConcern *writeconcern.WriteConcern
|
||||||
|
ZlibLevel int
|
||||||
|
ZstdLevel int
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigDefault is the default config
|
||||||
|
var ConfigDefault = Config{
|
||||||
|
Addr: "127.0.0.1:27017",
|
||||||
|
Database: "_database",
|
||||||
|
Collection: "_storage",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to set default values
|
||||||
|
func configDefault(cfg Config) Config {
|
||||||
|
if cfg.Addr == "" {
|
||||||
|
cfg.Addr = ConfigDefault.Addr
|
||||||
|
}
|
||||||
|
if cfg.Database == "" {
|
||||||
|
cfg.Database = ConfigDefault.Database
|
||||||
|
}
|
||||||
|
if cfg.Collection == "" {
|
||||||
|
cfg.Collection = ConfigDefault.Collection
|
||||||
|
}
|
||||||
|
return cfg
|
||||||
|
}
|
@@ -2,16 +2,17 @@ package mongodb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Storage interface that is implemented by storage providers
|
// Storage interface that is implemented by storage providers
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
col *mongo.Collection
|
db *mongo.Collection
|
||||||
}
|
}
|
||||||
|
|
||||||
type MongoStorage struct {
|
type MongoStorage struct {
|
||||||
@@ -22,7 +23,55 @@ type MongoStorage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new MongoDB storage
|
// New creates a new MongoDB storage
|
||||||
func New(col *mongo.Collection) *Storage {
|
func New(config ...Config) *Storage {
|
||||||
|
// Set default config
|
||||||
|
cfg := ConfigDefault
|
||||||
|
|
||||||
|
// Override config if provided
|
||||||
|
if len(config) > 0 {
|
||||||
|
cfg = configDefault(config[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set mongo options
|
||||||
|
opt := options.Client()
|
||||||
|
opt.SetAppName(cfg.AppName)
|
||||||
|
opt.SetAuth(cfg.Auth)
|
||||||
|
opt.SetAutoEncryptionOptions(cfg.AutoEncryptionOptions)
|
||||||
|
opt.SetConnectTimeout(cfg.ConnectTimeout)
|
||||||
|
opt.SetCompressors(cfg.Compressors)
|
||||||
|
opt.SetDialer(cfg.Dialer)
|
||||||
|
opt.SetDirect(cfg.Direct)
|
||||||
|
opt.SetDisableOCSPEndpointCheck(cfg.DisableOCSPEndpointCheck)
|
||||||
|
opt.SetHeartbeatInterval(cfg.HeartbeatInterval)
|
||||||
|
opt.SetHosts(cfg.Hosts)
|
||||||
|
opt.SetLocalThreshold(cfg.LocalThreshold)
|
||||||
|
opt.SetMaxConnIdleTime(cfg.MaxConnIdleTime)
|
||||||
|
opt.SetMaxPoolSize(cfg.MaxPoolSize)
|
||||||
|
opt.SetMinPoolSize(cfg.MinPoolSize)
|
||||||
|
opt.SetPoolMonitor(cfg.PoolMonitor)
|
||||||
|
opt.SetMonitor(cfg.Monitor)
|
||||||
|
opt.SetReadConcern(cfg.ReadConcern)
|
||||||
|
opt.SetReadPreference(cfg.ReadPreference)
|
||||||
|
opt.SetRegistry(cfg.Registry)
|
||||||
|
opt.SetReplicaSet(cfg.ReplicaSet)
|
||||||
|
opt.SetRetryReads(cfg.RetryReads)
|
||||||
|
opt.SetRetryWrites(cfg.RetryWrites)
|
||||||
|
opt.SetServerSelectionTimeout(cfg.ServerSelectionTimeout)
|
||||||
|
opt.SetSocketTimeout(cfg.SocketTimeout)
|
||||||
|
opt.SetTLSConfig(cfg.TLSConfig)
|
||||||
|
opt.SetWriteConcern(cfg.WriteConcern)
|
||||||
|
opt.SetZlibLevel(cfg.ZlibLevel)
|
||||||
|
opt.SetZstdLevel(cfg.ZstdLevel)
|
||||||
|
|
||||||
|
// Create mongo client
|
||||||
|
client, err := mongo.NewClient(opt.ApplyURI("mongodb://" + cfg.Addr))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get collection from database
|
||||||
|
db := client.Database(cfg.Database).Collection(cfg.Collection)
|
||||||
|
|
||||||
// expired data may exist for some time beyond the 60 second period between runs of the background task.
|
// expired data may exist for some time beyond the 60 second period between runs of the background task.
|
||||||
// more on https://docs.mongodb.com/manual/core/index-ttl/
|
// more on https://docs.mongodb.com/manual/core/index-ttl/
|
||||||
indexModel := mongo.IndexModel{
|
indexModel := mongo.IndexModel{
|
||||||
@@ -33,18 +82,18 @@ func New(col *mongo.Collection) *Storage {
|
|||||||
Options: options.Index().SetExpireAfterSeconds(0),
|
Options: options.Index().SetExpireAfterSeconds(0),
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := col.Indexes().CreateOne(context.TODO(), indexModel); err != nil {
|
if _, err := db.Indexes().CreateOne(context.TODO(), indexModel); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Storage{
|
return &Storage{
|
||||||
col: col,
|
db: db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value by key
|
// Get value by key
|
||||||
func (s *Storage) Get(key string) ([]byte, error) {
|
func (s *Storage) Get(key string) ([]byte, error) {
|
||||||
res := s.col.FindOne(context.TODO(), bson.M{"key": key})
|
res := s.db.FindOne(context.TODO(), bson.M{"key": key})
|
||||||
result := MongoStorage{}
|
result := MongoStorage{}
|
||||||
|
|
||||||
if err := res.Err(); err != nil {
|
if err := res.Err(); err != nil {
|
||||||
@@ -68,17 +117,17 @@ func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
|
|||||||
if exp != 0 {
|
if exp != 0 {
|
||||||
replace.Exp = time.Now().Add(exp).UTC()
|
replace.Exp = time.Now().Add(exp).UTC()
|
||||||
}
|
}
|
||||||
_, err := s.col.ReplaceOne(context.TODO(), filter, replace, options.Replace().SetUpsert(true))
|
_, err := s.db.ReplaceOne(context.TODO(), filter, replace, options.Replace().SetUpsert(true))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete document by key
|
// Delete document by key
|
||||||
func (s *Storage) Delete(key string) error {
|
func (s *Storage) Delete(key string) error {
|
||||||
_, err := s.col.DeleteOne(context.TODO(), bson.M{"key": key})
|
_, err := s.db.DeleteOne(context.TODO(), bson.M{"key": key})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all keys by drop collection
|
// Clear all keys by drop collection
|
||||||
func (s *Storage) Clear() error {
|
func (s *Storage) Clear() error {
|
||||||
return s.col.Drop(context.TODO())
|
return s.db.Drop(context.TODO())
|
||||||
}
|
}
|
||||||
|
@@ -16,26 +16,26 @@ type Config struct {
|
|||||||
var ConfigDefault = Config{}
|
var ConfigDefault = Config{}
|
||||||
|
|
||||||
// New creates a new storage
|
// New creates a new storage
|
||||||
func New(config ...Config) Storage {
|
func New(config ...Config) *Storage {
|
||||||
return Storage{}
|
return &Storage{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value by key
|
// Get value by key
|
||||||
func (store *Storage) Get(key string) ([]byte, error) {
|
func (s *Storage) Get(key string) ([]byte, error) {
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set key with value
|
// Set key with value
|
||||||
func (store *Storage) Set(key string, val []byte, exp time.Duration) error {
|
func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete key by key
|
// Delete key by key
|
||||||
func (store *Storage) Delete(key string) error {
|
func (s *Storage) Delete(key string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all keys
|
// Clear all keys
|
||||||
func (store *Storage) Clear() error {
|
func (s *Storage) Clear() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -16,26 +16,26 @@ type Config struct {
|
|||||||
var ConfigDefault = Config{}
|
var ConfigDefault = Config{}
|
||||||
|
|
||||||
// New creates a new storage
|
// New creates a new storage
|
||||||
func New(config ...Config) Storage {
|
func New(config ...Config) *Storage {
|
||||||
return Storage{}
|
return &Storage{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value by key
|
// Get value by key
|
||||||
func (store *Storage) Get(key string) ([]byte, error) {
|
func (s *Storage) Get(key string) ([]byte, error) {
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set key with value
|
// Set key with value
|
||||||
func (store *Storage) Set(key string, val []byte, exp time.Duration) error {
|
func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete key by key
|
// Delete key by key
|
||||||
func (store *Storage) Delete(key string) error {
|
func (s *Storage) Delete(key string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all keys
|
// Clear all keys
|
||||||
func (store *Storage) Clear() error {
|
func (s *Storage) Clear() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
# redis
|
|
@@ -11,6 +11,10 @@ import (
|
|||||||
|
|
||||||
// Config defines the config for redis storage.
|
// Config defines the config for redis storage.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
// Custom options
|
||||||
|
|
||||||
|
// https://pkg.go.dev/github.com/go-redis/redis/v8#Options
|
||||||
|
|
||||||
// The network type, either tcp or unix.
|
// The network type, either tcp or unix.
|
||||||
// Default is tcp.
|
// Default is tcp.
|
||||||
Network string
|
Network string
|
||||||
@@ -40,9 +44,11 @@ type Config struct {
|
|||||||
// Maximum number of retries before giving up.
|
// Maximum number of retries before giving up.
|
||||||
// Default is 3 retries.
|
// Default is 3 retries.
|
||||||
MaxRetries int
|
MaxRetries int
|
||||||
|
|
||||||
// Minimum backoff between each retry.
|
// Minimum backoff between each retry.
|
||||||
// Default is 8 milliseconds; -1 disables backoff.
|
// Default is 8 milliseconds; -1 disables backoff.
|
||||||
MinRetryBackoff time.Duration
|
MinRetryBackoff time.Duration
|
||||||
|
|
||||||
// Maximum backoff between each retry.
|
// Maximum backoff between each retry.
|
||||||
// Default is 512 milliseconds; -1 disables backoff.
|
// Default is 512 milliseconds; -1 disables backoff.
|
||||||
MaxRetryBackoff time.Duration
|
MaxRetryBackoff time.Duration
|
||||||
@@ -50,10 +56,12 @@ type Config struct {
|
|||||||
// Dial timeout for establishing new connections.
|
// Dial timeout for establishing new connections.
|
||||||
// Default is 5 seconds.
|
// Default is 5 seconds.
|
||||||
DialTimeout time.Duration
|
DialTimeout time.Duration
|
||||||
|
|
||||||
// Timeout for socket reads. If reached, commands will fail
|
// Timeout for socket reads. If reached, commands will fail
|
||||||
// with a timeout instead of blocking. Use value -1 for no timeout and 0 for default.
|
// with a timeout instead of blocking. Use value -1 for no timeout and 0 for default.
|
||||||
// Default is 3 seconds.
|
// Default is 3 seconds.
|
||||||
ReadTimeout time.Duration
|
ReadTimeout time.Duration
|
||||||
|
|
||||||
// Timeout for socket writes. If reached, commands will fail
|
// Timeout for socket writes. If reached, commands will fail
|
||||||
// with a timeout instead of blocking.
|
// with a timeout instead of blocking.
|
||||||
// Default is ReadTimeout.
|
// Default is ReadTimeout.
|
||||||
@@ -62,20 +70,25 @@ type Config struct {
|
|||||||
// Maximum number of socket connections.
|
// Maximum number of socket connections.
|
||||||
// Default is 10 connections per every CPU as reported by runtime.NumCPU.
|
// Default is 10 connections per every CPU as reported by runtime.NumCPU.
|
||||||
PoolSize int
|
PoolSize int
|
||||||
|
|
||||||
// Minimum number of idle connections which is useful when establishing
|
// Minimum number of idle connections which is useful when establishing
|
||||||
// new connection is slow.
|
// new connection is slow.
|
||||||
MinIdleConns int
|
MinIdleConns int
|
||||||
|
|
||||||
// Connection age at which client retires (closes) the connection.
|
// Connection age at which client retires (closes) the connection.
|
||||||
// Default is to not close aged connections.
|
// Default is to not close aged connections.
|
||||||
MaxConnAge time.Duration
|
MaxConnAge time.Duration
|
||||||
|
|
||||||
// Amount of time client waits for connection if all connections
|
// Amount of time client waits for connection if all connections
|
||||||
// are busy before returning an error.
|
// are busy before returning an error.
|
||||||
// Default is ReadTimeout + 1 second.
|
// Default is ReadTimeout + 1 second.
|
||||||
PoolTimeout time.Duration
|
PoolTimeout time.Duration
|
||||||
|
|
||||||
// Amount of time after which client closes idle connections.
|
// Amount of time after which client closes idle connections.
|
||||||
// Should be less than server's timeout.
|
// Should be less than server's timeout.
|
||||||
// Default is 5 minutes. -1 disables idle timeout check.
|
// Default is 5 minutes. -1 disables idle timeout check.
|
||||||
IdleTimeout time.Duration
|
IdleTimeout time.Duration
|
||||||
|
|
||||||
// Frequency of idle checks made by idle connections reaper.
|
// Frequency of idle checks made by idle connections reaper.
|
||||||
// Default is 1 minute. -1 disables idle connections reaper,
|
// Default is 1 minute. -1 disables idle connections reaper,
|
||||||
// but idle connections are still discarded by the client
|
// but idle connections are still discarded by the client
|
||||||
|
@@ -13,7 +13,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
|
||||||
|
|
||||||
@@ -52,14 +52,14 @@ func New(config ...Config) Storage {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
// Create new store
|
// Create new store
|
||||||
return Storage{
|
return &Storage{
|
||||||
db: db,
|
db: db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value by key
|
// Get value by key
|
||||||
func (store *Storage) Get(key string) ([]byte, error) {
|
func (s *Storage) Get(key string) ([]byte, error) {
|
||||||
val, err := store.db.Get(context.Background(), key).Bytes()
|
val, err := s.db.Get(context.Background(), key).Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != redis.Nil {
|
if err != redis.Nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -70,16 +70,16 @@ func (store *Storage) Get(key string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set key with value
|
// Set key with value
|
||||||
func (store *Storage) Set(key string, val []byte, exp time.Duration) error {
|
func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
|
||||||
return store.db.Set(context.Background(), key, val, exp).Err()
|
return s.db.Set(context.Background(), key, val, exp).Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete key by key
|
// Delete key by key
|
||||||
func (store *Storage) Delete(key string) error {
|
func (s *Storage) Delete(key string) error {
|
||||||
return store.db.Del(context.Background(), key).Err()
|
return s.db.Del(context.Background(), key).Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all keys
|
// Clear all keys
|
||||||
func (store *Storage) Clear() error {
|
func (s *Storage) Clear() error {
|
||||||
return store.db.FlushDB(context.Background()).Err()
|
return s.db.FlushDB(context.Background()).Err()
|
||||||
}
|
}
|
||||||
|
@@ -16,26 +16,26 @@ type Config struct {
|
|||||||
var ConfigDefault = Config{}
|
var ConfigDefault = Config{}
|
||||||
|
|
||||||
// New creates a new storage
|
// New creates a new storage
|
||||||
func New(config ...Config) Storage {
|
func New(config ...Config) *Storage {
|
||||||
return Storage{}
|
return &Storage{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get value by key
|
// Get value by key
|
||||||
func (store *Storage) Get(key string) ([]byte, error) {
|
func (s *Storage) Get(key string) ([]byte, error) {
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set key with value
|
// Set key with value
|
||||||
func (store *Storage) Set(key string, val []byte, exp time.Duration) error {
|
func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete key by key
|
// Delete key by key
|
||||||
func (store *Storage) Delete(key string) error {
|
func (s *Storage) Delete(key string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all keys
|
// Clear all keys
|
||||||
func (store *Storage) Clear() error {
|
func (s *Storage) Clear() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user