mirror of
https://github.com/gofiber/storage.git
synced 2025-10-05 08:37:10 +08:00
🎄 xmas present
This commit is contained in:
@@ -4,45 +4,49 @@ 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 host
|
||||
// Host name where the DB is hosted
|
||||
//
|
||||
// Optional. Default is "127.0.0.1"
|
||||
Host string
|
||||
|
||||
// DB port
|
||||
// Port where the DB is listening on
|
||||
//
|
||||
// Optional. Default is "5432"
|
||||
Port int64
|
||||
// Optional. Default is 5432
|
||||
Port int
|
||||
|
||||
// DB user name
|
||||
// Server username
|
||||
//
|
||||
// Optional. Default is ""
|
||||
Username string
|
||||
|
||||
// DB user password
|
||||
// Server password
|
||||
//
|
||||
// Optional. Default is ""
|
||||
Password string
|
||||
|
||||
// DB name
|
||||
// Database name
|
||||
//
|
||||
// Optional. Default is "fiber"
|
||||
Database string
|
||||
|
||||
// DB table name
|
||||
// Table name
|
||||
//
|
||||
// Optional. Default is "fiber"
|
||||
TableName string
|
||||
// Optional. Default is "fiber_storage"
|
||||
Table string
|
||||
|
||||
// Drop any existing table with the same name
|
||||
// Clear any existing keys in existing Table
|
||||
//
|
||||
// Optional. Default is false
|
||||
DropTable bool
|
||||
Clear bool
|
||||
|
||||
// Time before deleting expired keys
|
||||
//
|
||||
// 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.
|
||||
@@ -79,13 +83,12 @@ type Config struct {
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
GCInterval: 10 * time.Second,
|
||||
Host: "127.0.0.1",
|
||||
Port: 5432,
|
||||
Database: "fiber",
|
||||
TableName: "fiber",
|
||||
DropTable: false,
|
||||
timeout: 30 * time.Second,
|
||||
Table: "fiber_storage",
|
||||
Clear: false,
|
||||
GCInterval: 10 * time.Second,
|
||||
maxOpenConns: 100,
|
||||
maxIdleConns: 100,
|
||||
connMaxLifetime: 1 * time.Second,
|
||||
@@ -102,35 +105,20 @@ func configDefault(config ...Config) Config {
|
||||
cfg := config[0]
|
||||
|
||||
// Set default values
|
||||
if int(cfg.GCInterval) == 0 {
|
||||
cfg.GCInterval = ConfigDefault.GCInterval
|
||||
}
|
||||
if cfg.Host == "" {
|
||||
cfg.Host = ConfigDefault.Host
|
||||
}
|
||||
if cfg.Port == 0 {
|
||||
if cfg.Port <= 0 {
|
||||
cfg.Port = ConfigDefault.Port
|
||||
}
|
||||
if cfg.Host == "" {
|
||||
cfg.Host = ConfigDefault.Host
|
||||
}
|
||||
if cfg.Database == "" {
|
||||
cfg.Database = ConfigDefault.Database
|
||||
}
|
||||
if cfg.TableName == "" {
|
||||
cfg.TableName = ConfigDefault.TableName
|
||||
if cfg.Table == "" {
|
||||
cfg.Table = ConfigDefault.Table
|
||||
}
|
||||
if int(cfg.GCInterval) == 0 {
|
||||
cfg.GCInterval = ConfigDefault.GCInterval
|
||||
}
|
||||
// if int(cfg.Timeout) == 0 {
|
||||
// cfg.Timeout = ConfigDefault.Timeout
|
||||
// }
|
||||
// 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
|
||||
}
|
||||
|
@@ -44,13 +44,22 @@ func New(config ...Config) *Storage {
|
||||
cfg := configDefault(config...)
|
||||
|
||||
// Create data source name
|
||||
dsn := fmt.Sprintf("postgresql://%s:%s@%s:%d/%s?connect_timeout=%d&sslmode=disable",
|
||||
url.QueryEscape(cfg.Username),
|
||||
cfg.Password,
|
||||
url.QueryEscape(cfg.Host),
|
||||
cfg.Port,
|
||||
var dsn string = "postgresql://"
|
||||
if cfg.Username != "" {
|
||||
dsn += url.QueryEscape(cfg.Username)
|
||||
}
|
||||
if cfg.Password != "" {
|
||||
dsn += ":" + cfg.Password
|
||||
}
|
||||
if cfg.Username != "" || cfg.Password != "" {
|
||||
dsn += "@"
|
||||
}
|
||||
dsn += fmt.Sprintf("%s:%d", url.QueryEscape(cfg.Host), cfg.Port)
|
||||
dsn += "/" + url.QueryEscape(cfg.Database)
|
||||
dsn += fmt.Sprintf("/%s?connect_timeout=%d&sslmode=disable",
|
||||
url.QueryEscape(cfg.Database),
|
||||
int64(cfg.timeout.Seconds()))
|
||||
int64(cfg.timeout.Seconds()),
|
||||
)
|
||||
|
||||
// Create db
|
||||
db, err := sql.Open("postgres", dsn)
|
||||
@@ -69,8 +78,8 @@ func New(config ...Config) *Storage {
|
||||
}
|
||||
|
||||
// Drop table if set to true
|
||||
if cfg.DropTable {
|
||||
if _, err = db.Exec(fmt.Sprintf(dropQuery, cfg.TableName)); err != nil {
|
||||
if cfg.Clear {
|
||||
if _, err = db.Exec(fmt.Sprintf(dropQuery, cfg.Table)); err != nil {
|
||||
_ = db.Close()
|
||||
panic(err)
|
||||
}
|
||||
@@ -78,9 +87,9 @@ func New(config ...Config) *Storage {
|
||||
|
||||
// Init database queries
|
||||
for _, query := range initQuery {
|
||||
if _, err := db.Exec(fmt.Sprintf(query, cfg.TableName)); err != nil {
|
||||
if _, err := db.Exec(fmt.Sprintf(query, cfg.Table)); err != nil {
|
||||
_ = db.Close()
|
||||
fmt.Println(fmt.Sprintf(query, cfg.TableName))
|
||||
fmt.Println(fmt.Sprintf(query, cfg.Table))
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -89,11 +98,11 @@ func New(config ...Config) *Storage {
|
||||
store := &Storage{
|
||||
db: db,
|
||||
gcInterval: cfg.GCInterval,
|
||||
sqlSelect: fmt.Sprintf(`SELECT data, exp FROM %s WHERE key=$1;`, cfg.TableName),
|
||||
sqlInsert: fmt.Sprintf("INSERT INTO %s (key, data, exp) VALUES ($1, $2, $3)", cfg.TableName),
|
||||
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE key=$1", cfg.TableName),
|
||||
sqlClear: fmt.Sprintf("DELETE FROM %s;", cfg.TableName),
|
||||
sqlGC: fmt.Sprintf("DELETE FROM %s WHERE exp <= $1", cfg.TableName),
|
||||
sqlSelect: fmt.Sprintf(`SELECT data, exp FROM %s WHERE key=$1;`, cfg.Table),
|
||||
sqlInsert: fmt.Sprintf("INSERT INTO %s (key, data, exp) VALUES ($1, $2, $3)", cfg.Table),
|
||||
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE key=$1", cfg.Table),
|
||||
sqlClear: fmt.Sprintf("DELETE FROM %s;", cfg.Table),
|
||||
sqlGC: fmt.Sprintf("DELETE FROM %s WHERE exp <= $1", cfg.Table),
|
||||
}
|
||||
|
||||
// Start garbage collector
|
||||
@@ -107,7 +116,6 @@ 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.sqlSelect, key)
|
||||
|
||||
// Add db response to data
|
||||
var (
|
||||
data = []byte{}
|
||||
|
@@ -2,38 +2,38 @@
|
||||
|
||||
package postgres
|
||||
|
||||
var testStore *Storage
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
func init() {
|
||||
testConfig := ConfigDefault
|
||||
testConfig.Addr = "127.0.0.1:5432"
|
||||
"github.com/gofiber/utils"
|
||||
)
|
||||
|
||||
if v := os.Getenv("POSTGRES_ADDR"); v != "" {
|
||||
testConfig.Addr = v
|
||||
}
|
||||
var testStore = New(Config{
|
||||
Database: os.Getenv("POSTGRES_DATABASE"),
|
||||
Username: os.Getenv("POSTGRES_USERNAME"),
|
||||
Password: os.Getenv("POSTGRES_PASSWORD"),
|
||||
Clear: true,
|
||||
})
|
||||
|
||||
testStore = New(testConfig)
|
||||
}
|
||||
|
||||
func Test_Redis_Set(t *testing.T) {
|
||||
func Test_Postgres_Set(t *testing.T) {
|
||||
var (
|
||||
store = testStore
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
)
|
||||
|
||||
err := store.Set(key, val, 0)
|
||||
err := testStore.(key, val, 0)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
}
|
||||
|
||||
func Test_Redis_Get(t *testing.T) {
|
||||
func Test_Postgres_Get(t *testing.T) {
|
||||
var (
|
||||
store = testStore
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
)
|
||||
|
||||
err := store.Set(key, val, 0)
|
||||
err := testStore.(key, val, 0)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
result, err := store.Get(key)
|
||||
@@ -41,25 +41,23 @@ func Test_Redis_Get(t *testing.T) {
|
||||
utils.AssertEqual(t, val, result)
|
||||
}
|
||||
|
||||
func Test_Redis_Set_Expiration(t *testing.T) {
|
||||
func Test_Postgres_Set_Expiration(t *testing.T) {
|
||||
var (
|
||||
store = testStore
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
exp = 500 * time.Millisecond
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
exp = 500 * time.Millisecond
|
||||
)
|
||||
|
||||
err := store.Set(key, val, exp)
|
||||
err := testStore.(key, val, exp)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
}
|
||||
|
||||
func Test_Redis_Get_Expired(t *testing.T) {
|
||||
func Test_Postgres_Get_Expired(t *testing.T) {
|
||||
var (
|
||||
store = testStore
|
||||
key = "john"
|
||||
key = "john"
|
||||
)
|
||||
|
||||
result, err := store.Get(key)
|
||||
@@ -67,22 +65,21 @@ func Test_Redis_Get_Expired(t *testing.T) {
|
||||
utils.AssertEqual(t, true, len(result) == 0)
|
||||
}
|
||||
|
||||
func Test_Redis_Get_NotExist(t *testing.T) {
|
||||
var store = testStore
|
||||
func Test_Postgres_Get_NotExist(t *testing.T) {
|
||||
|
||||
|
||||
result, err := store.Get("notexist")
|
||||
utils.AssertEqual(t, ErrNotExist, err)
|
||||
utils.AssertEqual(t, true, len(result) == 0)
|
||||
}
|
||||
|
||||
func Test_Redis_Delete(t *testing.T) {
|
||||
func Test_Postgres_Delete(t *testing.T) {
|
||||
var (
|
||||
store = testStore
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
key = "john"
|
||||
val = []byte("doe")
|
||||
)
|
||||
|
||||
err := store.Set(key, val, 0)
|
||||
err := testStore.(key, val, 0)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
err = store.Delete(key)
|
||||
@@ -93,16 +90,15 @@ func Test_Redis_Delete(t *testing.T) {
|
||||
utils.AssertEqual(t, true, len(result) == 0)
|
||||
}
|
||||
|
||||
func Test_Redis_Clear(t *testing.T) {
|
||||
func Test_Postgres_Clear(t *testing.T) {
|
||||
var (
|
||||
store = testStore
|
||||
val = []byte("doe")
|
||||
val = []byte("doe")
|
||||
)
|
||||
|
||||
err := store.Set("john1", val, 0)
|
||||
err := testStore.("john1", val, 0)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
err = store.Set("john2", val, 0)
|
||||
err = testStore.("john2", val, 0)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
err = store.Clear()
|
||||
|
Reference in New Issue
Block a user