Getting Started:
Creating Objects
First let’s create a few objects and a bucket to keep them in:
val1 := uint32(1)
val1buf := make([]byte, 4)
binary.LittleEndian.PutUint32(val1buf, val1)
val2 := "two"
val3 := struct{ MyValue int }{3} // NB: ensure that members are exported (i.e. capitalized)
var val3json []byte
val3json, err = json.Marshal(val3)
if err != nil {
util.ErrExit(err)
}
bucket := "test"
util.Log.Println("Creating Objects In Riak...")
objs := []*riak.Object{
{
Bucket: bucket,
Key: "one",
ContentType: "application/octet-stream",
Value: val1buf,
},
{
Bucket: bucket,
Key: "two",
ContentType: "text/plain",
Value: []byte(val2),
},
{
Bucket: bucket,
Key: "three",
ContentType: "application/json",
Value: val3json,
},
}
var cmd riak.Command
wg := &sync.WaitGroup{}
for _, o := range objs {
cmd, err = riak.NewStoreValueCommandBuilder().
WithContent(o).
Build()
if err != nil {
util.ErrLog.Println(err)
continue
}
a := &riak.Async{
Command: cmd,
Wait: wg,
}
if err := c.ExecuteAsync(a); err != nil {
util.ErrLog.Println(err)
}
}
wg.Wait()
In our first object, we have stored the integer 1 with the lookup key
of one
:
{
Bucket: bucket,
Key: "one",
ContentType: "application/octet-stream",
Value: val1buf,
}
For our second object, we stored a simple string value of two
with a
matching key:
{
Bucket: bucket,
Key: "two",
ContentType: "text/plain",
Value: []byte(val2),
}
Finally, the third object we stored was a bit of JSON:
{
Bucket: bucket,
Key: "three",
ContentType: "application/json",
Value: val3json,
}
Reading Objects
Now that we have a few objects stored, let’s retrieve them and make sure they contain the values we expect.
Requesting the objects by key:
var cmd riak.Command
wg := &sync.WaitGroup{}
for _, o := range objs {
cmd, err = riak.NewStoreValueCommandBuilder().
WithContent(o).
Build()
if err != nil {
util.ErrLog.Println(err)
continue
}
a := &riak.Async{
Command: cmd,
Wait: wg,
}
if err := c.ExecuteAsync(a); err != nil {
util.ErrLog.Println(err)
}
}
wg.Wait()
util.Log.Println("Reading Objects From Riak...")
d := make(chan riak.Command, len(objs))
for _, o := range objs {
cmd, err = riak.NewFetchValueCommandBuilder().
WithBucket(bucket).
WithKey(o.Key).
Build()
if err != nil {
util.ErrLog.Println(err)
continue
}
a := &riak.Async{
Command: cmd,
Wait: wg,
Done: d,
}
if err := c.ExecuteAsync(a); err != nil {
util.ErrLog.Println(err)
}
}
wg.Wait()
close(d)
Converting to JSON to compare a string key to a symbol key:
for done := range d {
f := done.(*riak.FetchValueCommand)
/* un-comment to dump fetched object as JSON
if json, jerr := json.MarshalIndent(f.Response, "", " "); err != nil {
util.ErrLog.Println(jerr)
} else {
util.Log.Println("fetched value: ", string(json))
}
*/
obj := f.Response.Values[0]
switch obj.Key {
case "one":
if actual, expected := binary.LittleEndian.Uint32(obj.Value), val1; actual != expected {
util.ErrLog.Printf("key: %s, actual %v, expected %v", obj.Key, actual, expected)
}
case "two":
if actual, expected := string(obj.Value), val2; actual != expected {
util.ErrLog.Printf("key: %s, actual %v, expected %v", obj.Key, actual, expected)
}
case "three":
obj3 = obj
val3.MyValue = 0
if jerr := json.Unmarshal(obj.Value, &val3); jerr != nil {
util.ErrLog.Println(jerr)
} else {
if actual, expected := val3.MyValue, int(3); actual != expected {
util.ErrLog.Printf("key: %s, actual %v, expected %v", obj.Key, actual, expected)
}
}
default:
util.ErrLog.Printf("unrecognized key: %s", obj.Key)
}
}
Updating Objects
While some data may be static, other forms of data need to be updated.
Let’s update some values:
util.Log.Println("Updating Object Three In Riak...")
val3.MyValue = 42
obj3.Value, err = json.Marshal(val3)
if err != nil {
util.ErrExit(err)
}
cmd, err = riak.NewStoreValueCommandBuilder().
WithContent(obj3).
WithReturnBody(true).
Build()
if err != nil {
util.ErrLog.Println(err)
} else {
if err := c.Execute(cmd); err != nil {
util.ErrLog.Println(err)
}
}
svcmd := cmd.(*riak.StoreValueCommand)
svrsp := svcmd.Response
obj3 = svrsp.Values[0]
val3.MyValue = 0
if jerr := json.Unmarshal(obj3.Value, &val3); jerr != nil {
util.ErrLog.Println(jerr)
} else {
if actual, expected := val3.MyValue, int(42); actual != expected {
util.ErrLog.Printf("key: %s, actual %v, expected %v", obj3.Key, actual, expected)
}
}
util.Log.Println("updated object key: ", obj3.Key)
util.Log.Println("updated object value: ", val3.MyValue)
Deleting Objects
As a last step, we’ll demonstrate how to delete data. You’ll see that the delete message can be called against either the bucket or the object.
for _, o := range objs {
cmd, err = riak.NewDeleteValueCommandBuilder().
WithBucket(o.Bucket).
WithKey(o.Key).
Build()
if err != nil {
util.ErrLog.Println(err)
continue
}
a := &riak.Async{
Command: cmd,
Wait: wg,
}
if err := c.ExecuteAsync(a); err != nil {
util.ErrLog.Println(err)
}
}
wg.Wait()
Working With Complex Objects
Since the world is a little more complicated than simple integers and bits of strings, let’s see how we can work with more complex objects.
For example, this struct
that represents some information about
a book:
type Book struct {
ISBN string
Title string
Author string
Body string
CopiesOwned uint16
}
book := &Book{
ISBN: "1111979723",
Title: "Moby Dick",
Author: "Herman Melville",
Body: "Call me Ishmael. Some years ago...",
CopiesOwned: 3,
}
We now have some information about our Moby Dick collection that we want to save. Storing this to Riak should look familiar by now:
var jbook []byte
jbook, err = json.Marshal(book)
if err != nil {
util.ErrExit(err)
}
bookObj := &riak.Object{
Bucket: "books",
Key: book.ISBN,
ContentType: "application/json",
Value: jbook,
}
cmd, err = riak.NewStoreValueCommandBuilder().
WithContent(bookObj).
WithReturnBody(false).
Build()
if err != nil {
util.ErrLog.Println(err)
} else {
if err := c.Execute(cmd); err != nil {
util.ErrLog.Println(err)
}
}
If we fetch our book back and print the data:
cmd, err = riak.NewFetchValueCommandBuilder().
WithBucket("books").
WithKey(book.ISBN).
Build()
if err != nil {
util.ErrExit(err)
}
if err := c.Execute(cmd); err != nil {
util.ErrLog.Println(err)
}
fcmd := cmd.(*riak.FetchValueCommand)
bookObj = fcmd.Response.Values[0]
util.Log.Println(string(bookObj.Value))
The result is:
{"isbn":"1111979723","title":"Moby Dick","author":"Herman Melville",
"body":"Call me Ishmael. Some years ago...","copies_owned":3}
Now, let’s delete the book:
...