Skip to content
Permalink
Browse files

Mongo support

* Mongo caching support
  • Loading branch information...
faabiosr committed Nov 5, 2016
1 parent ef654d2 commit a5d3c26a05e1cc724da226b22c1cb2461a896bd7
Showing with 250 additions and 0 deletions.
  1. +1 −0 .travis.yml
  2. +21 −0 README.md
  3. +5 −0 docker-compose.yml
  4. +91 −0 mongo.go
  5. +132 −0 mongo_test.go
@@ -9,6 +9,7 @@ go:
services:
- memcached
- redis-server
- mongodb

before_install:
- go get github.com/axw/gocov/gocov
@@ -93,6 +93,27 @@ func init() {
}
```

### MongoDB

```go
package main
import (
"github.com/fabiorphp/cachego"
"gopkg.in/mgo.v2"
)
var cache cachego.Cache
func init() {
session, _ := mgo.Dial(address)
cache = &cachego.Mongo{
session.DB("cache").C("cache"),
}
}
```

### Chain

```go
@@ -8,3 +8,8 @@ redis:
image: "redis:alpine"
ports:
- "6379:6379"

mongodb:
image: "mongo:3.3"
ports:
- "27017:27017"
@@ -0,0 +1,91 @@
package cachego

import (
"errors"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"time"
)

type Mongo struct {
collection *mgo.Collection
}

type MongoContent struct {
Duration int64
Key string `bson:"_id"`
Value string
}

func (m *Mongo) Contains(key string) bool {
if _, err := m.Fetch(key); err != nil {
return false
}

return true
}

func (m *Mongo) Delete(key string) error {
return m.collection.Remove(bson.M{"_id": key})
}

func (m *Mongo) Fetch(key string) (string, error) {
content := &MongoContent{}

err := m.collection.Find(bson.M{"_id": key}).One(content)

if err != nil {
return "", err
}

if content.Duration == 0 {
return content.Value, nil
}

if content.Duration <= time.Now().Unix() {
m.Delete(key)
return "", errors.New("Cache expired")
}

return content.Value, nil
}

func (m *Mongo) FetchMulti(keys []string) map[string]string {
result := make(map[string]string)

iter := m.collection.Find(bson.M{"_id": bson.M{"$in": keys}}).Iter()

content := &MongoContent{}

for iter.Next(content) {
result[content.Key] = content.Value
}

return result
}

func (m *Mongo) Flush() error {
_, err := m.collection.RemoveAll(bson.M{})

return err
}

func (m *Mongo) Save(key string, value string, lifeTime time.Duration) error {
duration := int64(0)

if lifeTime > 0 {
duration = time.Now().Unix() + int64(lifeTime.Seconds())
}

content := &MongoContent{
duration,
key,
value,
}

if _, err := m.collection.Upsert(bson.M{"_id": key}, content); err != nil {
return err
}

return nil
}
@@ -0,0 +1,132 @@
package cachego

import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"gopkg.in/mgo.v2"
"net"
"testing"
"time"
)

type MongoTestSuite struct {
suite.Suite

assert *assert.Assertions
cache Cache
session *mgo.Session
}

func (s *MongoTestSuite) SetupTest() {
address := "localhost:27017"

if _, err := net.Dial("tcp", address); err != nil {
s.T().Skip()
}

session, err := mgo.Dial(address)

if err != nil {
s.T().Skip()
}

s.cache = &Mongo{
session.DB("cache").C("cache"),
}

s.assert = assert.New(s.T())
}

func (s *MongoTestSuite) TestSave() {
s.assert.Nil(s.cache.Save("foo", "bar", 10))
}

func (s *MongoTestSuite) TestFetchThrowError() {
result, err := s.cache.Fetch("bar")

s.assert.Error(err)
s.assert.Empty(result)
}

func (s *MongoTestSuite) TestFetchThrowErrorWhenExpired() {
key := "foo"
value := "bar"

s.cache.Save(key, value, 1*time.Second)

time.Sleep(1 * time.Second)

result, err := s.cache.Fetch(key)

s.assert.EqualError(err, "Cache expired")
s.assert.Empty(result)
}

func (s *MongoTestSuite) TestFetch() {
key := "foo"
value := "bar"

s.cache.Save(key, value, 0)

result, err := s.cache.Fetch(key)

s.assert.Nil(err)
s.assert.Equal(value, result)
}

func (s *MongoTestSuite) TestFetchLongCacheDuration() {
key := "foo"
value := "bar"

s.cache.Save(key, value, 10*time.Second)
result, err := s.cache.Fetch(key)

s.assert.Nil(err)
s.assert.Equal(value, result)
}

func (s *MongoTestSuite) TestContains() {
s.cache.Save("foo", "bar", 0)

s.assert.True(s.cache.Contains("foo"))
s.assert.False(s.cache.Contains("bar"))
}

func (s *MongoTestSuite) TestDeleteThrowError() {
s.assert.Error(s.cache.Delete("bar"))
}

func (s *MongoTestSuite) TestDelete() {
s.cache.Save("foo", "bar", 0)

s.assert.Nil(s.cache.Delete("foo"))
s.assert.False(s.cache.Contains("foo"))
}

func (s *MongoTestSuite) TestFlush() {
s.cache.Save("foo", "bar", 0)

s.assert.Nil(s.cache.Flush())
s.assert.False(s.cache.Contains("foo"))
}

func (s *MongoTestSuite) TestFetchMulti() {
s.cache.Save("foo", "bar", 0)
s.cache.Save("john", "doe", 0)

result := s.cache.FetchMulti([]string{"foo", "john"})

s.assert.Len(result, 2)
}

func (s *MongoTestSuite) TestFetchMultiWhenOnlyOneOfKeysExists() {
s.cache.Save("foo", "bar", 0)

result := s.cache.FetchMulti([]string{"foo", "alice"})

s.assert.Len(result, 1)
}

func TestMongoRunSuite(t *testing.T) {
suite.Run(t, new(MongoTestSuite))
}

0 comments on commit a5d3c26

Please sign in to comment.
You can’t perform that action at this time.