get without content
parent
eedb6cc6a5
commit
4a9ecd820a
|
|
@ -17,6 +17,18 @@ func (branch Branch) IsZero() bool {
|
||||||
return branch.Leaf == (Leaf{}) && len(branch.Branches) == 0
|
return branch.Leaf == (Leaf{}) && len(branch.Branches) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (branch Branch) Find(baseId string) ([]string, bool) {
|
||||||
|
if _, ok := branch.Branches[baseId]; ok {
|
||||||
|
return []string{baseId}, true
|
||||||
|
}
|
||||||
|
for pid, child := range branch.Branches {
|
||||||
|
if subids, ok := child.Find(baseId); ok {
|
||||||
|
return append([]string{pid}, subids...), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
type Leaf struct {
|
type Leaf struct {
|
||||||
Title string
|
Title string
|
||||||
Deleted bool
|
Deleted bool
|
||||||
|
|
@ -46,18 +58,30 @@ func (tree Tree) WithRoot(root string) Tree {
|
||||||
return tree
|
return tree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tree Tree) Find(baseId string) ([]string, bool) {
|
||||||
|
root, err := tree.GetRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return root.Find(baseId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tree Tree) GetRootMeta() (Branch, error) {
|
||||||
|
return tree.getRoot(false)
|
||||||
|
}
|
||||||
|
|
||||||
func (tree Tree) GetRoot() (Branch, error) {
|
func (tree Tree) GetRoot() (Branch, error) {
|
||||||
if !tree.cachedRoot.IsZero() {
|
if !tree.cachedRoot.IsZero() {
|
||||||
return tree.cachedRoot, nil
|
return tree.cachedRoot, nil
|
||||||
}
|
}
|
||||||
got, err := tree.getRoot()
|
got, err := tree.getRoot(true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
tree.cachedRoot = got
|
tree.cachedRoot = got
|
||||||
}
|
}
|
||||||
return got, err
|
return got, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tree Tree) getRoot() (Branch, error) {
|
func (tree Tree) getRoot(withContent bool) (Branch, error) {
|
||||||
m := Branch{Branches: map[string]Branch{}}
|
m := Branch{Branches: map[string]Branch{}}
|
||||||
entries, err := os.ReadDir(tree.root)
|
entries, err := os.ReadDir(tree.root)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
|
|
@ -73,8 +97,11 @@ func (tree Tree) getRoot() (Branch, error) {
|
||||||
} else if err := yaml.Unmarshal(b, &m.Leaf); err != nil {
|
} else if err := yaml.Unmarshal(b, &m.Leaf); err != nil {
|
||||||
return Branch{}, err
|
return Branch{}, err
|
||||||
}
|
}
|
||||||
|
if !withContent {
|
||||||
|
m.Leaf.Content = ""
|
||||||
|
}
|
||||||
} else if entry.IsDir() {
|
} else if entry.IsDir() {
|
||||||
if branch, err := tree.WithRoot(path.Join(tree.root, entry.Name())).getRoot(); err != nil {
|
if branch, err := tree.WithRoot(path.Join(tree.root, entry.Name())).getRoot(withContent); err != nil {
|
||||||
return Branch{}, err
|
return Branch{}, err
|
||||||
} else {
|
} else {
|
||||||
m.Branches[entry.Name()] = branch
|
m.Branches[entry.Name()] = branch
|
||||||
|
|
@ -110,11 +137,16 @@ func (tree Tree) Put(id []string, input Leaf) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ensureAndWrite(tree.toData(id), b)
|
if err := ensureAndWrite(tree.toData(id), b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tree.cachedRoot = Branch{}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tree Tree) Del(id []string) error {
|
func (tree Tree) Del(id []string) error {
|
||||||
os.RemoveAll(tree.toDir(id))
|
os.RemoveAll(tree.toDir(id))
|
||||||
|
tree.cachedRoot = Branch{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestTreeCrud(t *testing.T) {
|
func TestTreeCrud(t *testing.T) {
|
||||||
tree := NewTree(t.TempDir())
|
tree := NewTree(t.TempDir())
|
||||||
|
|
@ -27,4 +32,73 @@ func TestTreeCrud(t *testing.T) {
|
||||||
} else if l != want {
|
} else if l != want {
|
||||||
t.Fatal(want, l)
|
t.Fatal(want, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if withContent, err := tree.GetRoot(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if withoutContent, err := tree.GetRootMeta(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if fmt.Sprint(withContent) == fmt.Sprint(withoutContent) {
|
||||||
|
with, _ := json.MarshalIndent(withContent, "", " ")
|
||||||
|
without, _ := json.MarshalIndent(withoutContent, "", " ")
|
||||||
|
t.Fatalf("without content == with content: \n\twith=%s\n\twout=%s", with, without)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBranchFind(t *testing.T) {
|
||||||
|
cases := map[string]struct {
|
||||||
|
input string
|
||||||
|
want []string
|
||||||
|
found bool
|
||||||
|
branch Branch
|
||||||
|
}{
|
||||||
|
"empty": {
|
||||||
|
input: "id",
|
||||||
|
want: nil,
|
||||||
|
found: false,
|
||||||
|
branch: Branch{},
|
||||||
|
},
|
||||||
|
"yes top level": {
|
||||||
|
input: "id",
|
||||||
|
want: []string{"id"},
|
||||||
|
found: true,
|
||||||
|
branch: Branch{
|
||||||
|
Branches: map[string]Branch{"id": Branch{}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"yes deep level": {
|
||||||
|
input: "subsubid",
|
||||||
|
want: []string{"id", "subid", "subsubid"},
|
||||||
|
found: true,
|
||||||
|
branch: Branch{
|
||||||
|
Branches: map[string]Branch{"id": Branch{
|
||||||
|
Branches: map[string]Branch{"subid": Branch{
|
||||||
|
Branches: map[string]Branch{"subsubid": Branch{}}}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"no but has deep levels": {
|
||||||
|
input: "notsubsubid",
|
||||||
|
want: nil,
|
||||||
|
found: false,
|
||||||
|
branch: Branch{
|
||||||
|
Branches: map[string]Branch{"id": Branch{
|
||||||
|
Branches: map[string]Branch{"subid": Branch{
|
||||||
|
Branches: map[string]Branch{"subsubid": Branch{}}}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, d := range cases {
|
||||||
|
c := d
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
got, found := c.branch.Find(c.input)
|
||||||
|
if found != c.found {
|
||||||
|
t.Error(c.found, found)
|
||||||
|
}
|
||||||
|
if path.Join(got...) != path.Join(c.want...) {
|
||||||
|
t.Error(c.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue