Skip to content

Commit

Permalink
Delete method and some fixes are added (#7)
Browse files Browse the repository at this point in the history
Co-authored-by: Konstantin Zhernosenko <konstantin.zhernosenko@humans.net>
  • Loading branch information
kainobor and Konstantin Zhernosenko authored Feb 16, 2021
1 parent 8a452fe commit 71d1d1f
Show file tree
Hide file tree
Showing 8 changed files with 443 additions and 46 deletions.
11 changes: 7 additions & 4 deletions cmd/cimp/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package main

import (
"flag"
"io/ioutil"
"path/filepath"

"github.com/humans-group/cimp/lib/cimp"
"github.com/humans-group/cimp/lib/tree"
)

func main() {
pathRaw := flag.String("p", "./config.yaml", "Path to config-file which should be imported")
formatRaw := flag.String("f", "", "File format: json, yaml, edn. If empty - got from extension. Default: yaml")
arrayValueFormatRaw := flag.String("a", "", "Array value format: json, yaml, edn. If empty - got from extension. Default: yaml")
consulEndpoint := flag.String("c", "127.0.0.1:8500", "Consul endpoint in format `address:port`")
prefixRaw := flag.String("pref", "", "Prefix for all keys")

Expand All @@ -25,11 +26,13 @@ func main() {
format, err := cimp.NewFormat(*formatRaw, path)
check(err)

arrayValueFormat, err := cimp.NewFormat(*arrayValueFormatRaw, path)
cfgRaw, err := ioutil.ReadFile(path)
check(err)

kv := cimp.NewKV("", arrayValueFormat)
check(kv.FillFromFile(path, format))
kv := cimp.NewKV(tree.New())
unmarshaler := cimp.NewUnmarshaler(kv, format)
err = unmarshaler.Unmarshal(cfgRaw)
check(err)

kv.AddPrefix(*prefixRaw)

Expand Down
5 changes: 3 additions & 2 deletions lib/cimp/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cimp
import "fmt"

var (
ErrorNotFoundInKV = fmt.Errorf("value is not found in KV")
ErrorTypeIncorrect = fmt.Errorf("type is incorrect")
ErrorNotFoundInKV = fmt.Errorf("value is not found in KV")
ErrorParentNotFoundInKV = fmt.Errorf("parent value is not found in KV")
ErrorTypeIncorrect = fmt.Errorf("type is incorrect")
)
78 changes: 71 additions & 7 deletions lib/cimp/kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cimp
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
Expand All @@ -25,6 +26,8 @@ type treeConverter struct {
Indent int
}

const consulSep = "/"

func NewKV(t *tree.Tree) *KV {
idx := index(make(map[string]tree.Path))
idx.addKeys(t, nil)
Expand Down Expand Up @@ -70,9 +73,70 @@ func (kv *KV) GetString(key string) (string, error) {
}
}

func (kv *KV) Exists(fullKey string) bool {
if _, ok := kv.idx[fullKey]; ok {
return true
}

_, err := kv.tree.GetByFullKey(fullKey)

return err == nil
}

func (kv *KV) AddIfNotSet(m tree.Marshalable) error {
if _, ok := kv.idx[m.GetFullKey()]; ok {
return nil
}

lastSepIdx := strings.LastIndexAny(m.GetFullKey(), consulSep)
if lastSepIdx < 0 {
return ErrorParentNotFoundInKV
}
parentFullKey := m.GetFullKey()[:lastSepIdx]

parent, err := kv.tree.GetByFullKey(parentFullKey)
if err != nil {
if errors.Is(err, tree.ErrorNotFound) {
return ErrorParentNotFoundInKV
}
return fmt.Errorf("get parent: %w", err)
}

if item, err := parent.GetByFullKey(m.GetFullKey()); err == nil || item != nil {
return nil
} else if !errors.Is(err, tree.ErrorNotFound) {
return fmt.Errorf("check value %q existence: %w", m.GetFullKey(), err)
}

switch parItem := parent.(type) {
case *tree.Tree:
parItem.AddOrReplaceDirectly(m.GetName(), m)
case *tree.Branch:
parItem.Add(m)
default:
return ErrorTypeIncorrect
}

return nil
}

func (kv *KV) DeleteIfExists(fullKey string) error {
if err := kv.tree.Delete(fullKey); err != nil {
if errors.Is(err, tree.ErrorNotFound) {
return nil
}

return fmt.Errorf("delete by key %q: %w", fullKey, err)
}

delete(kv.idx, fullKey)

return nil
}

func (kv *KV) AddPrefix(prefix string) {
if !strings.HasSuffix(prefix, "/") {
prefix = prefix + "/"
if !strings.HasSuffix(prefix, consulSep) {
prefix = prefix + consulSep
}
kv.globalPrefix = prefix
}
Expand Down Expand Up @@ -164,10 +228,10 @@ func (c treeConverter) convertBranchesToString(mt *tree.Tree) (*tree.Tree, error
}
}

leaf := tree.NewLeaf(k, mt.FullKey, mt.NestingLevel)
leaf := tree.NewLeaf(k, mt.FullKey)
leafValueBuf := bytes.NewBufferString("\n")
leafValueBuf.Write(buf.Bytes())
endLineAndIndent := []byte("\n" + strings.Repeat(" ", int(leaf.NestingLevel)*c.Indent))
endLineAndIndent := []byte("\n" + strings.Repeat(" ", int(leaf.GetNestingLevel())*c.Indent))
leafValue := bytes.ReplaceAll(
leafValueBuf.Bytes(),
[]byte("\n"),
Expand Down Expand Up @@ -195,9 +259,9 @@ func (idx index) clear() {
}
}

func (idx index) addKeys(m tree.Marshalable, prevPath tree.Path) {
path := make(tree.Path, len(prevPath))
copy(path, prevPath)
func (idx index) addKeys(m tree.Marshalable, curPath tree.Path) {
path := make(tree.Path, len(curPath))
copy(path, curPath)

switch cur := m.(type) {
case *tree.Leaf:
Expand Down
5 changes: 4 additions & 1 deletion lib/tree/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ package tree

import "fmt"

var ErrorNotFound = fmt.Errorf("leaf is not found")
var (
ErrorNotFound = fmt.Errorf("not found")
ErrorUnsupported = fmt.Errorf("method is not supported")
)
12 changes: 6 additions & 6 deletions lib/tree/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,18 @@ func (mb *Branch) UnmarshalJSON(raw []byte) error {

delim, ok := token.(json.Delim)
if !ok {
leaf := NewLeaf(name, mb.FullKey, mb.NestingLevel)
leaf := NewLeaf(name, mb.FullKey)
leaf.decoder = mb.decoder
leaf.Value = token
child = leaf
} else {
switch delim {
case '{':
childTree := NewSubTree(name, mb.FullKey, mb.NestingLevel)
childTree := NewSubTree(name, mb.FullKey)
childTree.decoder = mb.decoder
child = childTree
case '[':
branch := NewBranch(name, mb.FullKey, mb.NestingLevel)
branch := NewBranch(name, mb.FullKey)
branch.decoder = mb.decoder
child = branch
default:
Expand Down Expand Up @@ -223,18 +223,18 @@ func (mt *Tree) UnmarshalJSON(raw []byte) error {

delim, ok := token.(json.Delim)
if !ok {
leaf := NewLeaf(name, mt.FullKey, mt.NestingLevel)
leaf := NewLeaf(name, mt.FullKey)
leaf.decoder = mt.decoder
leaf.Value = token
child = leaf
} else {
switch delim {
case '{':
childTree := NewSubTree(name, mt.FullKey, mt.NestingLevel)
childTree := NewSubTree(name, mt.FullKey)
childTree.decoder = mt.decoder
child = childTree
case '[':
branch := NewBranch(name, mt.FullKey, mt.NestingLevel)
branch := NewBranch(name, mt.FullKey)
branch.decoder = mt.decoder
child = branch
default:
Expand Down
Loading

0 comments on commit 71d1d1f

Please sign in to comment.