split db and bolt to store interface

This commit is contained in:
ston1th 2018-09-11 14:50:53 +02:00
commit 7e77fd7d27
14 changed files with 419 additions and 545 deletions

74
pkg/store/boltstore.go Normal file
View file

@ -0,0 +1,74 @@
package store
import (
"github.com/boltdb/bolt"
)
const defaultBoltBucket = "default"
type BoltStore struct {
Marshaler
db *bolt.DB
}
func NewBoltStore(file string, m Marshaler) (bs *BoltStore, err error) {
if m == nil {
m = NewGOB()
}
db, err := bolt.Open(file, 0666, nil)
if err != nil {
return
}
if err = db.Update(func(tx *bolt.Tx) error {
if _, err := tx.CreateBucketIfNotExists([]byte(defaultBoltBucket)); err != nil {
return err
}
return nil
}); err != nil {
return
}
bs = &BoltStore{m, db}
return
}
func (bs *BoltStore) Get(key string, v interface{}) (err error) {
err = bs.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(defaultBoltBucket)).Get([]byte(key))
if b == nil {
return ErrKeyNotFound
}
if v != nil {
return bs.Unmarshal(b, v)
}
return nil
})
return
}
func (bs *BoltStore) Set(key string, v interface{}) error {
return bs.db.Update(func(tx *bolt.Tx) error {
b, err := bs.Marshal(v)
if err != nil {
return err
}
return tx.Bucket([]byte(defaultBoltBucket)).Put([]byte(key), b)
})
}
func (bs *BoltStore) ForEach(f func(string, []byte) error) error {
return bs.db.View(func(tx *bolt.Tx) error {
return tx.Bucket([]byte(defaultBoltBucket)).ForEach(func(k, v []byte) error {
return f(string(k), v)
})
})
}
func (bs *BoltStore) Delete(key string) error {
return bs.db.Update(func(tx *bolt.Tx) error {
return tx.Bucket([]byte(defaultBoltBucket)).Delete([]byte(key))
})
}
func (bs *BoltStore) Close() error {
return bs.db.Close()
}

100
pkg/store/dump.go Normal file
View file

@ -0,0 +1,100 @@
// Copyright (C) 2018 Marius Schellenberger
package store
/*import (
"encoding/json"
"fmt"
"io"
"os"
)
type Dumper interface {
Dump(io.Writer) error
}
type Restorer interface {
Restore(io.Reader) error
}
type DBDump struct {
Pages []DumpPage `json:"pages"`
Snippets []Snippet `json:"snippets"`
Users []User `json:"users"`
}
type DumpPage struct {
Title string `json:"title"`
LinkTitle string `json:"link_title"`
MD string `json:"md"`
Created string `json:"created"`
Updated string `json:"updated"`
Public bool `json:"public"`
}
func verboseLog(prefix, title string, v bool) {
if v {
fmt.Fprintln(os.Stderr, prefix, title)
}
}
func Dump(path string, v bool) (err error) {
bs, err := NewBoltStore()
if err != nil {
return
}
var dump DBDump
//TODO bs.GetAllPages
var pages []*core.Page
for _, p := range pages {
if err != nil {
return
}
verboseLog("dump:", p.Title, v)
dump.Pages = append(dump.Pages, DumpPage{
Title: p.Title,
LinkTitle: p.LinkTitle,
MD: p.MD,
Created: p.Created,
Updated: p.Updated,
Public: p.Public,
})
}
//TODO snippets
//verboseLog("dump:", "snippets", v)
verboseLog("dump:", "users", v)
dump.Users, err = bs.DumpUsers()
if err != nil {
return
}
return json.NewEncoder(os.Stdout).Encode(dump)
}
func Restore(path string, v bool) (err error) {
i, err := NewIndex(path)
if err != nil {
return
}
defer i.Close()
bs, err := NewBoltStore()
if err != nil {
return
}
var dump DBDump
err = json.NewDecoder(os.Stdin).Decode(&dump)
if err != nil {
return
}
for _, art := range dump.Articles {
verboseLog("restore:", art.Title, v)
err = i.Restore(&art)
if err != nil {
return
}
}
//TODO snippets
//verboseLog("restore:", "snippets", v)
verboseLog("restore:", "users", v)
err = bs.RestoreUsers(dump.Users)
return
}*/

28
pkg/store/marshal.go Normal file
View file

@ -0,0 +1,28 @@
package store
import (
"bytes"
"encoding/gob"
)
type Marshaler interface {
Marshal(v interface{}) ([]byte, error)
Unmarshal(data []byte, v interface{}) error
}
type gobMarshaler struct{}
func NewGOB() Marshaler {
return gobMarshaler{}
}
func (gobMarshaler) Marshal(v interface{}) (b []byte, err error) {
buf := new(bytes.Buffer)
err = gob.NewEncoder(buf).Encode(v)
b = buf.Bytes()
return
}
func (gobMarshaler) Unmarshal(data []byte, v interface{}) error {
return gob.NewDecoder(bytes.NewBuffer(data)).Decode(v)
}

37
pkg/store/store.go Normal file
View file

@ -0,0 +1,37 @@
// Copyright (C) 2018 Marius Schellenberger
package store
import (
"fmt"
)
//const (
// dbFile = "gowiki.db"
// defUser = "admin"
// defPassword = "gowiki"
// userTable = "user"
// pageTable = "page"
// snippetTable = "snippet"
// bcryptCost = 13
// indexName = "Index"
// welcome = `# Welcome to GoWiki
//This is the [Index](/wiki/Index) page.
//You can customize it how you like.`
// wikiSection = "wiki"
//)
func storeErr(i interface{}) error {
return fmt.Errorf("store: %s", i)
}
var ErrKeyNotFound = storeErr("key not found")
type Store interface {
Marshaler
Get(string, interface{}) error
Set(string, interface{}) error
ForEach(func(string, []byte) error) error
Delete(string) error
Close() error
}