This is a simple example using Riakc to PUT a key into a Riak database. It assumes that you already have a Riak database up and running.
First you need to install riakc. Simply do: opam install riakc
. As of this writing, the latest version of riakc is 2.0.0 and the code given depends on that version.
Now, the code. The following is a complete CLI tool that will PUT a key and print back the result from Riak. It handles all errors that the library can generate as well as outputting siblings correctly.
(*
* This example is valid for version 2.0.0, and possibly later
*)
open Core.Std
open Async.Std
(*
* Take a string of bytes and convert them to hex string
* representation
*)
let hex_of_string =
String.concat_map ~f:(fun c -> sprintf "%X" (Char.to_int c))
(*
* An Robj can have multiple values in it, each one with its
* own content type, encoding, and value. This just prints
* the value, which is a string blob
*)
let print_contents contents =
List.iter
~f:(fun content ->
let module C = Riakc.Robj.Content in
printf "VALUE: %s\n" (C.value content))
contents
let fail s =
printf "%s\n" s;
shutdown 1
let exec () =
let host = Sys.argv.(1) in
let port = Int.of_string Sys.argv.(2) in
(*
* [with_conn] is a little helper function that will
* establish a connection, run a function on the connection
* and tear it down when done
*)
Riakc.Conn.with_conn
~host
~port
(fun c ->
let module R = Riakc.Robj in
let content = R.Content.create "some random data" in
let robj = R.create [] |> R.set_content content in
(*
* Put takes a bucket, a key, and an optional list of
* options. In this case we are setting the
* [Return_body] option which returns what the key
* looks like after the put. It is possible that
* siblings were created.
*)
Riakc.Conn.put
c
~b:"test_bucket"
~k:"test_key"
~opts:[Riakc.Opts.Put.Return_body]
robj)
let eval () =
exec () >>| function
| Ok (robj, key) -> begin
(*
* [put] returns a [Riakc.Robj.t] and a [string
* option], which is the key if Riak had to generate
* it
*)
let module R = Riakc.Robj in
(*
* Extract the vclock, if it exists, and convert it to
* to something printable
*)
let vclock =
Option.value
~default:"<none>"
(Option.map ~f:hex_of_string (R.vclock robj))
in
let key = Option.value ~default:"<none>" key in
printf "KEY: %s\n" key;
printf "VCLOCK: %s\n" vclock;
print_contents (R.contents robj);
shutdown 0
end
(*
* These are the various errors that can be returned.
* Many of then come directly from the ProtoBuf layer
* since there aren't really any more semantics to apply
* to the data if it matches the PB frame.
*)
| Error `Bad_conn -> fail "Bad_conn"
| Error `Bad_payload -> fail "Bad_payload"
| Error `Incomplete_payload -> fail "Incomplete_payload"
| Error `Notfound -> fail "Notfound"
| Error `Incomplete -> fail "Incomplete"
| Error `Overflow -> fail "Overflow"
| Error `Unknown_type -> fail "Unknown_type"
| Error `Wrong_type -> fail "Wrong_type"
let () =
ignore (eval ());
never_returns (Scheduler.go ())
Now compile it:
ocamlfind ocamlopt -thread -I +camlp4 -package riakc -c demo.ml
ocamlfind ocamlopt -package riakc -thread -linkpkg \
-o demo.native demo.cmx
Finally, you can run it: ./demo.native hostname port
...And More Detail
The API for Riakc is broken up into two modules: Riakc.Robj
and Riakc.Conn
with Riakc.Opts
being a third helper module. Below is in reference to version 2.0.0 of Riakc.
Riakc.Robj
Riakc.Robj
defines a representation of an object stored in Riak. Robj
is completely pure code. The API can be found here.
Riakc.Conn
This is the I/O layer. All interaction with the actual database happens through this module. Riakc.Conn
is somewhat clever in that it has a compile-time requirement that you have called Riakc.Robj.set_content
on any value you want to PUT. This guarantees you have resolved all siblings, somehow. Its API can be found here.
Riakc.Opts
Finally, various options are defined in Riakc.Opts
. These are options that GET and PUT take. Not all of them are actually supported but support is planned. The API can be viewed here.
Hopefully Riakc has a fairly straight forward API. While the example code might be longer than other clients, it is complete and correct (I hope).
No comments:
Post a Comment