mirror of
https://codeberg.org/scip/anydb.git
synced 2025-12-17 20:41:00 +01:00
fixes and additions:
- add ANYDB_PASSWORD env var - add config file support, including buckets dict - finalized custom bucket support - fine tuned info support
This commit is contained in:
22
README.md
22
README.md
@@ -95,9 +95,29 @@ anydb import -r backup.json
|
|||||||
|
|
||||||
# you can encrypt entries. anydb asks for a passphrase
|
# you can encrypt entries. anydb asks for a passphrase
|
||||||
# and will do the same when you retrieve the key using the
|
# and will do the same when you retrieve the key using the
|
||||||
# get command.
|
# get command. anydb will ask you interactively for a password
|
||||||
anydb set mypassword -e
|
anydb set mypassword -e
|
||||||
|
|
||||||
|
# but you can provide it via an environment variable too
|
||||||
|
ANYDB_PASSWORD=foo anydb set -e secretkey blahblah
|
||||||
|
|
||||||
|
# too tiresome to add -e every time you add an entry?
|
||||||
|
# use a per bucket config
|
||||||
|
cat ~/.config/anydb/anydb.toml
|
||||||
|
[buckets.data]
|
||||||
|
encrypt = true
|
||||||
|
anydb set foo bar # will be encrypted
|
||||||
|
|
||||||
|
# speaking of buckets, you can use different buckets
|
||||||
|
anydb -b test set foo bar
|
||||||
|
|
||||||
|
# and speaking of configs, you can place a config file at these places:
|
||||||
|
# ~/.config/anydb/anydb.toml
|
||||||
|
# ~/.anydb.toml
|
||||||
|
# anydb.toml (current directory)
|
||||||
|
# or specify one using -c <filename>
|
||||||
|
# look at example.toml
|
||||||
|
|
||||||
# using template output mode you can freely design how to print stuff
|
# using template output mode you can freely design how to print stuff
|
||||||
# here, we print the values in CSV format ONLY if they have some tag
|
# here, we print the values in CSV format ONLY if they have some tag
|
||||||
anydb ls -m template -T "{{ if .Tags }}{{ .Key }},{{ .Value }},{{ .Created}}{{ end }}"
|
anydb ls -m template -T "{{ if .Tags }}{{ .Key }},{{ .Value }},{{ .Created}}{{ end }}"
|
||||||
|
|||||||
4
TODO.md
4
TODO.md
@@ -1,7 +1,3 @@
|
|||||||
- repl
|
- repl
|
||||||
- mime-type => exec app + value
|
- mime-type => exec app + value
|
||||||
- custom buckets (like skate: key@bucket or key+bucket)
|
|
||||||
- encryption per bucket, one key for all entries (in that bucket)
|
|
||||||
- `-b bucket`, use B for encrypted bucke?
|
|
||||||
- [edit command](https://github.com/TLINDEN/rpnc/blob/master/command.go#L249)
|
- [edit command](https://github.com/TLINDEN/rpnc/blob/master/command.go#L249)
|
||||||
- env var for password
|
|
||||||
|
|||||||
4
anydb.1
4
anydb.1
@@ -1,4 +1,4 @@
|
|||||||
.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40)
|
.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42)
|
||||||
.\"
|
.\"
|
||||||
.\" Standard preamble:
|
.\" Standard preamble:
|
||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "ANYDB 1"
|
.IX Title "ANYDB 1"
|
||||||
.TH ANYDB 1 "2024-12-18" "1" "User Commands"
|
.TH ANYDB 1 "2024-12-22" "1" "User Commands"
|
||||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||||
.\" way too many mistakes in technical documents.
|
.\" way too many mistakes in technical documents.
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
|
|||||||
29
app/db.go
29
app/db.go
@@ -50,9 +50,11 @@ type DbEntry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BucketInfo struct {
|
type BucketInfo struct {
|
||||||
Name string
|
Name string
|
||||||
Keys int
|
Keys int
|
||||||
Size int
|
Size int
|
||||||
|
Sequence uint64
|
||||||
|
Stats bolt.BucketStats
|
||||||
}
|
}
|
||||||
|
|
||||||
type DbInfo struct {
|
type DbInfo struct {
|
||||||
@@ -264,6 +266,7 @@ func (db *DB) Get(attr *DbAttr) (*DbEntry, error) {
|
|||||||
|
|
||||||
jsonentry := bucket.Get([]byte(attr.Key))
|
jsonentry := bucket.Get([]byte(attr.Key))
|
||||||
if jsonentry == nil {
|
if jsonentry == nil {
|
||||||
|
// FIXME: shall we return a key not found error?
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,16 +376,23 @@ func (db *DB) Info() (*DbInfo, error) {
|
|||||||
info := &DbInfo{Path: db.Dbfile}
|
info := &DbInfo{Path: db.Dbfile}
|
||||||
|
|
||||||
err := db.DB.View(func(tx *bolt.Tx) error {
|
err := db.DB.View(func(tx *bolt.Tx) error {
|
||||||
err := tx.ForEach(func(name []byte, bucket *bolt.Bucket) error {
|
err := tx.ForEach(func(name []byte, bucket *bolt.Bucket) error {
|
||||||
binfo := BucketInfo{Name: string(name)}
|
stats := bucket.Stats()
|
||||||
|
|
||||||
|
binfo := BucketInfo{
|
||||||
|
Name: string(name),
|
||||||
|
Sequence: bucket.Sequence(),
|
||||||
|
Keys: stats.KeyN,
|
||||||
|
Stats: bucket.Stats(),
|
||||||
|
}
|
||||||
|
|
||||||
err := bucket.ForEach(func(key, entry []byte) error {
|
err := bucket.ForEach(func(key, entry []byte) error {
|
||||||
binfo.Size += len(entry)
|
binfo.Size += len(entry) + len(key)
|
||||||
binfo.Keys++
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to read keys: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
info.Buckets = append(info.Buckets, binfo)
|
info.Buckets = append(info.Buckets, binfo)
|
||||||
@@ -391,11 +401,12 @@ func (db *DB) Info() (*DbInfo, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to read from DB: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return info, err
|
return info, err
|
||||||
}
|
}
|
||||||
|
|||||||
106
cfg/config.go
106
cfg/config.go
@@ -1,20 +1,114 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2024 Thomas von Dein
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
package cfg
|
package cfg
|
||||||
|
|
||||||
import "github.com/tlinden/anydb/app"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/pelletier/go-toml"
|
||||||
|
"github.com/tlinden/anydb/app"
|
||||||
|
"github.com/tlinden/anydb/common"
|
||||||
|
)
|
||||||
|
|
||||||
var Version string = "v0.0.4"
|
var Version string = "v0.0.4"
|
||||||
|
|
||||||
|
type BucketConfig struct {
|
||||||
|
Encrypt bool
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Debug bool
|
Debug bool
|
||||||
Dbfile string
|
Dbfile string
|
||||||
Dbbucket string
|
Dbbucket string
|
||||||
Template string
|
Template string
|
||||||
Mode string // wide, table, yaml, json
|
Mode string // wide, table, yaml, json
|
||||||
NoHeaders bool
|
NoHeaders bool
|
||||||
NoHumanize bool
|
NoHumanize bool
|
||||||
Encrypt bool
|
Encrypt bool // one entry
|
||||||
DB *app.DB
|
|
||||||
File string
|
|
||||||
Tags []string
|
|
||||||
Listen string
|
Listen string
|
||||||
|
Buckets map[string]BucketConfig // config file only
|
||||||
|
|
||||||
|
Tags []string // internal
|
||||||
|
DB *app.DB // internal
|
||||||
|
File string // internal
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conf *Config) GetConfig(files []string) error {
|
||||||
|
for _, file := range files {
|
||||||
|
if err := conf.ParseConfigFile(file); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conf *Config) ParseConfigFile(file string) error {
|
||||||
|
if !common.FileExists(file) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err := os.OpenFile(file, os.O_RDONLY, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to open config file %s: %w", file, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := io.ReadAll(fd)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read from config file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
add := Config{}
|
||||||
|
err = toml.Unmarshal(data, &add)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshall toml: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge new values into existing config
|
||||||
|
switch {
|
||||||
|
case add.Debug != conf.Debug:
|
||||||
|
conf.Debug = add.Debug
|
||||||
|
case add.Dbfile != "":
|
||||||
|
conf.Dbfile = add.Dbfile
|
||||||
|
case add.Dbbucket != "":
|
||||||
|
conf.Dbbucket = add.Dbbucket
|
||||||
|
case add.Template != "":
|
||||||
|
conf.Template = add.Template
|
||||||
|
case add.NoHeaders != conf.NoHeaders:
|
||||||
|
conf.NoHeaders = add.NoHeaders
|
||||||
|
case add.NoHumanize != conf.NoHumanize:
|
||||||
|
conf.NoHumanize = add.NoHumanize
|
||||||
|
case add.Encrypt != conf.Encrypt:
|
||||||
|
conf.Encrypt = add.Encrypt
|
||||||
|
case add.Listen != "":
|
||||||
|
conf.Listen = add.Listen
|
||||||
|
}
|
||||||
|
|
||||||
|
// only supported in config files
|
||||||
|
conf.Buckets = add.Buckets
|
||||||
|
|
||||||
|
// determine bucket encryption mode
|
||||||
|
for name, bucket := range conf.Buckets {
|
||||||
|
if name == conf.Dbbucket {
|
||||||
|
conf.Encrypt = bucket.Encrypt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
25
cmd/crud.go
25
cmd/crud.go
@@ -65,7 +65,7 @@ func Set(conf *cfg.Config) *cobra.Command {
|
|||||||
|
|
||||||
// encrypt?
|
// encrypt?
|
||||||
if conf.Encrypt {
|
if conf.Encrypt {
|
||||||
pass, err := app.AskForPassword()
|
pass, err := getPassword()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ func Get(conf *cfg.Config) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if entry.Encrypted {
|
if entry.Encrypted {
|
||||||
pass, err := app.AskForPassword()
|
pass, err := getPassword()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -371,7 +371,26 @@ func Info(conf *cfg.Config) *cobra.Command {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.PersistentFlags().StringVarP(&conf.Listen, "listen", "l", "localhost:8787", "host:port")
|
cmd.PersistentFlags().BoolVarP(&conf.NoHumanize, "no-human", "N", false, "do not translate to human readable values")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPassword() ([]byte, error) {
|
||||||
|
var pass []byte
|
||||||
|
|
||||||
|
envpass := os.Getenv("ANYDB_PASSWORD")
|
||||||
|
|
||||||
|
if envpass == "" {
|
||||||
|
readpass, err := app.AskForPassword()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pass = readpass
|
||||||
|
} else {
|
||||||
|
pass = []byte(envpass)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pass, nil
|
||||||
|
}
|
||||||
|
|||||||
34
cmd/root.go
34
cmd/root.go
@@ -22,6 +22,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/alecthomas/repr"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/tlinden/anydb/app"
|
"github.com/tlinden/anydb/app"
|
||||||
"github.com/tlinden/anydb/cfg"
|
"github.com/tlinden/anydb/cfg"
|
||||||
@@ -45,10 +46,22 @@ func completion(cmd *cobra.Command, mode string) error {
|
|||||||
func Execute() {
|
func Execute() {
|
||||||
var (
|
var (
|
||||||
conf cfg.Config
|
conf cfg.Config
|
||||||
|
configfile string
|
||||||
ShowVersion bool
|
ShowVersion bool
|
||||||
ShowCompletion string
|
ShowCompletion string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchConfigs := []string{
|
||||||
|
filepath.Join(home, ".config", "anydb", "anydb.toml"),
|
||||||
|
filepath.Join(home, ".anydb.toml"),
|
||||||
|
"anydb.toml",
|
||||||
|
}
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "anydb <command> [options]",
|
Use: "anydb <command> [options]",
|
||||||
Short: "anydb",
|
Short: "anydb",
|
||||||
@@ -61,6 +74,21 @@ func Execute() {
|
|||||||
|
|
||||||
conf.DB = db
|
conf.DB = db
|
||||||
|
|
||||||
|
var configs []string
|
||||||
|
if configfile != "" {
|
||||||
|
configs = []string{configfile}
|
||||||
|
} else {
|
||||||
|
configs = SearchConfigs
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := conf.GetConfig(configs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.Debug {
|
||||||
|
repr.Println(conf)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -82,11 +110,6 @@ func Execute() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
home, err := os.UserHomeDir()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// options
|
// options
|
||||||
rootCmd.PersistentFlags().BoolVarP(&ShowVersion, "version", "v", false, "Print program version")
|
rootCmd.PersistentFlags().BoolVarP(&ShowVersion, "version", "v", false, "Print program version")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&conf.Debug, "debug", "d", false, "Enable debugging")
|
rootCmd.PersistentFlags().BoolVarP(&conf.Debug, "debug", "d", false, "Enable debugging")
|
||||||
@@ -94,6 +117,7 @@ func Execute() {
|
|||||||
filepath.Join(home, ".config", "anydb", "default.db"), "DB file to use")
|
filepath.Join(home, ".config", "anydb", "default.db"), "DB file to use")
|
||||||
rootCmd.PersistentFlags().StringVarP(&conf.Dbbucket, "bucket", "b",
|
rootCmd.PersistentFlags().StringVarP(&conf.Dbbucket, "bucket", "b",
|
||||||
app.BucketData, "use other bucket (default: "+app.BucketData+")")
|
app.BucketData, "use other bucket (default: "+app.BucketData+")")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&configfile, "config", "c", "", "toml config file")
|
||||||
|
|
||||||
rootCmd.AddCommand(Set(&conf))
|
rootCmd.AddCommand(Set(&conf))
|
||||||
rootCmd.AddCommand(List(&conf))
|
rootCmd.AddCommand(List(&conf))
|
||||||
|
|||||||
36
common/io.go
Normal file
36
common/io.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2024 Thomas von Dein
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package common
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
func CleanError(file string, err error) error {
|
||||||
|
// remove given [backup] file and forward the given error
|
||||||
|
os.Remove(file)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileExists(filename string) bool {
|
||||||
|
info, err := os.Stat(filename)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// return false on any error
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return !info.IsDir()
|
||||||
|
}
|
||||||
1
go.mod
1
go.mod
@@ -16,6 +16,7 @@ require (
|
|||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/rivo/uniseg v0.2.0 // indirect
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||||
github.com/spf13/cobra v1.8.1 // indirect
|
github.com/spf13/cobra v1.8.1 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -45,6 +45,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
|
|||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
|
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/dustin/go-humanize"
|
||||||
"github.com/tlinden/anydb/app"
|
"github.com/tlinden/anydb/app"
|
||||||
"github.com/tlinden/anydb/cfg"
|
"github.com/tlinden/anydb/cfg"
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
@@ -96,12 +98,33 @@ func WriteFile(writer io.Writer, conf *cfg.Config, attr *app.DbAttr, entry *app.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Info(writer io.Writer, conf *cfg.Config, info *app.DbInfo) error {
|
func Info(writer io.Writer, conf *cfg.Config, info *app.DbInfo) error {
|
||||||
// repr.Println(info)
|
|
||||||
fmt.Fprintf(writer, "Database: %s\n", info.Path)
|
fmt.Fprintf(writer, "Database: %s\n", info.Path)
|
||||||
|
|
||||||
for _, bucket := range info.Buckets {
|
for _, bucket := range info.Buckets {
|
||||||
|
if conf.NoHumanize {
|
||||||
|
fmt.Fprintf(
|
||||||
|
writer,
|
||||||
|
"%19s: %s\n%19s: %d\n%19s: %d\n",
|
||||||
|
"Bucket", bucket.Name,
|
||||||
|
"Size", bucket.Size,
|
||||||
|
"Keys", bucket.Keys)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(
|
||||||
|
writer,
|
||||||
|
"%19s: %s\n%19s: %s\n%19s: %d\n",
|
||||||
|
"Bucket", bucket.Name,
|
||||||
|
"Size", humanize.Bytes(uint64(bucket.Size)),
|
||||||
|
"Keys", bucket.Keys)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Fprintf(writer, "Bucket: %s\n Size: %d\n Keys: %d\n\n", bucket.Name, bucket.Size, bucket.Keys)
|
if conf.Debug {
|
||||||
|
val := reflect.ValueOf(&bucket.Stats).Elem()
|
||||||
|
for i := 0; i < val.NumField(); i++ {
|
||||||
|
fmt.Fprintf(writer, "%19s: %d\n", val.Type().Field(i).Name, val.Field(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(writer)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user