def remove_index(self, field=None, value=None): """ Remove the specified field/value pair as an index on this object. :param field: The index field. :type field: string :param value: The index value. :type value: string or integer :rtype: self """ if not field and not value: ries = self._metadata[MD_INDEX][:] elif field and not value: ries = [ x for x in self._metadata[MD_INDEX] if x.get_field() == field ] elif field and value: ries = [RiakIndexEntry(field, value)] else: raise Exception( "Cannot pass value without a field name while removing index") for rie in ries: if rie in self._metadata[MD_INDEX]: self._metadata[MD_INDEX].remove(rie) return self
def set_indexes(self, indexes): """ Replaces all indexes on a Riak object. Currenly supports an iterable of 2 item tuples, (field, value) :param indexes: iterable of 2 item tuples consisting the field and value. :rtype: self """ new_indexes = [] for field, value in indexes: rie = RiakIndexEntry(field, value) new_indexes.append(rie) self._metadata[MD_INDEX] = new_indexes return self
def add_index(self, field, value): """ Tag this object with the specified field/value pair for indexing. :param field: The index field. :type field: string :param value: The index value. :type value: string or integer :rtype: self """ rie = RiakIndexEntry(field, value) if not rie in self._metadata[MD_INDEX]: self._metadata[MD_INDEX].append(rie) return self
def decode_content(self, rpb_content): metadata = {} if rpb_content.HasField("deleted"): metadata[MD_DELETED] = True if rpb_content.HasField("content_type"): metadata[MD_CTYPE] = rpb_content.content_type if rpb_content.HasField("charset"): metadata[MD_CHARSET] = rpb_content.charset if rpb_content.HasField("content_encoding"): metadata[MD_ENCODING] = rpb_content.content_encoding if rpb_content.HasField("vtag"): metadata[MD_VTAG] = rpb_content.vtag links = [] for link in rpb_content.links: if link.HasField("bucket"): bucket = link.bucket else: bucket = None if link.HasField("key"): key = link.key else: key = None if link.HasField("tag"): tag = link.tag else: tag = None links.append(RiakLink(bucket, key, tag)) if links: metadata[MD_LINKS] = links if rpb_content.HasField("last_mod"): metadata[MD_LASTMOD] = rpb_content.last_mod if rpb_content.HasField("last_mod_usecs"): metadata[MD_LASTMOD_USECS] = rpb_content.last_mod_usecs usermeta = {} for usermd in rpb_content.usermeta: usermeta[usermd.key] = usermd.value if len(usermeta) > 0: metadata[MD_USERMETA] = usermeta indexes = [] for index in rpb_content.indexes: rie = RiakIndexEntry(index.key, index.value) indexes.append(rie) if len(indexes) > 0: metadata[MD_INDEX] = indexes return metadata, rpb_content.value
def test_secondary_index_store(self): if not self.is_2i_supported(): return True # Create a new object with indexes... bucket = self.client.bucket('indexbucket') rand = self.randint() obj = bucket.new('mykey1', rand) obj.add_index('field1_bin', 'val1a') obj.add_index('field1_int', 1011) obj.store() # Retrieve the object, check that the correct indexes exist... obj = bucket.get('mykey1') self.assertEqual(['val1a'], sorted(obj.get_indexes('field1_bin'))) self.assertEqual(['1011'], sorted(obj.get_indexes('field1_int'))) # Add more indexes and save... obj.add_index('field1_bin', 'val1b') obj.add_index('field1_int', 1012) obj.store() # Retrieve the object, check that the correct indexes exist... obj = bucket.get('mykey1') self.assertEqual(['val1a', 'val1b'], sorted(obj.get_indexes('field1_bin'))) self.assertEqual(['1011', '1012'], sorted(obj.get_indexes('field1_int'))) # Check the get_indexes() function... self.assertEqual([ RiakIndexEntry('field1_bin', 'val1a'), RiakIndexEntry('field1_bin', 'val1b'), RiakIndexEntry('field1_int', 1011), RiakIndexEntry('field1_int', 1012) ], sorted(obj.get_indexes())) # Delete an index... obj.remove_index('field1_bin', 'val1a') obj.remove_index('field1_int', 1011) obj.store() # Retrieve the object, check that the correct indexes exist... obj = bucket.get('mykey1') self.assertEqual(['val1b'], sorted(obj.get_indexes('field1_bin'))) self.assertEqual(['1012'], sorted(obj.get_indexes('field1_int'))) # Check duplicate entries... obj.add_index('field1_bin', 'val1a') obj.add_index('field1_bin', 'val1a') obj.add_index('field1_bin', 'val1a') obj.add_index('field1_int', 1011) obj.add_index('field1_int', 1011) obj.add_index('field1_int', 1011) self.assertEqual([ RiakIndexEntry('field1_bin', 'val1a'), RiakIndexEntry('field1_bin', 'val1b'), RiakIndexEntry('field1_int', 1011), RiakIndexEntry('field1_int', 1012) ], sorted(obj.get_indexes())) obj.store() obj = bucket.get('mykey1') self.assertEqual([ RiakIndexEntry('field1_bin', 'val1a'), RiakIndexEntry('field1_bin', 'val1b'), RiakIndexEntry('field1_int', 1011), RiakIndexEntry('field1_int', 1012) ], sorted(obj.get_indexes())) # Clean up... bucket.get('mykey1').delete()
def parse_body(self, response, expected_statuses): """ Given the output of RiakUtils.http_request and a list of statuses, populate the object. Only for use by the Riak client library. @return self """ # If no response given, then return. if response is None: return self # Make sure expected code came back self.check_http_code(response, expected_statuses) # Update the object... headers = response[0] data = response[1] status = headers['http_code'] # Check if the server is down(status==0) if not status: ### we need the host/port that was used. m = 'Could not contact Riak Server: http://$HOST:$PORT !' raise RiakError(m) # If 404(Not Found), then clear the object. if status == 404: return None # If 300(Siblings), then return the list of siblings elif status == 300: # Parse and get rid of 'Siblings:' string in element 0 siblings = data.strip().split('\n') siblings.pop(0) return siblings # Parse the headers... vclock = None metadata = {MD_USERMETA: {}, MD_INDEX: []} links = [] for header, value in headers.iteritems(): if header == 'content-type': metadata[MD_CTYPE] = value elif header == 'charset': metadata[MD_CHARSET] = value elif header == 'content-encoding': metadata[MD_CTYPE] = value elif header == 'etag': metadata[MD_VTAG] = value elif header == 'link': self.parse_links(links, headers['link']) elif header == 'last-modified': metadata[MD_LASTMOD] = value elif header.startswith('x-riak-meta-'): metadata[MD_USERMETA][header.replace('x-riak-meta-', '')] = value elif header.startswith('x-riak-index-'): field = header.replace('x-riak-index-', '') reader = csv.reader([value], skipinitialspace=True) for line in reader: for token in line: rie = RiakIndexEntry(field, token) metadata[MD_INDEX].append(rie) elif header == 'x-riak-vclock': vclock = value if links: metadata[MD_LINKS] = links return vclock, [(metadata, data)]