Couchbase client in Go

A smart client for couchbase in go

This is a unoffical version of a Couchbase Golang client. If you are looking for the Offical Couchbase Golang client please see [CB-go])[https://github.com/couchbaselabs/gocb].

This is an evolving package, but does provide a useful interface to a couchbase server including all of the pool/bucket discovery features, compatible key distribution with other clients, and vbucket motion awareness so application can continue to operate during rebalances.

It also supports view querying with source node randomization so you don't bang on all one node to do all the work.

Install

go get github.com/couchbase/go-couchbase

Example

c, err := couchbase.Connect("http://dev-couchbase.example.com:8091/")
if err != nil {
	log.Fatalf("Error connecting:  %v", err)
}

pool, err := c.GetPool("default")
if err != nil {
	log.Fatalf("Error getting pool:  %v", err)
}

bucket, err := pool.GetBucket("default")
if err != nil {
	log.Fatalf("Error getting bucket:  %v", err)
}

bucket.Set("someKey", 0, []string{"an", "example", "list"})
Comments
  • Does not work with Docker

    Does not work with Docker

    I'm running my Couchbase server in Docker with port mapping to my local machine for development. This works fine for the .NET SDK, however, when using this Go SDK, the SDK tries to talk to the Docker IP.

    2016/09/26 09:03:27 dial tcp 172.17.0.2:11210: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
    exit status 1
    

    The 172.17.0.2 is the internal IP for the container, and is not accessible from the outside. Do note that this is not the IP I provided when trying to connect to the server: I provided http://localhost:8091,

    Does this mean that we cannot use Couchbase hosted in Docker for development environments?

  • fatal error: all goroutines are asleep - deadlock!

    fatal error: all goroutines are asleep - deadlock!

    Hello,

    I would like to report an error encountered recently after update with golang v1.9.1 . The following error frequently happens when it calls. Not always, but sometime happens. Can anybody please look into this and hopefully fix this soon?

    Thank you!

    fatal error: all goroutines are asleep - deadlock!

    goroutine 1 [select]: net/http.(*persistConn).roundTrip(0xc042092fc0, 0xc04206aae0, 0x0, 0x0, 0x0) C:/Go/src/net/http/transport.go:1970 +0x60f net/http.(*Transport).RoundTrip(0x8008a0, 0xc0420fa000, 0x8008a0, 0x0, 0x0) C:/Go/src/net/http/transport.go:413 +0x999 net/http.send(0xc0420fa000, 0x7ceca0, 0x8008a0, 0x0, 0x0, 0x0, 0xc042076048, 0x4 1034d, 0xc042073390, 0x1) C:/Go/src/net/http/client.go:249 +0x1b0 net/http.(*Client).send(0x7fc020, 0xc0420fa000, 0x0, 0x0, 0x0, 0xc042076048, 0x0 , 0x1, 0x12200ffffffff) C:/Go/src/net/http/client.go:173 +0x104 net/http.(*Client).Do(0x7fc020, 0xc0420fa000, 0x0, 0xc0420735c8, 0x4437de) C:/Go/src/net/http/client.go:602 +0x294 github.com/couchbase/go-couchbase.doHTTPRequest(0xc0420fa000, 0x0, 0x0, 0x0) C:/goproject/src/github.com/couchbase/go-couchbase/pools.go:534 +0x9f github.com/couchbase/go-couchbase.queryRestAPI(0xc042080100, 0x6a6c3a, 0x6, 0x0, 0x0, 0x638a40, 0xc0420ec1f8, 0x0, 0x0) C:/goproject/src/github.com/couchbase/go-couchbase/pools.go:632 +0x26a github.com/couchbase/go-couchbase.(*Client).parseURLResponse(0xc0420ec1e0, 0x6a6 c3a, 0x6, 0x638a40, 0xc0420ec1f8, 0x0, 0x410801) C:/goproject/src/github.com/couchbase/go-couchbase/pools.go:652 +0x6f github.com/couchbase/go-couchbase.ConnectWithAuth(0xc042074030, 0x24, 0x0, 0x0, 0x346010, 0x0, 0x0, 0x805280, 0x3406a8, 0x0, ...) C:/goproject/src/github.com/couchbase/go-couchbase/pools.go:773 +0xdf github.com/couchbase/go-couchbase.Connect(0xc042074030, 0x24, 0x0, 0x0, 0x0, 0x0 , 0x0, 0x0, 0x0, 0x0, ...) C:/goproject/src/github.com/couchbase/go-couchbase/pools.go:792 +0xcd main.(repoCouchbase3).open(0xc042073cc8, 0xc042074030, 0x24, 0xc0420560c0, 0x7, 0xc0420d8660, 0x20) C:/goproject/src/****:298 +0xd9 main.bucketsImpl(0xc042074030, 0x24, 0xc0420560c0, 0x7, 0xc0420521f0, 0x1, 0x1, 0x0, 0x0) C:/goproject/src/*:245 +0xcf laszlo/tree.Main(0x6bab10, 0x6bab20, 0x6baaf8, 0x6bab00, 0x6bab30, 0x6baae8, 0x6 87000) C:/goproject/src/*:194 +0x13c9 main.main() C:/goproject/src/*****:32 +0x222

    goroutine 22 [IO wait]: internal/poll.runtime_pollWait(0xb24f70, 0x72, 0x0) C:/Go/src/runtime/netpoll.go:173 +0x5e internal/poll.(*pollDesc).wait(0xc042094c98, 0x72, 0x7cd200, 0x0, 0x0) C:/Go/src/internal/poll/fd_poll_runtime.go:85 +0xb5 internal/poll.(*ioSrv).ExecIO(0x802d78, 0xc042094b58, 0x6baa30, 0x0, 0x0, 0x0) C:/Go/src/internal/poll/fd_windows.go:195 +0x13a internal/poll.(*FD).Read(0xc042094b40, 0xc04210a000, 0x1000, 0x1000, 0x0, 0x0, 0 x0) C:/Go/src/internal/poll/fd_windows.go:439 +0x266 net.(*netFD).Read(0xc042094b40, 0xc04210a000, 0x1000, 0x1000, 0x345430, 0x0, 0x0 ) C:/Go/src/net/fd_windows.go:151 +0x59 net.(*conn).Read(0xc042076058, 0xc04210a000, 0x1000, 0x1000, 0x0, 0x0, 0x0) C:/Go/src/net/net.go:176 +0x74 net/http.(*persistConn).Read(0xc042092fc0, 0xc04210a000, 0x1000, 0x1000, 0x20, 0 x677300, 0xc042105b68) C:/Go/src/net/http/transport.go:1391 +0x147 bufio.(*Reader).fill(0xc0420ec600) C:/Go/src/bufio/bufio.go:97 +0x121 bufio.(*Reader).Peek(0xc0420ec600, 0x1, 0xc042016060, 0xc042105c80, 0x805280, 0x 3406a8, 0x0) C:/Go/src/bufio/bufio.go:129 +0x41 net/http.(*persistConn).readLoop(0xc042092fc0) C:/Go/src/net/http/transport.go:1539 +0x18c created by net/http.(*Transport).dialConn C:/Go/src/net/http/transport.go:1186 +0xa35

    goroutine 23 [select]: net/http.(*persistConn).writeLoop(0xc042092fc0) C:/Go/src/net/http/transport.go:1759 +0x16c created by net/http.(*Transport).dialConn C:/Go/src/net/http/transport.go:1187 +0xa5a

  • cannot get or set values to a 'Memcached' type bucket

    cannot get or set values to a 'Memcached' type bucket

    Using the following stub code below against a cluster with a 'Memcached' type bucket called 'memcached_bucket' I get the following error everytime I try to read or write a value:

    ahurt1:local ahurt$ go build cb-test.go; ./cb-test
    2015/03/16 17:08:05 Error setting key: go-couchbase: vbmap smaller than vbucket list: 6536 vs. []
    

    Thank you in advance!

    package main
    
    import (
        "bytes"
        "github.com/couchbase/go-couchbase"
        "log"
    )
    
    const (
        CB_HOST   = "http://some-host:8091/"
        CB_BUCKET = "memcached_bucket"
    )
    
    func main() {
        c, err := couchbase.Connect(CB_HOST)
        if err != nil {
            log.Fatalf("Error connecting:  %v", err)
        }
    
        pool, err := c.GetPool("default")
        if err != nil {
            log.Fatalf("Error getting pool:  %v", err)
        }
    
        bucket, err := pool.GetBucket(CB_BUCKET)
        if err != nil {
            log.Fatalf("Error getting bucket:  %v", err)
        }
    
        buff := bytes.NewBufferString("someValue")
    
        err = bucket.SetRaw("someKey", 0, buff.Bytes())
        if err != nil {
            log.Fatalf("Error setting key: %v", err)
        }
    }
    
  • Support for creating/deleting buckets

    Support for creating/deleting buckets

    Would you be interested in adding support for creating / deleting buckets? If so, does the API change in the attached patch look reasonable? If yes, I'd be happy to clean up the implementation as needed, add docs, tests, etc.

    This functionality would be useful for writing integration tests.

  • Auth issue when connecting to default bucket via cbdatasource

    Auth issue when connecting to default bucket via cbdatasource

    I'm connecting to a default bucket via CBGT, which uses the go-couchbase cbdatasource connection library.

    The problem appears to be in this method:

    func maybeAddAuth(req *http.Request, ah AuthHandler) error {
        if hah, ok := ah.(HTTPAuthHandler); ok {
            return hah.SetCredsForRequest(req)
        }
        if ah != nil {
            user, pass, _ := ah.GetCredentials()
            req.Header.Set("Authorization", "Basic "+
                base64.StdEncoding.EncodeToString([]byte(user+":"+pass)))
        }
        return nil
    }
    

    Even though user and pass are both empty, it tries to add the Basic Authorization header, which ends up failing to connect with 401 errors.

    A workaround that appears to work is:

    func maybeAddAuth(req *http.Request, ah AuthHandler) error {
        if hah, ok := ah.(HTTPAuthHandler); ok {
            return hah.SetCredsForRequest(req)
        }
        if ah != nil {
            user, pass, _ := ah.GetCredentials()
            if user != "" {
                req.Header.Set("Authorization", "Basic "+
                    base64.StdEncoding.EncodeToString([]byte(user+":"+pass)))
            }
        }
        return nil
    }
    

    This works around the issue by only adding the Basic Auth header if the user is non-empty.

    I'm not sure why it has a non-nil AuthHandler if the username and password are both empty. That might be a bug somewhere up in the callstack of the code that calls this method. Even so, checking for a non-empty user seems like good defensive coding, since it doesn't seem like a valid use case to set a Basic Auth header with an empty user.

  • Modified go get README because new URL doesn't work

    Modified go get README because new URL doesn't work

    I've got that weird error when I use github.com/couchbase/go-couchbase as couchbase package:

    github.com/couchbase/go-couchbase/conn_pool.go:56: conn.SetKeepAliveOptions undefined (type *memcached.Client has no field or method SetKeepAliveOptions)
    

    I am using now github.com/couchbaselabs/go-couchbase in all my projects and it works better.

    Let me now what you think

  • Adding new interface AuthWithSaslHandler

    Adding new interface AuthWithSaslHandler

    It is required to pass the auth for memcached with http auth. So added a new interface couchbase.AuthWithSaslHandler.

    Change-Id: Id8541e0a1b8559c5c141e595bb629e4f66e964c5

  • avoid nil being json marshaled

    avoid nil being json marshaled

    Since nil is JSON marshaled to null, b.Set(key, exp, nil) will store a blank value (not even a { }) for the key, which is both a bit confusing and different from func Write's comments

    • A nil value causes a delete
    • If Raw is not given, v will be marshaled as JSON before being written. It must be JSON-marshalable and it must not be nil.

    The change I made was first

    if opt&Raw == 0 && v != nil {
        data, err = json.Marshal(v)
        if err != nil {
            return err
        }
    } else if v != nil {
        data = v.([]byte)
    }
    

    then I refactor it to current way.

  • implemented more flexible auth support

    implemented more flexible auth support

    Specifically it's now possible to have different kind of auth on per bucket basis. As well as perform special auth exchange on freshly established memcached connections.

    This is going to be used by cbauth integration.

  • # github.com/couchbaselabs/go-couchbase ../../src/github.com/couchbaselabs/go-couchbase/upr.go:150: too many arguments in call to singleFeed.uprFeed.UprRequestStream

    # github.com/couchbaselabs/go-couchbase ../../src/github.com/couchbaselabs/go-couchbase/upr.go:150: too many arguments in call to singleFeed.uprFeed.UprRequestStream

    After commit cf12df69ce. I am unable to build.

    github.com/couchbaselabs/go-couchbase ../../src/github.com/couchbaselabs/go-couchbase/upr.go:150: too many arguments in call to singleFeed.uprFeed.UprRequestStream

  • Fixing issues with gomemcached dependency

    Fixing issues with gomemcached dependency

    Appears that the go.mod entry for the github.com/couchbase/gomemcached package is invalid.

    This simply fixes the reference.

    Note: it's good practice to include the go.sum file.

  • Misleading license info

    Misleading license info

    I'd like to bring up an issue and ask if this is intentional or a mistake.

    The "go-couchbase" repo says it's MIT licensed. However this looks quite misleading because at various places code from goutils is used. The license of that repo [1] is clearly a proprietary license and not anything alike a MIT license.

    This essentially means every package including go-couchbase will inadvertently include non-free code. This came up in a discussion at Gentoo due to the Gitea package including that code [2]. I also reported this to Gitea [3].

    Please either consider relicensing goutils or make at least clear that go-couchbase is not just "MIT-licensed", but also includes proprietary code.

    [1] https://github.com/couchbase/goutils/blob/master/LICENSE.md [2] https://github.com/gentoo/gentoo/pull/12597 [3] https://github.com/go-gitea/gitea/issues/8575

  • possible race condition in connection pool

    possible race condition in connection pool

    see conn_pool.go see connectionPool see connectionPool --> connCount see func (cp *connectionPool) connCloser()

    You are using connCloser() as a go routine. Inside connCloser there is the assignment connCount = cp.connCount

    Please consider using connCount = atomic.LoadUint64(&cp.connCount) instead, as the current solution might lead to race conditions.

    I am not using/invested in couchbase, so please forgive the bad report style.

  • Can't get clusterName

    Can't get clusterName

    The default Pool data structure can not match the Couchbase RESTful API pool/default. Pool struct can not only cover 3 fields while the API(Version: EE6.0.0) has more.

    // A Pool of nodes and buckets.
    type Pool struct {
    	BucketMap map[string]*Bucket
    	Nodes     []Node
    
    	BucketURL map[string]string `json:"buckets"`
    
    	client Client
    }
    

    I think ClusterName is an important field for cluster overview, and the structure can match the API better if the other fields in the API have been added.

  • bad strings.Replace call arguments

    bad strings.Replace call arguments

    https://github.com/couchbase/go-couchbase/pull/87

    - strings.Replace(buf.String(), "`", "` + \"`\" + `", 0))
    + strings.Replace(buf.String(), "`", "` + \"`\" + `", -1))
    

    Reporting an issue, but it's not convenient for me to send a gerrit CL. You can see a fix in a referenced PR.

  • perf/perf.go:101:10: assignment mismatch: 2 variables but 3 values

    perf/perf.go:101:10: assignment mismatch: 2 variables but 3 values

    perf does not build with Go 1.10 x86_64

    cd /builddir/build/BUILD/go-couchbase-a064ca416844fb169255a76fbdac7e80101b6049/_build/src/github.com/couchbase/go-couchbase/perf
    /usr/lib/golang/pkg/tool/linux_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -shared -p main -complete -installsuffix shared -bui
    ldid xg8dqXZtFmAoDE_d3Yjw/xg8dqXZtFmAoDE_d3Yjw -goversion go1.10 -D "" -importcfg $WORK/b001/importcfg -pack ./generate-json.go ./perf.go
    # github.com/couchbase/go-couchbase/perf
    perf/perf.go:101:10: assignment mismatch: 2 variables but 3 values
    perf/perf.go:101:22: not enough arguments in call to b.GetBulk
            have ([]string)
            want ([]string, time.Time, []string)
    error: Bad exit status from /var/tmp/rpm-tmp.tCh9vC (%build)
    
Aerospike Client Go

Aerospike Go Client An Aerospike library for Go. This library is compatible with Go 1.9+ and supports the following operating systems: Linux, Mac OS X

Dec 14, 2022
Go client library for Pilosa

Go Client for Pilosa Go client for Pilosa high performance distributed index. What's New? See: CHANGELOG Requirements Go 1.12 and higher. Install Down

Dec 3, 2022
Golang client for redislabs' ReJSON module with support for multilple redis clients (redigo, go-redis)

Go-ReJSON - a golang client for ReJSON (a JSON data type for Redis) Go-ReJSON is a Go client for ReJSON Redis Module. ReJSON is a Redis module that im

Dec 25, 2022
redis client implement by golang, inspired by jedis.

godis redis client implement by golang, refers to jedis. this library implements most of redis command, include normal redis command, cluster command,

Dec 6, 2022
Go Memcached client library #golang

About This is a memcache client library for the Go programming language (http://golang.org/). Installing Using go get $ go get github.com/bradfitz/gom

Jan 8, 2023
Neo4j Rest API Client for Go lang

neo4j.go Implementation of client package for communication with Neo4j Rest API. For more information and documentation please read Godoc Neo4j Page s

Nov 9, 2022
Neo4j REST Client in golang

DEPRECATED! Consider these instead: https://github.com/johnnadratowski/golang-neo4j-bolt-driver https://github.com/go-cq/cq Install: If you don't ha

Nov 9, 2022
Neo4j client for Golang

neoism - Neo4j client for Go Package neoism is a Go client library providing access to the Neo4j graph database via its REST API. Status System Status

Dec 30, 2022
Go client for Redis

Redigo Redigo is a Go client for the Redis database. Features A Print-like API with support for all Redis commands. Pipelining, including pipelined tr

Jan 1, 2023
Type-safe Redis client for Golang

Redis client for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Reference Exam

Jan 1, 2023
Go Redis Client

xredis Built on top of github.com/garyburd/redigo with the idea to simplify creating a Redis client, provide type safe calls and encapsulate the low l

Sep 26, 2022
godis - an old Redis client for Go

godis Implements a few database clients for Redis. There is a stable client and an experimental client, redis and exp, respectively. To use any of the

Apr 16, 2022
Google Go Client and Connectors for Redis

Go-Redis Go Clients and Connectors for Redis. The initial release provides the interface and implementation supporting the (~) full set of current Red

Oct 25, 2022
Redis client library for Go

go-redis go-redis is a Redis client library for the Go programming language. It's built on the skeleton of gomemcache. It is safe to use by multiple g

Nov 8, 2022
Type-safe Redis client for Golang

Redis client for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Reference Exam

Jan 4, 2023
Redis client Mock Provide mock test for redis query

Redis client Mock Provide mock test for redis query, Compatible with github.com/go-redis/redis/v8 Install Confirm that you are using redis.Client the

Dec 27, 2022
GoBigdis is a persistent database that implements the Redis server protocol. Any Redis client can interface with it and start to use it right away.

GoBigdis GoBigdis is a persistent database that implements the Redis server protocol. Any Redis client can interface with it and start to use it right

Apr 27, 2022
HDFS for Go - This is a native golang client for hdfs.

HDFS for Go This is a native golang client for hdfs. It connects directly to the namenode using the protocol buffers API. It tries to be idiomatic by

Dec 24, 2022
PostgreSQL API Client

PostgreSQL API language search PostgreSQL API functions response: We don't use PostgreSQL in the usual way. We do everything through API functions, wh

May 9, 2022