def test_intersect_should_accept_sortedset_key_as_string(self): zset_key = unique_key(self.connection) self.connection.zadd(zset_key, 1.0, 1, 2.0, 2) collection = set(Group.collection().intersect(zset_key)) self.assertEqual(self.last_interstore_call['command'], 'zinterstore') self.assertEqual(collection, {'1', '2'}) zset_key = unique_key(self.connection) self.connection.zadd(zset_key, 1.0, 1, 2.0, 2, 10.0, 10, 50.0, 50) collection = set(Group.collection().intersect(zset_key)) self.assertEqual(collection, {'1', '2'})
def test_intersect_should_accept_list_key_as_string(self): list_key = unique_key(self.connection) self.connection.lpush(list_key, 1, 2) collection = set(Group.collection().intersect(list_key)) self.assertEqual(self.last_interstore_call['command'], 'sinterstore') self.assertEqual(collection, {'1', '2'}) list_key = unique_key(self.connection) self.connection.lpush(list_key, 1, 2, 10, 50) collection = set(Group.collection().intersect(list_key)) self.assertEqual(collection, {'1', '2'})
def test_intersect_should_accept_string(self): set_key = unique_key(self.connection) self.connection.sadd(set_key, 1, 2) collection = set(Group.collection().intersect(set_key)) self.assertEqual(self.last_interstore_call['command'], 'sinterstore') self.assertEqual(collection, set(['1', '2'])) set_key = unique_key(self.connection) self.connection.sadd(set_key, 1, 2, 10, 50) collection = set(Group.collection().intersect(set_key)) self.assertEqual(collection, set(['1', '2']))
def get_filtered_keys(self, suffix, *args, **kwargs): """Return the set used by the index for the given "value" (`args`) For the parameters, see ``BaseIndex.get_filtered_keys`` """ accepted_key_types = kwargs.get('accepted_key_types', None) if accepted_key_types and 'set' not in accepted_key_types: raise ImplementationError( '%s can only return keys of type "set"' % self.__class__.__name__ ) # special "in" case: we get n keys and make an unionstore with them then return this key if suffix == 'in': args = list(args) values = set(args.pop()) if not values: return [] # no keys in_keys = [ self.get_storage_key(transform_value=False, *(args+[value])) for value in values ] tmp_key = unique_key(self.connection) self.connection.sunionstore(tmp_key, *in_keys) return [(tmp_key, 'set', True)] # do not transform because we already have the value we want to look for return [(self.get_storage_key(transform_value=False, *args), 'set', False)]
def _unique_key(self, prefix=None): """ Create a unique key. """ prefix_parts = [self.model._name, '__collection__'] if prefix: prefix_parts.append(prefix) return unique_key(self.connection, prefix=make_key(*prefix_parts))
def test_intersect_should_not_accept_hkey_key_as_string(self): hash_key = unique_key(self.connection) self.connection.hset(hash_key, 'foo', 'bar') with self.assertRaises(ValueError): set(Group.collection().intersect(hash_key))
def test_generated_key_must_be_unique(self): key1 = unique_key(self.connection) key2 = unique_key(self.connection) self.assertNotEqual(key1, key2)
def test_generated_key_must_be_a_string(self): key = unique_key(self.connection) self.assertTrue(isinstance(key, str))
def test_generated_key_must_accept_prefix(self): key1 = unique_key(self.connection, 'foo') self.assertTrue(key1.startswith('foo:')) key2 = unique_key(self.connection) self.assertNotEqual(key1, key2)
def _unique_key(self): """ Create a unique key. """ return unique_key(self.cls.get_connection())
def test_generated_key_must_be_a_string(self): key = unique_key(self.connection) self.assertEqual(type(key), str)
def test_intersect_should_consider_non_existent_key_as_set(self): no_key = unique_key(self.connection) collection = set(Group.collection().intersect(no_key)) self.assertEqual(self.last_interstore_call['command'], 'sinterstore') self.assertEqual(collection, set())
def get_filtered_keys(self, suffix, *args, **kwargs): """Returns the index key for the given args "value" (`args`) Parameters ---------- kwargs: dict use_lua: bool Default to ``True``, if scripting is supported. If ``True``, the process of reading from the sorted-set, extracting the primary keys, excluding some values if needed, and putting the primary keys in a set or zset, is done in lua at the redis level. Else, data is fetched, manipulated here, then returned to redis. For the other parameters, see ``BaseIndex.get_filtered_keys`` """ accepted_key_types = kwargs.get('accepted_key_types', None) if accepted_key_types\ and 'set' not in accepted_key_types and 'zset' not in accepted_key_types: raise ImplementationError( '%s can only return keys of type "set" or "zset"' % self.__class__.__name__ ) key_type = 'set' if not accepted_key_types or 'set' in accepted_key_types else 'zset' tmp_key = unique_key(self.connection) args = list(args) # special "in" case: we get n keys and make an unionstore with them then return this key if suffix == 'in': values = set(args.pop()) if not values: return [] # no keys in_keys = [ self.get_filtered_keys('eq', *(args+[value]), **kwargs)[0][0] for value in values ] if key_type == 'set': self.connection.sunionstore(tmp_key, *in_keys) else: self.connection.zunionstore(tmp_key, *in_keys) # we can delete the temporary keys for in_key in in_keys: self.connection.delete(in_key) return [(tmp_key, key_type, True)] use_lua = self.model.database.support_scripting() and kwargs.get('use_lua', True) key = self.get_storage_key(*args) value = self.normalize_value(args[-1], transform=False) real_suffix = self.remove_prefix(suffix) if use_lua: start, end, exclude = self.get_boundaries(real_suffix, value) self.call_script(key, tmp_key, key_type, start, end, exclude) else: pks = self.get_pks_for_filter(key, real_suffix, value) if pks: if key_type == 'set': self.connection.sadd(tmp_key, *pks) else: self.connection.zadd(tmp_key, **{pk: idx for idx, pk in enumerate(pks)}) return [(tmp_key, key_type, True)]
def test_intersect_should_not_accept_string_key_as_string(self): str_key = unique_key(self.connection, 'tests') self.connection.set(str_key, 'foo') with self.assertRaises(ValueError): set(Group.collection().intersect(str_key))