Skip to content

Add head parameter #509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Contributors
* Soren Hansen
* Sreejith Kesavan
* Timothée Peignier
* [`tobixx`](https://github.com/tobixx)
* [Tin Tvrtković](https://github.com/Tinche)
* [Vitaly Shestovskiy](https://github.com/lamp0chka)
* William Kral
Expand Down
4 changes: 4 additions & 0 deletions RELNOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Riak Python Client Release Notes

## [`2.7.0` Release](https://github.com/basho/riak-python-client/issues?q=milestone%3Ariak-python-client-2.7.0)
* Riak TS 1.5 support
* Support for `head` parameter

## [`2.6.1` Release](https://github.com/basho/riak-python-client/issues?q=milestone%3Ariak-python-client-2.6.0)
* NOTE: Due to pypi upload errors, `2.6.1` takes the place of `2.6.0`.

Expand Down
17 changes: 13 additions & 4 deletions riak/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def new(self, key=None, data=None, content_type='application/json',
return obj

def get(self, key, r=None, pr=None, timeout=None, include_context=None,
basic_quorum=None, notfound_ok=None):
basic_quorum=None, notfound_ok=None, head_only=False):
"""
Retrieve a :class:`~riak.riak_object.RiakObject` or
:class:`~riak.datatypes.Datatype`, based on the presence and value
Expand All @@ -216,6 +216,9 @@ def get(self, key, r=None, pr=None, timeout=None, include_context=None,
:type basic_quorum: bool
:param notfound_ok: whether to treat not-found responses as successful
:type notfound_ok: bool
:param head_only: whether to fetch without value, so only metadata
(only available on PB transport)
:type head_only: bool
:rtype: :class:`RiakObject <riak.riak_object.RiakObject>` or
:class:`~riak.datatypes.Datatype`

Expand All @@ -231,10 +234,12 @@ def get(self, key, r=None, pr=None, timeout=None, include_context=None,
obj = RiakObject(self._client, self, key)
return obj.reload(r=r, pr=pr, timeout=timeout,
basic_quorum=basic_quorum,
notfound_ok=notfound_ok)
notfound_ok=notfound_ok,
head_only=head_only)

def multiget(self, keys, r=None, pr=None, timeout=None,
basic_quorum=None, notfound_ok=None):
basic_quorum=None, notfound_ok=None,
head_only=False):
"""
Retrieves a list of keys belonging to this bucket in parallel.

Expand All @@ -251,14 +256,18 @@ def multiget(self, keys, r=None, pr=None, timeout=None,
:type basic_quorum: bool
:param notfound_ok: whether to treat not-found responses as successful
:type notfound_ok: bool
:param head_only: whether to fetch without value, so only metadata
(only available on PB transport)
:type head_only: bool
:rtype: list of :class:`RiakObjects <riak.riak_object.RiakObject>`,
:class:`Datatypes <riak.datatypes.Datatype>`, or tuples of
bucket_type, bucket, key, and the exception raised on fetch
"""
bkeys = [(self.bucket_type.name, self.name, key) for key in keys]
return self._client.multiget(bkeys, r=r, pr=pr, timeout=timeout,
basic_quorum=basic_quorum,
notfound_ok=notfound_ok)
notfound_ok=notfound_ok,
head_only=head_only)

def _get_resolver(self):
if callable(self._resolver):
Expand Down
8 changes: 6 additions & 2 deletions riak/client/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ def ts_stream_keys(self, table, timeout=None):

@retryable
def get(self, transport, robj, r=None, pr=None, timeout=None,
basic_quorum=None, notfound_ok=None):
basic_quorum=None, notfound_ok=None, head_only=False):
"""
get(robj, r=None, pr=None, timeout=None)

Expand All @@ -700,6 +700,9 @@ def get(self, transport, robj, r=None, pr=None, timeout=None,
:type basic_quorum: bool
:param notfound_ok: whether to treat not-found responses as successful
:type notfound_ok: bool
:param head_only: whether to fetch without value, so only metadata
(only available on PB transport)
:type head_only: bool
"""
_validate_timeout(timeout)
if not isinstance(robj.key, six.string_types):
Expand All @@ -708,7 +711,8 @@ def get(self, transport, robj, r=None, pr=None, timeout=None,

return transport.get(robj, r=r, pr=pr, timeout=timeout,
basic_quorum=basic_quorum,
notfound_ok=notfound_ok)
notfound_ok=notfound_ok,
head_only=head_only)

@retryable
def delete(self, transport, robj, rw=None, r=None, w=None, dw=None,
Expand Down
4 changes: 3 additions & 1 deletion riak/codecs/pbuf.py
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,8 @@ def decode_preflist(self, item):
return result

def encode_get(self, robj, r=None, pr=None, timeout=None,
basic_quorum=None, notfound_ok=None):
basic_quorum=None, notfound_ok=None,
head_only=False):
bucket = robj.bucket
req = riak.pb.riak_kv_pb2.RpbGetReq()
if r:
Expand All @@ -914,6 +915,7 @@ def encode_get(self, robj, r=None, pr=None, timeout=None,
req.bucket = str_to_bytes(bucket.name)
self._add_bucket_type(req, bucket.bucket_type)
req.key = str_to_bytes(robj.key)
req.head = head_only
mc = riak.pb.messages.MSG_CODE_GET_REQ
rc = riak.pb.messages.MSG_CODE_GET_RESP
return Msg(mc, req.SerializeToString(), rc)
Expand Down
2 changes: 2 additions & 0 deletions riak/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ def _serialize(self, value):
format(self.content_type))

def _deserialize(self, value):
if not value:
return value
decoder = self._robject.bucket.get_decoder(self.content_type)
if decoder:
return decoder(value)
Expand Down
7 changes: 5 additions & 2 deletions riak/riak_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def store(self, w=None, dw=None, pw=None, return_body=True,
return self

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

self.client.get(self, r=r, pr=pr, timeout=timeout)
self.client.get(self, r=r, pr=pr, timeout=timeout, head_only=head_only)
return self

def delete(self, r=None, w=None, dw=None, pr=None, pw=None,
Expand Down
15 changes: 14 additions & 1 deletion riak/tests/test_kv.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from time import sleep
from riak import ConflictError, RiakBucket, RiakError
from riak.resolver import default_resolver, last_written_resolver
from riak.tests import RUN_KV, RUN_RESOLVE
from riak.tests import RUN_KV, RUN_RESOLVE, PROTOCOL
from riak.tests.base import IntegrationTestBase
from riak.tests.comparison import Comparison

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

@unittest.skipUnless(PROTOCOL == 'pbc', 'Only available on pbc')
def test_get_no_returnbody(self):
bucket = self.client.bucket(self.bucket_name)
o = bucket.new(self.key_name, "Ain't no body")
o.store()

stored_object = bucket.get(self.key_name, head_only=True)
self.assertFalse(stored_object.data)

list_of_objects = bucket.multiget([self.key_name], head_only=True)
for stored_object in list_of_objects:
self.assertFalse(stored_object.data)

def test_many_link_headers_should_work_fine(self):
bucket = self.client.bucket(self.bucket_name)
o = bucket.new("lots_of_links", "My god, it's full of links!")
Expand Down
2 changes: 1 addition & 1 deletion riak/transports/http/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def get_resources(self):
return {}

def get(self, robj, r=None, pr=None, timeout=None, basic_quorum=None,
notfound_ok=None):
notfound_ok=None, head_only=False):
"""
Get a bucket/key from the server
"""
Expand Down
4 changes: 2 additions & 2 deletions riak/transports/tcp/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,15 @@ def _set_client_id(self, client_id):
doc="""the client ID for this connection""")

def get(self, robj, r=None, pr=None, timeout=None, basic_quorum=None,
notfound_ok=None):
notfound_ok=None, head_only=False):
"""
Serialize get request and deserialize response
"""
msg_code = riak.pb.messages.MSG_CODE_GET_REQ
codec = self._get_codec(msg_code)
msg = codec.encode_get(robj, r, pr,
timeout, basic_quorum,
notfound_ok)
notfound_ok, head_only)
resp_code, resp = self._request(msg, codec)
return codec.decode_get(robj, resp)

Expand Down
2 changes: 1 addition & 1 deletion riak/transports/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def ping(self):
raise NotImplementedError

def get(self, robj, r=None, pr=None, timeout=None, basic_quorum=None,
notfound_ok=None):
notfound_ok=None, head_only=False):
"""
Fetches an object.
"""
Expand Down