goriak - Go language driver for Riak KV

goriak Build Status codecov Go Report Card

Current version: v3.2.1.
Riak KV version: 2.0 or higher, the latest version of Riak KV is always recommended.

What is goriak?

goriak is a wrapper around riak-go-client (version 1.9.0 or newer is required) to make it easier and more friendly for developers to use Riak KV.

Installation

As a Go module (requires Go 1.11 or later):

go get github.com/zegl/goriak/[email protected]

As a Go package:

go get -u gopkg.in/zegl/goriak.v3

Maps (Riak Data Types)

The main feature of goriak is that goriak automatically can marshal/unmarshal your Go types into Riak data types.

Set (Riak Data Types)

In the example below Name will be saved as a register, and Aliases will be a set.

type User struct {
    Name    string
    Aliases []string
}

user := User {
    Name:   "Foo",
    Alises: []string{"Foo", "Bar"},
}

goriak.Bucket("bucket-name", "bucket-type").Set(user).Key("key").Run(c)

Tags

Struct tags can be used to change the name of the item, or to ignore it.

type User struct {
    Name    string   `goriak:"-"`       // Ignore field
    Aliases []string `goriak:"aliases"` // Save as "aliases" in Riak KV
}

Get (Riak Data Types)

The map can later be retreived as a whole:

var res User
goriak.Bucket("bucket-name", "bucket-type").Get("key", &res).Run(c)

Supported Go types

Go Type Riak Type
struct map
string register
[n]byte register
[]byte register
[]slice set
[]slice set
[][]byte set
map map
time.Time register
int [1] register

1: All signed and unsigned integer types are supported.

Golang map types

Supported key types: all integer types, string.
Supported value types: string, []byte.

Helper types

Some actions are more complicated then necessary with the use of the default Go types and MapOperations.

This is why goriak contains the types Counter, Set, Flag and Register. All of these types will help you performing actions such as incrementing a value, or adding/removing items.

Counters

Riak Counters is supported with the special goriak.Counter type.

Example:

type Article struct {
    Title string
    Views *goriak.Counter
}

// Get our object
var article Article
goriak.Bucket("articles", "map").Get("1-hello-world", &article).Run(con)

// Increase views by 1
err := article.Views.Increase(1).Exec(con)

// check err

Counter.Exec(con) will make a lightweight request to Riak, and the counter is the only object that will be updated.

You can also save the changes to your counter with SetMap(), this is useful if you want to change multiple counters at the same time.

Check godoc for more information.

Sets

You can chose to use goriak.Set to help you with Set related actions, such as adding and removing items. goriak.Set also has support for sending incremental actions to Riak so that you don't have to build that functionality yourself.

Example:

type Article struct {
    Title string
    Tags *goriak.Set
}

// Get our object
var article Article
goriak.Bucket("articles", "map").Get("1-hello-world", &article).Run(con)

// Add the tag "animals"
err := article.Tags.AddString("animals").Exec(con)

// check err

Check godoc for more information.

Values

Values can be automatically JSON Marshalled/Unmarshalled by using SetJSON() and GetJSON(). There is also SetRaw() and GetRaw() that works directly on []bytes.

JSON

// Set object
goriak.Bucket("bucket-name", "bucket-type").SetJSON(obj).Key("key").Run(con)

// Get object
goriak.Bucket("bucket-name", "bucket-type").GetJSON("key", &obj).Run(con)

MapOperation

There is a time in everyones life where you need to perform raw MapOperations on your Riak Data Values.

Some operations, such as RemoveFromSet requires a Context to perform the operation. A Context can be retreived from Get by setting a special context type.

type ourType struct {
    Aliases []string

    // The context from Riak will be added if the tag goriakcontext is provided
    Context []byte `goriak:"goriakcontext"`
}

// ... GetMap()

// Works with MapOperation from github.com/basho/riak-go-client
operation := goriak.NewMapOperation()
operation.AddToSet("Aliases", []byte("Baz"))

goriak.MapOperation("bucket-name", "bucket-type", "key", operation, val.Context)

Secondary Indexes

You can set secondary indexes automatically with SetJSON() by using struct tags.

Strings and all signed integer types are supported. Both as-is and in slices.

type User struct {
    Name    string `goriakindex:"nameindex_bin"`
    Aliases []string
}

Indexes can also be used in slices. If you are using a slice every value in the slice will be added to the index.

type User struct {
    Aliases []string `goriakindex:"aliasesindex_bin"`
}

When saved the next time the index will be updated.

KeysInIndex

Keys in a particular index can be retreived with KeysInIndex.

callback := func(item goriak.SecondaryIndexQueryResult) {
    // use item
}

goriak.Bucket("bucket-name", "bucket-type").
    KeysInIndex("nameindex_bin", "Value", callback).
    Run(con)

AddToIndex

An alternative way of setting Secondary Indexes is by using AddToIndex().

goriak.Bucket("bucket-name", "bucket-type").
    SetRaw(data).
    AddToIndex("indexname_bin", "value").
    Run(con)
Owner
Gustav Westling
SRE at Tink. Kubernaut, Gopher.
Gustav Westling
Comments
  • What is the meaning of `NotFound` field in `Result` struct ?

    What is the meaning of `NotFound` field in `Result` struct ?

    Hello,

    Could you please explain why there is a NotFound field in Result struct ? For instance I see that here https://github.com/zegl/goriak/blob/853c1d1c26fcb79ded29a53b802c60989cf46013/map_get.go#L58 a tuple returned that consists of struct with NotFound: true field and a "not found" error.

    It seems that these two are counterintuitive — if we already return NotFound error, why do we have to return ... a basically invalid Result ?

    Hope my question finds you well. Thank you!

  • Change SetJSON to correctly handle pointer args

    Change SetJSON to correctly handle pointer args

    This fixes an issue with not grabbed goriakindex tags when we pass the pointer to SetJSON method.

    Before this commit the behavior was:

    • call SetJSON with the pointer to a struct which has goriakindex tag.
    • under the hood, the method determinates kind of passed value as ptr and doesn't try to find the field with tag.
    • data are silently written into a bucket, without a secondary key.

    In this commit added an extra check on pointer and data passed by pointer handled in the same way as data passed by value. Test case included into the commit.

  • Add a Gitter chat badge to README.md

    Add a Gitter chat badge to README.md

    zegl/goriak now has a Chat Room on Gitter

    @zegl has just created a chat room. You can visit it here: https://gitter.im/golangriak/Lobby.

    This pull-request adds this badge to your README.md:

    Gitter

    If my aim is a little off, please let me know.

    Happy chatting.

    PS: Click here if you would prefer not to receive automatic pull-requests from Gitter in future.

  • Bundle riak-go-client in releases

    Bundle riak-go-client in releases

    1.9.0 of riak-go-client is not compatible with earlier releases of itself. This will bundle the dependency in goriak to avoid backwards incompabilities in the future.

  • Middleware

    Middleware

    General middleware that can run on all commands

    type RunMiddlewarer interface {
    	Key() string
    	Bucket() string
    	BucketType() string
    }
    
    • [x] GetRaw
    • [x] SetRaw
    • [x] Set
    • [x] Get
    • [x] SetJSON
    • [x] GetJSON
  • Nested structures

    Nested structures

    I'm curious how to store and restore nested structures, for example slice/array of structs, or map where key is string and value is some other struct (arbitrarily nested). What would be the best strategy for this?

    I was able to store and restore JSON as is, but what If I have some already mapped structs, is it possible to reuse them somehow? For example:

    type TB struct { B string DataTB map[string]string }

    type A struct { A string DataTA map[string]string B TB DataTC map[string]TC }

    At the moment, all thins except DataTC which is map[string]TC, will be stored and restored properly. Only DataTC will end up as an empty map. What is the best solution for this?

  • Go 1.17

    Go 1.17

    Update and test with go 1.17


    This PR was created from Gustav Westling's (zegl) workspace on Sturdy.

    Join your team, and code and collaborate on Sturdy, join now!.

    Update this PR by making changes through Sturdy.

  • Upgrade to GitHub-native Dependabot

    Upgrade to GitHub-native Dependabot

    Dependabot Preview will be shut down on August 3rd, 2021. In order to keep getting Dependabot updates, please merge this PR and migrate to GitHub-native Dependabot before then.

    Dependabot has been fully integrated into GitHub, so you no longer have to install and manage a separate app. This pull request migrates your configuration from Dependabot.com to a config file, using the new syntax. When merged, we'll swap out dependabot-preview (me) for a new dependabot app, and you'll be all set!

    With this change, you'll now use the Dependabot page in GitHub, rather than the Dependabot dashboard, to monitor your version updates, and you'll configure Dependabot through the new config file rather than a UI.

    If you've got any questions or feedback for us, please let us know by creating an issue in the dependabot/dependabot-core repository.

    Learn more about migrating to GitHub-native Dependabot

    Please note that regular @dependabot commands do not work on this pull request.

  • Do connections need management?

    Do connections need management?

    I've looked at the examples folder and I saw how the connection is created:

    con, err := goriak.Connect(goriak.ConnectOpts{Address: "127.0.0.1"})

    Do we have to manage this somehow like defer conn.Close() (I have not seen such API call) or is it entirely managed via underlying riak-go-client?

    Their (Basho's) code does something like this:

    defer func() { stopping = true close(sc) if serr := c.Stop(); serr != nil { util.ErrExit(serr) } close(sdc) close(fdc) }()

    Nice repo BTW, I'm playing with it right now, good work!

Qmgo - The Go driver for MongoDB. It‘s based on official mongo-go-driver but easier to use like Mgo.

Qmgo English | 简体中文 Qmgo is a Go driver for MongoDB . It is based on MongoDB official driver, but easier to use like mgo (such as the chain call). Qmg

Dec 28, 2022
Go driver for PostgreSQL over SSH. This driver can connect to postgres on a server via SSH using the local ssh-agent, password, or private-key.

pqssh Go driver for PostgreSQL over SSH. This driver can connect to postgres on a server via SSH using the local ssh-agent, password, or private-key.

Nov 6, 2022
Microsoft SQL server driver written in go language

A pure Go MSSQL driver for Go's database/sql package Install Requires Go 1.8 or above. Install with go get github.com/denisenkom/go-mssqldb . Connecti

Dec 26, 2022
Go language driver for RethinkDB
Go language driver for RethinkDB

RethinkDB-go - RethinkDB Driver for Go Go driver for RethinkDB Current version: v6.2.1 (RethinkDB v2.4) Please note that this version of the driver on

Dec 24, 2022
Mirror of Apache Calcite - Avatica Go SQL Driver

Apache Avatica/Phoenix SQL Driver Apache Calcite's Avatica Go is a Go database/sql driver for the Avatica server. Avatica is a sub-project of Apache C

Nov 3, 2022
Firebird RDBMS sql driver for Go (golang)

firebirdsql (Go firebird sql driver) Firebird RDBMS http://firebirdsql.org SQL driver for Go Requirements Firebird 2.5 or higher Golang 1.13 or higher

Dec 20, 2022
Microsoft ActiveX Object DataBase driver for go that using exp/sql

go-adodb Microsoft ADODB driver conforming to the built-in database/sql interface Installation This package can be installed with the go get command:

Dec 30, 2022
Oracle driver for Go using database/sql

go-oci8 Description Golang Oracle database driver conforming to the Go database/sql interface Installation Install Oracle full client or Instant Clien

Dec 30, 2022
sqlite3 driver for go using database/sql

go-sqlite3 Latest stable version is v1.14 or later not v2. NOTE: The increase to v2 was an accident. There were no major changes or features. Descript

Jan 8, 2023
GO DRiver for ORacle DB

Go DRiver for ORacle godror is a package which is a database/sql/driver.Driver for connecting to Oracle DB, using Anthony Tuininga's excellent OCI wra

Jan 5, 2023
Go Sql Server database driver.

gofreetds Go FreeTDS wrapper. Native Sql Server database driver. Features: can be used as database/sql driver handles calling stored procedures handle

Dec 16, 2022
PostgreSQL driver and toolkit for Go

pgx - PostgreSQL Driver and Toolkit pgx is a pure Go driver and toolkit for PostgreSQL. pgx aims to be low-level, fast, and performant, while also ena

Jan 4, 2023
Pure Go Postgres driver for database/sql

pq - A pure Go postgres driver for Go's database/sql package Install go get github.com/lib/pq Features SSL Handles bad connections for database/sql S

Jan 2, 2023
Lightweight Golang driver for ArangoDB

Arangolite Arangolite is a lightweight ArangoDB driver for Go. It focuses on pure AQL querying. See AranGO for a more ORM-like experience. IMPORTANT:

Sep 26, 2022
Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver)
Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver)

Mongo Go Models Important Note: We changed package name from github.com/Kamva/mgm/v3(uppercase Kamva) to github.com/kamva/mgm/v3(lowercase kamva) in v

Jan 2, 2023
The MongoDB driver for Go

The MongoDB driver for Go This fork has had a few improvements by ourselves as well as several PR's merged from the original mgo repo that are current

Jan 8, 2023
The Go driver for MongoDB
The Go driver for MongoDB

MongoDB Go Driver The MongoDB supported driver for Go. Requirements Installation Usage Bugs / Feature Reporting Testing / Development Continuous Integ

Dec 31, 2022
RethinkDB-go - RethinkDB Driver for Go
RethinkDB-go - RethinkDB Driver for Go

Go language driver for RethinkDB

Dec 24, 2022
SAP (formerly sybase) ASE/RS/IQ driver written in pure go

tds import "github.com/thda/tds" Package tds is a pure Go Sybase ASE/IQ/RS driver for the database/sql package. Status This is a beta release. This dr

Dec 7, 2022