High level struct wrapper for riaken-core.
It provides the ability to pass structs in and out of Riak as other formats such as JSON, XML, etc.
go get gopkg.in/riaken/riaken-struct.v1
http://godoc.org/gopkg.in/riaken/riaken-struct.v1
The following methods being wrapped for struct usage are:
- Object->Fetch
- Object->Store
- Query->SecondaryIndexes
- Query->Search
The rest of the underlying riaken-core API is exposed as normal.
Not much different from riaken-core, with the exception of passing a marshaller.
package main
import "log"
import "github.com/riaken/riaken-struct"
func main() {
// Marshaller
marshaller := NewStructMarshal("json", JsonMarshaller, JsonUnmarshaller)
// Riak cluster addresses
addrs := []string{"127.0.0.1:8083", "127.0.0.1:8084", "127.0.0.1:8085", "127.0.0.1:8086", "127.0.0.1:8087"}
// Create a client, passing the addresses, and number of connections to maintain per cluster node
client := riaken_struct.NewClient(addrs, 1, marshaller)
// Dial the servers
if err := client.Dial(); err != nil {
log.Fatal(err.Error()) // all nodes are down
}
// Gracefully close all the connections when finished
defer client.Close()
// Grab a session to interact with the cluster
session := client.Session()
// Release the session
defer session.Release()
}
The marshaller allows structs with tag data to be parsed to and from their target format, in this case JSON. If a format other than JSON is desired consider using struct_marshall.go
as a guideline.
Note that all methods can utilize the same Do()
construct as riaken-core.
Standard struct data.
type User struct {
Name string `json:"name"`
}
user := &User{
Name: "User",
}
bucket := session.GetBucket("b1")
object := bucket.Object("o1")
if _, err := object.Store(user); err != nil {
log.Error(err.Error())
}
check := User{}
if _, err := object.Fetch(&check); err != nil {
log.Error(err.Error())
}
log.Print(check.Name) // User
Since we are querying out fields where we don't know the keys, there are a few things to note.
type Animal struct {
Id string
Name string `json:"name" riak:"index"`
}
Id
is arbitrarily named, but necessary. It will contain the key from the server.riak:"index"
allows us to specify this member as a queryable 2i index.
Note that each method below chains with Key()
and Out()
. The first specifies the struct member in which to place the key, the second the struct slice to output results to.
These can potentially run the application out of memory, so use with care. As opposed to their lower level riaken-core counterparts they actively fetch the object for every key found as well (without duplicates). If lower level behavior is desired through this driver consider calling session.Query().CoreQuery()
and manually fetching objects as required.
var check []Animal
query := session.Query()
if _, err := query.Key("Id").Out(&check).SecondaryIndexes([]byte("animals"), []byte("name_bin"), []byte("chicken"), nil, nil, 0, nil); err != nil {
log.Error(err.Error())
}
var animals []Animal
query := session.Query()
if _, err := query.Key("Id").Out(&animals).Search([]byte("animals"), []byte("name:pig OR name:dog")); err != nil {
log.Error(err.Error())
}
Brian Jones - [email protected] - https://twitter.com/mojobojo