Skip to content

Commit

Permalink
fixed crash in api list, added filter support to api list
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas von Dein committed Jan 1, 2025
1 parent 675d10d commit 9afca91
Show file tree
Hide file tree
Showing 10 changed files with 31 additions and 29 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ curl localhost:8787/anydb/v1/foo
# list keys
curl localhost:8787/anydb/v1/

# same, but do a full text search by content, searching for "foo"
curl -X POST http://127.0.0.1:8787/anydb/v1/ \
-H 'Content-Type: application/json'
-d '{"key":"foo", "fulltext": true}'

# as you might correctly suspect you can store multi-line values or
# the content of text files. but what to do if you want to change it?
# here's one way:
Expand Down
20 changes: 0 additions & 20 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,16 @@
- mime-type => exec app + value
- add waitgroup to db.go funcs
- RestList does not support any params?
- lc() incoming tags+keys

## DB Structure

- put tags into sub bucket see #1
- change structure to:

data bucket
key => {key,value[0:60],isbin:bool}

value bucket
key => value (maybe always use []byte here)

tags bucket
key/tag => tag/key
tag/key => tag

So, list just uses the data bucket, no large contents.
A tag search only looksup matching tags, see #1.
Only a full text search and get would need to dig into the value bucket.

A delete would just delete all keys from all values and then:
lookup in tags bucket for all key/*, then iterate over the values and
remove all tag/key's. Then deleting a key would not leave any residue
behind.

However, maybe change the list command to just list everything and add
an extra find command for fulltext or tag search. Maybe still provide
filter options in list command but only filter for keys.

DONE: most of the above, except the tag stuff. manpage needs update and tests.

maybe stitch the find command and just add -f (full text search) to list.
2 changes: 1 addition & 1 deletion anydb.1
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "ANYDB 1"
.TH ANYDB 1 "2024-12-30" "1" "User Commands"
.TH ANYDB 1 "2025-01-01" "1" "User Commands"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
Expand Down
3 changes: 3 additions & 0 deletions app/attr.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ type DbAttr struct {
File string
Encrypted bool
Binary bool

// conf flags, needed for incoming rest requests
Fulltext bool
}

// check if value is to be read from a file or stdin, setup preview
Expand Down
15 changes: 13 additions & 2 deletions app/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,15 @@ func (db *DB) List(attr *DbAttr, fulltext bool) (DbEntries, error) {
var filter *regexp.Regexp

if len(attr.Args) > 0 {
// via cli
filter = regexp.MustCompile(attr.Args[0])
}

if len(attr.Key) > 0 {
// via api
filter = regexp.MustCompile(attr.Key)
}

err := db.DB.View(func(tx *bolt.Tx) error {
root := tx.Bucket([]byte(db.Bucket))
if root == nil {
Expand All @@ -120,7 +126,13 @@ func (db *DB) List(attr *DbAttr, fulltext bool) (DbEntries, error) {
return fmt.Errorf("failed to unmarshal from protobuf: %w", err)
}

entry.Value = databucket.Get([]byte(entry.Key)) // empty is ok
if fulltext {
// avoid crash due to access fault
value := databucket.Get([]byte(entry.Key)) // empty is ok
vc := make([]byte, len(value))
copy(vc, value)
entry.Value = vc
}

var include bool

Expand Down Expand Up @@ -327,7 +339,6 @@ func (db *DB) Get(attr *DbAttr) (*DbEntry, error) {
}

func (db *DB) Del(attr *DbAttr) error {
// FIXME: check if it exists prior to just call bucket.Delete()?
if err := db.Open(); err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cfg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"github.com/tlinden/anydb/common"
)

var Version string = "v0.1.0"
var Version string = "v0.1.1"

type BucketConfig struct {
Encrypt bool
Expand Down
2 changes: 1 addition & 1 deletion cmd/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func List(conf *cfg.Config) *cobra.Command {
)

var cmd = &cobra.Command{
Use: "list [<filter-regex> | -t <tag> ] [-m <mode>] [-nNif] [-T <tpl>]",
Use: "list [<filter-regex> | -t <tag> ] [-m <mode>] [-nNis] [-T <tpl>]",
Short: "List database contents",
Long: `List database contents`,
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
1 change: 0 additions & 1 deletion output/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (
)

func List(writer io.Writer, conf *cfg.Config, entries app.DbEntries) error {
// FIXME: call sort here
switch conf.Mode {
case "wide", "", "table":
return ListTable(writer, conf, entries)
Expand Down
3 changes: 1 addition & 2 deletions rest/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ func RestList(c *fiber.Ctx, conf *cfg.Config) error {
attr := new(app.DbAttr)

if len(c.Body()) > 0 {

if err := c.BodyParser(attr); err != nil {
return c.Status(fiber.StatusUnprocessableEntity).JSON(fiber.Map{
"errors": err.Error(),
Expand All @@ -54,7 +53,7 @@ func RestList(c *fiber.Ctx, conf *cfg.Config) error {
}

// get list
entries, err := conf.DB.List(attr, false)
entries, err := conf.DB.List(attr, attr.Fulltext)
if err != nil {
return JsonStatus(c, fiber.StatusForbidden,
"Unable to list keys: "+err.Error())
Expand Down
7 changes: 6 additions & 1 deletion rest/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ func Runserver(conf *cfg.Config, args []string) error {
return RestList(c, conf)
})

api.Post("/", func(c *fiber.Ctx) error {
// same thing as above but allows to supply parameters, see app.Dbattr{}
return RestList(c, conf)
})

api.Get("/:key", func(c *fiber.Ctx) error {
return RestGet(c, conf)
})
Expand Down Expand Up @@ -78,7 +83,7 @@ func SetupServer(conf *cfg.Config) *fiber.App {
})

router.Use(logger.New(logger.Config{
Format: "${pid} ${ip}:${port} ${status} - ${method} ${path}\n",
Format: "${pid} ${ip}:${port} ${status} - ${method} ${path}\n",
DisableColors: true,
}))

Expand Down

0 comments on commit 9afca91

Please sign in to comment.