diff --git a/key.go b/key.go index 5b77598..76c21f8 100644 --- a/key.go +++ b/key.go @@ -40,6 +40,24 @@ func NewKey(s string) Key { return k } +// RawKey creates a new Key without safety checking the input. Use with care. +func RawKey(s string) Key { + // accept an empty string and fix it to avoid special cases + // elsewhere + if len(s) == 0 { + return Key{"/"} + } + + // perform a quick sanity check that the key is in the correct + // format, if it is not then it is a programmer error and it is + // okay to panic + if len(s) == 0 || s[0] != '/' || s[len(s)-1] == '/' { + panic("invalid datastore key: " + s) + } + + return Key{s} +} + // KeyWithNamespaces constructs a key out of a namespace slice. func KeyWithNamespaces(ns []string) Key { return NewKey(strings.Join(ns, "/")) @@ -156,7 +174,7 @@ func (k Key) Path() Key { func (k Key) Parent() Key { n := k.List() if len(n) == 1 { - return NewKey("/") + return RawKey("/") } return NewKey(strings.Join(n[:len(n)-1], "/")) } @@ -165,7 +183,14 @@ func (k Key) Parent() Key { // NewKey("/Comedy/MontyPython").Child(NewKey("Actor:JohnCleese")) // NewKey("/Comedy/MontyPython/Actor:JohnCleese") func (k Key) Child(k2 Key) Key { - return NewKey(k.string + "/" + k2.string) + switch { + case k.string == "/": + return k2 + case k2.string == "/": + return k + default: + return RawKey(k.string + k2.string) + } } // ChildString returns the `child` Key of this Key -- string helper. diff --git a/keytransform/keytransform.go b/keytransform/keytransform.go index ad1033a..f9813e4 100644 --- a/keytransform/keytransform.go +++ b/keytransform/keytransform.go @@ -67,7 +67,7 @@ func (d *ktds) Query(q dsq.Query) (dsq.Results, error) { for r := range qr.Next() { if r.Error == nil { - r.Entry.Key = d.InvertKey(ds.NewKey(r.Entry.Key)).String() + r.Entry.Key = d.InvertKey(ds.RawKey(r.Entry.Key)).String() } ch <- r } diff --git a/namespace/namespace.go b/namespace/namespace.go index 8aed619..1cf53fa 100644 --- a/namespace/namespace.go +++ b/namespace/namespace.go @@ -2,7 +2,6 @@ package namespace import ( "fmt" - "strings" ds "github.com/ipfs/go-datastore" ktds "github.com/ipfs/go-datastore/keytransform" @@ -29,8 +28,8 @@ func PrefixTransform(prefix ds.Key) ktds.KeyTransform { panic("expected prefix not found") } - s := strings.TrimPrefix(k.String(), prefix.String()) - return ds.NewKey(s) + s := k.String()[len(prefix.String()):] + return ds.RawKey(s) }, } } @@ -70,7 +69,7 @@ func (d *datastore) Query(q dsq.Query) (dsq.Results, error) { continue } - k := ds.NewKey(r.Entry.Key) + k := ds.RawKey(r.Entry.Key) if !d.prefix.IsAncestorOf(k) { continue }