mirror of
https://github.com/taigrr/bitcask
synced 2025-01-18 04:03:17 -08:00
Initial Commit
This commit is contained in:
46
cmd/bitcask/del.go
Normal file
46
cmd/bitcask/del.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/prologic/bitcask"
|
||||
)
|
||||
|
||||
var delCmd = &cobra.Command{
|
||||
Use: "del <key>",
|
||||
Aliases: []string{"delete", "remove", "rm"},
|
||||
Short: "Delete a key and its value",
|
||||
Long: `This deletes a key and its value`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
path := viper.GetString("path")
|
||||
|
||||
key := args[0]
|
||||
|
||||
os.Exit(del(path, key))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(delCmd)
|
||||
}
|
||||
|
||||
func del(path, key string) int {
|
||||
db, err := bitcask.Open(path)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error opening database")
|
||||
return 1
|
||||
}
|
||||
|
||||
err = db.Delete(key)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error deleting key")
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
50
cmd/bitcask/get.go
Normal file
50
cmd/bitcask/get.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/prologic/bitcask"
|
||||
)
|
||||
|
||||
var getCmd = &cobra.Command{
|
||||
Use: "get <key>",
|
||||
Aliases: []string{"view"},
|
||||
Short: "Get a new Key and display its Value",
|
||||
Long: `This retrieves a key and display its value`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
path := viper.GetString("path")
|
||||
|
||||
key := args[0]
|
||||
|
||||
os.Exit(get(path, key))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(getCmd)
|
||||
}
|
||||
|
||||
func get(path, key string) int {
|
||||
db, err := bitcask.Open(path)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error opening database")
|
||||
return 1
|
||||
}
|
||||
|
||||
value, err := db.Get(key)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error reading key")
|
||||
return 1
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", string(value))
|
||||
log.WithField("key", key).WithField("value", value).Debug("key/value")
|
||||
|
||||
return 0
|
||||
}
|
||||
48
cmd/bitcask/keys.go
Normal file
48
cmd/bitcask/keys.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/prologic/bitcask"
|
||||
)
|
||||
|
||||
var keysCmd = &cobra.Command{
|
||||
Use: "keys",
|
||||
Aliases: []string{"list", "ls"},
|
||||
Short: "Display all keys in Database",
|
||||
Long: `This displays all known keys in the Database"`,
|
||||
Args: cobra.ExactArgs(0),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
path := viper.GetString("path")
|
||||
|
||||
os.Exit(keys(path))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(keysCmd)
|
||||
}
|
||||
|
||||
func keys(path string) int {
|
||||
db, err := bitcask.Open(path)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error opening database")
|
||||
return 1
|
||||
}
|
||||
|
||||
err = db.Fold(func(key string) error {
|
||||
fmt.Printf("%s\n", key)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error listing keys")
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
5
cmd/bitcask/main.go
Normal file
5
cmd/bitcask/main.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
Execute()
|
||||
}
|
||||
50
cmd/bitcask/merge.go
Normal file
50
cmd/bitcask/merge.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/prologic/bitcask"
|
||||
)
|
||||
|
||||
var mergeCmd = &cobra.Command{
|
||||
Use: "merge",
|
||||
Aliases: []string{"clean", "compact", "defrag"},
|
||||
Short: "Merges the Datafiles in the Database",
|
||||
Long: `This merges all non-active Datafiles in the Database and
|
||||
compacts the data stored on disk. Old values are removed as well as deleted
|
||||
keys.`,
|
||||
Args: cobra.ExactArgs(0),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
path := viper.GetString("path")
|
||||
force, err := cmd.Flags().GetBool("force")
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error parsing force flag")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
os.Exit(merge(path, force))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(mergeCmd)
|
||||
|
||||
mergeCmd.Flags().BoolP(
|
||||
"force", "f", false,
|
||||
"Force a re-merge even if .hint files exist",
|
||||
)
|
||||
}
|
||||
|
||||
func merge(path string, force bool) int {
|
||||
err := bitcask.Merge(path, force)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error merging database")
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
60
cmd/bitcask/root.go
Normal file
60
cmd/bitcask/root.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/prologic/bitcask"
|
||||
)
|
||||
|
||||
// RootCmd represents the base command when called without any subcommands
|
||||
var RootCmd = &cobra.Command{
|
||||
Use: "bitcask",
|
||||
Version: bitcask.FullVersion(),
|
||||
Short: "Command-line tools for bitcask",
|
||||
Long: `This is the command-line tool to interact with a bitcask database.
|
||||
|
||||
This lets you get, set and delete key/value pairs as well as perform merge
|
||||
(or compaction) operations. This tool serves as an example implementation
|
||||
however is also intended to be useful in shell scripts.`,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
// set logging level
|
||||
if viper.GetBool("debug") {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
} else {
|
||||
log.SetLevel(log.InfoLevel)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Execute adds all child commands to the root command
|
||||
// and sets flags appropriately.
|
||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||
func Execute() {
|
||||
if err := RootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.PersistentFlags().BoolP(
|
||||
"debug", "d", false,
|
||||
"Enable debug logging",
|
||||
)
|
||||
|
||||
RootCmd.PersistentFlags().StringP(
|
||||
"path", "p", "/tmp/bitcask",
|
||||
"Path to Bitcask database",
|
||||
)
|
||||
|
||||
viper.BindPFlag("path", RootCmd.PersistentFlags().Lookup("path"))
|
||||
viper.SetDefault("path", "/tmp/bitcask")
|
||||
|
||||
viper.BindPFlag("debug", RootCmd.PersistentFlags().Lookup("debug"))
|
||||
viper.SetDefault("debug", false)
|
||||
}
|
||||
64
cmd/bitcask/set.go
Normal file
64
cmd/bitcask/set.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/prologic/bitcask"
|
||||
)
|
||||
|
||||
var setCmd = &cobra.Command{
|
||||
Use: "set <key> [<value>]",
|
||||
Aliases: []string{"add"},
|
||||
Short: "Add/Set a new Key/Value pair",
|
||||
Long: `This adds or sets a new key/value pair.
|
||||
|
||||
If the value is not specified as an argument it is read from standard input.`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
path := viper.GetString("path")
|
||||
|
||||
key := args[0]
|
||||
|
||||
var value io.Reader
|
||||
if len(args) > 1 {
|
||||
value = bytes.NewBufferString(args[1])
|
||||
} else {
|
||||
value = os.Stdin
|
||||
}
|
||||
|
||||
os.Exit(set(path, key, value))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(setCmd)
|
||||
}
|
||||
|
||||
func set(path, key string, value io.Reader) int {
|
||||
db, err := bitcask.Open(path)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error opening database")
|
||||
return 1
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(value)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error writing key")
|
||||
return 1
|
||||
}
|
||||
|
||||
err = db.Put(key, data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error writing key")
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user