better-riak-client 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. data/LICENSE +16 -0
  2. data/README.markdown +198 -0
  3. data/RELEASE_NOTES.md +211 -0
  4. data/better-riak-client.gemspec +61 -0
  5. data/erl_src/riak_kv_test014_backend.beam +0 -0
  6. data/erl_src/riak_kv_test014_backend.erl +189 -0
  7. data/erl_src/riak_kv_test_backend.beam +0 -0
  8. data/erl_src/riak_kv_test_backend.erl +697 -0
  9. data/erl_src/riak_search_test_backend.beam +0 -0
  10. data/erl_src/riak_search_test_backend.erl +175 -0
  11. data/lib/riak/bucket.rb +221 -0
  12. data/lib/riak/client/beefcake/messages.rb +213 -0
  13. data/lib/riak/client/beefcake/object_methods.rb +111 -0
  14. data/lib/riak/client/beefcake_protobuffs_backend.rb +226 -0
  15. data/lib/riak/client/decaying.rb +36 -0
  16. data/lib/riak/client/excon_backend.rb +162 -0
  17. data/lib/riak/client/feature_detection.rb +88 -0
  18. data/lib/riak/client/http_backend/configuration.rb +211 -0
  19. data/lib/riak/client/http_backend/key_streamer.rb +43 -0
  20. data/lib/riak/client/http_backend/object_methods.rb +106 -0
  21. data/lib/riak/client/http_backend/request_headers.rb +34 -0
  22. data/lib/riak/client/http_backend/transport_methods.rb +201 -0
  23. data/lib/riak/client/http_backend.rb +340 -0
  24. data/lib/riak/client/net_http_backend.rb +82 -0
  25. data/lib/riak/client/node.rb +115 -0
  26. data/lib/riak/client/protobuffs_backend.rb +173 -0
  27. data/lib/riak/client/search.rb +91 -0
  28. data/lib/riak/client.rb +540 -0
  29. data/lib/riak/cluster.rb +151 -0
  30. data/lib/riak/core_ext/blank.rb +53 -0
  31. data/lib/riak/core_ext/deep_dup.rb +13 -0
  32. data/lib/riak/core_ext/extract_options.rb +7 -0
  33. data/lib/riak/core_ext/json.rb +15 -0
  34. data/lib/riak/core_ext/slice.rb +18 -0
  35. data/lib/riak/core_ext/stringify_keys.rb +10 -0
  36. data/lib/riak/core_ext/symbolize_keys.rb +10 -0
  37. data/lib/riak/core_ext/to_param.rb +31 -0
  38. data/lib/riak/core_ext.rb +7 -0
  39. data/lib/riak/encoding.rb +6 -0
  40. data/lib/riak/failed_request.rb +81 -0
  41. data/lib/riak/i18n.rb +5 -0
  42. data/lib/riak/json.rb +52 -0
  43. data/lib/riak/link.rb +94 -0
  44. data/lib/riak/locale/en.yml +53 -0
  45. data/lib/riak/locale/fr.yml +52 -0
  46. data/lib/riak/map_reduce/filter_builder.rb +103 -0
  47. data/lib/riak/map_reduce/phase.rb +98 -0
  48. data/lib/riak/map_reduce.rb +225 -0
  49. data/lib/riak/map_reduce_error.rb +7 -0
  50. data/lib/riak/node/configuration.rb +293 -0
  51. data/lib/riak/node/console.rb +133 -0
  52. data/lib/riak/node/control.rb +207 -0
  53. data/lib/riak/node/defaults.rb +83 -0
  54. data/lib/riak/node/generation.rb +106 -0
  55. data/lib/riak/node/log.rb +34 -0
  56. data/lib/riak/node/version.rb +43 -0
  57. data/lib/riak/node.rb +38 -0
  58. data/lib/riak/robject.rb +318 -0
  59. data/lib/riak/search.rb +3 -0
  60. data/lib/riak/serializers.rb +74 -0
  61. data/lib/riak/stamp.rb +77 -0
  62. data/lib/riak/test_server.rb +89 -0
  63. data/lib/riak/util/escape.rb +76 -0
  64. data/lib/riak/util/headers.rb +53 -0
  65. data/lib/riak/util/multipart/stream_parser.rb +62 -0
  66. data/lib/riak/util/multipart.rb +52 -0
  67. data/lib/riak/util/tcp_socket_extensions.rb +58 -0
  68. data/lib/riak/util/translation.rb +19 -0
  69. data/lib/riak/version.rb +3 -0
  70. data/lib/riak/walk_spec.rb +105 -0
  71. data/lib/riak.rb +21 -0
  72. metadata +348 -0
@@ -0,0 +1,175 @@
1
+ %% -------------------------------------------------------------------
2
+ %%
3
+ %% Copyright (c) 2007-2010 Basho Technologies, Inc. All Rights Reserved.
4
+ %%
5
+ %% -------------------------------------------------------------------
6
+
7
+ -module(riak_search_test_backend).
8
+ -behavior(riak_search_backend).
9
+
10
+ -export([
11
+ reset/0,
12
+ start/2,
13
+ stop/1,
14
+ index/2,
15
+ delete/2,
16
+ stream/6,
17
+ range/8,
18
+ info/5,
19
+ fold/3,
20
+ is_empty/1,
21
+ drop/1
22
+ ]).
23
+ -export([
24
+ stream_results/3
25
+ ]).
26
+
27
+ -include_lib("riak_search/include/riak_search.hrl").
28
+ -define(T(P), list_to_atom("rs" ++ integer_to_list(P))).
29
+ -record(state, {partition, table}).
30
+
31
+ reset() ->
32
+ {ok, Ring} = riak_core_ring_manager:get_my_ring(),
33
+ [ catch ets:delete_all_objects(?T(P)) ||
34
+ P <- riak_core_ring:my_indices(Ring) ],
35
+ riak_search_config:clear(),
36
+ ok.
37
+
38
+ start(Partition, _Config) ->
39
+ Table = ets:new(?T(Partition),
40
+ [named_table, public, ordered_set]),
41
+ {ok, #state{partition=Partition, table=Table}}.
42
+
43
+ stop(State) ->
44
+ maybe_delete(State).
45
+
46
+ index(IFTVPKList, #state{table=Table}=State) ->
47
+ lists:foreach(
48
+ fun({I, F, T, V, P, K}) ->
49
+ Key = {b(I), b(F), b(T), b(V)},
50
+ case ets:lookup(Table, Key) of
51
+ [{_, _, ExistingKeyClock}] ->
52
+ if ExistingKeyClock > K ->
53
+ %% stored data is newer
54
+ ok;
55
+ true ->
56
+ %% stored data is older
57
+ ets:update_element(Table, Key,
58
+ [{2, P},{3, K}])
59
+ end;
60
+ [] ->
61
+ ets:insert(Table, {Key, P, K})
62
+ end
63
+ end,
64
+ IFTVPKList),
65
+ {reply, {indexed, node()}, State}.
66
+
67
+ delete(IFTVKList, State) ->
68
+ Table = State#state.table,
69
+ lists:foreach(fun(IFTVK) -> delete_fun(IFTVK, Table) end, IFTVKList),
70
+ {reply, {deleted, node()}, State}.
71
+
72
+ delete_fun({I, F, T, V, K}, Table) ->
73
+ Key = {b(I), b(F), b(T), b(V)},
74
+ case ets:lookup(Table, Key) of
75
+ [{Key, _Props, ExistingKeyClock}] ->
76
+ if ExistingKeyClock > K ->
77
+ %% stored data is newer
78
+ ok;
79
+ true ->
80
+ %% stored data is older
81
+ ets:delete(Table, Key)
82
+ end;
83
+ [] ->
84
+ ok
85
+ end;
86
+ delete_fun({I, F, T, V, _P, K}, Table) ->
87
+ %% copied idea from merge_index_backend
88
+ %% other operations include Props, though delete shouldn't
89
+ delete_fun({I, F, T, V, K}, Table).
90
+
91
+ info(Index, Field, Term, Sender, State) ->
92
+ Count = ets:select_count(State#state.table,
93
+ [{{{b(Index), b(Field), b(Term), '_'},
94
+ '_', '_'},
95
+ [],[true]}]),
96
+ riak_search_backend:info_response(Sender, [{Term, node(), Count}]),
97
+ noreply.
98
+
99
+ -define(STREAM_SIZE, 100).
100
+
101
+ range(Index, Field, StartTerm, EndTerm, _Size, FilterFun, Sender, State) ->
102
+ ST = b(StartTerm),
103
+ ET = b(EndTerm),
104
+ spawn(riak_search_ets_backend, stream_results,
105
+ [Sender,
106
+ FilterFun,
107
+ ets:select(State#state.table,
108
+ [{{{b(Index), b(Field), '$1', '$2'}, '$3', '_'},
109
+ [{'>=', '$1', ST}, {'=<', '$1', ET}],
110
+ [{{'$2', '$3'}}]}],
111
+ ?STREAM_SIZE)]),
112
+ noreply.
113
+
114
+ stream(Index, Field, Term, FilterFun, Sender, State) ->
115
+ spawn(riak_search_ets_backend, stream_results,
116
+ [Sender,
117
+ FilterFun,
118
+ ets:select(State#state.table,
119
+ [{{{b(Index), b(Field), b(Term), '$1'}, '$2', '_'},
120
+ [], [{{'$1', '$2'}}]}],
121
+ ?STREAM_SIZE)]),
122
+ noreply.
123
+
124
+ stream_results(Sender, FilterFun, {Results0, Continuation}) ->
125
+ case lists:filter(fun({V,P}) -> FilterFun(V, P) end, Results0) of
126
+ [] ->
127
+ ok;
128
+ Results ->
129
+ riak_search_backend:response_results(Sender, Results)
130
+ end,
131
+ stream_results(Sender, FilterFun, ets:select(Continuation));
132
+ stream_results(Sender, _, '$end_of_table') ->
133
+ riak_search_backend:response_done(Sender).
134
+
135
+ fold(FoldFun, Acc, State) ->
136
+ Fun = fun({{I,F,T,V},P,K}, {OuterAcc, {{I,{F,T}},InnerAcc}}) ->
137
+ %% same IFT, just accumulate doc/props/clock
138
+ {OuterAcc, {{I,{F,T}},[{V,P,K}|InnerAcc]}};
139
+ ({{I,F,T,V},P,K}, {OuterAcc, {FoldKey, VPKList}}) ->
140
+ %% finished a string of IFT, send it off
141
+ %% (sorted order is assumed)
142
+ NewOuterAcc = FoldFun(FoldKey, VPKList, OuterAcc),
143
+ {NewOuterAcc, {{I,{F,T}},[{V,P,K}]}};
144
+ ({{I,F,T,V},P,K}, {OuterAcc, undefined}) ->
145
+ %% first round through the fold - just start building
146
+ {OuterAcc, {{I,{F,T}},[{V,P,K}]}}
147
+ end,
148
+ {OuterAcc0, Final} = ets:foldl(Fun, {Acc, undefined}, State#state.table),
149
+ OuterAcc = case Final of
150
+ {FoldKey, VPKList} ->
151
+ %% one last IFT to send off
152
+ FoldFun(FoldKey, VPKList, OuterAcc0);
153
+ undefined ->
154
+ %% this partition was empty
155
+ OuterAcc0
156
+ end,
157
+ {reply, OuterAcc, State}.
158
+
159
+ is_empty(State) ->
160
+ 0 == ets:info(State#state.table, size).
161
+
162
+ drop(State) ->
163
+ maybe_delete(State).
164
+
165
+ maybe_delete(State) ->
166
+ case lists:member(State#state.table, ets:all()) of
167
+ true ->
168
+ ets:delete(State#state.table),
169
+ ok;
170
+ false ->
171
+ ok
172
+ end.
173
+
174
+ b(Binary) when is_binary(Binary) -> Binary;
175
+ b(List) when is_list(List) -> iolist_to_binary(List).
@@ -0,0 +1,221 @@
1
+ require 'riak/util/translation'
2
+ require 'riak/client'
3
+ require 'riak/robject'
4
+ require 'riak/failed_request'
5
+
6
+ module Riak
7
+ # Represents and encapsulates operations on a Riak bucket. You may retrieve a bucket
8
+ # using {Client#bucket}, or create it manually and retrieve its meta-information later.
9
+ class Bucket
10
+ include Util::Translation
11
+
12
+ # (Riak Search) The precommit specification for kv/search integration
13
+ SEARCH_PRECOMMIT_HOOK = {"mod" => "riak_search_kv_hook", "fun" => "precommit"}
14
+
15
+ # @return [Riak::Client] the associated client
16
+ attr_reader :client
17
+
18
+ # @return [String] the bucket name
19
+ attr_reader :name
20
+
21
+ # Create a Riak bucket manually.
22
+ # @param [Client] client the {Riak::Client} for this bucket
23
+ # @param [String] name the name of the bucket
24
+ def initialize(client, name)
25
+ raise ArgumentError, t("client_type", :client => client.inspect) unless Client === client
26
+ raise ArgumentError, t("string_type", :string => name.inspect) unless String === name
27
+ @client, @name = client, name
28
+ end
29
+
30
+ # Retrieves a list of keys in this bucket.
31
+ # If a block is given, keys will be streamed through
32
+ # the block (useful for large buckets). When streaming,
33
+ # results of the operation will not be returned to the caller.
34
+ # @yield [Array<String>] a list of keys from the current chunk
35
+ # @return [Array<String>] Keys in this bucket
36
+ # @note This operation has serious performance implications and
37
+ # should not be used in production applications.
38
+ def keys(&block)
39
+ warn(t('list_keys', :backtrace => caller.join("\n "))) unless Riak.disable_list_keys_warnings
40
+ if block_given?
41
+ @client.list_keys(self, &block)
42
+ else
43
+ @client.list_keys(self)
44
+ end
45
+ end
46
+
47
+ # Sets internal properties on the bucket
48
+ # Note: this results in a request to the Riak server!
49
+ # @param [Hash] properties new properties for the bucket
50
+ # @option properties [Fixnum] :n_val (3) The N value (replication factor)
51
+ # @option properties [true,false] :allow_mult (false) Whether to permit object siblings
52
+ # @option properties [true,false] :last_write_wins (false) Whether to ignore vclocks
53
+ # @option properties [Array<Hash>] :precommit ([]) precommit hooks
54
+ # @option properties [Array<Hash>] :postcommit ([])postcommit hooks
55
+ # @option properties [Fixnum,String] :r ("quorum") read quorum (numeric or
56
+ # symbolic)
57
+ # @option properties [Fixnum,String] :w ("quorum") write quorum (numeric or
58
+ # symbolic)
59
+ # @option properties [Fixnum,String] :dw ("quorum") durable write quorum
60
+ # (numeric or symbolic)
61
+ # @option properties [Fixnum,String] :rw ("quorum") delete quorum (numeric or
62
+ # symbolic)
63
+ # @return [Hash] the merged bucket properties
64
+ # @raise [FailedRequest] if the new properties were not accepted by the Riakserver
65
+ # @see #n_value, #allow_mult, #r, #w, #dw, #rw
66
+ def props=(properties)
67
+ raise ArgumentError, t("hash_type", :hash => properties.inspect) unless Hash === properties
68
+ props.merge!(properties)
69
+ @client.set_bucket_props(self, properties)
70
+ props
71
+ end
72
+ alias :'properties=' :'props='
73
+
74
+ # @return [Hash] Internal Riak bucket properties.
75
+ # @see #props=
76
+ def props
77
+ @props ||= @client.get_bucket_props(self)
78
+ end
79
+ alias :properties :props
80
+
81
+ # Retrieve an object from within the bucket.
82
+ # @param [String] key the key of the object to retrieve
83
+ # @param [Hash] options query parameters for the request
84
+ # @option options [Fixnum] :r - the read quorum for the request - how many nodes should concur on the read
85
+ # @return [Riak::RObject] the object
86
+ # @raise [FailedRequest] if the object is not found or some other error occurs
87
+ def get(key, options={})
88
+ @client.get_object(self, key, options)
89
+ end
90
+ alias :[] :get
91
+
92
+ # Create a new blank object
93
+ # @param [String] key the key of the new object
94
+ # @return [RObject] the new, unsaved object
95
+ def new(key=nil)
96
+ RObject.new(self, key).tap do |obj|
97
+ obj.content_type = "application/json"
98
+ end
99
+ end
100
+
101
+ # Fetches an object if it exists, otherwise creates a new one with the given key
102
+ # @param [String] key the key to fetch or create
103
+ # @return [RObject] the new or existing object
104
+ def get_or_new(key, options={})
105
+ begin
106
+ get(key, options)
107
+ rescue Riak::FailedRequest => fr
108
+ if fr.not_found?
109
+ new(key)
110
+ else
111
+ raise fr
112
+ end
113
+ end
114
+ end
115
+
116
+ # Checks whether an object exists in Riak.
117
+ # @param [String] key the key to check
118
+ # @param [Hash] options quorum options
119
+ # @option options [Fixnum] :r - the read quorum value for the request (R)
120
+ # @return [true, false] whether the key exists in this bucket
121
+ def exists?(key, options={})
122
+ begin
123
+ get(key, options)
124
+ true
125
+ rescue Riak::FailedRequest
126
+ false
127
+ end
128
+ end
129
+ alias :exist? :exists?
130
+
131
+ # Deletes a key from the bucket
132
+ # @param [String] key the key to delete
133
+ # @param [Hash] options quorum options
134
+ # @option options [Fixnum] :rw - the read/write quorum for the
135
+ # delete
136
+ # @option options [String] :vclock - the vector clock of the
137
+ # object being deleted
138
+ def delete(key, options={})
139
+ client.delete_object(self, key, options)
140
+ end
141
+
142
+ # Queries a secondary index on the bucket.
143
+ # @note This will only work if your Riak installation supports 2I.
144
+ # @param [String] index the name of the index
145
+ # @param [String,Integer,Range] query the value of the index, or a
146
+ # Range of values to query
147
+ # @return [Array<String>] a list of keys that match the index
148
+ # query
149
+ def get_index(index, query)
150
+ client.get_index(self, index, query)
151
+ end
152
+
153
+ # @return [true, false] whether the bucket allows divergent siblings
154
+ def allow_mult
155
+ props['allow_mult']
156
+ end
157
+
158
+ # Set the allow_mult property. *NOTE* This will result in a PUT request to Riak.
159
+ # @param [true, false] value whether the bucket should allow siblings
160
+ def allow_mult=(value)
161
+ self.props = {'allow_mult' => value}
162
+ value
163
+ end
164
+
165
+ # @return [Fixnum] the N value, or number of replicas for this bucket
166
+ def n_value
167
+ props['n_val']
168
+ end
169
+ alias :n_val :n_value
170
+
171
+ # Set the N value (number of replicas). *NOTE* This will result in a PUT request to Riak.
172
+ # Setting this value after the bucket has objects stored in it may have unpredictable results.
173
+ # @param [Fixnum] value the number of replicas the bucket should keep of each object
174
+ def n_value=(value)
175
+ self.props = {'n_val' => value}
176
+ value
177
+ end
178
+ alias :'n_val=' :'n_value='
179
+
180
+ %w(r w dw rw).each do |q|
181
+ define_method(q) { props[q] }
182
+ define_method("#{q}=") { |value|
183
+ self.props = { q => value }
184
+ value
185
+ }
186
+ end
187
+
188
+ # (Riak Search) Installs a precommit hook that automatically indexes objects
189
+ # into riak_search.
190
+ def enable_index!
191
+ unless is_indexed?
192
+ self.props = {"precommit" => (props['precommit'] + [SEARCH_PRECOMMIT_HOOK]), "search" => true}
193
+ end
194
+ end
195
+
196
+ # (Riak Search) Removes the precommit hook that automatically indexes objects
197
+ # into riak_search.
198
+ def disable_index!
199
+ if is_indexed?
200
+ self.props = {"precommit" => (props['precommit'] - [SEARCH_PRECOMMIT_HOOK]), "search" => false}
201
+ end
202
+ end
203
+
204
+ # (Riak Search) Detects whether the bucket is automatically indexed into
205
+ # riak_search.
206
+ # @return [true,false] whether the bucket includes the search indexing hook
207
+ def is_indexed?
208
+ props['search'] == true || props['precommit'].include?(SEARCH_PRECOMMIT_HOOK)
209
+ end
210
+
211
+ # @return [String] a representation suitable for IRB and debugging output
212
+ def inspect
213
+ "#<Riak::Bucket {#{name}}#{" keys=[#{keys.join(',')}]" if defined?(@keys)}>"
214
+ end
215
+
216
+ # @return [true,false] whether the other is equivalent
217
+ def ==(other)
218
+ Bucket === other && other.client == client && other.name == name
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,213 @@
1
+ require 'beefcake'
2
+
3
+ module Riak
4
+ class Client
5
+ # @private
6
+ class BeefcakeProtobuffsBackend
7
+ # Embedded messages
8
+ class RpbPair
9
+ include Beefcake::Message
10
+ required :key, :bytes, 1
11
+ optional :value, :bytes, 2
12
+ end
13
+
14
+ class RpbBucketProps
15
+ include Beefcake::Message
16
+ optional :n_val, :uint32, 1
17
+ optional :allow_mult, :bool, 2
18
+ end
19
+
20
+ class RpbLink
21
+ include Beefcake::Message
22
+ optional :bucket, :bytes, 1
23
+ optional :key, :bytes, 2
24
+ optional :tag, :bytes, 3
25
+ end
26
+
27
+ class RpbContent
28
+ include Beefcake::Message
29
+ required :value, :bytes, 1
30
+ optional :content_type, :bytes, 2
31
+ optional :charset, :bytes, 3
32
+ optional :content_encoding, :bytes, 4
33
+ optional :vtag, :bytes, 5
34
+ repeated :links, RpbLink, 6
35
+ optional :last_mod, :uint32, 7
36
+ optional :last_mod_usecs, :uint32, 8
37
+ repeated :usermeta, RpbPair, 9
38
+ repeated :indexes, RpbPair, 10
39
+ end
40
+
41
+ # Primary messages
42
+ class RpbErrorResp
43
+ include Beefcake::Message
44
+ required :errmsg, :bytes, 1
45
+ required :errcode, :uint32, 2
46
+ end
47
+
48
+ class RpbGetClientIdResp
49
+ include Beefcake::Message
50
+ required :client_id, :bytes, 1
51
+ end
52
+
53
+ class RpbSetClientIdReq
54
+ include Beefcake::Message
55
+ required :client_id, :bytes, 1
56
+ end
57
+
58
+ class RpbGetServerInfoResp
59
+ include Beefcake::Message
60
+ optional :node, :bytes, 1
61
+ optional :server_version, :bytes, 2
62
+ end
63
+
64
+ class RpbGetReq
65
+ include Beefcake::Message
66
+ required :bucket, :bytes, 1
67
+ required :key, :bytes, 2
68
+ optional :r, :uint32, 3
69
+ optional :pr, :uint32, 4
70
+ optional :basic_quorum, :bool, 5
71
+ optional :notfound_ok, :bool, 6
72
+ optional :if_modified, :bytes, 7
73
+ optional :head, :bool, 8
74
+ optional :deletedvclock, :bool, 9
75
+ end
76
+
77
+ class RpbGetResp
78
+ include Beefcake::Message
79
+ repeated :content, RpbContent, 1
80
+ optional :vclock, :bytes, 2
81
+ optional :unchanged, :bool, 3
82
+ end
83
+
84
+ class RpbPutReq
85
+ include Beefcake::Message
86
+ required :bucket, :bytes, 1
87
+ optional :key, :bytes, 2
88
+ optional :vclock, :bytes, 3
89
+ required :content, RpbContent, 4
90
+ optional :w, :uint32, 5
91
+ optional :dw, :uint32, 6
92
+ optional :returnbody, :bool, 7
93
+ optional :pw, :uint32, 8
94
+ optional :if_not_modified, :bool, 9
95
+ optional :if_none_match, :bool, 10
96
+ optional :return_head, :bool, 11
97
+ end
98
+
99
+ class RpbPutResp
100
+ include Beefcake::Message
101
+ repeated :content, RpbContent, 1
102
+ optional :vclock, :bytes, 2
103
+ optional :key, :bytes, 3
104
+ end
105
+
106
+ class RpbDelReq
107
+ include Beefcake::Message
108
+ required :bucket, :bytes, 1
109
+ required :key, :bytes, 2
110
+ optional :rw, :uint32, 3
111
+ optional :vclock, :bytes, 4
112
+ optional :r, :uint32, 5
113
+ optional :w, :uint32, 6
114
+ optional :pr, :uint32, 7
115
+ optional :pw, :uint32, 8
116
+ optional :dw, :uint32, 9
117
+ end
118
+
119
+ class RpbListBucketsResp
120
+ include Beefcake::Message
121
+ repeated :buckets, :bytes, 1
122
+ end
123
+
124
+ class RpbListKeysReq
125
+ include Beefcake::Message
126
+ required :bucket, :bytes, 1
127
+ end
128
+
129
+ class RpbListKeysResp
130
+ include Beefcake::Message
131
+ repeated :keys, :bytes, 1
132
+ optional :done, :bool, 2
133
+ end
134
+
135
+ class RpbGetBucketReq
136
+ include Beefcake::Message
137
+ required :bucket, :bytes, 1
138
+ end
139
+
140
+ class RpbGetBucketResp
141
+ include Beefcake::Message
142
+ required :props, RpbBucketProps, 1
143
+ end
144
+
145
+ class RpbSetBucketReq
146
+ include Beefcake::Message
147
+ required :bucket, :bytes, 1
148
+ required :props, RpbBucketProps, 2
149
+ end
150
+
151
+ class RpbMapRedReq
152
+ include Beefcake::Message
153
+ required :request, :bytes, 1
154
+ required :content_type, :bytes, 2
155
+ end
156
+
157
+ class RpbMapRedResp
158
+ include Beefcake::Message
159
+ optional :phase, :uint32, 1
160
+ optional :response, :bytes, 2
161
+ optional :done, :bool, 3
162
+ end
163
+
164
+ class RpbIndexReq
165
+ include Beefcake::Message
166
+ module IndexQueryType
167
+ EQ = 0
168
+ RANGE = 1
169
+ end
170
+
171
+ required :bucket, :bytes, 1
172
+ required :index, :bytes, 2
173
+ required :qtype, IndexQueryType, 3
174
+ optional :key, :bytes, 4
175
+ optional :range_min, :bytes, 5
176
+ optional :range_max, :bytes, 6
177
+ end
178
+
179
+ class RpbIndexResp
180
+ include Beefcake::Message
181
+ repeated :keys, :bytes, 1
182
+ end
183
+
184
+ class RpbSearchDoc
185
+ include Beefcake::Message
186
+ # We have to name this differently than the .proto file does
187
+ # because Beefcake uses 'fields' as an instance method.
188
+ repeated :properties, RpbPair, 1
189
+ end
190
+
191
+ class RpbSearchQueryReq
192
+ include Beefcake::Message
193
+ required :q, :bytes, 1
194
+ required :index, :bytes, 2
195
+ optional :rows, :uint32, 3
196
+ optional :start, :uint32, 4
197
+ optional :sort, :bytes, 5
198
+ optional :filter, :bytes, 6
199
+ optional :df, :bytes, 7
200
+ optional :op, :bytes, 8
201
+ repeated :fl, :bytes, 9
202
+ optional :presort, :bytes, 10
203
+ end
204
+
205
+ class RpbSearchQueryResp
206
+ include Beefcake::Message
207
+ repeated :docs, RpbSearchDoc, 1, :default => []
208
+ optional :max_score, :float, 2
209
+ optional :num_found, :uint32, 3
210
+ end
211
+ end
212
+ end
213
+ end