support LevelDB key/value database.

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
Bo-Yi Wu 2016-09-19 16:19:20 +08:00
parent 2fba9b3d74
commit bf56f592e8
9 changed files with 238 additions and 16 deletions

View File

@ -40,7 +40,7 @@ build_static:
build: clean
sh script/build.sh $(VERSION)
test: redis_test boltdb_test memory_test config_test
test: redis_test boltdb_test memory_test buntdb_test leveldb_test config_test
go test -v -cover ./gorush/...
redis_test: init
@ -55,6 +55,9 @@ memory_test: init
buntdb_test: init
go test -v -cover ./storage/buntdb/...
leveldb_test: init
go test -v -cover ./storage/leveldb/...
config_test: init
go test -v -cover ./config/...

View File

@ -65,10 +65,11 @@ type SectionLog struct {
// SectionStat is sub seciont of config.
type SectionStat struct {
Engine string `yaml:"engine"`
Redis SectionRedis `yaml:"redis"`
BoltDB SectionBoltDB `yaml:"boltdb"`
BuntDB SectionBuntDB `yaml:"buntdb"`
Engine string `yaml:"engine"`
Redis SectionRedis `yaml:"redis"`
BoltDB SectionBoltDB `yaml:"boltdb"`
BuntDB SectionBuntDB `yaml:"buntdb"`
LevelDB SectionLevelDB `yaml:"leveldb"`
}
// SectionRedis is sub seciont of config.
@ -89,6 +90,11 @@ type SectionBuntDB struct {
Path string `yaml:"path"`
}
// SectionLevelDB is sub seciont of config.
type SectionLevelDB struct {
Path string `yaml:"path"`
}
// SectionPID is sub seciont of config.
type SectionPID struct {
Enabled bool `yaml:"enabled"`
@ -148,6 +154,7 @@ func BuildDefaultPushConf() ConfYaml {
conf.Stat.BoltDB.Bucket = "gorush"
conf.Stat.BuntDB.Path = "gorush.db"
conf.Stat.LevelDB.Path = "gorush.db"
return conf
}

View File

@ -49,3 +49,5 @@ stat:
bucket: "gorush"
buntdb:
path: "gorush.db"
leveldb:
path: "gorush.db"

View File

@ -102,6 +102,7 @@ func (suite *ConfigTestSuite) TestValidateConfDefault() {
assert.Equal(suite.T(), "gorush", suite.ConfGorushDefault.Stat.BoltDB.Bucket)
assert.Equal(suite.T(), "gorush.db", suite.ConfGorushDefault.Stat.BuntDB.Path)
assert.Equal(suite.T(), "gorush.db", suite.ConfGorushDefault.Stat.LevelDB.Path)
}
func (suite *ConfigTestSuite) TestValidateConf() {
@ -154,6 +155,7 @@ func (suite *ConfigTestSuite) TestValidateConf() {
assert.Equal(suite.T(), "gorush", suite.ConfGorush.Stat.BoltDB.Bucket)
assert.Equal(suite.T(), "gorush.db", suite.ConfGorush.Stat.BuntDB.Path)
assert.Equal(suite.T(), "gorush.db", suite.ConfGorush.Stat.LevelDB.Path)
}
func TestConfigTestSuite(t *testing.T) {

24
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: a723ec6556a185c4a20185378b0e042fd41453232da81489e06307b0ac8feba7
updated: 2016-08-02T15:01:02.331147237+08:00
hash: 6aef366747559fbcb1075ebe6f923f2e5197544a0b02ce039d5120c7241e8df2
updated: 2016-09-19T15:54:05.13589289+08:00
imports:
- name: github.com/asdine/storm
version: 00b2f2df7ab7af9db746b826649395628cb5374e
@ -22,6 +22,8 @@ imports:
version: 2402d76f3d41f928c7902a765dfc872356dd3aad
subpackages:
- proto
- name: github.com/golang/snappy
version: d9eb7a3d35ec988b8585d4a0068e462c27d28380
- name: github.com/google/go-gcm
version: 190e93b4cedb43562b5bd558eb1a1bbd38695bcd
- name: github.com/jpillora/backoff
@ -45,6 +47,21 @@ imports:
- assert
- suite
- require
- name: github.com/syndtr/goleveldb
version: 6ae1797c0b42b9323fc27ff7dcf568df88f2f33d
subpackages:
- leveldb
- leveldb/cache
- leveldb/comparer
- leveldb/errors
- leveldb/filter
- leveldb/iterator
- leveldb/journal
- leveldb/memdb
- leveldb/opt
- leveldb/storage
- leveldb/table
- leveldb/util
- name: github.com/thoas/stats
version: 69e3c072eec2df2df41afe6214f62eb940e4cd80
- name: github.com/tidwall/btree
@ -103,9 +120,10 @@ imports:
version: b5e368500d0a508ef8f16e9c2d4025a8a46bcc29
subpackages:
- internal
- internal/consistenthash
- internal/hashtag
- internal/pool
- name: gopkg.in/redis.v3/internal/consistenthash
version: b5e368500d0a508ef8f16e9c2d4025a8a46bcc29
- name: gopkg.in/yaml.v2
version: a83829b6f1293c91addabc89d0571c246397bbf4
testImports:

View File

@ -19,3 +19,4 @@ import:
- package: github.com/buger/jsonparser
- package: github.com/thoas/stats
- package: github.com/tidwall/buntdb
- package: github.com/syndtr/goleveldb

View File

@ -2,6 +2,8 @@ package gorush
import (
"github.com/appleboy/gorush/storage/boltdb"
"github.com/appleboy/gorush/storage/buntdb"
"github.com/appleboy/gorush/storage/leveldb"
"github.com/appleboy/gorush/storage/memory"
"github.com/appleboy/gorush/storage/redis"
"github.com/gin-gonic/gin"
@ -40,20 +42,24 @@ func InitAppStatus() error {
StatStorage = memory.New()
case "redis":
StatStorage = redis.New(PushConf)
err := StatStorage.Init()
if err != nil {
LogError.Error("redis error: " + err.Error())
return err
}
case "boltdb":
StatStorage = boltdb.New(PushConf)
case "buntdb":
StatStorage = buntdb.New(PushConf)
case "leveldb":
StatStorage = leveldb.New(PushConf)
default:
StatStorage = memory.New()
}
err := StatStorage.Init()
if err != nil {
LogError.Error("storage error: " + err.Error())
return err
}
return nil
}

134
storage/leveldb/leveldb.go Normal file
View File

@ -0,0 +1,134 @@
package leveldb
import (
"fmt"
"github.com/appleboy/gorush/config"
"github.com/syndtr/goleveldb/leveldb"
"strconv"
)
// Stat variable for redis
const (
TotalCountKey = "gorush-total-count"
IosSuccessKey = "gorush-ios-success-count"
IosErrorKey = "gorush-ios-error-count"
AndroidSuccessKey = "gorush-android-success-count"
AndroidErrorKey = "gorush-android-error-count"
)
var dbPath string
func setLevelDB(key string, count int64) {
db, _ := leveldb.OpenFile(dbPath, nil)
value := fmt.Sprintf("%d", count)
_ = db.Put([]byte(key), []byte(value), nil)
defer db.Close()
}
func getLevelDB(key string, count *int64) {
db, _ := leveldb.OpenFile(dbPath, nil)
data, _ := db.Get([]byte(key), nil)
*count, _ = strconv.ParseInt(string(data), 10, 64)
defer db.Close()
}
// New func implements the storage interface for gorush (https://github.com/appleboy/gorush)
func New(config config.ConfYaml) *Storage {
return &Storage{
config: config,
}
}
// Storage is interface structure
type Storage struct {
config config.ConfYaml
}
// Init client storage.
func (s *Storage) Init() error {
dbPath = s.config.Stat.LevelDB.Path
return nil
}
// Reset Client storage.
func (s *Storage) Reset() {
setLevelDB(TotalCountKey, 0)
setLevelDB(IosSuccessKey, 0)
setLevelDB(IosErrorKey, 0)
setLevelDB(AndroidSuccessKey, 0)
setLevelDB(AndroidErrorKey, 0)
}
// AddTotalCount record push notification count.
func (s *Storage) AddTotalCount(count int64) {
total := s.GetTotalCount() + count
setLevelDB(TotalCountKey, total)
}
// AddIosSuccess record counts of success iOS push notification.
func (s *Storage) AddIosSuccess(count int64) {
total := s.GetIosSuccess() + count
setLevelDB(IosSuccessKey, total)
}
// AddIosError record counts of error iOS push notification.
func (s *Storage) AddIosError(count int64) {
total := s.GetIosError() + count
setLevelDB(IosErrorKey, total)
}
// AddAndroidSuccess record counts of success Android push notification.
func (s *Storage) AddAndroidSuccess(count int64) {
total := s.GetAndroidSuccess() + count
setLevelDB(AndroidSuccessKey, total)
}
// AddAndroidError record counts of error Android push notification.
func (s *Storage) AddAndroidError(count int64) {
total := s.GetAndroidError() + count
setLevelDB(AndroidErrorKey, total)
}
// GetTotalCount show counts of all notification.
func (s *Storage) GetTotalCount() int64 {
var count int64
getLevelDB(TotalCountKey, &count)
return count
}
// GetIosSuccess show success counts of iOS notification.
func (s *Storage) GetIosSuccess() int64 {
var count int64
getLevelDB(IosSuccessKey, &count)
return count
}
// GetIosError show error counts of iOS notification.
func (s *Storage) GetIosError() int64 {
var count int64
getLevelDB(IosErrorKey, &count)
return count
}
// GetAndroidSuccess show success counts of Android notification.
func (s *Storage) GetAndroidSuccess() int64 {
var count int64
getLevelDB(AndroidSuccessKey, &count)
return count
}
// GetAndroidError show error counts of Android notification.
func (s *Storage) GetAndroidError() int64 {
var count int64
getLevelDB(AndroidErrorKey, &count)
return count
}

View File

@ -0,0 +1,49 @@
package leveldb
import (
c "github.com/appleboy/gorush/config"
"github.com/stretchr/testify/assert"
"os"
"testing"
)
func TestLevelDBEngine(t *testing.T) {
var val int64
config := c.BuildDefaultPushConf()
if _, err := os.Stat(config.Stat.LevelDB.Path); os.IsNotExist(err) {
os.RemoveAll(config.Stat.LevelDB.Path)
}
levelDB := New(config)
levelDB.Init()
levelDB.Reset()
levelDB.AddTotalCount(10)
val = levelDB.GetTotalCount()
assert.Equal(t, int64(10), val)
levelDB.AddTotalCount(10)
val = levelDB.GetTotalCount()
assert.Equal(t, int64(20), val)
levelDB.AddIosSuccess(20)
val = levelDB.GetIosSuccess()
assert.Equal(t, int64(20), val)
levelDB.AddIosError(30)
val = levelDB.GetIosError()
assert.Equal(t, int64(30), val)
levelDB.AddAndroidSuccess(40)
val = levelDB.GetAndroidSuccess()
assert.Equal(t, int64(40), val)
levelDB.AddAndroidError(50)
val = levelDB.GetAndroidError()
assert.Equal(t, int64(50), val)
levelDB.Reset()
val = levelDB.GetAndroidError()
assert.Equal(t, int64(0), val)
}