Skip to content

Commit

Permalink
implement db export to json
Browse files Browse the repository at this point in the history
  • Loading branch information
laktak committed Dec 22, 2024
1 parent b2269fc commit 63eb070
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 13 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ Commands:
init-db <path> [flags]
initialize a new index database at the given path for use with --db
export-db <path> [flags]
export a database to a json for archiving
show-ignored-only <paths> ... [flags]
only show ignored files
Expand Down
11 changes: 11 additions & 0 deletions cmd/chkbit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ type CLI struct {
Force bool `help:"force init if a database already exists"`
} `cmd:"" help:"initialize a new index database at the given path for use with --db"`

ExportDb struct {
Path string `arg:"" help:"directory for the database"`
} `cmd:"" help:"export a database to a json for archiving"`

ShowIgnoredOnly struct {
Paths []string `arg:"" name:"paths" help:"directories to list"`
} `cmd:"" help:"only show ignored files"`
Expand Down Expand Up @@ -377,6 +381,13 @@ func (m *Main) run() int {
return 1
}
return 0
case "export-db <path>":
m.log("chkbit export-db " + cli.ExportDb.Path)
if err := chkbit.ExportIndexDb(cli.ExportDb.Path, cli.IndexName); err != nil {
fmt.Println("error: " + err.Error())
return 1
}
return 0
case "tips":
fmt.Println(strings.ReplaceAll(helpTips, "<config-file>", configPath))
return 0
Expand Down
86 changes: 73 additions & 13 deletions store.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package chkbit

import (
"encoding/json"
"errors"
"io"
"os"
Expand Down Expand Up @@ -38,19 +39,8 @@ func (s *store) Open(readOnly bool) error {
var err error
s.readOnly = readOnly
if s.useDb {
optR := &bolt.Options{
ReadOnly: true,
Timeout: 0,
NoGrowSync: false,
FreelistType: bolt.FreelistArrayType,
}
optW := &bolt.Options{
Timeout: 0,
NoGrowSync: false,
FreelistType: bolt.FreelistArrayType,
}
s.dbFile = getDbFile(s.dbPath, s.indexName, "")
s.connR, err = bolt.Open(s.dbFile, 0600, optR)
s.connR, err = bolt.Open(s.dbFile, 0600, getBoltOptions(true))

if !readOnly {
s.newFile = getDbFile(s.dbPath, s.indexName, newDbSuffix)
Expand All @@ -64,7 +54,7 @@ func (s *store) Open(readOnly bool) error {
return err
}

s.connW, err = bolt.Open(s.newFile, 0600, optW)
s.connW, err = bolt.Open(s.newFile, 0600, getBoltOptions(false))
if err == nil {
err = s.connW.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte("data"))
Expand Down Expand Up @@ -188,6 +178,67 @@ func LocateIndexDb(path, indexName string) (string, error) {
}
}

func ExportIndexDb(path, indexName string) error {

dbFile := getDbFile(path, indexName, "")
connR, err := bolt.Open(dbFile, 0600, getBoltOptions(true))
if err != nil {
return err
}

file, err := os.Create(getDbFile(path, indexName, ".json"))
if err != nil {
return err
}
defer file.Close() // Ensure the file is closed when the function exits

_, err = file.WriteString("{")
if err != nil {
return err
}

err = connR.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("data"))
c := b.Cursor()
var ierr error
first := true
for k, v := c.First(); k != nil; k, v = c.Next() {

if first {
first = false
} else {
if _, ierr = file.WriteString(","); ierr != nil {
break
}
}

if idxPath, ierr := json.Marshal(string(k)); ierr == nil {
if _, ierr = file.Write(idxPath); ierr != nil {
break
}
} else {
break
}

if _, ierr = file.WriteString(":"); ierr != nil {
break
}

if _, ierr = file.Write(v); ierr != nil {
break
}
}
return ierr
})

_, err = file.WriteString("}")
if err != nil {
return err
}

return err
}

func getDbFile(path, indexFilename, suffix string) string {
return filepath.Join(path, indexFilename+dbSuffix+suffix)
}
Expand Down Expand Up @@ -217,3 +268,12 @@ func copyFile(src, dst string) error {
_, err = io.Copy(df, sf)
return err
}

func getBoltOptions(readOnly bool) *bolt.Options {
return &bolt.Options{
ReadOnly: readOnly,
Timeout: 0,
NoGrowSync: false,
FreelistType: bolt.FreelistArrayType,
}
}

0 comments on commit 63eb070

Please sign in to comment.