mirror of
https://github.com/gofiber/storage.git
synced 2025-09-27 04:46:08 +08:00
Compare commits
36 Commits
s3/v1.4.0
...
postgres/v
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2441f85244 | ||
![]() |
c1aaef52f7 | ||
![]() |
f07e641c06 | ||
![]() |
14d989aaab | ||
![]() |
57f18bb17e | ||
![]() |
5627741945 | ||
![]() |
dd9a30caed | ||
![]() |
478527cfe6 | ||
![]() |
94187f16f7 | ||
![]() |
155991d08b | ||
![]() |
8e7e1286be | ||
![]() |
4b273b74cb | ||
![]() |
1fc6144cc0 | ||
![]() |
90e5588e5d | ||
![]() |
c57db8ae34 | ||
![]() |
634e4f7bbb | ||
![]() |
4f9889ce48 | ||
![]() |
55e5545d5b | ||
![]() |
8922818463 | ||
![]() |
1914d5fb39 | ||
![]() |
98df5fc473 | ||
![]() |
ae951cdfcc | ||
![]() |
a567590b51 | ||
![]() |
e76d7e56b6 | ||
![]() |
6d004c4bca | ||
![]() |
bab82c9802 | ||
![]() |
73a941a879 | ||
![]() |
868c89fd7e | ||
![]() |
c050ff8e3d | ||
![]() |
1fec873770 | ||
![]() |
877dae612d | ||
![]() |
5bf7da2074 | ||
![]() |
9c850f5235 | ||
![]() |
bd837d91ab | ||
![]() |
c4e1c722b1 | ||
![]() |
85e612ec79 |
13
.github/labeler.yml
vendored
13
.github/labeler.yml
vendored
@@ -2,16 +2,19 @@ version: v1
|
||||
labels:
|
||||
- label: '📒 Documentation'
|
||||
matcher:
|
||||
title: '\b(docs|doc:|\[doc\]|README|typos|comment|documentation)\b|[📝📒📚]'
|
||||
title: '\b(docs|doc:|\[doc\]|README|typos|comment|documentation)\b'
|
||||
- label: '☢️ Bug'
|
||||
matcher:
|
||||
title: '\b(fix|race|bug|missing|correct)\b|[🐛☢🩹🚨]'
|
||||
title: '\b(fix|race|bug|missing|correct)\b'
|
||||
- label: '🧹 Updates'
|
||||
matcher:
|
||||
title: '\b(improve|update|refactor|deprecated|remove|unused|test)\b|[⚡👷🚧♻️🎨🧪🧹]'
|
||||
title: '\b(improve|update|refactor|deprecated|remove|unused|test)\b'
|
||||
- label: '🤖 Dependencies'
|
||||
matcher:
|
||||
title: '\b(bumb|bdependencies)/b|[📦🤖]'
|
||||
title: '\b(bumb|bdependencies)\b'
|
||||
- label: '✏️ Feature'
|
||||
matcher:
|
||||
title: '\b(feature|create|implement|add)\b|[🚀✨🔥]'
|
||||
title: '\b(feature|create|implement|add)\b'
|
||||
- label: '🤔 Question'
|
||||
matcher:
|
||||
title: '\b(question|how)\b'
|
||||
|
3
.github/workflows/test-postgres.yml
vendored
3
.github/workflows/test-postgres.yml
vendored
@@ -27,9 +27,8 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version:
|
||||
- 1.16.x
|
||||
- 1.18.x
|
||||
- 1.19.x
|
||||
- 1.20.x
|
||||
platform:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Postgres
|
||||
|
||||
A Postgres storage driver using [lib/pq](https://github.com/lib/pq).
|
||||
A Postgres storage driver using [jackc/pgx](https://github.com/jackc/pgx).
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
@@ -17,7 +17,7 @@ func (s *Storage) Set(key string, val []byte, exp time.Duration) error
|
||||
func (s *Storage) Delete(key string) error
|
||||
func (s *Storage) Reset() error
|
||||
func (s *Storage) Close() error
|
||||
func (s *Storage) Conn() *sql.DB
|
||||
func (s *Storage) Conn() *pgxpool.Pool
|
||||
```
|
||||
### Installation
|
||||
Postgres is tested on the 2 last [Go versions](https://golang.org/dl/) with support for modules. So make sure to initialize one first if you didn't do that yet:
|
||||
@@ -26,13 +26,13 @@ go mod init github.com/<user>/<repo>
|
||||
```
|
||||
And then install the postgres implementation:
|
||||
```bash
|
||||
go get github.com/gofiber/storage/postgres
|
||||
go get github.com/gofiber/storage/postgres/v2
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the storage package.
|
||||
```go
|
||||
import "github.com/gofiber/storage/postgres"
|
||||
import "github.com/gofiber/storage/postgres/v2"
|
||||
```
|
||||
|
||||
You can use the following possibilities to create a storage:
|
||||
@@ -42,20 +42,10 @@ store := postgres.New()
|
||||
|
||||
// Initialize custom config
|
||||
store := postgres.New(postgres.Config{
|
||||
Host: "127.0.0.1",
|
||||
Port: 5432,
|
||||
Database: "fiber",
|
||||
Db: dbPool,
|
||||
Table: "fiber_storage",
|
||||
Reset: false,
|
||||
GCInterval: 10 * time.Second,
|
||||
SslMode: "disable",
|
||||
})
|
||||
|
||||
// Initialize custom config using connection string
|
||||
store := postgres.New(postgres.Config{
|
||||
ConnectionURI: "postgresql://user:password@localhost:5432/fiber"
|
||||
Reset: false,
|
||||
GCInterval: 10 * time.Second,
|
||||
})
|
||||
```
|
||||
|
||||
@@ -63,6 +53,11 @@ store := postgres.New(postgres.Config{
|
||||
```go
|
||||
// Config defines the config for storage.
|
||||
type Config struct {
|
||||
// DB pgxpool.Pool object will override connection uri and other connection fields
|
||||
//
|
||||
// Optional. Default is nil
|
||||
DB *pgxpool.Pool
|
||||
|
||||
// Connection string to use for DB. Will override all other authentication values if used
|
||||
//
|
||||
// Optional. Default is ""
|
||||
@@ -98,6 +93,11 @@ type Config struct {
|
||||
// Optional. Default is "fiber_storage"
|
||||
Table string
|
||||
|
||||
// The SSL mode for the connection
|
||||
//
|
||||
// Optional. Default is "disable"
|
||||
SSLMode string
|
||||
|
||||
// Reset clears any existing keys in existing Table
|
||||
//
|
||||
// Optional. Default is false
|
||||
@@ -107,24 +107,20 @@ type Config struct {
|
||||
//
|
||||
// Optional. Default is 10 * time.Second
|
||||
GCInterval time.Duration
|
||||
|
||||
// The SSL mode for the connection
|
||||
//
|
||||
// Optional. Default is "disable"
|
||||
SslMode string
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
ConnectionURI: "",
|
||||
Host: "127.0.0.1",
|
||||
Port: 5432,
|
||||
Database: "fiber",
|
||||
Table: "fiber_storage",
|
||||
Reset: false,
|
||||
GCInterval: 10 * time.Second,
|
||||
SslMode: "disable",
|
||||
ConnectionURI: "",
|
||||
Host: "127.0.0.1",
|
||||
Port: 5432,
|
||||
Database: "fiber",
|
||||
Table: "fiber_storage",
|
||||
SSLMode: "disable",
|
||||
Reset: false,
|
||||
GCInterval: 10 * time.Second,
|
||||
}
|
||||
```
|
||||
|
@@ -1,11 +1,21 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// Config defines the config for storage.
|
||||
type Config struct {
|
||||
// DB pgxpool.Pool object will override connection uri and other connection fields
|
||||
//
|
||||
// Optional. Default is nil
|
||||
DB *pgxpool.Pool
|
||||
|
||||
// Connection string to use for DB. Will override all other authentication values if used
|
||||
//
|
||||
// Optional. Default is ""
|
||||
@@ -44,7 +54,7 @@ type Config struct {
|
||||
// The SSL mode for the connection
|
||||
//
|
||||
// Optional. Default is "disable"
|
||||
SslMode string
|
||||
SSLMode string
|
||||
|
||||
// Reset clears any existing keys in existing Table
|
||||
//
|
||||
@@ -55,57 +65,50 @@ type Config struct {
|
||||
//
|
||||
// Optional. Default is 10 * time.Second
|
||||
GCInterval time.Duration
|
||||
|
||||
////////////////////////////////////
|
||||
// Adaptor related config options //
|
||||
////////////////////////////////////
|
||||
|
||||
// Maximum wait for connection, in seconds. Zero or
|
||||
// n < 0 means wait indefinitely.
|
||||
timeout time.Duration
|
||||
|
||||
// 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 max idle connections is currently 2. This may change in
|
||||
// a future release.
|
||||
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 0 (unlimited).
|
||||
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.
|
||||
connMaxLifetime time.Duration
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
ConnectionURI: "",
|
||||
Host: "127.0.0.1",
|
||||
Port: 5432,
|
||||
Database: "fiber",
|
||||
Table: "fiber_storage",
|
||||
SslMode: "disable",
|
||||
Reset: false,
|
||||
GCInterval: 10 * time.Second,
|
||||
maxOpenConns: 100,
|
||||
maxIdleConns: 100,
|
||||
connMaxLifetime: 1 * time.Second,
|
||||
ConnectionURI: "",
|
||||
Host: "127.0.0.1",
|
||||
Port: 5432,
|
||||
Database: "fiber",
|
||||
Table: "fiber_storage",
|
||||
SSLMode: "disable",
|
||||
Reset: false,
|
||||
GCInterval: 10 * time.Second,
|
||||
}
|
||||
|
||||
func (c *Config) getDSN() string {
|
||||
// Just return ConnectionURI if it's already exists
|
||||
if c.ConnectionURI != "" {
|
||||
return c.ConnectionURI
|
||||
}
|
||||
|
||||
// Generate DSN
|
||||
dsn := "postgresql://"
|
||||
if c.Username != "" {
|
||||
dsn += url.QueryEscape(c.Username)
|
||||
}
|
||||
if c.Password != "" {
|
||||
dsn += ":" + url.QueryEscape(c.Password)
|
||||
}
|
||||
if c.Username != "" || c.Password != "" {
|
||||
dsn += "@"
|
||||
}
|
||||
|
||||
// unix socket host path
|
||||
if strings.HasPrefix(c.Host, "/") {
|
||||
dsn += fmt.Sprintf("%s:%d", c.Host, c.Port)
|
||||
} else {
|
||||
dsn += fmt.Sprintf("%s:%d", url.QueryEscape(c.Host), c.Port)
|
||||
}
|
||||
|
||||
dsn += fmt.Sprintf("/%s?sslmode=%s",
|
||||
url.QueryEscape(c.Database),
|
||||
c.SSLMode)
|
||||
|
||||
return dsn
|
||||
}
|
||||
|
||||
// Helper function to set default values
|
||||
@@ -114,7 +117,6 @@ func configDefault(config ...Config) Config {
|
||||
if len(config) < 1 {
|
||||
return ConfigDefault
|
||||
}
|
||||
|
||||
// Override default config
|
||||
cfg := config[0]
|
||||
|
||||
@@ -131,8 +133,8 @@ func configDefault(config ...Config) Config {
|
||||
if cfg.Table == "" {
|
||||
cfg.Table = ConfigDefault.Table
|
||||
}
|
||||
if cfg.SslMode == "" {
|
||||
cfg.SslMode = ConfigDefault.SslMode
|
||||
if cfg.Table == "" {
|
||||
cfg.Table = ConfigDefault.Table
|
||||
}
|
||||
if int(cfg.GCInterval.Seconds()) <= 0 {
|
||||
cfg.GCInterval = ConfigDefault.GCInterval
|
||||
|
@@ -1,8 +1,17 @@
|
||||
module github.com/gofiber/storage/postgres
|
||||
module github.com/gofiber/storage/postgres/v2
|
||||
|
||||
go 1.16
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/gofiber/utils v1.0.1
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/jackc/pgx/v5 v5.3.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
)
|
||||
|
@@ -1,4 +1,27 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/gofiber/utils v1.0.1 h1:knct4cXwBipWQqFrOy1Pv6UcgPM+EXo9jDgc66V1Qio=
|
||||
github.com/gofiber/utils v1.0.1/go.mod h1:pacRFtghAE3UoknMOUiXh2Io/nLWSUHtQCi/3QASsOc=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
|
||||
github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
|
||||
github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk=
|
||||
github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
@@ -1,19 +1,20 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// Storage interface that is implemented by storage providers
|
||||
type Storage struct {
|
||||
db *sql.DB
|
||||
db *pgxpool.Pool
|
||||
gcInterval time.Duration
|
||||
done chan struct{}
|
||||
|
||||
@@ -45,62 +46,33 @@ func New(config ...Config) *Storage {
|
||||
// Set default config
|
||||
cfg := configDefault(config...)
|
||||
|
||||
// Create data source name
|
||||
var dsn string
|
||||
if cfg.ConnectionURI != "" {
|
||||
dsn = cfg.ConnectionURI
|
||||
} else {
|
||||
dsn = "postgresql://"
|
||||
if cfg.Username != "" {
|
||||
dsn += url.QueryEscape(cfg.Username)
|
||||
// Select db connection
|
||||
var err error
|
||||
db := cfg.DB
|
||||
if db == nil {
|
||||
db, err = pgxpool.New(context.Background(), cfg.getDSN())
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to create connection pool: %v\n", err)
|
||||
}
|
||||
if cfg.Password != "" {
|
||||
dsn += ":" + url.QueryEscape(cfg.Password)
|
||||
}
|
||||
if cfg.Username != "" || cfg.Password != "" {
|
||||
dsn += "@"
|
||||
}
|
||||
// unix socket host path
|
||||
if strings.HasPrefix(cfg.Host, "/") {
|
||||
dsn += fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
|
||||
} else {
|
||||
dsn += fmt.Sprintf("%s:%d", url.QueryEscape(cfg.Host), cfg.Port)
|
||||
}
|
||||
dsn += fmt.Sprintf("/%s?connect_timeout=%d&sslmode=%s",
|
||||
url.QueryEscape(cfg.Database),
|
||||
int64(cfg.timeout.Seconds()),
|
||||
cfg.SslMode)
|
||||
}
|
||||
|
||||
// Create db
|
||||
db, err := sql.Open("postgres", dsn)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Set database options
|
||||
db.SetMaxOpenConns(cfg.maxOpenConns)
|
||||
db.SetMaxIdleConns(cfg.maxIdleConns)
|
||||
db.SetConnMaxLifetime(cfg.connMaxLifetime)
|
||||
|
||||
// Ping database
|
||||
if err := db.Ping(); err != nil {
|
||||
if err := db.Ping(context.Background()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Drop table if set to true
|
||||
if cfg.Reset {
|
||||
if _, err = db.Exec(fmt.Sprintf(dropQuery, cfg.Table)); err != nil {
|
||||
_ = db.Close()
|
||||
if _, err := db.Exec(context.Background(), fmt.Sprintf(dropQuery, cfg.Table)); err != nil {
|
||||
db.Close()
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Init database queries
|
||||
for _, query := range initQuery {
|
||||
if _, err := db.Exec(fmt.Sprintf(query, cfg.Table)); err != nil {
|
||||
_ = db.Close()
|
||||
|
||||
if _, err := db.Exec(context.Background(), fmt.Sprintf(query, cfg.Table)); err != nil {
|
||||
db.Close()
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -125,21 +97,19 @@ func New(config ...Config) *Storage {
|
||||
return store
|
||||
}
|
||||
|
||||
var noRows = errors.New("sql: no rows in result set")
|
||||
|
||||
// Get value by key
|
||||
func (s *Storage) Get(key string) ([]byte, error) {
|
||||
if len(key) <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
row := s.db.QueryRow(s.sqlSelect, key)
|
||||
row := s.db.QueryRow(context.Background(), s.sqlSelect, key)
|
||||
// Add db response to data
|
||||
var (
|
||||
data = []byte{}
|
||||
data []byte
|
||||
exp int64 = 0
|
||||
)
|
||||
if err := row.Scan(&data, &exp); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
@@ -163,7 +133,7 @@ func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
|
||||
if exp != 0 {
|
||||
expSeconds = time.Now().Add(exp).Unix()
|
||||
}
|
||||
_, err := s.db.Exec(s.sqlInsert, key, val, expSeconds, val, expSeconds)
|
||||
_, err := s.db.Exec(context.Background(), s.sqlInsert, key, val, expSeconds, val, expSeconds)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -173,24 +143,26 @@ func (s *Storage) Delete(key string) error {
|
||||
if len(key) <= 0 {
|
||||
return nil
|
||||
}
|
||||
_, err := s.db.Exec(s.sqlDelete, key)
|
||||
_, err := s.db.Exec(context.Background(), s.sqlDelete, key)
|
||||
return err
|
||||
}
|
||||
|
||||
// Reset all entries, including unexpired
|
||||
func (s *Storage) Reset() error {
|
||||
_, err := s.db.Exec(s.sqlReset)
|
||||
_, err := s.db.Exec(context.Background(), s.sqlReset)
|
||||
return err
|
||||
}
|
||||
|
||||
// Close the database
|
||||
func (s *Storage) Close() error {
|
||||
s.done <- struct{}{}
|
||||
return s.db.Close()
|
||||
s.db.Stat()
|
||||
s.db.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return database client
|
||||
func (s *Storage) Conn() *sql.DB {
|
||||
func (s *Storage) Conn() *pgxpool.Pool {
|
||||
return s.db
|
||||
}
|
||||
|
||||
@@ -210,13 +182,13 @@ func (s *Storage) gcTicker() {
|
||||
|
||||
// gc deletes all expired entries
|
||||
func (s *Storage) gc(t time.Time) {
|
||||
_, _ = s.db.Exec(s.sqlGC, t.Unix())
|
||||
_, _ = s.db.Exec(context.Background(), s.sqlGC, t.Unix())
|
||||
}
|
||||
|
||||
func (s *Storage) checkSchema(tableName string) {
|
||||
var data []byte
|
||||
|
||||
row := s.db.QueryRow(fmt.Sprintf(checkSchemaQuery, tableName))
|
||||
row := s.db.QueryRow(context.Background(), fmt.Sprintf(checkSchemaQuery, tableName))
|
||||
if err := row.Scan(&data); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@@ -1,12 +1,13 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/utils"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
var testStore = New(Config{
|
||||
@@ -133,9 +134,9 @@ func Test_Postgres_GC(t *testing.T) {
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
testStore.gc(time.Now())
|
||||
row := testStore.db.QueryRow(testStore.sqlSelect, "john")
|
||||
row := testStore.db.QueryRow(context.Background(), testStore.sqlSelect, "john")
|
||||
err = row.Scan(nil, nil)
|
||||
utils.AssertEqual(t, sql.ErrNoRows, err)
|
||||
utils.AssertEqual(t, pgx.ErrNoRows, err)
|
||||
|
||||
// This key should not expire
|
||||
err = testStore.Set("john", testVal, 0)
|
||||
@@ -166,18 +167,14 @@ func Test_SslRequiredMode(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
_ = New(Config{
|
||||
Database: "fiber",
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
Reset: true,
|
||||
SslMode: "require",
|
||||
Reset: true,
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Postgres_Close(t *testing.T) {
|
||||
utils.AssertEqual(t, nil, testStore.Close())
|
||||
}
|
||||
|
||||
func Test_Postgres_Conn(t *testing.T) {
|
||||
utils.AssertEqual(t, true, testStore.Conn() != nil)
|
||||
}
|
||||
|
||||
func Test_Postgres_Close(t *testing.T) {
|
||||
utils.AssertEqual(t, nil, testStore.Close())
|
||||
}
|
||||
|
Reference in New Issue
Block a user