|
|
@@ -9,6 +9,7 @@ package db
|
|
|
import (
|
|
|
"bytes"
|
|
|
"encoding/binary"
|
|
|
+ "fmt"
|
|
|
"os"
|
|
|
"sort"
|
|
|
"strings"
|
|
|
@@ -60,31 +61,32 @@ func Open(file string) (*Instance, error) {
|
|
|
// the database and reindexing...
|
|
|
l.Infoln("Database corruption detected, unable to recover. Reinitializing...")
|
|
|
if err := os.RemoveAll(file); err != nil {
|
|
|
- return nil, err
|
|
|
+ return nil, errorSuggestion{err, "failed to delete corrupted database"}
|
|
|
}
|
|
|
db, err = leveldb.OpenFile(file, opts)
|
|
|
}
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return nil, errorSuggestion{err, "is another instance of Syncthing running?"}
|
|
|
}
|
|
|
|
|
|
- return newDBInstance(db, file), nil
|
|
|
+ return newDBInstance(db, file)
|
|
|
}
|
|
|
|
|
|
func OpenMemory() *Instance {
|
|
|
db, _ := leveldb.Open(storage.NewMemStorage(), nil)
|
|
|
- return newDBInstance(db, "<memory>")
|
|
|
+ ldb, _ := newDBInstance(db, "<memory>")
|
|
|
+ return ldb
|
|
|
}
|
|
|
|
|
|
-func newDBInstance(db *leveldb.DB, location string) *Instance {
|
|
|
+func newDBInstance(db *leveldb.DB, location string) (*Instance, error) {
|
|
|
i := &Instance{
|
|
|
DB: db,
|
|
|
location: location,
|
|
|
}
|
|
|
i.folderIdx = newSmallIndex(i, []byte{KeyTypeFolderIdx})
|
|
|
i.deviceIdx = newSmallIndex(i, []byte{KeyTypeDeviceIdx})
|
|
|
- i.updateSchema()
|
|
|
- return i
|
|
|
+ err := i.updateSchema()
|
|
|
+ return i, err
|
|
|
}
|
|
|
|
|
|
// Committed returns the number of items committed to the database since startup
|
|
|
@@ -935,3 +937,12 @@ func resize(k []byte, reqLen int) []byte {
|
|
|
}
|
|
|
return k[:reqLen]
|
|
|
}
|
|
|
+
|
|
|
+type errorSuggestion struct {
|
|
|
+ inner error
|
|
|
+ suggestion string
|
|
|
+}
|
|
|
+
|
|
|
+func (e errorSuggestion) Error() string {
|
|
|
+ return fmt.Sprintf("%s (%s)", e.inner.Error(), e.suggestion)
|
|
|
+}
|