Skip to content

Commit 4122875

Browse files
authored
Merge pull request #509 from basho/features/lrb/head-support
Add head parameter
2 parents d74824d + a663b92 commit 4122875

File tree

11 files changed

+52
-14
lines changed

11 files changed

+52
-14
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ Contributors
142142
* Soren Hansen
143143
* Sreejith Kesavan
144144
* Timothée Peignier
145+
* [`tobixx`](https://github.com/tobixx)
145146
* [Tin Tvrtković](https://github.com/Tinche)
146147
* [Vitaly Shestovskiy](https://github.com/lamp0chka)
147148
* William Kral

RELNOTES.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Riak Python Client Release Notes
22

3+
## [`2.7.0` Release](https://github.com/basho/riak-python-client/issues?q=milestone%3Ariak-python-client-2.7.0)
4+
* Riak TS 1.5 support
5+
* Support for `head` parameter
6+
37
## [`2.6.1` Release](https://github.com/basho/riak-python-client/issues?q=milestone%3Ariak-python-client-2.6.0)
48
* NOTE: Due to pypi upload errors, `2.6.1` takes the place of `2.6.0`.
59

riak/bucket.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def new(self, key=None, data=None, content_type='application/json',
194194
return obj
195195

196196
def get(self, key, r=None, pr=None, timeout=None, include_context=None,
197-
basic_quorum=None, notfound_ok=None):
197+
basic_quorum=None, notfound_ok=None, head_only=False):
198198
"""
199199
Retrieve a :class:`~riak.riak_object.RiakObject` or
200200
:class:`~riak.datatypes.Datatype`, based on the presence and value
@@ -216,6 +216,9 @@ def get(self, key, r=None, pr=None, timeout=None, include_context=None,
216216
:type basic_quorum: bool
217217
:param notfound_ok: whether to treat not-found responses as successful
218218
:type notfound_ok: bool
219+
:param head_only: whether to fetch without value, so only metadata
220+
(only available on PB transport)
221+
:type head_only: bool
219222
:rtype: :class:`RiakObject <riak.riak_object.RiakObject>` or
220223
:class:`~riak.datatypes.Datatype`
221224
@@ -231,10 +234,12 @@ def get(self, key, r=None, pr=None, timeout=None, include_context=None,
231234
obj = RiakObject(self._client, self, key)
232235
return obj.reload(r=r, pr=pr, timeout=timeout,
233236
basic_quorum=basic_quorum,
234-
notfound_ok=notfound_ok)
237+
notfound_ok=notfound_ok,
238+
head_only=head_only)
235239

236240
def multiget(self, keys, r=None, pr=None, timeout=None,
237-
basic_quorum=None, notfound_ok=None):
241+
basic_quorum=None, notfound_ok=None,
242+
head_only=False):
238243
"""
239244
Retrieves a list of keys belonging to this bucket in parallel.
240245
@@ -251,14 +256,18 @@ def multiget(self, keys, r=None, pr=None, timeout=None,
251256
:type basic_quorum: bool
252257
:param notfound_ok: whether to treat not-found responses as successful
253258
:type notfound_ok: bool
259+
:param head_only: whether to fetch without value, so only metadata
260+
(only available on PB transport)
261+
:type head_only: bool
254262
:rtype: list of :class:`RiakObjects <riak.riak_object.RiakObject>`,
255263
:class:`Datatypes <riak.datatypes.Datatype>`, or tuples of
256264
bucket_type, bucket, key, and the exception raised on fetch
257265
"""
258266
bkeys = [(self.bucket_type.name, self.name, key) for key in keys]
259267
return self._client.multiget(bkeys, r=r, pr=pr, timeout=timeout,
260268
basic_quorum=basic_quorum,
261-
notfound_ok=notfound_ok)
269+
notfound_ok=notfound_ok,
270+
head_only=head_only)
262271

263272
def _get_resolver(self):
264273
if callable(self._resolver):

riak/client/operations.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ def ts_stream_keys(self, table, timeout=None):
678678

679679
@retryable
680680
def get(self, transport, robj, r=None, pr=None, timeout=None,
681-
basic_quorum=None, notfound_ok=None):
681+
basic_quorum=None, notfound_ok=None, head_only=False):
682682
"""
683683
get(robj, r=None, pr=None, timeout=None)
684684
@@ -700,6 +700,9 @@ def get(self, transport, robj, r=None, pr=None, timeout=None,
700700
:type basic_quorum: bool
701701
:param notfound_ok: whether to treat not-found responses as successful
702702
:type notfound_ok: bool
703+
:param head_only: whether to fetch without value, so only metadata
704+
(only available on PB transport)
705+
:type head_only: bool
703706
"""
704707
_validate_timeout(timeout)
705708
if not isinstance(robj.key, six.string_types):
@@ -708,7 +711,8 @@ def get(self, transport, robj, r=None, pr=None, timeout=None,
708711

709712
return transport.get(robj, r=r, pr=pr, timeout=timeout,
710713
basic_quorum=basic_quorum,
711-
notfound_ok=notfound_ok)
714+
notfound_ok=notfound_ok,
715+
head_only=head_only)
712716

713717
@retryable
714718
def delete(self, transport, robj, rw=None, r=None, w=None, dw=None,

riak/codecs/pbuf.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,8 @@ def decode_preflist(self, item):
895895
return result
896896

897897
def encode_get(self, robj, r=None, pr=None, timeout=None,
898-
basic_quorum=None, notfound_ok=None):
898+
basic_quorum=None, notfound_ok=None,
899+
head_only=False):
899900
bucket = robj.bucket
900901
req = riak.pb.riak_kv_pb2.RpbGetReq()
901902
if r:
@@ -914,6 +915,7 @@ def encode_get(self, robj, r=None, pr=None, timeout=None,
914915
req.bucket = str_to_bytes(bucket.name)
915916
self._add_bucket_type(req, bucket.bucket_type)
916917
req.key = str_to_bytes(robj.key)
918+
req.head = head_only
917919
mc = riak.pb.messages.MSG_CODE_GET_REQ
918920
rc = riak.pb.messages.MSG_CODE_GET_RESP
919921
return Msg(mc, req.SerializeToString(), rc)

riak/content.py

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ def _serialize(self, value):
9090
format(self.content_type))
9191

9292
def _deserialize(self, value):
93+
if not value:
94+
return value
9395
decoder = self._robject.bucket.get_decoder(self.content_type)
9496
if decoder:
9597
return decoder(value)

riak/riak_object.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ def store(self, w=None, dw=None, pw=None, return_body=True,
269269
return self
270270

271271
def reload(self, r=None, pr=None, timeout=None, basic_quorum=None,
272-
notfound_ok=None):
272+
notfound_ok=None, head_only=False):
273273
"""
274274
Reload the object from Riak. When this operation completes, the
275275
object could contain new metadata and a new value, if the object
@@ -293,10 +293,13 @@ def reload(self, r=None, pr=None, timeout=None, basic_quorum=None,
293293
:type basic_quorum: bool
294294
:param notfound_ok: whether to treat not-found responses as successful
295295
:type notfound_ok: bool
296+
:param head_only: whether to fetch without value, so only metadata
297+
(only available on PB transport)
298+
:type head_only: bool
296299
:rtype: :class:`RiakObject`
297300
"""
298301

299-
self.client.get(self, r=r, pr=pr, timeout=timeout)
302+
self.client.get(self, r=r, pr=pr, timeout=timeout, head_only=head_only)
300303
return self
301304

302305
def delete(self, r=None, w=None, dw=None, pr=None, pw=None,

riak/tests/test_kv.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from time import sleep
99
from riak import ConflictError, RiakBucket, RiakError
1010
from riak.resolver import default_resolver, last_written_resolver
11-
from riak.tests import RUN_KV, RUN_RESOLVE
11+
from riak.tests import RUN_KV, RUN_RESOLVE, PROTOCOL
1212
from riak.tests.base import IntegrationTestBase
1313
from riak.tests.comparison import Comparison
1414

@@ -79,6 +79,19 @@ def test_no_returnbody(self):
7979
o = bucket.new(self.key_name, "bar").store(return_body=False)
8080
self.assertEqual(o.vclock, None)
8181

82+
@unittest.skipUnless(PROTOCOL == 'pbc', 'Only available on pbc')
83+
def test_get_no_returnbody(self):
84+
bucket = self.client.bucket(self.bucket_name)
85+
o = bucket.new(self.key_name, "Ain't no body")
86+
o.store()
87+
88+
stored_object = bucket.get(self.key_name, head_only=True)
89+
self.assertFalse(stored_object.data)
90+
91+
list_of_objects = bucket.multiget([self.key_name], head_only=True)
92+
for stored_object in list_of_objects:
93+
self.assertFalse(stored_object.data)
94+
8295
def test_many_link_headers_should_work_fine(self):
8396
bucket = self.client.bucket(self.bucket_name)
8497
o = bucket.new("lots_of_links", "My god, it's full of links!")

riak/transports/http/transport.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def get_resources(self):
107107
return {}
108108

109109
def get(self, robj, r=None, pr=None, timeout=None, basic_quorum=None,
110-
notfound_ok=None):
110+
notfound_ok=None, head_only=False):
111111
"""
112112
Get a bucket/key from the server
113113
"""

riak/transports/tcp/transport.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,15 @@ def _set_client_id(self, client_id):
133133
doc="""the client ID for this connection""")
134134

135135
def get(self, robj, r=None, pr=None, timeout=None, basic_quorum=None,
136-
notfound_ok=None):
136+
notfound_ok=None, head_only=False):
137137
"""
138138
Serialize get request and deserialize response
139139
"""
140140
msg_code = riak.pb.messages.MSG_CODE_GET_REQ
141141
codec = self._get_codec(msg_code)
142142
msg = codec.encode_get(robj, r, pr,
143143
timeout, basic_quorum,
144-
notfound_ok)
144+
notfound_ok, head_only)
145145
resp_code, resp = self._request(msg, codec)
146146
return codec.decode_get(robj, resp)
147147

riak/transports/transport.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def ping(self):
5454
raise NotImplementedError
5555

5656
def get(self, robj, r=None, pr=None, timeout=None, basic_quorum=None,
57-
notfound_ok=None):
57+
notfound_ok=None, head_only=False):
5858
"""
5959
Fetches an object.
6060
"""

0 commit comments

Comments
 (0)