-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdb_manager.go
60 lines (48 loc) · 1.68 KB
/
db_manager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package main
import (
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/opt"
)
// DBManager interface defines methods for working with a database.
type DBManager interface {
Close() error
NewDatastore() Datastore
}
type dbOpener func(dbPath string, o *opt.Options) (*leveldb.DB, error)
type dbRecoverer func(dbPath string, o *opt.Options) (*leveldb.DB, error)
type levelDBManager struct {
db *leveldb.DB
}
// NewDBManager will return a new DBManager instance.
func NewDBManager(config *Config) (DBManager, error) {
db, err := openLevelDBFromFile(leveldb.OpenFile, leveldb.RecoverFile, config.DBPath, nil)
if err != nil {
return nil, err
}
return &levelDBManager{db: db}, nil
}
// Close will close the database.
func (m *levelDBManager) Close() error {
return m.db.Close()
}
// NewDatastore will return a new Datastore instance.
func (m *levelDBManager) NewDatastore() Datastore {
return &levelDBDatastore{db: m.db}
}
// OpenDBFromFile will attempt to open (or create) a connection to the database
// specified by dbPath using options o. If it detects that the database files
// are corrupt, this method will attempt to automatically recover them.
func openLevelDBFromFile(opener dbOpener, recoverer dbRecoverer, dbPath string, o *opt.Options) (*leveldb.DB, error) {
db, err := opener(dbPath, o)
if err != nil {
if _, ok := err.(leveldb.ErrCorrupted); ok {
db, err = attemptRecovery(recoverer, dbPath, o)
}
}
return db, err
}
// AttemptRecovery attempts to recover from a corrupt database specified by
// dbPath using options o.
func attemptRecovery(recoverer dbRecoverer, dbPath string, o *opt.Options) (*leveldb.DB, error) {
return recoverer(dbPath, o)
}