async def rename_mailbox(self, before: str, after: str) -> None: redis = self._redis while True: pipe = watch_pipe(redis, self._keys.mailboxes) pipe.hgetall(self._keys.mailboxes) _, _, all_keys = await pipe.execute() all_mbx = {modutf7_decode(key): ns for key, ns in all_keys.items()} tree = ListTree(self.delimiter).update('INBOX', *all_mbx.keys()) before_entry = tree.get(before) after_entry = tree.get(after) if before_entry is None: raise MailboxNotFound(before) elif after_entry is not None: raise MailboxConflict(after) multi = redis.multi_exec() for before_name, after_name in tree.get_renames(before, after): before_id = all_mbx[before_name] before_key = modutf7_encode(before_name) after_key = modutf7_encode(after_name) multi.hset(self._keys.mailboxes, after_key, before_id) multi.hdel(self._keys.mailboxes, before_key) multi.hincrby(self._keys.uid_validity, after_key) if before == 'INBOX': inbox_id = ObjectId.random_mailbox_id() multi.hset(self._keys.mailboxes, b'INBOX', inbox_id.value) multi.hincrby(self._keys.uid_validity, b'INBOX') try: await multi.execute() except MultiExecError: if await check_errors(multi): raise else: break
def test_random(self): mailbox_id = ObjectId.random_mailbox_id() self.assertEqual(b'F', mailbox_id.value[0:1]) self.assertTrue(len(mailbox_id.value)) email_id = ObjectId.random_email_id() self.assertEqual(b'M', email_id.value[0:1]) self.assertTrue(len(email_id.value)) thread_id = ObjectId.random_thread_id() self.assertEqual(b'T', thread_id.value[0:1]) self.assertTrue(len(thread_id.value))
def __init__(self, content_cache: _ContentCache, thread_cache: _ThreadCache) -> None: self._mailbox_id = ObjectId.random_mailbox_id() self._content_cache = content_cache self._thread_cache = thread_cache self._readonly = False self._messages_lock = subsystem.get().new_rwlock() self._selected_set = SelectedSet() self._uid_validity = MailboxSnapshot.new_uid_validity() self._max_uid = 100 self._mod_sequences = _ModSequenceMapping() self._messages: Dict[int, Message] = OrderedDict()
async def add_mailbox(self, name: str) -> ObjectId: redis = self._redis name_key = modutf7_encode(name) while True: mbx_id = ObjectId.random_mailbox_id() pipe = watch_pipe(redis, self._keys.mailboxes) pipe.incr(self._keys.max_order) pipe.hexists(self._keys.mailboxes, name_key) _, _, order, exists = await pipe.execute() if exists: raise MailboxConflict(name) multi = redis.multi_exec() multi.hset(self._keys.mailboxes, name_key, mbx_id.value) multi.zadd(self._keys.order, order, mbx_id.value) multi.hincrby(self._keys.uid_validity, name_key) try: _, _, uidval = await multi.execute() except MultiExecError: if await check_errors(multi): raise else: break return mbx_id