mirror of
https://github.com/gofiber/storage.git
synced 2025-10-05 00:33:03 +08:00
🚤 Improve sql storage
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
|||||||
type Storage struct {
|
type Storage struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
gcInterval time.Duration
|
gcInterval time.Duration
|
||||||
|
done chan struct{}
|
||||||
|
|
||||||
sqlSelect string
|
sqlSelect string
|
||||||
sqlInsert string
|
sqlInsert string
|
||||||
@@ -80,6 +81,7 @@ func New(config ...Config) *Storage {
|
|||||||
store := &Storage{
|
store := &Storage{
|
||||||
gcInterval: cfg.GCInterval,
|
gcInterval: cfg.GCInterval,
|
||||||
db: db,
|
db: db,
|
||||||
|
done: make(chan struct{}),
|
||||||
sqlSelect: fmt.Sprintf("SELECT v, e FROM %s WHERE k=?;", cfg.Table),
|
sqlSelect: fmt.Sprintf("SELECT v, e FROM %s WHERE k=?;", cfg.Table),
|
||||||
sqlInsert: fmt.Sprintf("INSERT INTO %s (k, v, e) VALUES (?,?,?) ON DUPLICATE KEY UPDATE v = ?, e = ?", cfg.Table),
|
sqlInsert: fmt.Sprintf("INSERT INTO %s (k, v, e) VALUES (?,?,?) ON DUPLICATE KEY UPDATE v = ?, e = ?", cfg.Table),
|
||||||
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE k=?", cfg.Table),
|
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE k=?", cfg.Table),
|
||||||
@@ -150,16 +152,20 @@ func (s *Storage) Reset() error {
|
|||||||
|
|
||||||
// Close the database
|
// Close the database
|
||||||
func (s *Storage) Close() error {
|
func (s *Storage) Close() error {
|
||||||
|
s.done <- struct{}{}
|
||||||
return s.db.Close()
|
return s.db.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Garbage collector to delete expired keys
|
// Garbage collector to delete expired keys
|
||||||
func (s *Storage) gc() {
|
func (s *Storage) gc() {
|
||||||
tick := time.NewTicker(s.gcInterval)
|
ticker := time.NewTicker(s.gcInterval)
|
||||||
|
defer ticker.Stop()
|
||||||
for {
|
for {
|
||||||
<-tick.C
|
select {
|
||||||
if _, err := s.db.Exec(s.sqlGC); err != nil {
|
case <-s.done:
|
||||||
panic(err)
|
return
|
||||||
|
case t := <-ticker.C:
|
||||||
|
_, _ = s.db.Exec(s.sqlGC, t.Unix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -121,3 +121,8 @@ func Test_MYSQL_Clear(t *testing.T) {
|
|||||||
utils.AssertEqual(t, ErrNotExist, err)
|
utils.AssertEqual(t, ErrNotExist, err)
|
||||||
utils.AssertEqual(t, true, len(result) == 0)
|
utils.AssertEqual(t, true, len(result) == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Mysql_Close(t *testing.T) {
|
||||||
|
err := testStore.Close()
|
||||||
|
utils.AssertEqual(t, nil, err)
|
||||||
|
}
|
||||||
|
@@ -15,6 +15,7 @@ import (
|
|||||||
type Storage struct {
|
type Storage struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
gcInterval time.Duration
|
gcInterval time.Duration
|
||||||
|
done chan struct{}
|
||||||
|
|
||||||
sqlSelect string
|
sqlSelect string
|
||||||
sqlInsert string
|
sqlInsert string
|
||||||
@@ -97,6 +98,7 @@ func New(config ...Config) *Storage {
|
|||||||
store := &Storage{
|
store := &Storage{
|
||||||
db: db,
|
db: db,
|
||||||
gcInterval: cfg.GCInterval,
|
gcInterval: cfg.GCInterval,
|
||||||
|
done: make(chan struct{}),
|
||||||
sqlSelect: fmt.Sprintf(`SELECT v, e FROM %s WHERE k=$1;`, cfg.Table),
|
sqlSelect: fmt.Sprintf(`SELECT v, e FROM %s WHERE k=$1;`, cfg.Table),
|
||||||
sqlInsert: fmt.Sprintf("INSERT INTO %s (k, v, e) VALUES ($1, $2, $3) ON CONFLICT (k) DO UPDATE SET v = $4, e = $5", cfg.Table),
|
sqlInsert: fmt.Sprintf("INSERT INTO %s (k, v, e) VALUES ($1, $2, $3) ON CONFLICT (k) DO UPDATE SET v = $4, e = $5", cfg.Table),
|
||||||
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE k=$1", cfg.Table),
|
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE k=$1", cfg.Table),
|
||||||
@@ -164,16 +166,20 @@ func (s *Storage) Reset() error {
|
|||||||
|
|
||||||
// Close the database
|
// Close the database
|
||||||
func (s *Storage) Close() error {
|
func (s *Storage) Close() error {
|
||||||
|
s.done <- struct{}{}
|
||||||
return s.db.Close()
|
return s.db.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GC deletes all expired entries
|
// GC deletes all expired entries
|
||||||
func (s *Storage) gc() {
|
func (s *Storage) gc() {
|
||||||
tick := time.NewTicker(s.gcInterval)
|
ticker := time.NewTicker(s.gcInterval)
|
||||||
|
defer ticker.Stop()
|
||||||
for {
|
for {
|
||||||
<-tick.C
|
select {
|
||||||
if _, err := s.db.Exec(s.sqlGC); err != nil {
|
case <-s.done:
|
||||||
panic(err)
|
return
|
||||||
|
case t := <-ticker.C:
|
||||||
|
_, _ = s.db.Exec(s.sqlGC, t.Unix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -121,3 +121,8 @@ func Test_Postgres_Clear(t *testing.T) {
|
|||||||
utils.AssertEqual(t, ErrNotExist, err)
|
utils.AssertEqual(t, ErrNotExist, err)
|
||||||
utils.AssertEqual(t, true, len(result) == 0)
|
utils.AssertEqual(t, true, len(result) == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Postgres_Close(t *testing.T) {
|
||||||
|
err := testStore.Close()
|
||||||
|
utils.AssertEqual(t, nil, err)
|
||||||
|
}
|
||||||
|
@@ -15,6 +15,7 @@ import (
|
|||||||
type Storage struct {
|
type Storage struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
gcInterval time.Duration
|
gcInterval time.Duration
|
||||||
|
done chan struct{}
|
||||||
|
|
||||||
sqlSelect string
|
sqlSelect string
|
||||||
sqlInsert string
|
sqlInsert string
|
||||||
@@ -80,6 +81,7 @@ func New(config ...Config) *Storage {
|
|||||||
store := &Storage{
|
store := &Storage{
|
||||||
db: db,
|
db: db,
|
||||||
gcInterval: cfg.GCInterval,
|
gcInterval: cfg.GCInterval,
|
||||||
|
done: make(chan struct{}),
|
||||||
sqlSelect: fmt.Sprintf(`SELECT v, e FROM %s WHERE k=?;`, cfg.Table),
|
sqlSelect: fmt.Sprintf(`SELECT v, e FROM %s WHERE k=?;`, cfg.Table),
|
||||||
sqlInsert: fmt.Sprintf("INSERT OR REPLACE INTO %s (k, v, e) VALUES (?,?,?)", cfg.Table),
|
sqlInsert: fmt.Sprintf("INSERT OR REPLACE INTO %s (k, v, e) VALUES (?,?,?)", cfg.Table),
|
||||||
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE k=?", cfg.Table),
|
sqlDelete: fmt.Sprintf("DELETE FROM %s WHERE k=?", cfg.Table),
|
||||||
@@ -143,16 +145,20 @@ func (s *Storage) Reset() error {
|
|||||||
|
|
||||||
// Close the database
|
// Close the database
|
||||||
func (s *Storage) Close() error {
|
func (s *Storage) Close() error {
|
||||||
|
s.done <- struct{}{}
|
||||||
return s.db.Close()
|
return s.db.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GC deletes all expired entries
|
// GC deletes all expired entries
|
||||||
func (s *Storage) gc() {
|
func (s *Storage) gc() {
|
||||||
tick := time.NewTicker(s.gcInterval)
|
ticker := time.NewTicker(s.gcInterval)
|
||||||
|
defer ticker.Stop()
|
||||||
for {
|
for {
|
||||||
<-tick.C
|
select {
|
||||||
if _, err := s.db.Exec(s.sqlGC); err != nil {
|
case <-s.done:
|
||||||
panic(err)
|
return
|
||||||
|
case t := <-ticker.C:
|
||||||
|
_, _ = s.db.Exec(s.sqlGC, t.Unix())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -118,3 +118,8 @@ func Test_SQLite3_Clear(t *testing.T) {
|
|||||||
utils.AssertEqual(t, ErrNotExist, err)
|
utils.AssertEqual(t, ErrNotExist, err)
|
||||||
utils.AssertEqual(t, true, len(result) == 0)
|
utils.AssertEqual(t, true, len(result) == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_SQLite3_Close(t *testing.T) {
|
||||||
|
err := testStore.Close()
|
||||||
|
utils.AssertEqual(t, nil, err)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user