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:
...
