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
99991062
Commit
99991062
authored
10 years ago
by
Brian Tiger Chow
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: initial redis datastore implementation
parent
8f62ac82
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
192 additions
and
0 deletions
+192
-0
thirdparty/redis-datastore/datastore.go
thirdparty/redis-datastore/datastore.go
+84
-0
thirdparty/redis-datastore/datastore_test.go
thirdparty/redis-datastore/datastore_test.go
+108
-0
No files found.
thirdparty/redis-datastore/datastore.go
0 → 100644
View file @
99991062
package
redis
import
(
"errors"
"fmt"
"sync"
"time"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/fzzy/radix/redis"
datastore
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
query
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/query"
)
var
_
datastore
.
Datastore
=
&
RedisDatastore
{}
var
_
datastore
.
ThreadSafeDatastore
=
&
RedisDatastore
{}
var
ErrInvalidType
=
errors
.
New
(
"redis datastore: invalid type error. this datastore only supports []byte values"
)
func
NewExpiringDatastore
(
client
*
redis
.
Client
,
ttl
time
.
Duration
)
(
datastore
.
ThreadSafeDatastore
,
error
)
{
return
&
RedisDatastore
{
client
:
client
,
ttl
:
ttl
,
},
nil
}
func
NewDatastore
(
client
*
redis
.
Client
)
(
datastore
.
ThreadSafeDatastore
,
error
)
{
return
&
RedisDatastore
{
client
:
client
,
},
nil
}
type
RedisDatastore
struct
{
mu
sync
.
Mutex
client
*
redis
.
Client
ttl
time
.
Duration
}
func
(
ds
*
RedisDatastore
)
Put
(
key
datastore
.
Key
,
value
interface
{})
error
{
ds
.
mu
.
Lock
()
defer
ds
.
mu
.
Unlock
()
data
,
ok
:=
value
.
([]
byte
)
if
!
ok
{
return
ErrInvalidType
}
ds
.
client
.
Append
(
"SET"
,
key
.
String
(),
data
)
if
ds
.
ttl
!=
0
{
ds
.
client
.
Append
(
"EXPIRE"
,
key
.
String
(),
ds
.
ttl
.
Seconds
())
}
if
err
:=
ds
.
client
.
GetReply
()
.
Err
;
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to put value: %s"
,
err
)
}
if
ds
.
ttl
!=
0
{
if
err
:=
ds
.
client
.
GetReply
()
.
Err
;
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to set expiration: %s"
,
err
)
}
}
return
nil
}
func
(
ds
*
RedisDatastore
)
Get
(
key
datastore
.
Key
)
(
value
interface
{},
err
error
)
{
ds
.
mu
.
Lock
()
defer
ds
.
mu
.
Unlock
()
return
ds
.
client
.
Cmd
(
"GET"
,
key
.
String
())
.
Bytes
()
}
func
(
ds
*
RedisDatastore
)
Has
(
key
datastore
.
Key
)
(
exists
bool
,
err
error
)
{
ds
.
mu
.
Lock
()
defer
ds
.
mu
.
Unlock
()
return
ds
.
client
.
Cmd
(
"EXISTS"
,
key
.
String
())
.
Bool
()
}
func
(
ds
*
RedisDatastore
)
Delete
(
key
datastore
.
Key
)
(
err
error
)
{
ds
.
mu
.
Lock
()
defer
ds
.
mu
.
Unlock
()
return
ds
.
client
.
Cmd
(
"DEL"
,
key
.
String
())
.
Err
}
func
(
ds
*
RedisDatastore
)
Query
(
q
query
.
Query
)
(
query
.
Results
,
error
)
{
return
nil
,
errors
.
New
(
"TODO implement query for redis datastore?"
)
}
func
(
ds
*
RedisDatastore
)
IsThreadSafe
()
{}
This diff is collapsed.
Click to expand it.
thirdparty/redis-datastore/datastore_test.go
0 → 100644
View file @
99991062
package
redis
import
(
"bytes"
"os"
"testing"
"time"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/fzzy/radix/redis"
datastore
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
"github.com/jbenet/go-ipfs/thirdparty/assert"
)
const
RedisEnv
=
"REDIS_DATASTORE_TEST_HOST"
func
TestPutGetBytes
(
t
*
testing
.
T
)
{
client
:=
clientOrAbort
(
t
)
ds
,
err
:=
NewDatastore
(
client
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
key
,
val
:=
datastore
.
NewKey
(
"foo"
),
[]
byte
(
"bar"
)
assert
.
Nil
(
ds
.
Put
(
key
,
val
),
t
)
v
,
err
:=
ds
.
Get
(
key
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
bytes
.
Compare
(
v
.
([]
byte
),
val
)
!=
0
{
t
.
Fail
()
}
}
func
TestHasBytes
(
t
*
testing
.
T
)
{
client
:=
clientOrAbort
(
t
)
ds
,
err
:=
NewDatastore
(
client
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
key
,
val
:=
datastore
.
NewKey
(
"foo"
),
[]
byte
(
"bar"
)
has
,
err
:=
ds
.
Has
(
key
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
has
{
t
.
Fail
()
}
assert
.
Nil
(
ds
.
Put
(
key
,
val
),
t
)
hasAfterPut
,
err
:=
ds
.
Has
(
key
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
!
hasAfterPut
{
t
.
Fail
()
}
}
func
TestDelete
(
t
*
testing
.
T
)
{
client
:=
clientOrAbort
(
t
)
ds
,
err
:=
NewDatastore
(
client
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
key
,
val
:=
datastore
.
NewKey
(
"foo"
),
[]
byte
(
"bar"
)
assert
.
Nil
(
ds
.
Put
(
key
,
val
),
t
)
assert
.
Nil
(
ds
.
Delete
(
key
),
t
)
hasAfterDelete
,
err
:=
ds
.
Has
(
key
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
hasAfterDelete
{
t
.
Fail
()
}
}
func
TestExpiry
(
t
*
testing
.
T
)
{
ttl
:=
1
*
time
.
Second
client
:=
clientOrAbort
(
t
)
ds
,
err
:=
NewExpiringDatastore
(
client
,
ttl
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
key
,
val
:=
datastore
.
NewKey
(
"foo"
),
[]
byte
(
"bar"
)
assert
.
Nil
(
ds
.
Put
(
key
,
val
),
t
)
time
.
Sleep
(
ttl
+
1
*
time
.
Second
)
assert
.
Nil
(
ds
.
Delete
(
key
),
t
)
hasAfterExpiration
,
err
:=
ds
.
Has
(
key
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
hasAfterExpiration
{
t
.
Fail
()
}
}
func
clientOrAbort
(
t
*
testing
.
T
)
*
redis
.
Client
{
c
,
err
:=
redis
.
Dial
(
"tcp"
,
os
.
Getenv
(
RedisEnv
))
if
err
!=
nil
{
t
.
Log
(
"could not connect to a redis instance"
)
t
.
SkipNow
()
}
if
err
:=
c
.
Cmd
(
"FLUSHALL"
)
.
Err
;
err
!=
nil
{
t
.
Fatal
(
err
)
}
return
c
}
This diff is collapsed.
Click to expand it.
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