Anonymous avatar Anonymous committed 0b02326

bucket names are now binaries, instead of atoms

Comments (0)

Files changed (16)

src/jaywalker_resource.erl

      RD, Ctx}.
 
 resource_exists(RD, Ctx=#ctx{jiak_client=JiakClient}) ->
-    Bucket = list_to_atom(mochiweb_util:unquote(
-                            wrq:path_info(bucket, RD))),
+    Bucket = list_to_binary(mochiweb_util:unquote(
+                              wrq:path_info(bucket, RD))),
     Key = list_to_binary(mochiweb_util:unquote(
                            wrq:path_info(key, RD))),
     case JiakClient:get(Bucket, Key, 2) of
 parts_to_query([[B,T,A]|Rest], Acc) ->
     parts_to_query(Rest,
                    [{if B == "_" -> '_';
-                        true     -> list_to_atom(mochiweb_util:unquote(B))
+                        true     -> list_to_binary(mochiweb_util:unquote(B))
                      end,
                      if T == "_" -> '_';
                         true     -> list_to_binary(mochiweb_util:unquote(T))

src/jiak_client.erl

 %%       {error, Err :: term()}
 %% @doc Fetch the object at Bucket/Key.  Return a value as soon as R
 %%      nodes have responded with a value or error, or TimeoutMillisecs passes.
-get(Bucket, Key, R, Timeout) when is_atom(Bucket), is_binary(Key) ->
+get(Bucket, Key, R, Timeout) when is_binary(Bucket), is_binary(Key) ->
     case RiakClient:get(Bucket, Key, R, Timeout) of
         {ok, RiakObject} ->
             JiakObject = jiak_object:from_riak_object(RiakObject),

src/jiak_default_tests.erl

 
 write_test_() ->
     M = jiak_default:new([]),
-    O = jiak_object:new(bucket_ignored, <<"key_ignored">>),
+    O = jiak_object:new(<<"bucket_ignored">>, <<"key_ignored">>),
     {"*_write functions",
      [{"check_write", 
        ?_assertEqual(

src/jiak_object.erl

 %%        "links" :L
 %%       }
 %%     Important: O should be a valid mochijson2 object
-new(B, K, O={struct, _}, L) when is_atom(B), is_binary(K), is_list(L) ->
+new(B, K, O={struct, _}, L) when is_binary(B), is_binary(K), is_list(L) ->
     {struct, [{<<"bucket">>, B},
               {<<"key">>, K},
               {<<"object">>, O},
 %% @spec add_link(jiak_object(), link()) -> jiak_object()
 %% @doc Add NewLink to the object's links.  If the link is already in
 %%      JiakObject, then JiakObject is not modified.
-add_link(JiakObject, NewLink=[B, K, _T]) when is_atom(B), is_binary(K) ->
+add_link(JiakObject, NewLink=[B, K, _T]) when is_binary(B), is_binary(K) ->
     Links = links(JiakObject),
     case lists:member(NewLink, Links) of
         true  -> JiakObject;
 
 test_to_riak_object() ->
     Object = {struct, [{<<"fake_field">>, <<"fake_value">>}]},
-    Links = [[other_fake_bucket,<<"other_fake_key">>,<<"fake_tag">>]],
-    J0 = jiak_object:new(fake_bucket, <<"fake_key">>, Object, Links),
+    Links = [[<<"other_fake_bucket">>,<<"other_fake_key">>,<<"fake_tag">>]],
+    J0 = jiak_object:new(<<"fake_bucket">>, <<"fake_key">>, Object, Links),
     R0 = to_riak_object(J0),
     ?assertEqual(bucket(J0), riak_object:bucket(R0)),
     ?assertEqual(key(J0), riak_object:key(R0)),
 test_from_riak_object() ->
     R0 = to_riak_object(
            setf(jiak_object:new(
-                  fake_bucket, <<"fake_key">>,
+                  <<"fake_bucket">>, <<"fake_key">>,
                   {struct, [{<<"fake_field">>, <<"fake_value">>}]},
-                  [[other_fake_bucket,<<"other_fake_key">>,
+                  [[<<"other_fake_bucket">>,<<"other_fake_key">>,
                     <<"fake_tag">>]]),
                 <<"vclock">>,
                 vclock_to_headers(vclock:increment(<<"a">>, vclock:fresh())))),
                  binary_to_list(vtag(J1))).
 
 object_props_test() ->
-    A = jiak_object:new(fake_bucket, <<"fake_key">>),
+    A = jiak_object:new(<<"fake_bucket">>, <<"fake_key">>),
     ?assertEqual([], props(A)),
 
     B = setp(A, <<"foo">>, 42),
     ?assertEqual(<<"check">>, getp(E, <<"bar">>)).
 
 links_test() ->
-    A = jiak_object:new(fake_object, <<"fake_key">>),
+    A = jiak_object:new(<<"fake_object">>, <<"fake_key">>),
     ?assertEqual([], links(A)),
     
-    L0 = [other_fake_bucket,<<"other_fake_key">>,<<"fake_tag">>],
+    L0 = [<<"other_fake_bucket">>,<<"other_fake_key">>,<<"fake_tag">>],
     B = add_link(A, L0),
     ?assertEqual([L0], links(B)),
     ?assertEqual([L0], links(B, '_', '_')),
-    ?assertEqual([L0], links(B, other_fake_bucket)),
-    ?assertEqual([],   links(B, wrong_fake_bucket)),
+    ?assertEqual([L0], links(B, <<"other_fake_bucket">>)),
+    ?assertEqual([],   links(B, <<"wrong_fake_bucket">>)),
     ?assertEqual([L0], links(B, '_', <<"fake_tag">>)),
     ?assertEqual([],   links(B, '_', <<"wrong_tag">>)),
-    ?assertEqual([L0], links(B, other_fake_bucket, <<"fake_tag">>)),
-    ?assertEqual([],   links(B, other_fake_bucket, <<"wrong_tag">>)),
-    ?assertEqual([],   links(B, wrong_fake_bucket, <<"fake_tag">>)),
+    ?assertEqual([L0], links(B, <<"other_fake_bucket">>, <<"fake_tag">>)),
+    ?assertEqual([],   links(B, <<"other_fake_bucket">>, <<"wrong_tag">>)),
+    ?assertEqual([],   links(B, <<"wrong_fake_bucket">>, <<"fake_tag">>)),
     
     ?assertEqual(B, add_link(B, L0)), %%don't double-add links
 
     ?assertEqual(remove_link(B, L0),
                  remove_link(B, hd(L0), hd(tl(L0)), hd(tl(tl(L0))))),
     
-    L1 = [other_fake_bucket,<<"second_fake_key">>,<<"new_fake_tag">>],
-    L2 = [new_fake_bucket,<<"third_fake_key">>,<<"fake_tag">>],
+    L1 = [<<"other_fake_bucket">>,<<"second_fake_key">>,<<"new_fake_tag">>],
+    L2 = [<<"new_fake_bucket">>,<<"third_fake_key">>,<<"fake_tag">>],
     C = add_link(add_link(B, L1), L2),
     ?assertEqual(3, length(links(C))),
-    ?assertEqual(2, length(links(C, other_fake_bucket))),
+    ?assertEqual(2, length(links(C, <<"other_fake_bucket">>))),
     ?assertEqual(2, length(links(C, '_', <<"fake_tag">>))),
     ?assertEqual([L1], links(C, '_', <<"new_fake_tag">>)),
-    ?assertEqual([L2], links(C, new_fake_bucket)).
+    ?assertEqual([L2], links(C, <<"new_fake_bucket">>)).
 
 mapreduce_test_() ->
     [fun test_linkfun/0,
 
 mr_riak_object() ->
     R0 = to_riak_object(
-           jiak_object:new(fake_bucket, <<"fake_key">>,
+           jiak_object:new(<<"fake_bucket">>, <<"fake_key">>,
                            {struct, [{<<"a">>, 1}]},
                            [[b1, <<"k1">>, <<"t1">>],
                             [b1, <<"k2">>, <<"t2">>],
 diff_base_empty_test() ->
     %% base empty - no added props or links
     ?assertEqual({[],{[],[]}},
-                 diff(undefined, jiak_object:new(fake, <<"fake">>))).
+                 diff(undefined, jiak_object:new(<<"fake">>, <<"fake">>))).
 
 diff_base_full_test() ->
-    Obj = jiak_object:new(fake, <<"fake">>,
+    Obj = jiak_object:new(<<"fake">>, <<"fake">>,
                           {struct, [{<<"f1">>, <<"v1">>},
                                     {<<"f2">>, <<"v2">>}]},
                           [[fake1, <<"fake1">>, <<"tag1">>],
     ?assertEqual([], RemovedLinks).
 
 diff_complex_test() ->
-    OldObj = jiak_object:new(fake, <<"fake">>,
+    OldObj = jiak_object:new(<<"fake">>, <<"fake">>,
                              {struct, [{<<"changeme">>, <<"v1">>},
                                        {<<"remme">>,    <<"v2">>},
                                        {<<"leaveme">>,   <<"v3">>}]},
-                             [[remove_me, <<"rem1">>, <<"tag1">>],
-                              [leave_me, <<"leave2">>, <<"tag2">>]]),
+                             [[<<"remove_me">>, <<"rem1">>, <<"tag1">>],
+                              [<<"leave_me">>, <<"leave2">>, <<"tag2">>]]),
     NewObj = jiak_object:setp(
                jiak_object:removep(
                  jiak_object:setp(
                    jiak_object:remove_link(
                      jiak_object:add_link(
-                       OldObj, [im_added, <<"added3">>, <<"tag3">>]),
-                     [remove_me, <<"rem1">>, <<"tag1">>]),
+                       OldObj, [<<"im_added">>, <<"added3">>, <<"tag3">>]),
+                     [<<"remove_me">>, <<"rem1">>, <<"tag1">>]),
                    <<"imadded">>, <<"v4">>),
                  <<"remme">>),
                <<"changeme">>, <<"didchange">>),
                  lists:keysearch(<<"imadded">>, 1, PropDiff)),
     ?assertEqual(3, length(PropDiff)),
     
-    ?assert(lists:member(hd(jiak_object:links(NewObj, im_added)),
+    ?assert(lists:member(hd(jiak_object:links(NewObj, <<"im_added">>)),
                          AddedLinks)),
     ?assertEqual(1, length(AddedLinks)),
 
-    ?assert(lists:member(hd(jiak_object:links(OldObj, remove_me)),
+    ?assert(lists:member(hd(jiak_object:links(OldObj, <<"remove_me">>)),
                          RemovedLinks)),
     ?assertEqual(1, length(RemovedLinks)).
 
     %% for that are in jiak:standard_sibling_merge_test/0,
     %% just need to make sure that the sibling merge branch
     %% gets called
-    J0 = jiak_object:new(fake, <<"fake">>,
+    riak_ring_manager:start_link(test),
+    riak_eventer:start_link(test),    
+    riak_bucket:set_bucket(<<"jiak_example">>,
+                           [{bucket_mod, jiak_example}]),
+
+    J0 = jiak_object:new(<<"fake">>, <<"fake">>,
                          {struct, [{<<"a">>, 1}]},
-                         [[a,<<"a">>,<<"a">>]]),
-    J1 = jiak_object:new(fake, <<"fake">>,
+                         [[<<"a">>,<<"a">>,<<"a">>]]),
+    J1 = jiak_object:new(<<"fake">>, <<"fake">>,
                          {struct, [{<<"b">>, 2}]},
-                         [[b,<<"b">>,<<"b">>]]),
+                         [[<<"b">>,<<"b">>,<<"b">>]]),
     [{M0,V0}] = riak_object:get_contents(to_riak_object(J0)),
     [{M1,V1}] = riak_object:get_contents(to_riak_object(J1)),
     M0p = dict:store(<<"X-Riak-Last-Modified">>,
     
     R = riak_object:increment_vclock(
           riak_object:set_contents(
-            riak_object:new(jiak_example, <<"fake">>, ignore),
+            riak_object:new(<<"jiak_example">>, <<"fake">>, ignore),
             [{M0p,V0},{M1p,V1}]),
           <<"tester">>),
 
     J = from_riak_object(R),
 
+    riak_ring_manager:stop(),
+    riak_eventer:stop(),
+
     ?assertEqual(getp(J0, <<"a">>), getp(J, <<"a">>)),
     ?assertEqual(getp(J1, <<"b">>), getp(J, <<"b">>)),
     ?assertEqual(2, length(props(J))),
     
-    ?assertEqual(links(J0, a), links(J, a)),
-    ?assertEqual(links(J1, b), links(J, b)),
+    ?assertEqual(links(J0, <<"a">>), links(J, <<"a">>)),
+    ?assertEqual(links(J1, <<"b">>), links(J, <<"b">>)),
     ?assertEqual(2, length(links(J))).

src/jiak_resource.erl

 
 %% @type context() = term()
 %% @type jiak_module() = atom()|{jiak_default, list()}
--record(ctx, {bucket,       %% atom() - Bucket name (from uri)
+-record(ctx, {bucket,       %% binary() - Bucket name (from uri)
               key,          %% binary()|container|schema - Key (or sentinal
                             %%   meaning "no key provided")
               module,       %% atom()
     {ServiceAvailable, NewCtx} = 
         case wrq:method(ReqData) of
             'PUT' -> 
-                _ = list_to_atom(mochiweb_util:unquote(
-                                   wrq:path_info(bucket, ReqData))),
+                _ = list_to_binary(mochiweb_util:unquote(
+                                     wrq:path_info(bucket, ReqData))),
                 Mod = jiak_default:new([]),
                 {true, Context#ctx{module=Mod, key=schema}};
             _ ->
               _         -> list_to_binary(mochiweb_util:unquote(
                                             wrq:path_info(key, RD)))
           end,
-    case jiak_util:bucket_from_uri(RD) of
-        {ok, Bucket} ->
-            {ok, JC} = Mod:init(Key, jiak_context:new(not_diffed_yet, [])),
-            Ctx = Ctx0#ctx{bucket=Bucket, key=Key, jiak_context=JC},
-            case Key of
-                container ->
-                    %% buckets have GET for list_keys, POST for create
-                    {['HEAD', 'GET', 'POST'], RD, Ctx};
-                schema ->
-                    {['PUT'], RD, Ctx};
-                _ ->
-                    %% keys have the "full" doc store set
-                    {['HEAD', 'GET', 'POST', 'PUT', 'DELETE'], RD, Ctx}
-            end;
-        {error, no_such_bucket} ->
-            %% no bucket, nothing but GET/HEAD allowed, and POST for 
-            %% schema mods
-            {['HEAD', 'GET', 'PUT'], RD, Ctx0#ctx{bucket={error, no_such_bucket}}}
+    Bucket = jiak_util:bucket_from_reqdata(RD),
+    {ok, JC} = Mod:init(Key, jiak_context:new(not_diffed_yet, [])),
+    Ctx = Ctx0#ctx{bucket=Bucket, key=Key, jiak_context=JC},
+    case Key of
+        container ->
+            %% buckets have GET for list_keys, POST for create
+            {['HEAD', 'GET', 'POST'], RD, Ctx};
+        schema ->
+            {['PUT'], RD, Ctx};
+        _ ->
+            %% keys have the "full" doc store set
+            {['HEAD', 'GET', 'POST', 'PUT', 'DELETE'], RD, Ctx}
     end.
 
 %% @spec malformed_request(webmachine:wrq(), context()) ->
 %%      GET is always properly constructed
 %%      PUT/POST is malformed if:
 %%        - request body is not a valid JSON object
-%%        - the object contains a link to a bucket that is
-%%          "unknown" (non-existent atom)
+%%        - the object is in a bucket that is "undefined"
 %%      PUT is malformed if:
 %%        - the "bucket" field of the object does not match the
 %%          bucket component of the URI
         false -> {false, ReqData, Context};
         true ->
             case decode_object(wrq:req_body(ReqData)) of
-                {ok, JiakObject0={struct,_}} ->
-                    case atomify_buckets(JiakObject0) of
-                        {ok, JiakObject} ->
-                            PT = wrq:method(ReqData) == 'PUT',
-                            KM = jiak_object:key(JiakObject) == Key,
-                            BM = jiak_object:bucket(JiakObject) == Bucket,
-                            if (not PT); (PT andalso KM andalso BM) ->
-                                    {false, ReqData, Context#ctx{incoming=JiakObject}};
-                               not KM ->
-                                    {true,
-                                     wrq:append_to_response_body("Object key does not match URI",
-                                                                 ReqData),
-                                     Context};
-                               not BM ->
-                                    {true,
-                                     wrq:append_to_response_body("Object bucket does not match URI",
-                                                                 ReqData),
-                                     Context}
-                            end;
-                        _ ->
+                {ok, JiakObject={struct,_}} ->
+                    PT = wrq:method(ReqData) == 'PUT',
+                    KM = jiak_object:key(JiakObject) == Key,
+                    BM = jiak_object:bucket(JiakObject) == Bucket,
+                    if (not PT); (PT andalso KM andalso BM) ->
+                            {false, ReqData, Context#ctx{incoming=JiakObject}};
+                       not KM ->
                             {true,
-                             wrq:append_to_response_body("Unknown bucket in link.",
+                             wrq:append_to_response_body("Object key does not match URI",
+                                                         ReqData),
+                             Context};
+                       not BM ->
+                            {true,
+                             wrq:append_to_response_body("Object bucket does not match URI",
                                                          ReqData),
                              Context}
                     end;
     try {ok, mochijson2:decode(Body)}
     catch _:_ -> {error, bad_json} end.
 
-%% @spec atomify_buckets(mochijson2()) ->
-%%         {ok, mochijson2()}|{error, no_such_bucket}
-%% @doc Convert binary() bucket names into atom() bucket names in the
-%%      "bucket" and "links" fields.  This is necessary because
-%%      mochijson2:encode/1 converts Erlang atoms to JSON strings, but
-%%      mochijson2:decode/1 converts JSON strings to Erlange binaries.
-atomify_buckets({struct,JOProps}) ->
-    try
-        BinBucket = proplists:get_value(<<"bucket">>, JOProps),
-        Bucket = list_to_existing_atom(binary_to_list(BinBucket)),
-        BinLinks = proplists:get_value(<<"links">>, JOProps),
-        Links = [ [list_to_existing_atom(binary_to_list(B)), K, T] || [B,K,T] <- BinLinks],
-        {ok, {struct, [{<<"bucket">>, Bucket},
-                       {<<"links">>, Links}
-                       |[{K,V} || {K,V} <- JOProps,
-                                  K /= <<"bucket">>, K /= <<"links">>]]}}
-    catch _:_ -> {error, no_such_bucket} end.
-
 %% @spec check_required(jiak_object(), [binary()]) -> boolean()
 %% @doc Determine whether Obj contains all of the fields named in
 %%      the Fields parameter.  Returns 'true' if all Fields are
 %% @doc Get the string-path for the bucket and subpath under jiak.
 make_uri(JiakName,Bucket,Path) ->
     "/" ++ JiakName ++ 
-        "/" ++ mochiweb_util:quote_plus(atom_to_list(Bucket)) ++
+        "/" ++ mochiweb_util:quote_plus(Bucket) ++
         "/" ++ Path.
 
 %% @spec handle_incoming(webmachine:wrq(), context()) ->
 handle_incoming(ReqData, Context=#ctx{key=schema, 
                                       bucket=Bucket,
                                       incoming=SchemaPL}) ->
-    SchemaProps = [{list_to_atom(binary_to_list(K)),V} || {K,V} <- SchemaPL],
+    SchemaProps = [{list_to_atom(binary_to_list(K)), V} || {K,V} <- SchemaPL],
     ok = riak_bucket:set_bucket(Bucket, SchemaProps),
     {<<>>, ReqData, Context};
 handle_incoming(ReqData, Context=#ctx{bucket=Bucket,key=Key,
 %%
 
 mochijson_roundtrip_test() ->
-    J0 = jiak_object:new(fake_bucket, <<"fake_key">>,
+    J0 = jiak_object:new(<<"fake_bucket">>, <<"fake_key">>,
                          {struct, [{<<"a">>, 1}]},
-                         [[other_bucket, <<"other_key">>, <<"fake_tag">>]]),
+                         [[<<"other_bucket">>, <<"other_key">>, <<"fake_tag">>]]),
     R0 = jiak_object:to_riak_object(J0),
     [{M,V}] = riak_object:get_contents(R0),
     R1 = riak_object:set_vclock(
                V}]),
            vclock:increment(<<"foo">>, vclock:fresh())),
     J1 = jiak_object:from_riak_object(R1),
-    {ok, J2} = atomify_buckets(mochijson2:decode(mochijson2:encode(J1))),
+    J2 = mochijson2:decode(mochijson2:encode(J1)),
     ?assertEqual(jiak_object:bucket(J1), jiak_object:bucket(J2)),
     ?assertEqual(jiak_object:key(J1), jiak_object:key(J2)),
     ?assertEqual(jiak_object:vclock(J1), jiak_object:vclock(J2)),
                             {read_mask,
                              [<<"read0">>, <<"read1">>]}]),
     Masked = jiak_object:new(
-               fake_bucket, <<"fake_key">>,
+               <<"fake_bucket">>, <<"fake_key">>,
                {struct, [{<<"read0">>, <<"val0">>}]},
                []),
     UnMasked = jiak_object:new(
-                 fake_bucket, <<"fake_key">>,
+                 <<"fake_bucket">>, <<"fake_key">>,
                  {struct, [{<<"read0">>, <<"val1">>},
                            {<<"read1">>, <<"val2">>},
                            {<<"unread0">>, <<"val3">>}]},
     Mod = jiak_default:new([{read_mask,
                              [<<"read0">>,<<"read1">>,<<"read2">>]}]),
     UnMasked = jiak_object:new(
-                 fake_bucket, <<"fake_key">>,
+                 <<"fake_bucket">>, <<"fake_key">>,
                  {struct, [{<<"read0">>, <<"val1">>},
                            {<<"read1">>, <<"val2">>},
                            {<<"unreadable0">>, <<"val1">>},

src/jiak_util.erl

 -export([jiak_required_props/0,
          jiak_module_for_bucket/1, 
          get_jiak_module/1, 
-         default_jiak_module/1,
-         bucket_from_uri/1]).
+         bucket_from_reqdata/1]).
 
 -include_lib("eunit/include/eunit.hrl").
 
 jiak_required_props() -> [allowed_fields,required_fields,read_mask,write_mask].
 
 %% @private
-default_jiak_module(BucketName) when is_atom(BucketName) ->
+jiak_module_for_bucket(BucketName) when is_binary(BucketName) ->
     BucketProps = riak_bucket:get_bucket(BucketName),
-    case lists:filter(
-           fun(I) -> 
-                   proplists:get_value(I, BucketProps) =:= undefined
-           end, 
-           jiak_required_props()) of
-        [] ->
-            jiak_default:new(BucketProps);
-        _ ->
-            undefined
+    case proplists:lookup(bucket_mod, BucketProps) of
+        {bucket_mod, Module} ->
+            Module;
+        none ->
+            case bucket_props_defined(BucketProps) of
+                true ->
+                    jiak_default:new(BucketProps);
+                false ->
+                    undefined
+            end
     end.
 
+bucket_props_defined(BucketProps) ->
+    [] == lists:filter(
+            fun(I) -> 
+                    proplists:get_value(I, BucketProps) =:= undefined
+            end, 
+            jiak_required_props()).
+
 %% @private
 get_jiak_module(ReqData) ->
-    case bucket_from_uri(ReqData) of
-        {ok, Bucket} when is_atom(Bucket) ->
-            jiak_module_for_bucket(Bucket);
-        {error, no_such_bucket} -> 
-            undefined
-    end.
+    jiak_module_for_bucket(bucket_from_reqdata(ReqData)).
 
-%% @private
-jiak_module_for_bucket(Bucket) when is_atom(Bucket) ->
-    case code:which(Bucket) of
-        non_existing ->
-            case default_jiak_module(Bucket) of
-                undefined -> undefined;
-                Mod when is_tuple(Mod) -> Mod
-            end;
-        ModPath when is_list(ModPath) -> Bucket;
-        cover_compiled -> Bucket %% used during eunit testing
-    end.
-
-%% @spec bucket_from_uri(webmachine:wrq()) ->
-%%         {ok, atom()}|{error, no_such_bucket}
-%% @doc Extract the bucket name, as an atom, from the request URI.
-%%      The bucket name must be an existing atom, or this function
-%%      will return {error, no_such_bucket}
-bucket_from_uri(RD) ->
-    try {ok, list_to_existing_atom(mochiweb_util:unquote(
-                                     wrq:path_info(bucket, RD)))}
-    catch _:_ -> {error, no_such_bucket} end.
+%% @spec bucket_from_reqdata(webmachine:wrq()) -> binary()
+%% @doc Extract the bucket name, as a binary, from the request URI.
+bucket_from_reqdata(RD) ->
+    list_to_binary(mochiweb_util:unquote(wrq:path_info(bucket, RD))).
 
 dynamic_bucket_test() ->
     riak_ring_manager:start_link(test),
                    {required_fields, []},
                    {read_mask, [<<"test">>]},
                    {write_mask, [<<"test">>]}],
-    riak_bucket:set_bucket(dynamic_bucket_test, BucketProps),
-    Mod = jiak_module_for_bucket(dynamic_bucket_test),
+    riak_bucket:set_bucket(<<"dynamic_bucket_test">>, BucketProps),
+    Mod = jiak_module_for_bucket(<<"dynamic_bucket_test">>),
     ?assertEqual([<<"test">>], Mod:allowed_fields()),
     ?assertEqual([], Mod:required_fields()),
     ?assertEqual([<<"test">>], Mod:read_mask()),
     riak_ring_manager:stop(),
     riak_eventer:stop().
 
-existing_bucket_from_uri_test() ->
-    foo, %% make sure the atom exists
+module_bucket_test() ->
+    riak_ring_manager:start_link(test),
+    riak_eventer:start_link(test),    
+    BucketProps = [{bucket_mod, jiak_example}],
+    riak_bucket:set_bucket(<<"module_bucket_test">>, BucketProps),
+    Mod = jiak_module_for_bucket(<<"module_bucket_test">>),
+    ?assertEqual([<<"foo">>,<<"bar">>,<<"baz">>,<<"quux">>],
+                 Mod:allowed_fields()),
+    ?assertEqual([<<"foo">>], Mod:required_fields()),
+    ?assertEqual([<<"foo">>,<<"bar">>], Mod:read_mask()),
+    ?assertEqual([<<"foo">>,<<"baz">>], Mod:write_mask()),
+    riak_ring_manager:stop(),
+    riak_eventer:stop().
+    
+
+bucket_from_uri_test() ->
     PI = dict:store(bucket, "foo", dict:new()),
     RD0 = wrq:create('PUT', "1.1", "/jiak/foo", mochiweb_headers:empty()),
     RD = wrq:load_dispatch_data(PI, none, none, none, none, RD0),
-    ?assertEqual({ok, foo}, bucket_from_uri(RD)).
-
-nonexisiting_bucket_from_uri_test() ->
-    PI = dict:store(bucket, "thisatomshouldntexistever", dict:new()),
-    RD0 = wrq:create('PUT', "1.1", "/jiak/foo", mochiweb_headers:empty()),
-    RD = wrq:load_dispatch_data(PI, none, none, none, none, RD0),    
-    ?assertEqual({error, no_such_bucket}, bucket_from_uri(RD)).
-    
+    ?assertEqual(<<"foo">>, bucket_from_reqdata(RD)).

src/riak_client.erl

 %%       {error, Err :: term()}
 %% @doc Fetch the object at Bucket/Key.  Return a value as soon as R
 %%      nodes have responded with a value or error, or TimeoutMillisecs passes.
-get(Bucket, Key, R, Timeout) when is_atom(Bucket), is_binary(Key),
+get(Bucket, Key, R, Timeout) when is_binary(Bucket), is_binary(Key),
                                   is_integer(R), is_integer(Timeout) ->
     Me = self(),
     spawn(Node, riak_get_fsm, start, [Bucket,Key,R,Timeout,Me]),

src/riak_ets_backend.erl

         Err -> {error, Err}
     end.
 
-% put(state(), {B :: atom(), K :: binary()}, Key :: binary(),
-%     Val :: binary()) ->
+% put(state(), riak_object:bkey(), Val :: binary()) ->
 %   ok | {error, Reason :: term()}
 % key must be 160b
 put(SrvRef, BKey, Val) -> gen_server:call(SrvRef,{put,BKey,Val}).
 list([],Acc) -> Acc;
 list([[K]|Rest],Acc) -> list(Rest,[K|Acc]).
 
-% list_bucket(Bucket :: atom(), state()) -> [Key :: binary()]
+% list_bucket(term(), Bucket :: riak_object:bucket()) -> [Key :: binary()]
 list_bucket(SrvRef, Bucket) ->
     gen_server:call(SrvRef,{list_bucket, Bucket}).
 srv_list_bucket(State, {filter, Bucket, Fun}) ->

src/riak_fs_backend.erl

     [B64,_,_,_,K64] = string:tokens(Path, "/"),
     {decode_bucket(B64), decode_key(K64)}.
 
-%% @spec encode_bucket(atom()) -> string()
+%% @spec encode_bucket(binary()) -> string()
 %% @doc make a filename out of a Riak bucket
 encode_bucket(Bucket) ->
-    clean(base64:encode_to_string(atom_to_list(Bucket))).
+    clean(base64:encode_to_string(Bucket)).
 
-%% @spec decode_bucket(string()) -> atom()
+%% @spec decode_bucket(string()) -> binary()
 %% @doc reconstruct a Riak bucket, given a filename
 %% @see encode_bucket/1
 decode_bucket(B64) ->
-    list_to_atom(base64:decode_to_string(dirty(B64))).
+    base64:decode(dirty(B64)).
 
 %% @spec encode_key(binary()) -> string()
 %% @doc make a filename out of a Riak object key

src/riak_map_phase_fsm.erl

 code_change(_OldVsn, StateName, State, _Extra) -> {ok, StateName, State}.
 
 convert_input(I={{_B,_K},_D})
-  when is_atom(_B) andalso (is_list(_K) orelse is_binary(_K)) -> I;
+  when is_binary(_B) andalso (is_list(_K) orelse is_binary(_K)) -> I;
 convert_input(I={_B,_K})
-  when is_atom(_B) andalso (is_list(_K) orelse is_binary(_K)) -> {I,undefined}.
+  when is_binary(_B) andalso (is_list(_K) orelse is_binary(_K)) -> {I,undefined}.
 

src/riak_mapreduce.erl

 %% unit tests %%
 
 map_identity_test() ->
-    O1 = riak_object:new(a, <<"1">>, "value1"),
+    O1 = riak_object:new(<<"a">>, <<"1">>, "value1"),
     [O1] = map_identity(O1, test, test).
 
 map_object_value_test() ->
-    O1 = riak_object:new(a, <<"1">>, "value1"),
-    O2 = riak_object:new(a, <<"1">>, ["value1"]),
+    O1 = riak_object:new(<<"a">>, <<"1">>, "value1"),
+    O2 = riak_object:new(<<"a">>, <<"1">>, ["value1"]),
     ["value1"] = map_object_value(O1, test, test),
     ["value1"] = map_object_value_list(O2, test, test).
 

src/riak_object.erl

 
 %% @type riak_object().  Opaque container for Riak objects.
 -record(r_object, {
-          bucket :: atom(),
+          bucket :: binary(),
           key :: binary(),
           contents :: [#r_content{}],
           vclock :: [vclock:vclock()],
 -define(MAX_KEY_SIZE, 65536).
 
 %% @type key()=binary().
-%% @type bucket()=atom().
+%% @type bucket()=binary().
+%% @type bkey()={bucket(),key()}
 %% @type value()=term().
 
 -export([new/3, ancestors/1, reconcile/2, increment_vclock/2, equal/2]).
 
 %% @spec new(Bucket::bucket(), Key::key(), Value::value()) -> riak_object()
 %% @doc Constructor for new riak objects.
-new(B, K, V) when is_atom(B), is_binary(K) ->
+new(B, K, V) when is_binary(B), is_binary(K) ->
     case size(K) > ?MAX_KEY_SIZE of
         true ->
             throw({error,key_too_large});
     end.
 
 object_test() ->
-    B = buckets_are_atoms,
+    B = <<"buckets_are_binaries">>,
     K = <<"keys are binaries">>,
     V = <<"values are anything">>,
     O = riak_object:new(B,K,V),
     2 = riak_object:value_count(O3).
 
 merge3_test() ->
-    O0 = riak_object:new(test, <<"test">>, hi),
+    O0 = riak_object:new(<<"test">>, <<"test">>, hi),
     O1 = riak_object:increment_vclock(O0, x),
     ?assertEqual(O1, riak_object:syntactic_merge(O1, O1, z)).
 
 merge4_test() ->
-    O0 = riak_object:new(test, <<"test">>, hi),
+    O0 = riak_object:new(<<"test">>, <<"test">>, hi),
     O1 = riak_object:increment_vclock(
            riak_object:update_value(O0, bye), x),
     OM = riak_object:syntactic_merge(O0, O1, y),
 equality1_test() ->
     MD0 = dict:new(),
     MD = dict:store("X-Riak-Test", "value", MD0),
-    O1 = riak_object:new(test, <<"a">>, "value"),
-    O2 = riak_object:new(test, <<"a">>, "value"),
+    O1 = riak_object:new(<<"test">>, <<"a">>, "value"),
+    O2 = riak_object:new(<<"test">>, <<"a">>, "value"),
     O3 = riak_object:increment_vclock(O1, self()),
     O4 = riak_object:increment_vclock(O2, self()),
     O5 = riak_object:update_metadata(O3, MD),
     true = riak_object:equal(O5, O6).
 
 inequality_value_test() ->
-    O1 = riak_object:new(test, <<"a">>, "value"),
-    O2 = riak_object:new(test, <<"a">>, "value1"),
+    O1 = riak_object:new(<<"test">>, <<"a">>, "value"),
+    O2 = riak_object:new(<<"test">>, <<"a">>, "value1"),
     false = riak_object:equal(O1, O2).    
 
 inequality_multivalue_test() ->
-    O1 = riak_object:new(test, <<"a">>, "value"),
+    O1 = riak_object:new(<<"test">>, <<"a">>, "value"),
     [C] = riak_object:get_contents(O1),
     O1p = riak_object:set_contents(O1, [C,C]),
     false = riak_object:equal(O1, O1p),
     false = riak_object:equal(O1p, O1).
 
 inequality_metadata_test() ->
-    O1 = riak_object:new(test, <<"a">>, "value"),
-    O2 = riak_object:new(test, <<"a">>, "value"),
+    O1 = riak_object:new(<<"test">>, <<"a">>, "value"),
+    O2 = riak_object:new(<<"test">>, <<"a">>, "value"),
     O1p = riak_object:apply_updates(
             riak_object:update_metadata(
               O1, dict:store(<<"X-Riak-Test">>, "value",
     false = riak_object:equal(O1p, O2).
 
 inequality_key_test() ->
-    O1 = riak_object:new(test, <<"a">>, "value"),
-    O2 = riak_object:new(test, <<"b">>, "value"),
+    O1 = riak_object:new(<<"test">>, <<"a">>, "value"),
+    O2 = riak_object:new(<<"test">>, <<"b">>, "value"),
     false = riak_object:equal(O1, O2).    
 
 inequality_vclock_test() ->
-    O1 = riak_object:new(test, <<"a">>, "value"),
+    O1 = riak_object:new(<<"test">>, <<"a">>, "value"),
     false = riak_object:equal(O1, riak_object:increment_vclock(O1, foo)).
 
 inequality_bucket_test() ->
-    O1 = riak_object:new(test1, <<"a">>, "value"),
-    O2 = riak_object:new(test, <<"a">>, "value"),
+    O1 = riak_object:new(<<"test1">>, <<"a">>, "value"),
+    O2 = riak_object:new(<<"test">>, <<"a">>, "value"),
     false = riak_object:equal(O1, O2). 
 
 inequality_updatecontents_test() ->
     MD1 = dict:new(),
     MD2 = dict:store("X-Riak-Test", "value", MD1),
     MD3 = dict:store("X-Riak-Test", "value1", MD1),
-    O1 = riak_object:new(test, <<"a">>, "value"),
-    O2 = riak_object:new(test, <<"a">>, "value"),    
+    O1 = riak_object:new(<<"test">>, <<"a">>, "value"),
+    O2 = riak_object:new(<<"test">>, <<"a">>, "value"),    
     O3 = riak_object:update_metadata(O1, MD2),
     false = riak_object:equal(O3, riak_object:update_metadata(O2, MD3)),
     O5 = riak_object:update_value(O1, "value1"),
 largekey_test() ->
     TooLargeKey = <<0:(65537*8)>>,
     try
-        riak_object:new(a, TooLargeKey, <<>>)
+        riak_object:new(<<"a">>, TooLargeKey, <<>>)
     catch throw:{error, key_too_large} ->
             ok
     end.
     false = riak_object:equal(O4, O5).
 
 get_update_value_test() ->
-    O = riak_object:new(test, <<"test">>, old_val),
+    O = riak_object:new(<<"test">>, <<"test">>, old_val),
     NewVal = new_val,
     ?assertEqual(NewVal,
                  riak_object:get_update_value(
                    riak_object:update_value(O, NewVal))).
 
 get_update_metadata_test() ->
-    O = riak_object:new(test, <<"test">>, val),
+    O = riak_object:new(<<"test">>, <<"test">>, val),
     OldMD = riak_object:get_metadata(O),
     NewMD = dict:store(<<"X-Riak-Test">>, "testval", OldMD),
     ?assertNot(NewMD =:= OldMD),
                    riak_object:update_metadata(O, NewMD))).
 
 is_updated_test() ->
-    O = riak_object:new(test, <<"test">>, test),
+    O = riak_object:new(<<"test">>, <<"test">>, test),
     ?assertNot(is_updated(O)),
     OMu = riak_object:update_metadata(
             O, dict:store(<<"X-Test-Update">>, "testupdate",
     ?assert(is_updated(OVu)).
 
 remove_duplicates_test() ->
-    O0 = riak_object:new(test, <<"test">>, zero),
-    O1 = riak_object:new(test, <<"test">>, one),
+    O0 = riak_object:new(<<"test">>, <<"test">>, zero),
+    O1 = riak_object:new(<<"test">>, <<"test">>, one),
     ND = remove_duplicate_objects([O0, O0, O1, O1, O0, O1]),
     ?assertEqual(2, length(ND)),
     ?assert(lists:member(O0, ND)),

src/riak_osmos_backend.erl

 stop(#state{table=Table}) ->
     osmos:close(Table).
 
-%% get(state(), Key :: binary()) ->
+%% get(state(), BKey :: riak_object:bkey()) ->
 %%   {ok, Val :: binary()} | {error, Reason :: term()}
 %% key must be 160b
 get(#state{table=Table}, BKey) ->
         not_found   -> {error, notfound}
     end.
 
-%% put(state(), Key :: binary(), Val :: binary()) ->
+%% put(state(), BKey :: riak_object:bkey(), Val :: binary()) ->
 %%   ok | {error, Reason :: term()}
 %% key must be 160b
 put(#state{table=Table},BKey,Val) ->       
     osmos:write(Table, term_to_binary(BKey), Val).
 
-%% delete(state(), Key :: binary()) ->
+%% delete(state(), Key :: riak_object:key()) ->
 %%   ok | {error, Reason :: term()}
 %% key must be 160b
 delete(#state{table=Table}, BKey) ->
 
 -define(SELECT_CHUNK, 1000).
 
-%% list(state()) -> [Key :: binary()]
+%% list(state()) -> [Key :: riak_object:key()]
 list(#state{table=Table}) ->
     accum(Table, fun(K,_) -> {true, binary_to_term(K)} end).
 
-%% list_bucket(state(), Bucket :: atom()) -> [Key :: binary()]
+%% list_bucket(state(), Bucket :: riak_object:bucket()) -> [Key :: binary()]
 list_bucket(#state{table=Table}, Bucket) ->
     accum(Table,
           fun(Key,_) ->

src/riak_put_fsm.erl

     riak_util:integer_to_list(HashAsNum,62).
 
 % following two are just utility functions for test assist
-vc_obj(VC) -> riak_object:set_vclock(riak_object:new(b,<<"k">>,<<"v">>), VC).
+vc_obj(VC) -> riak_object:set_vclock(riak_object:new(<<"b">>,<<"k">>,<<"v">>), VC).
 obj_vc(OB) -> riak_object:vclock(OB).
 
 prune_small_vclock_test() ->
     ?assert(length(obj_vc(prune_vclock(vc_obj(VC), Props))) =:= 1).
 
 make_vtag_test() ->
-    Obj = riak_object:new(b,<<"k">>,<<"v1">>),
+    Obj = riak_object:new(<<"b">>,<<"k">>,<<"v1">>),
     ?assertNot(make_vtag(Obj) =:= 
                make_vtag(riak_object:increment_vclock(Obj,<<"client_id">>))).

src/riak_test_util.erl

 
 standard_backend_test(BackendMod) ->
     {ok, S} = BackendMod:start(42),
-    ?assertEqual(ok, BackendMod:put(S,{b1,<<"k1">>},<<"v1">>)),
-    ?assertEqual(ok, BackendMod:put(S,{b2,<<"k2">>},<<"v2">>)),
-    ?assertEqual({ok,<<"v2">>}, BackendMod:get(S,{b2,<<"k2">>})),
-    ?assertEqual({error, notfound}, BackendMod:get(S, {b1,<<"k3">>})),
-    ?assertEqual([{b1,<<"k1">>},{b2,<<"k2">>}],
+    ?assertEqual(ok, BackendMod:put(S,{<<"b1">>,<<"k1">>},<<"v1">>)),
+    ?assertEqual(ok, BackendMod:put(S,{<<"b2">>,<<"k2">>},<<"v2">>)),
+    ?assertEqual({ok,<<"v2">>}, BackendMod:get(S,{<<"b2">>,<<"k2">>})),
+    ?assertEqual({error, notfound}, BackendMod:get(S, {<<"b1">>,<<"k3">>})),
+    ?assertEqual([{<<"b1">>,<<"k1">>},{<<"b2">>,<<"k2">>}],
                  lists:sort(BackendMod:list(S))),
-    ?assertEqual([<<"k2">>], BackendMod:list_bucket(S, b2)),
-    ?assertEqual([<<"k1">>], BackendMod:list_bucket(S, b1)),
-    ?assertEqual(ok, BackendMod:delete(S,{b2,<<"k2">>})),
-    ?assertEqual({error, notfound}, BackendMod:get(S, {b2, <<"k2">>})),
-    ?assertEqual([{b1, <<"k1">>}], BackendMod:list(S)),
+    ?assertEqual([<<"k2">>], BackendMod:list_bucket(S, <<"b2">>)),
+    ?assertEqual([<<"k1">>], BackendMod:list_bucket(S, <<"b1">>)),
+    ?assertEqual(ok, BackendMod:delete(S,{<<"b2">>,<<"k2">>})),
+    ?assertEqual({error, notfound}, BackendMod:get(S, {<<"b2">>, <<"k2">>})),
+    ?assertEqual([{<<"b1">>, <<"k1">>}], BackendMod:list(S)),
     ok = BackendMod:stop(S).
 
 setup_mockring1() ->

src/riak_util.erl

     ?assert(M2 >= M1).
 
 deleted_test() ->
-    O = riak_object:new(test, <<"k">>, "v"),
+    O = riak_object:new(<<"test">>, <<"k">>, "v"),
     false = is_x_deleted(O),
     MD = dict:new(),
     O1 = riak_object:apply_updates(
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.