steem-block-db/db.go

174 lines
3.7 KiB
Go
Raw Normal View History

2018-10-28 16:31:26 +00:00
package main
2018-10-31 08:48:53 +00:00
import log "github.com/sirupsen/logrus"
2018-10-28 16:31:26 +00:00
import "io/ioutil"
import "github.com/dgraph-io/badger"
2018-10-31 08:48:53 +00:00
import "github.com/spf13/afero"
import "github.com/go-redis/redis"
2018-10-31 09:44:19 +00:00
import "fmt"
import "strconv"
const appPrefix = "steem-block-fetcher"
type SteemDataStorer interface {
SetCurrentBlockHeight(BlockNumber) error
CurrentBlockHeight() BlockNumber
HaveOpsForBlock(BlockNumber) bool
StoreBlockOps(BlockNumber, *[]byte) error
}
2018-10-28 16:31:26 +00:00
// SteemDataStore is the object with which the rest of this tool interacts
type SteemDataStore struct {
2018-10-31 08:48:53 +00:00
kv KVStorer
2018-10-28 16:31:26 +00:00
}
func NewSteemDataStore(dir string) *SteemDataStore {
self := new(SteemDataStore)
2018-10-31 08:48:53 +00:00
self.kv = NewRedisKVStore()
2018-10-28 16:31:26 +00:00
return self
}
2018-10-31 09:44:19 +00:00
func (self *SteemDataStore) SetCurrentBlockHeight(blockNum BlockNumber) error {
panic("unimplemented")
return nil
}
func (self *SteemDataStore) StoreBlockOps(blockNum BlockNumber, blockOps *[]byte) error {
panic("unimplemented")
}
func (self *SteemDataStore) HaveOpsForBlock(blockNum BlockNumber) bool {
panic("unimplemented")
}
func (self *SteemDataStore) CurrentBlockHeight() BlockNumber {
keyname := fmt.Sprintf("%s:global:CurrentBlockHeight", appPrefix)
val, err := self.kv.Get(&keyname)
//FIXME(sneak) make this init the key to 0 if not found
if err != nil {
panic("unable to query redis")
}
intval, err := strconv.ParseUint(*val, 10, 64)
return BlockNumber(intval)
2018-10-28 16:31:26 +00:00
}
// KeyValueStorer is an interface for the backend kv store used by
// SteemDataStore
// it could be fs, badgerdb, whatever
2018-10-31 08:48:53 +00:00
type KVStorer interface {
2018-10-28 16:31:26 +00:00
Open(string)
Get(*string) (*string, error)
Put(*string, *string) error
Close()
}
2018-10-31 08:48:53 +00:00
type RedisKVStore struct {
rc *redis.Client
}
func NewRedisKVStore() *RedisKVStore {
rkvs := new(RedisKVStore)
rkvs.Open("localhost:6379") //FIXME(sneak) use viper
return rkvs
}
func (self *RedisKVStore) Get(keyname *string) (*string, error) {
val, err := self.rc.Get(*keyname).Result()
if err != nil {
2018-10-31 09:44:19 +00:00
log.Panicf("unable to fetch key '%s' from redis", *keyname)
2018-10-31 08:48:53 +00:00
//FIXME(sneak) we should probably distinguish between key not
//existing and fetch error
}
return &val, nil
}
func (self *RedisKVStore) Put(keyname *string, value *string) error {
err := self.rc.Set(*keyname, *value, 0).Err()
if err != nil {
panic("unable to write to redis")
}
return nil
}
func (self *RedisKVStore) Close() {
self.rc.Close()
}
func (self *RedisKVStore) Open(hostname string) {
self.rc = redis.NewClient(&redis.Options{
Addr: hostname,
Password: "", // no password set
DB: 0, // use default DB
})
_, err := self.rc.Ping().Result()
if err != nil {
panic(err)
}
}
type AferoFSKVStore struct {
fs *afero.Fs
}
// BadgerKVStore is an object that conforms to KeyValueStorer for use
2018-10-28 16:31:26 +00:00
// by SteemDataStore to persist Steem data
2018-10-31 08:48:53 +00:00
type BadgerKVStore struct {
2018-10-28 16:31:26 +00:00
db *badger.DB
}
2018-10-31 08:48:53 +00:00
func NewBadgerKVStore(dir string) *BadgerKVStore {
kv := new(BadgerKVStore)
2018-10-28 16:31:26 +00:00
kv.Open(dir)
return kv
}
2018-10-31 08:48:53 +00:00
func (kv *BadgerKVStore) Open(dir string) {
2018-10-28 16:31:26 +00:00
dir, err := ioutil.TempDir("", "badger")
if err != nil {
log.Fatal(err)
}
opts := badger.DefaultOptions
opts.Dir = dir
opts.ValueDir = dir
kv.db, err = badger.Open(opts)
if err != nil {
log.Fatal(err)
}
}
2018-10-31 08:48:53 +00:00
func (kv *BadgerKVStore) Close() {
2018-10-28 16:31:26 +00:00
kv.db.Close()
}
2018-10-31 08:48:53 +00:00
func (kv *BadgerKVStore) Put(key *string, value *string) error {
2018-10-28 16:31:26 +00:00
txn := kv.db.NewTransaction(true) // Read-write txn
err := txn.Set([]byte(*key), []byte(*value))
if err != nil {
log.Fatal(err)
}
err = txn.Commit(nil)
if err != nil {
log.Fatal(err)
}
return nil
}
2018-10-31 08:48:53 +00:00
func (kv *BadgerKVStore) Get(key *string) (*string, error) {
txn := kv.db.NewTransaction(false)
2018-10-28 16:31:26 +00:00
item, err := txn.Get([]byte(*key))
if err != nil {
return nil, err
}
val, err := item.ValueCopy(nil)
if err != nil {
return nil, err
}
s := string(val)
return &s, nil
}