Skip to content

Commit f6189cd

Browse files
evanmccSean Cribbs
authored andcommitted
Flatten and reapply basho#202 on top of master.
1 parent cd1bfd4 commit f6189cd

File tree

10 files changed

+221
-450
lines changed

10 files changed

+221
-450
lines changed

riak/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
@author Jay Baird (@skatterbean) ([email protected])
3131
"""
3232

33-
__all__ = ['RiakClient', 'RiakBucket', 'RiakNode', 'RiakObject',
33+
__all__ = ['RiakBucket', 'RiakNode', 'RiakObject', 'RiakClient',
3434
'RiakMapReduce', 'RiakKeyFilter', 'RiakLink', 'RiakError',
3535
'ONE', 'ALL', 'QUORUM', 'key_filter']
3636

riak/metadata.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

riak/riak_object.py

Lines changed: 21 additions & 216 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ def __init__(self, client, bucket, key=None):
5656
self._data = None
5757
self._encoded_data = None
5858
self.vclock = None
59-
self.metadata = {MD_USERMETA: {}, MD_INDEX: []}
59+
self.charset = None
60+
self.content_type = 'application/json'
61+
self.content_encoding = None
62+
self.usermeta = {}
63+
self.indexes = set()
6064
self.links = []
6165
self.siblings = []
6266
self.exists = False
@@ -141,26 +145,6 @@ def _deserialize(self, value):
141145
raise TypeError('No decoder for content type "{0}"'.
142146
format(self.content_type))
143147

144-
def _get_usermeta(self):
145-
if MD_USERMETA in self.metadata:
146-
return self.metadata[MD_USERMETA]
147-
else:
148-
return {}
149-
150-
def _set_usermeta(self, usermeta):
151-
self.metadata[MD_USERMETA] = usermeta
152-
return self
153-
154-
usermeta = property(_get_usermeta, _set_usermeta,
155-
doc="""
156-
The custom user metadata on this object. This doesn't
157-
include things like content type and links, but only
158-
user-defined meta attributes stored with the Riak object.
159-
160-
:param userdata: The user metadata to store.
161-
:type userdata: dict
162-
""")
163-
164148
def add_index(self, field, value):
165149
"""
166150
Tag this object with the specified field/value pair for
@@ -176,9 +160,7 @@ def add_index(self, field, value):
176160
raise RiakError("Riak 2i fields must end with either '_bin'"
177161
" or '_int'.")
178162

179-
rie = (field, value)
180-
if not rie in self.metadata[MD_INDEX]:
181-
self.metadata[MD_INDEX].append(rie)
163+
self.indexes.add((field, value))
182164

183165
return self
184166

@@ -194,117 +176,20 @@ def remove_index(self, field=None, value=None):
194176
:rtype: RiakObject
195177
"""
196178
if not field and not value:
197-
ries = self.metadata[MD_INDEX][:]
179+
self.indexes.clear()
198180
elif field and not value:
199-
ries = [x for x in self.metadata[MD_INDEX]
200-
if x[0] == field]
181+
for index in [x for x in self.indexes if x[0] == field]:
182+
self.indexes.remove(index)
201183
elif field and value:
202-
ries = [(field, value)]
184+
self.indexes.remove((field, value))
203185
else:
204186
raise RiakError("Cannot pass value without a field"
205187
" name while removing index")
206188

207-
# This removes the index entries that's in the ries list.
208-
# Done because this is preferred over metadata[MD_INDEX].remove(rie)
209-
self.metadata[MD_INDEX] = [rie for rie in self.metadata[MD_INDEX]
210-
if rie not in ries]
211189
return self
212190

213191
remove_indexes = remove_index
214192

215-
def set_indexes(self, indexes):
216-
"""
217-
Replaces all indexes on a Riak object. Currently supports an
218-
iterable of 2 item tuples, (field, value).
219-
220-
:param indexes: iterable of 2 item tuples consisting the field
221-
and value. Both the field and the value must
222-
be a string.
223-
:rtype: RiakObject
224-
"""
225-
# makes a copy and does type conversion
226-
# this seems rather slow
227-
self.metadata[MD_INDEX] = indexes[:]
228-
return self
229-
230-
def get_indexes(self, field=None):
231-
"""
232-
Get a list of the index entries for this object. If a field is
233-
provided, returns a list
234-
235-
:param field: The index field.
236-
:type field: string or None
237-
:rtype: (array of 2 element tuples with field, value) or
238-
(array of string or integer)
239-
"""
240-
if field is None:
241-
return self.metadata[MD_INDEX]
242-
else:
243-
return [v for f, v in self.metadata[MD_INDEX] if f == field]
244-
245-
def _get_content_type(self):
246-
try:
247-
return self.metadata[MD_CTYPE]
248-
except KeyError:
249-
if self._data:
250-
return "application/json"
251-
else:
252-
return "application/octet-stream"
253-
254-
def _set_content_type(self, content_type):
255-
"""
256-
Set the content type of this object.
257-
258-
:param content_type: The new content type.
259-
:type content_type: string
260-
:rtype: self
261-
"""
262-
self.metadata[MD_CTYPE] = content_type
263-
return self
264-
265-
content_type = property(_get_content_type, _set_content_type,
266-
doc="""
267-
The content type of this object. This is either
268-
``application/json``, or the provided content type if the
269-
object was created via :func:`RiakBucket.new_binary
270-
<riak.bucket.RiakBucket.new_binary>`.
271-
272-
:rtype: string """)
273-
274-
def set_links(self, links, all_link=False):
275-
"""
276-
Replaces all links to a RiakObject
277-
278-
:param links: An iterable of 2-item tuples, consisting of
279-
(RiakObject, tag). This could also be an iterable of just
280-
a RiakObject, instead of the tuple, then a tag of None
281-
would be used. Lastly, it could also be an iterable of
282-
3 item tuples with the format of (bucket, key, tag), where tag
283-
could be None
284-
285-
:param all_link: A boolean indicates if links are all 3 item tuples
286-
objects This speeds up the operation so there is no iterating
287-
through and parsing elements.
288-
"""
289-
if all_link:
290-
self.metadata[MD_LINKS] = links
291-
return self
292-
293-
new_links = []
294-
for item in links:
295-
if isinstance(item, tuple):
296-
if len(item) == 3:
297-
link = item
298-
elif len(item) == 2:
299-
link = (item[0].bucket.name, item[0].key, item[1])
300-
elif isinstance(item, RiakObject):
301-
link = (item.bucket.name, item.key, None)
302-
303-
new_links.append(link)
304-
305-
self.metadata[MD_LINKS] = new_links
306-
return self
307-
308193
def add_link(self, obj, tag=None):
309194
"""
310195
Add a link to a RiakObject.
@@ -322,45 +207,9 @@ def add_link(self, obj, tag=None):
322207
else:
323208
newlink = (obj.bucket.name, obj.key, tag)
324209

325-
self.remove_link(newlink)
326-
links = self.metadata[MD_LINKS]
327-
links.append(newlink)
328-
return self
329-
330-
def remove_link(self, obj, tag=None):
331-
"""
332-
Remove a link to a RiakObject.
333-
334-
:param obj: Either a RiakObject or 3 item link tuple consisting
335-
of (bucket, key, tag).
336-
:type obj: mixed
337-
:param tag: Optional link tag. Defaults to bucket name. It is ignored
338-
if ``obj`` is a 3 item link tuple.
339-
:type tag: string
340-
:rtype: RiakObject
341-
"""
342-
if isinstance(obj, tuple):
343-
oldlink = obj
344-
else:
345-
oldlink = (obj.bucket.name, obj.key, tag)
346-
347-
a = []
348-
links = self.metadata.get(MD_LINKS, [])
349-
for link in links:
350-
if not link == oldlink:
351-
a.append(link)
352-
353-
self.metadata[MD_LINKS] = a
210+
self.links.append(newlink)
354211
return self
355212

356-
def get_links(self):
357-
"""
358-
Return an array of 3 item link tuples.
359-
360-
:rtype: list
361-
"""
362-
return self.metadata.get(MD_LINKS, [])
363-
364213
def store(self, w=None, dw=None, pw=None, return_body=True,
365214
if_none_match=False):
366215
"""
@@ -392,14 +241,11 @@ def store(self, w=None, dw=None, pw=None, return_body=True,
392241
"store one of the siblings instead")
393242

394243
if self.key is None:
395-
key, vclock, metadata = self.client.put_new(
244+
result = self.client.put_new(
396245
self, w=w, dw=dw, pw=pw,
397246
return_body=return_body,
398247
if_none_match=if_none_match)
399-
self.exists = True
400-
self.key = key
401-
self.vclock = vclock
402-
self.metadata = metadata
248+
self._populate(result)
403249
else:
404250
result = self.client.put(self, w=w, dw=dw, pw=pw,
405251
return_body=return_body,
@@ -422,10 +268,10 @@ def reload(self, r=None, pr=None, vtag=None):
422268
"""
423269

424270
result = self.client.get(self, r=r, pr=pr, vtag=vtag)
425-
426-
self.clear()
427-
if result is not None and result != ('', []):
271+
if result and result != ('', []):
428272
self._populate(result)
273+
else:
274+
self.clear()
429275

430276
return self
431277

@@ -483,30 +329,11 @@ def _populate(self, result):
483329
If a list of vtags is returned there are multiple
484330
sibling that need to be retrieved with get.
485331
"""
486-
self.clear()
487-
if result is None:
332+
if result is None or result is self:
488333
return self
489-
elif type(result) is list:
490-
self._set_siblings(result)
491-
elif type(result) is tuple:
492-
(vclock, contents) = result
493-
self.vclock = vclock
494-
if len(contents) > 0:
495-
(metadata, data) = contents.pop(0)
496-
self.exists = True
497-
if not MD_INDEX in metadata:
498-
metadata[MD_INDEX] = []
499-
self.metadata = metadata
500-
self._encoded_data = data
501-
# Create objects for all siblings
502-
siblings = [self]
503-
for (metadata, data) in contents:
504-
sibling = copy.copy(self)
505-
sibling.metadata = metadata
506-
sibling.encoded_data = data
507-
siblings.append(sibling)
508-
for sibling in siblings:
509-
sibling._set_siblings(siblings)
334+
elif type(result) is RiakObject:
335+
self.clear()
336+
self.__dict__ = result.__dict__.copy()
510337
else:
511338
raise RiakError("do not know how to handle type %s" % type(result))
512339

@@ -531,31 +358,9 @@ def get_sibling(self, i, r=None, pr=None):
531358

532359
# And make sure it knows who its siblings are
533360
self.siblings[i] = obj
534-
obj._set_siblings(self.siblings)
361+
obj.siblings = self.siblings
535362
return obj
536363

537-
def _set_siblings(self, siblings):
538-
"""
539-
Set the array of siblings - used internally
540-
541-
.. warning::
542-
543-
Make sure this object is at index 0 so get_siblings(0)
544-
always returns the current object
545-
"""
546-
try:
547-
i = siblings.index(self)
548-
if i != 0:
549-
siblings.pop(i)
550-
siblings.insert(0, self)
551-
except ValueError:
552-
pass
553-
554-
if len(siblings) > 1:
555-
self.siblings = siblings
556-
else:
557-
self.siblings = []
558-
559364
def add(self, *args):
560365
"""
561366
Start assembling a Map/Reduce operation.

0 commit comments

Comments
 (0)