Skip to content

Commit

Permalink
add couchbase storage
Browse files Browse the repository at this point in the history
  • Loading branch information
mstrYoda committed May 29, 2023
1 parent 9cd6304 commit a5b87a0
Show file tree
Hide file tree
Showing 9 changed files with 481 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ updates:
- "🤖 Dependencies"
schedule:
interval: "daily"
- package-ecosystem: "gomod"
directory: "/couchbase/" # Location of package manifests
labels:
- "🤖 Dependencies"
schedule:
interval: "daily"
- package-ecosystem: "gomod"
directory: "/dynamodb/" # Location of package manifests
labels:
Expand Down
43 changes: 43 additions & 0 deletions .github/release-drafter-couchbase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name-template: 'Couchbase - v$RESOLVED_VERSION'
tag-template: 'couchbase/v$RESOLVED_VERSION'
tag-prefix: couchbase/v
include-paths:
- couchbase
categories:
- title: '🚀 New'
labels:
- '✏️ Feature'
- title: '🧹 Updates'
labels:
- '🧹 Updates'
- '🤖 Dependencies'
- title: '🐛 Fixes'
labels:
- '☢️ Bug'
- title: '📚 Documentation'
labels:
- '📒 Documentation'
change-template: '- $TITLE (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
version-resolver:
major:
labels:
- 'major'
minor:
labels:
- 'minor'
- '✏️ Feature'
patch:
labels:
- 'patch'
- '📒 Documentation'
- '☢️ Bug'
- '🤖 Dependencies'
- '🧹 Updates'
default: patch
template: |
$CHANGES
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...couchbase/v$RESOLVED_VERSION
Thank you $CONTRIBUTORS for making this update possible.
19 changes: 19 additions & 0 deletions .github/workflows/release-drafter-couchbase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Release Drafter Couchbase
on:
push:
# branches to consider in the event; optional, defaults to all
branches:
- master
- main
paths:
- 'couchbase/**'
jobs:
draft_release_couchbase:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: release-drafter/release-drafter@v5
with:
config-name: release-drafter-couchbase.yml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83 changes: 83 additions & 0 deletions couchbase/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Couchbase

A Couchbase storage driver using [couchbase/gocb](https://github.com/couchbase/gocb).

### Table of Contents
- [Signatures](#signatures)
- [Installation](#installation)
- [Examples](#examples)
- [Config](#config)
- [Default Config](#default-config)

### Signatures
```go
func New(config ...Config) Storage
func (s *Storage) Get(key string) ([]byte, error)
func (s *Storage) Set(key string, val []byte, exp time.Duration) error
func (s *Storage) Delete(key string) error
func (s *Storage) Reset() error
func (s *Storage) Close() error
func (s *Storage) Conn() *gocb.Cluster
```
### Installation
Couchbase is tested on the 2 last [Go versions](https://golang.org/dl/) with support for modules. So make sure to initialize one first if you didn't do that yet:
```bash
go mod init github.com/<user>/<repo>
```
And then install the Couchbase implementation:
```bash
go get github.com/gofiber/storage/couchbase
```

### Examples
Import the storage package.
```go
import "github.com/gofiber/storage/couchbase"
```

You can use the following possibilities to create a storage:
```go
// Initialize default config
store := couchbase.New()

// Initialize Couchbase storage with custom config
store := couchbase.New(couchbase.Config{
Host: "127.0.0.1:8091",
Username: "",
Password: "",
Bucket: 0,
ConnectionTimeout: 3* time.Second,
KVTimeout: 1* time.Second,
})
```

### Config
```go
type Config struct {
// The application username to Connect to the Couchbase cluster
Username string
// The application password to Connect to the Couchbase cluster
Password string
// The connection string for the Couchbase cluster
Host string
// The name of the bucket to Connect to
Bucket string
// The timeout for connecting to the Couchbase cluster
ConnectionTimeout time.Duration
// The timeout for performing operations on the Couchbase cluster
KVTimeout time.Duration
}
```

### Default Config
```go
// ConfigDefault is the default config
var ConfigDefault = Config{
Host: "127.0.0.1:8091",
Username: "admin",
Password: "123456",
Bucket: "fiber_storage",
ConnectionTimeout: 3 * time.Second,
KVTimeout: 1 * time.Second,
}
```
62 changes: 62 additions & 0 deletions couchbase/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package couchbase

import (
"time"
)

type Config struct {
// The application username to Connect to the Couchbase cluster
Username string
// The application password to Connect to the Couchbase cluster
Password string
// The connection string for the Couchbase cluster
Host string
// The name of the bucket to Connect to
Bucket string
// The timeout for connecting to the Couchbase cluster
ConnectionTimeout time.Duration
// The timeout for performing operations on the Couchbase cluster
KVTimeout time.Duration
}

// ConfigDefault is the default config
var ConfigDefault = Config{
Host: "127.0.0.1:8091",
Username: "admin",
Password: "123456",
Bucket: "fiber_storage",
ConnectionTimeout: 3 * time.Second,
KVTimeout: 1 * time.Second,
}

func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}

// Override default config
cfg := config[0]

// Set default values
if cfg.Username == "" {
cfg.Username = ConfigDefault.Username
}
if cfg.Password == "" {
cfg.Password = ConfigDefault.Password
}
if cfg.Host == "" {
cfg.Host = ConfigDefault.Host
}
if cfg.Bucket == "" {
cfg.Bucket = ConfigDefault.Bucket
}
if cfg.ConnectionTimeout == 0 {
cfg.ConnectionTimeout = ConfigDefault.ConnectionTimeout
}
if cfg.KVTimeout == 0 {
cfg.KVTimeout = ConfigDefault.KVTimeout
}

return cfg
}
97 changes: 97 additions & 0 deletions couchbase/couchbase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package couchbase

import (
"time"

"github.com/couchbase/gocb/v2"
)

type Storage struct {
cb *gocb.Cluster
bucket *gocb.Bucket
}

func New(config ...Config) *Storage {
// Set default config
cfg := configDefault(config...)

cb, err := gocb.Connect(cfg.Host, gocb.ClusterOptions{
Authenticator: gocb.PasswordAuthenticator{
Username: cfg.Username,
Password: cfg.Password,
},
TimeoutsConfig: gocb.TimeoutsConfig{
ConnectTimeout: cfg.ConnectionTimeout,
KVTimeout: cfg.KVTimeout,
},
Transcoder: gocb.NewLegacyTranscoder(),
})

if err != nil {
panic(err)
}

_, err = cb.Ping(&gocb.PingOptions{
Timeout: cfg.ConnectionTimeout,
})

if err != nil {
panic(err)
}

b := cb.Bucket(cfg.Bucket)

return &Storage{cb: cb, bucket: b}
}

func (s *Storage) Get(key string) ([]byte, error) {
out, err := s.bucket.DefaultCollection().Get(key, nil)
if err != nil {
switch e := err.(type) {
case *gocb.KeyValueError:
if e.InnerError.Error() == gocb.ErrDocumentNotFound.Error() {
return nil, nil
}
default: //*gocb.TimeoutError,...
return nil, err
}

return nil, err
}

var value []byte
if err := out.Content(&value); err != nil {
return nil, err
}

return value, nil
}

func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
if _, err := s.bucket.DefaultCollection().Upsert(key, val, &gocb.UpsertOptions{
Expiry: exp,
}); err != nil {
return err
}

return nil
}

func (s *Storage) Delete(key string) error {
if _, err := s.bucket.DefaultCollection().Remove(key, nil); err != nil {
return err
}
return nil
}

func (s *Storage) Reset() error {
return s.cb.Buckets().FlushBucket(s.bucket.Name(), nil)
}

func (s *Storage) Close() error {
return s.cb.Close(nil)
}

func (s *Storage) Conn() *gocb.Cluster {
return s.cb
}
Loading

0 comments on commit a5b87a0

Please sign in to comment.