Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-dms3
Commits
4cb48da2
Commit
4cb48da2
authored
Oct 21, 2014
by
Juan Batiz-Benet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated datastore
parent
ac62d13e
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
475 additions
and
110 deletions
+475
-110
Godeps/Godeps.json
Godeps/Godeps.json
+1
-1
Godeps/_workspace/src/github.com/jbenet/datastore.go/basic_ds_test.go
...space/src/github.com/jbenet/datastore.go/basic_ds_test.go
+0
-13
Godeps/_workspace/src/github.com/jbenet/datastore.go/key.go
Godeps/_workspace/src/github.com/jbenet/datastore.go/key.go
+97
-45
Godeps/_workspace/src/github.com/jbenet/datastore.go/key_test.go
..._workspace/src/github.com/jbenet/datastore.go/key_test.go
+32
-3
Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform/doc.go
...ce/src/github.com/jbenet/datastore.go/keytransform/doc.go
+25
-0
Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform/interface.go
.../github.com/jbenet/datastore.go/keytransform/interface.go
+34
-0
Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform/keytransform.go
...thub.com/jbenet/datastore.go/keytransform/keytransform.go
+15
-40
Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform/keytransform_test.go
...com/jbenet/datastore.go/keytransform/keytransform_test.go
+34
-8
Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace/doc.go
...space/src/github.com/jbenet/datastore.go/namespace/doc.go
+24
-0
Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace/example_test.go
.../github.com/jbenet/datastore.go/namespace/example_test.go
+30
-0
Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace/namespace.go
...src/github.com/jbenet/datastore.go/namespace/namespace.go
+44
-0
Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace/namespace_test.go
...ithub.com/jbenet/datastore.go/namespace/namespace_test.go
+72
-0
Godeps/_workspace/src/github.com/jbenet/datastore.go/panic/panic.go
...rkspace/src/github.com/jbenet/datastore.go/panic/panic.go
+67
-0
No files found.
Godeps/Godeps.json
View file @
4cb48da2
...
...
@@ -68,7 +68,7 @@
},
{
"ImportPath"
:
"github.com/jbenet/datastore.go"
,
"Rev"
:
"
60ebc56447b5a8264cfed3ae3ff48deb984d7cf1
"
"Rev"
:
"
da593f5071b3ce60bf45b548193863bc3c885c3c
"
},
{
"ImportPath"
:
"github.com/jbenet/go-base58"
,
...
...
Godeps/_workspace/src/github.com/jbenet/datastore.go/basic_ds_test.go
deleted
100644 → 0
View file @
ac62d13e
package
datastore_test
import
(
.
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
.
"launchpad.net/gocheck"
)
// Hook up gocheck into the "go test" runner.
func
Test
(
t
*
testing
.
T
)
{
TestingT
(
t
)
}
type
BasicSuite
struct
{}
var
_
=
Suite
(
&
BasicSuite
{})
Godeps/_workspace/src/github.com/jbenet/datastore.go/key.go
View file @
4cb48da2
package
datastore
import
(
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go-uuid/uuid"
"path"
"strings"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go-uuid/uuid"
)
/*
...
...
@@ -30,93 +31,126 @@ type Key struct {
string
}
// NewKey constructs a key from string. it will clean the value.
func
NewKey
(
s
string
)
Key
{
k
:=
Key
{
s
}
k
.
Clean
()
return
k
}
// Cleans up a Key, using path.Clean.
// KeyWithNamespaces constructs a key out of a namespace slice.
func
KeyWithNamespaces
(
ns
[]
string
)
Key
{
return
NewKey
(
strings
.
Join
(
ns
,
"/"
))
}
// Clean up a Key, using path.Clean.
func
(
k
*
Key
)
Clean
()
{
k
.
string
=
path
.
Clean
(
"/"
+
k
.
string
)
}
//
Return
s the string value of Key
//
Strings i
s the string value of Key
func
(
k
Key
)
String
()
string
{
return
k
.
string
}
//
R
eturns the
bytes
value of Key
//
Bytes r
eturns the
string
value of Key
as a []byte
func
(
k
Key
)
Bytes
()
[]
byte
{
return
[]
byte
(
k
.
string
)
}
// Returns the `list` representation of this Key.
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
// ["Comedy", "MontyPythong", "Actor:JohnCleese"]
// Equal checks equality of two keys
func
(
k
Key
)
Equal
(
k2
Key
)
bool
{
return
k
.
string
==
k2
.
string
}
// Less checks whether this key is sorted lower than another.
func
(
k
Key
)
Less
(
k2
Key
)
bool
{
list1
:=
k
.
List
()
list2
:=
k2
.
List
()
for
i
,
c1
:=
range
list1
{
if
len
(
list2
)
<
(
i
+
1
)
{
return
false
}
c2
:=
list2
[
i
]
if
c1
<
c2
{
return
true
}
else
if
c1
>
c2
{
return
false
}
// c1 == c2, continue
}
// list1 is shorter or exactly the same.
return
len
(
list1
)
<
len
(
list2
)
}
// List returns the `list` representation of this Key.
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
// ["Comedy", "MontyPythong", "Actor:JohnCleese"]
func
(
k
Key
)
List
()
[]
string
{
return
strings
.
Split
(
k
.
string
,
"/"
)[
1
:
]
}
// Returns the reverse of this Key.
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Reverse()
// NewKey("/Actor:JohnCleese/MontyPython/Comedy")
// Re
verse re
turns the reverse of this Key.
//
NewKey("/Comedy/MontyPython/Actor:JohnCleese").Reverse()
//
NewKey("/Actor:JohnCleese/MontyPython/Comedy")
func
(
k
Key
)
Reverse
()
Key
{
l
:=
k
.
List
()
r
:=
make
([]
string
,
len
(
l
),
len
(
l
))
for
i
,
e
:=
range
l
{
r
[
len
(
l
)
-
i
-
1
]
=
e
}
return
NewKey
(
strings
.
Join
(
r
,
"/"
)
)
return
KeyWithNamespaces
(
r
)
}
//
R
eturns the `namespaces` making up this Key.
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
// ["Comedy", "MontyPythong", "Actor:JohnCleese"]
//
Namespaces r
eturns the `namespaces` making up this Key.
//
NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
//
["Comedy", "MontyPythong", "Actor:JohnCleese"]
func
(
k
Key
)
Namespaces
()
[]
string
{
return
k
.
List
()
}
//
R
eturns the "base" namespace of this key (
like
path.Base(filename))
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").BaseNamespace()
// "Actor:JohnCleese"
//
BaseNamespace r
eturns the "base" namespace of this key (path.Base(filename))
//
NewKey("/Comedy/MontyPython/Actor:JohnCleese").BaseNamespace()
//
"Actor:JohnCleese"
func
(
k
Key
)
BaseNamespace
()
string
{
n
:=
k
.
Namespaces
()
return
n
[
len
(
n
)
-
1
]
}
//
R
eturns the "type" of this key (value of last namespace).
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
// "Actor"
//
Type r
eturns the "type" of this key (value of last namespace).
//
NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
//
"Actor"
func
(
k
Key
)
Type
()
string
{
return
NamespaceType
(
k
.
BaseNamespace
())
}
//
R
eturns the "name" of this key (field of last namespace).
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
// "Actor"
//
Name r
eturns the "name" of this key (field of last namespace).
//
NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
//
"Actor"
func
(
k
Key
)
Name
()
string
{
return
NamespaceValue
(
k
.
BaseNamespace
())
}
//
R
eturns an "instance" of this type key (appends value to namespace).
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
// "JohnCleese"
//
Instance r
eturns an "instance" of this type key (appends value to namespace).
//
NewKey("/Comedy/MontyPython/Actor:JohnCleese").List()
//
"JohnCleese"
func
(
k
Key
)
Instance
(
s
string
)
Key
{
return
NewKey
(
k
.
string
+
":"
+
s
)
}
//
R
eturns the "path" of this key (parent + type).
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Path()
// NewKey("/Comedy/MontyPython/Actor")
//
Path r
eturns the "path" of this key (parent + type).
//
NewKey("/Comedy/MontyPython/Actor:JohnCleese").Path()
//
NewKey("/Comedy/MontyPython/Actor")
func
(
k
Key
)
Path
()
Key
{
s
:=
k
.
Parent
()
.
string
+
"/"
+
NamespaceType
(
k
.
BaseNamespace
())
return
NewKey
(
s
)
}
//
R
eturns the `parent` Key of this Key.
// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Parent()
// NewKey("/Comedy/MontyPython")
//
Parent r
eturns the `parent` Key of this Key.
//
NewKey("/Comedy/MontyPython/Actor:JohnCleese").Parent()
//
NewKey("/Comedy/MontyPython")
func
(
k
Key
)
Parent
()
Key
{
n
:=
k
.
List
()
if
len
(
n
)
==
1
{
...
...
@@ -125,16 +159,23 @@ func (k Key) Parent() Key {
return
NewKey
(
strings
.
Join
(
n
[
:
len
(
n
)
-
1
],
"/"
))
}
// Returns the `child` Key of this Key.
// NewKey("/Comedy/MontyPython").Child("Actor:JohnCleese")
// NewKey("/Comedy/MontyPython/Actor:JohnCleese")
func
(
k
Key
)
Child
(
s
string
)
Key
{
// Child returns the `child` Key of this Key.
// NewKey("/Comedy/MontyPython").Child("Actor:JohnCleese")
// NewKey("/Comedy/MontyPython/Actor:JohnCleese")
func
(
k
Key
)
Child
(
k2
Key
)
Key
{
return
NewKey
(
k
.
string
+
"/"
+
k2
.
string
)
}
// ChildString returns the `child` Key of this Key -- string helper.
// NewKey("/Comedy/MontyPython").Child("Actor:JohnCleese")
// NewKey("/Comedy/MontyPython/Actor:JohnCleese")
func
(
k
Key
)
ChildString
(
s
string
)
Key
{
return
NewKey
(
k
.
string
+
"/"
+
s
)
}
//
R
eturns whether this key is a
n ancestor
of `other`
// NewKey("/Comedy").IsAncestorOf("/Comedy/MontyPython")
// true
//
IsAncestorOf r
eturns whether this key is a
prefix
of `other`
//
NewKey("/Comedy").IsAncestorOf("/Comedy/MontyPython")
//
true
func
(
k
Key
)
IsAncestorOf
(
other
Key
)
bool
{
if
other
.
string
==
k
.
string
{
return
false
...
...
@@ -142,9 +183,9 @@ func (k Key) IsAncestorOf(other Key) bool {
return
strings
.
HasPrefix
(
other
.
string
,
k
.
string
)
}
//
R
eturns whether this key
is a descendent of `other`
// NewKey("/Comedy/MontyPython").IsDescendantOf("/Comedy")
// true
//
IsDescendantOf r
eturns whether this key
contains another as a prefix.
//
NewKey("/Comedy/MontyPython").IsDescendantOf("/Comedy")
//
true
func
(
k
Key
)
IsDescendantOf
(
other
Key
)
bool
{
if
other
.
string
==
k
.
string
{
return
false
...
...
@@ -152,13 +193,14 @@ func (k Key) IsDescendantOf(other Key) bool {
return
strings
.
HasPrefix
(
k
.
string
,
other
.
string
)
}
// IsTopLevel returns whether this key has only one namespace.
func
(
k
Key
)
IsTopLevel
()
bool
{
return
len
(
k
.
List
())
==
1
}
// Returns a randomly (uuid) generated key.
// RandomKey()
// NewKey("/f98719ea086343f7b71f32ea9d9d521d")
// R
andomKey r
eturns a randomly (uuid) generated key.
//
RandomKey()
//
NewKey("/f98719ea086343f7b71f32ea9d9d521d")
func
RandomKey
()
Key
{
return
NewKey
(
strings
.
Replace
(
uuid
.
New
(),
"-"
,
""
,
-
1
))
}
...
...
@@ -175,6 +217,7 @@ A namespace can optionally include a type (delimited by ':')
Music:Song
*/
// NamespaceType is the first component of a namespace. `foo` in `foo:bar`
func
NamespaceType
(
namespace
string
)
string
{
parts
:=
strings
.
Split
(
namespace
,
":"
)
if
len
(
parts
)
<
2
{
...
...
@@ -183,7 +226,16 @@ func NamespaceType(namespace string) string {
return
strings
.
Join
(
parts
[
0
:
len
(
parts
)
-
1
],
":"
)
}
// NamespaceValue returns the last component of a namespace. `baz` in `f:b:baz`
func
NamespaceValue
(
namespace
string
)
string
{
parts
:=
strings
.
Split
(
namespace
,
":"
)
return
parts
[
len
(
parts
)
-
1
]
}
// KeySlice attaches the methods of sort.Interface to []Key,
// sorting in increasing order.
type
KeySlice
[]
Key
func
(
p
KeySlice
)
Len
()
int
{
return
len
(
p
)
}
func
(
p
KeySlice
)
Less
(
i
,
j
int
)
bool
{
return
p
[
i
]
.
Less
(
p
[
j
])
}
func
(
p
KeySlice
)
Swap
(
i
,
j
int
)
{
p
[
i
],
p
[
j
]
=
p
[
j
],
p
[
i
]
}
Godeps/_workspace/src/github.com/jbenet/datastore.go/key_test.go
View file @
4cb48da2
...
...
@@ -54,14 +54,24 @@ func (ks *KeySuite) SubtestKey(s string, c *C) {
c
.
Check
(
NewKey
(
s
)
.
Path
()
.
String
(),
Equals
,
kpath
)
c
.
Check
(
NewKey
(
s
)
.
Instance
(
"inst"
)
.
String
(),
Equals
,
kinstance
)
c
.
Check
(
NewKey
(
s
)
.
Child
(
"cchildd"
)
.
String
(),
Equals
,
kchild
)
c
.
Check
(
NewKey
(
s
)
.
Child
(
"cchildd"
)
.
Parent
()
.
String
(),
Equals
,
fixed
)
c
.
Check
(
NewKey
(
s
)
.
Child
(
NewKey
(
"cchildd"
))
.
String
(),
Equals
,
kchild
)
c
.
Check
(
NewKey
(
s
)
.
Child
(
NewKey
(
"cchildd"
))
.
Parent
()
.
String
(),
Equals
,
fixed
)
c
.
Check
(
NewKey
(
s
)
.
ChildString
(
"cchildd"
)
.
String
(),
Equals
,
kchild
)
c
.
Check
(
NewKey
(
s
)
.
ChildString
(
"cchildd"
)
.
Parent
()
.
String
(),
Equals
,
fixed
)
c
.
Check
(
NewKey
(
s
)
.
Parent
()
.
String
(),
Equals
,
kparent
)
c
.
Check
(
len
(
NewKey
(
s
)
.
List
()),
Equals
,
len
(
namespaces
))
c
.
Check
(
len
(
NewKey
(
s
)
.
Namespaces
()),
Equals
,
len
(
namespaces
))
for
i
,
e
:=
range
NewKey
(
s
)
.
List
()
{
c
.
Check
(
namespaces
[
i
],
Equals
,
e
)
}
c
.
Check
(
NewKey
(
s
),
Equals
,
NewKey
(
s
))
c
.
Check
(
NewKey
(
s
)
.
Equal
(
NewKey
(
s
)),
Equals
,
true
)
c
.
Check
(
NewKey
(
s
)
.
Equal
(
NewKey
(
"/fdsafdsa/"
+
s
)),
Equals
,
false
)
// less
c
.
Check
(
NewKey
(
s
)
.
Less
(
NewKey
(
s
)
.
Parent
()),
Equals
,
false
)
c
.
Check
(
NewKey
(
s
)
.
Less
(
NewKey
(
s
)
.
ChildString
(
"foo"
)),
Equals
,
true
)
}
func
(
ks
*
KeySuite
)
TestKeyBasic
(
c
*
C
)
{
...
...
@@ -100,7 +110,8 @@ func (ks *KeySuite) TestKeyAncestry(c *C) {
CheckTrue
(
c
,
!
k1
.
IsAncestorOf
(
NewKey
(
"/A"
)))
CheckTrue
(
c
,
!
k2
.
IsAncestorOf
(
k2
))
CheckTrue
(
c
,
!
k1
.
IsAncestorOf
(
k1
))
c
.
Check
(
k1
.
Child
(
"D"
)
.
String
(),
Equals
,
k2
.
String
())
c
.
Check
(
k1
.
Child
(
NewKey
(
"D"
))
.
String
(),
Equals
,
k2
.
String
())
c
.
Check
(
k1
.
ChildString
(
"D"
)
.
String
(),
Equals
,
k2
.
String
())
c
.
Check
(
k1
.
String
(),
Equals
,
k2
.
Parent
()
.
String
())
c
.
Check
(
k1
.
Path
()
.
String
(),
Equals
,
k2
.
Parent
()
.
Path
()
.
String
())
}
...
...
@@ -126,3 +137,21 @@ func (ks *KeySuite) TestRandom(c *C) {
}
CheckTrue
(
c
,
len
(
keys
)
==
1000
)
}
func
(
ks
*
KeySuite
)
TestLess
(
c
*
C
)
{
checkLess
:=
func
(
a
,
b
string
)
{
ak
:=
NewKey
(
a
)
bk
:=
NewKey
(
b
)
c
.
Check
(
ak
.
Less
(
bk
),
Equals
,
true
)
c
.
Check
(
bk
.
Less
(
ak
),
Equals
,
false
)
}
checkLess
(
"/a/b/c"
,
"/a/b/c/d"
)
checkLess
(
"/a/b"
,
"/a/b/c/d"
)
checkLess
(
"/a"
,
"/a/b/c/d"
)
checkLess
(
"/a/a/c"
,
"/a/b/c"
)
checkLess
(
"/a/a/d"
,
"/a/b/c"
)
checkLess
(
"/a/b/c/d/e/f/g/h"
,
"/b"
)
checkLess
(
"/"
,
"/a"
)
}
Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform/doc.go
0 → 100644
View file @
4cb48da2
// Package keytransform introduces a Datastore Shim that transforms keys before
// passing them to its child. It can be used to manipulate what keys look like
// to the user, for example namespacing keys, reversing them, etc.
//
// Use the Wrap function to wrap a datastore with any KeyTransform.
// A KeyTransform is simply an interface with two functions, a conversion and
// its inverse. For example:
//
// import (
// ktds "github.com/jbenet/datastore.go/keytransform"
// ds "github.com/jbenet/datastore.go"
// )
//
// func reverseKey(k ds.Key) ds.Key {
// return k.Reverse()
// }
//
// func invertKeys(d ds.Datastore) {
// return ktds.Wrap(d, &ktds.Pair{
// Convert: reverseKey,
// Invert: reverseKey, // reverse is its own inverse.
// })
// }
//
package
keytransform
Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform/interface.go
0 → 100644
View file @
4cb48da2
package
keytransform
import
ds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
// KeyMapping is a function that maps one key to annother
type
KeyMapping
func
(
ds
.
Key
)
ds
.
Key
// KeyTransform is an object with a pair of functions for (invertibly)
// transforming keys
type
KeyTransform
interface
{
ConvertKey
(
ds
.
Key
)
ds
.
Key
InvertKey
(
ds
.
Key
)
ds
.
Key
}
// Datastore is a keytransform.Datastore
type
Datastore
interface
{
ds
.
Shim
KeyTransform
}
// Wrap wraps a given datastore with a KeyTransform function.
// The resulting wrapped datastore will use the transform on all Datastore
// operations.
func
Wrap
(
child
ds
.
Datastore
,
t
KeyTransform
)
Datastore
{
if
t
==
nil
{
panic
(
"t (KeyTransform) is nil"
)
}
if
child
==
nil
{
panic
(
"child (ds.Datastore) is nil"
)
}
return
&
ktds
{
child
:
child
,
KeyTransform
:
t
}
}
Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform/keytransform.go
View file @
4cb48da2
...
...
@@ -2,49 +2,24 @@ package keytransform
import
ds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
// KeyTransform is a function that transforms one key into another.
type
KeyTransform
func
(
ds
.
Key
)
ds
.
Key
// Datastore is a keytransform.Datastore
type
Datastore
interface
{
ds
.
Shim
type
Pair
struct
{
Convert
KeyMapping
Invert
KeyMapping
}
// Transform runs the transformation function
Transform
(
ds
.
Key
)
ds
.
Key
func
(
t
*
Pair
)
ConvertKey
(
k
ds
.
Key
)
ds
.
Key
{
return
t
.
Convert
(
k
)
}
// TransformFunc returns the KeyTransform function
TransformFunc
()
KeyTransform
func
(
t
*
Pair
)
InvertKey
(
k
ds
.
Key
)
ds
.
Key
{
return
t
.
Invert
(
k
)
}
// ktds keeps a KeyTransform function
type
ktds
struct
{
child
ds
.
Datastore
xform
KeyTransform
}
// WrapDatastore wraps a given datastore with a KeyTransform function.
// The resulting wrapped datastore will use the transform on all Datastore
// operations.
func
WrapDatastore
(
child
ds
.
Datastore
,
f
KeyTransform
)
Datastore
{
if
f
==
nil
{
panic
(
"f (KeyTransform) is nil"
)
}
if
child
==
nil
{
panic
(
"child (ds.Datastore) is nil"
)
}
return
&
ktds
{
child
,
f
}
}
// TransformFunc returns the KeyTransform function
func
(
d
*
ktds
)
TransformFunc
()
KeyTransform
{
return
d
.
xform
}
// Transform runs the KeyTransform function
func
(
d
*
ktds
)
Transform
(
k
ds
.
Key
)
ds
.
Key
{
return
d
.
xform
(
k
)
KeyTransform
}
// Children implements ds.Shim
...
...
@@ -54,23 +29,23 @@ func (d *ktds) Children() []ds.Datastore {
// Put stores the given value, transforming the key first.
func
(
d
*
ktds
)
Put
(
key
ds
.
Key
,
value
interface
{})
(
err
error
)
{
return
d
.
child
.
Put
(
d
.
Transform
(
key
),
value
)
return
d
.
child
.
Put
(
d
.
ConvertKey
(
key
),
value
)
}
// Get returns the value for given key, transforming the key first.
func
(
d
*
ktds
)
Get
(
key
ds
.
Key
)
(
value
interface
{},
err
error
)
{
return
d
.
child
.
Get
(
d
.
Transform
(
key
))
return
d
.
child
.
Get
(
d
.
ConvertKey
(
key
))
}
// Has returns whether the datastore has a value for a given key, transforming
// the key first.
func
(
d
*
ktds
)
Has
(
key
ds
.
Key
)
(
exists
bool
,
err
error
)
{
return
d
.
child
.
Has
(
d
.
Transform
(
key
))
return
d
.
child
.
Has
(
d
.
ConvertKey
(
key
))
}
// Delete removes the value for given key
func
(
d
*
ktds
)
Delete
(
key
ds
.
Key
)
(
err
error
)
{
return
d
.
child
.
Delete
(
d
.
Transform
(
key
))
return
d
.
child
.
Delete
(
d
.
ConvertKey
(
key
))
}
// KeyList returns a list of all keys in the datastore, transforming keys out.
...
...
@@ -82,7 +57,7 @@ func (d *ktds) KeyList() ([]ds.Key, error) {
}
for
i
,
k
:=
range
keys
{
keys
[
i
]
=
d
.
Transform
(
k
)
keys
[
i
]
=
d
.
InvertKey
(
k
)
}
return
keys
,
nil
}
Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform/keytransform_test.go
View file @
4cb48da2
...
...
@@ -2,6 +2,7 @@ package keytransform_test
import
(
"bytes"
"sort"
"testing"
ds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
...
...
@@ -12,19 +13,28 @@ import (
// Hook up gocheck into the "go test" runner.
func
Test
(
t
*
testing
.
T
)
{
TestingT
(
t
)
}
type
DSSuite
struct
{
dir
string
ds
ds
.
Datastore
}
type
DSSuite
struct
{}
var
_
=
Suite
(
&
DSSuite
{})
func
(
ks
*
DSSuite
)
TestBasic
(
c
*
C
)
{
pair
:=
&
kt
.
Pair
{
Convert
:
func
(
k
ds
.
Key
)
ds
.
Key
{
return
ds
.
NewKey
(
"/abc"
)
.
Child
(
k
)
},
Invert
:
func
(
k
ds
.
Key
)
ds
.
Key
{
// remove abc prefix
l
:=
k
.
List
()
if
l
[
0
]
!=
"abc"
{
panic
(
"key does not have prefix. convert failed?"
)
}
return
ds
.
KeyWithNamespaces
(
l
[
1
:
])
},
}
mpds
:=
ds
.
NewMapDatastore
()
ktds
:=
kt
.
WrapDatastore
(
mpds
,
func
(
k
ds
.
Key
)
ds
.
Key
{
return
k
.
Reverse
()
})
ktds
:=
kt
.
Wrap
(
mpds
,
pair
)
keys
:=
strsToKeys
([]
string
{
"foo"
,
...
...
@@ -45,10 +55,26 @@ func (ks *DSSuite) TestBasic(c *C) {
c
.
Check
(
err
,
Equals
,
nil
)
c
.
Check
(
bytes
.
Equal
(
v1
.
([]
byte
),
[]
byte
(
k
.
String
())),
Equals
,
true
)
v2
,
err
:=
mpds
.
Get
(
k
.
Reverse
(
))
v2
,
err
:=
mpds
.
Get
(
ds
.
NewKey
(
"abc"
)
.
Child
(
k
))
c
.
Check
(
err
,
Equals
,
nil
)
c
.
Check
(
bytes
.
Equal
(
v2
.
([]
byte
),
[]
byte
(
k
.
String
())),
Equals
,
true
)
}
listA
,
errA
:=
mpds
.
KeyList
()
listB
,
errB
:=
ktds
.
KeyList
()
c
.
Check
(
errA
,
Equals
,
nil
)
c
.
Check
(
errB
,
Equals
,
nil
)
c
.
Check
(
len
(
listA
),
Equals
,
len
(
listB
))
// sort them cause yeah.
sort
.
Sort
(
ds
.
KeySlice
(
listA
))
sort
.
Sort
(
ds
.
KeySlice
(
listB
))
for
i
,
kA
:=
range
listA
{
kB
:=
listB
[
i
]
c
.
Check
(
pair
.
Invert
(
kA
),
Equals
,
kB
)
c
.
Check
(
kA
,
Equals
,
pair
.
Convert
(
kB
))
}
}
func
strsToKeys
(
strs
[]
string
)
[]
ds
.
Key
{
...
...
Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace/doc.go
0 → 100644
View file @
4cb48da2
// Package namespace introduces a namespace Datastore Shim, which basically
// mounts the entire child datastore under a prefix.
//
// Use the Wrap function to wrap a datastore with any Key prefix. For example:
//
// import (
// "fmt"
//
// ds "github.com/jbenet/datastore.go"
// nsds "github.com/jbenet/datastore.go/namespace"
// )
//
// func main() {
// mp := ds.NewMapDatastore()
// ns := nsds.Wrap(mp, ds.NewKey("/foo/bar"))
//
// // in the Namespace Datastore:
// ns.Put(ds.NewKey("/beep"), "boop")
// v2, _ := ns.Get(ds.NewKey("/beep")) // v2 == "boop"
//
// // and, in the underlying MapDatastore:
// v3, _ := mp.Get(ds.NewKey("/foo/bar/beep")) // v3 == "boop"
// }
package
namespace
Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace/example_test.go
0 → 100644
View file @
4cb48da2
package
namespace_test
import
(
"fmt"
ds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
nsds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace"
)
func
Example
()
{
mp
:=
ds
.
NewMapDatastore
()
ns
:=
nsds
.
Wrap
(
mp
,
ds
.
NewKey
(
"/foo/bar"
))
k
:=
ds
.
NewKey
(
"/beep"
)
v
:=
"boop"
ns
.
Put
(
k
,
v
)
fmt
.
Printf
(
"ns.Put %s %s
\n
"
,
k
,
v
)
v2
,
_
:=
ns
.
Get
(
k
)
fmt
.
Printf
(
"ns.Get %s -> %s
\n
"
,
k
,
v2
)
k3
:=
ds
.
NewKey
(
"/foo/bar/beep"
)
v3
,
_
:=
mp
.
Get
(
k3
)
fmt
.
Printf
(
"mp.Get %s -> %s
\n
"
,
k3
,
v3
)
// Output:
// ns.Put /beep -> boop
// ns.Get /beep -> boop
// mp.Get /foo/bar/beep -> boop
}
Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace/namespace.go
0 → 100644
View file @
4cb48da2
package
namespace
import
(
"fmt"
"strings"
ds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
ktds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go/keytransform"
)
// PrefixTransform constructs a KeyTransform with a pair of functions that
// add or remove the given prefix key.
//
// Warning: will panic if prefix not found when it should be there. This is
// to avoid insidious data inconsistency errors.
func
PrefixTransform
(
prefix
ds
.
Key
)
ktds
.
KeyTransform
{
return
&
ktds
.
Pair
{
// Convert adds the prefix
Convert
:
func
(
k
ds
.
Key
)
ds
.
Key
{
return
prefix
.
Child
(
k
)
},
// Invert removes the prefix. panics if prefix not found.
Invert
:
func
(
k
ds
.
Key
)
ds
.
Key
{
if
!
prefix
.
IsAncestorOf
(
k
)
{
fmt
.
Errorf
(
"Expected prefix (%s) in key (%s)"
,
prefix
,
k
)
panic
(
"expected prefix not found"
)
}
s
:=
strings
.
TrimPrefix
(
k
.
String
(),
prefix
.
String
())
return
ds
.
NewKey
(
s
)
},
}
}
// Wrap wraps a given datastore with a key-prefix.
func
Wrap
(
child
ds
.
Datastore
,
prefix
ds
.
Key
)
ktds
.
Datastore
{
if
child
==
nil
{
panic
(
"child (ds.Datastore) is nil"
)
}
return
ktds
.
Wrap
(
child
,
PrefixTransform
(
prefix
))
}
Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace/namespace_test.go
0 → 100644
View file @
4cb48da2
package
namespace_test
import
(
"bytes"
"sort"
"testing"
ds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
ns
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go/namespace"
.
"launchpad.net/gocheck"
)
// Hook up gocheck into the "go test" runner.
func
Test
(
t
*
testing
.
T
)
{
TestingT
(
t
)
}
type
DSSuite
struct
{}
var
_
=
Suite
(
&
DSSuite
{})
func
(
ks
*
DSSuite
)
TestBasic
(
c
*
C
)
{
mpds
:=
ds
.
NewMapDatastore
()
nsds
:=
ns
.
Wrap
(
mpds
,
ds
.
NewKey
(
"abc"
))
keys
:=
strsToKeys
([]
string
{
"foo"
,
"foo/bar"
,
"foo/bar/baz"
,
"foo/barb"
,
"foo/bar/bazb"
,
"foo/bar/baz/barb"
,
})
for
_
,
k
:=
range
keys
{
err
:=
nsds
.
Put
(
k
,
[]
byte
(
k
.
String
()))
c
.
Check
(
err
,
Equals
,
nil
)
}
for
_
,
k
:=
range
keys
{
v1
,
err
:=
nsds
.
Get
(
k
)
c
.
Check
(
err
,
Equals
,
nil
)
c
.
Check
(
bytes
.
Equal
(
v1
.
([]
byte
),
[]
byte
(
k
.
String
())),
Equals
,
true
)
v2
,
err
:=
mpds
.
Get
(
ds
.
NewKey
(
"abc"
)
.
Child
(
k
))
c
.
Check
(
err
,
Equals
,
nil
)
c
.
Check
(
bytes
.
Equal
(
v2
.
([]
byte
),
[]
byte
(
k
.
String
())),
Equals
,
true
)
}
listA
,
errA
:=
mpds
.
KeyList
()
listB
,
errB
:=
nsds
.
KeyList
()
c
.
Check
(
errA
,
Equals
,
nil
)
c
.
Check
(
errB
,
Equals
,
nil
)
c
.
Check
(
len
(
listA
),
Equals
,
len
(
listB
))
// sort them cause yeah.
sort
.
Sort
(
ds
.
KeySlice
(
listA
))
sort
.
Sort
(
ds
.
KeySlice
(
listB
))
for
i
,
kA
:=
range
listA
{
kB
:=
listB
[
i
]
c
.
Check
(
nsds
.
InvertKey
(
kA
),
Equals
,
kB
)
c
.
Check
(
kA
,
Equals
,
nsds
.
ConvertKey
(
kB
))
}
}
func
strsToKeys
(
strs
[]
string
)
[]
ds
.
Key
{
keys
:=
make
([]
ds
.
Key
,
len
(
strs
))
for
i
,
s
:=
range
strs
{
keys
[
i
]
=
ds
.
NewKey
(
s
)
}
return
keys
}
Godeps/_workspace/src/github.com/jbenet/datastore.go/panic/panic.go
0 → 100644
View file @
4cb48da2
package
sync
import
(
"fmt"
"os"
ds
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
)
type
datastore
struct
{
child
ds
.
Datastore
}
// Wrap shims a datastore such than _any_ operation failing triggers a panic
// This is useful for debugging invariants.
func
Wrap
(
d
ds
.
Datastore
)
ds
.
Shim
{
return
&
datastore
{
child
:
d
}
}
func
(
d
*
datastore
)
Children
()
[]
ds
.
Datastore
{
return
[]
ds
.
Datastore
{
d
.
child
}
}
func
(
d
*
datastore
)
Put
(
key
ds
.
Key
,
value
interface
{})
error
{
err
:=
d
.
child
.
Put
(
key
,
value
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stdout
,
"panic datastore: %s"
,
err
)
panic
(
"panic datastore: Put failed"
)
}
return
nil
}
func
(
d
*
datastore
)
Get
(
key
ds
.
Key
)
(
interface
{},
error
)
{
val
,
err
:=
d
.
child
.
Get
(
key
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stdout
,
"panic datastore: %s"
,
err
)
panic
(
"panic datastore: Get failed"
)
}
return
val
,
nil
}
func
(
d
*
datastore
)
Has
(
key
ds
.
Key
)
(
bool
,
error
)
{
e
,
err
:=
d
.
child
.
Has
(
key
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stdout
,
"panic datastore: %s"
,
err
)
panic
(
"panic datastore: Has failed"
)
}
return
e
,
nil
}
func
(
d
*
datastore
)
Delete
(
key
ds
.
Key
)
error
{
err
:=
d
.
child
.
Delete
(
key
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stdout
,
"panic datastore: %s"
,
err
)
panic
(
"panic datastore: Delete failed"
)
}
return
nil
}
func
(
d
*
datastore
)
KeyList
()
([]
ds
.
Key
,
error
)
{
kl
,
err
:=
d
.
child
.
KeyList
()
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stdout
,
"panic datastore: %s"
,
err
)
panic
(
"panic datastore: KeyList failed"
)
}
return
kl
,
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment