aboutsummaryrefslogtreecommitdiff
path: root/tx.go
diff options
context:
space:
mode:
Diffstat (limited to 'tx.go')
-rw-r--r--tx.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/tx.go b/tx.go
index fd456eb..35d47f8 100644
--- a/tx.go
+++ b/tx.go
@@ -3,6 +3,8 @@ package bolt
import (
"errors"
"fmt"
+ "io"
+ "os"
"sort"
"time"
"unsafe"
@@ -227,6 +229,55 @@ func (tx *Tx) close() {
tx.db = nil
}
+// Copy writes the entire database to a writer.
+// A reader transaction is maintained during the copy so it is safe to continue
+// using the database while a copy is in progress.
+func (tx *Tx) Copy(w io.Writer) error {
+
+ // Open reader on the database.
+ f, err := os.Open(tx.db.path)
+ if err != nil {
+ _ = tx.Rollback()
+ return err
+ }
+
+ // Copy the meta pages.
+ tx.db.metalock.Lock()
+ _, err = io.CopyN(w, f, int64(tx.db.pageSize*2))
+ tx.db.metalock.Unlock()
+ if err != nil {
+ _ = tx.Rollback()
+ _ = f.Close()
+ return fmt.Errorf("meta copy: %s", err)
+ }
+
+ // Copy data pages.
+ if _, err := io.Copy(w, f); err != nil {
+ _ = tx.Rollback()
+ _ = f.Close()
+ return err
+ }
+
+ return f.Close()
+}
+
+// CopyFile copies the entire database to file at the given path.
+// A reader transaction is maintained during the copy so it is safe to continue
+// using the database while a copy is in progress.
+func (tx *Tx) CopyFile(path string, mode os.FileMode) error {
+ f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
+ if err != nil {
+ return err
+ }
+
+ err = tx.Copy(f)
+ if err != nil {
+ _ = f.Close()
+ return err
+ }
+ return f.Close()
+}
+
// Check performs several consistency checks on the database for this transaction.
// An error is returned if any inconsistency is found or if executed on a read-only transaction.
func (tx *Tx) Check() error {