from collections import namedtuple __all__ = 'HandlerUser', 'User' User = namedtuple('User', ['obj', 'db', 'msg']) class HandlerUser: tb = 'user' user_key = '#account_id' def __init__(self, db_client, db_name): self.users = dict() self.db_client = db_client self.receive_data = [] self.db_name = db_name def execute(self): account_ids = set(item.msg.get('#account_id') for item in self.receive_data) - set( self.users.setdefault(self.db_name, {})) if not account_ids: return self.get_users(account_ids) for item in self.receive_data: item.obj(item.db, item.msg) self.receive_data.clear() def get_users(self, account_ids: set): where = f'`#account_id` in {tuple(account_ids)}' res = self.db_client.get_all(self.db_name, 'user_view', where) for item in res.values(): self.users.setdefault(self.db_name, {}).setdefault(item['#account_id'], item) def get_user(self, db, account_id, data=None): user = self.users.get(db, {}).get(account_id) if user: return user user = self.db_client.get_one(db, f'{self.tb}_view', **{'#account_id': account_id}) if user: self.users.setdefault(db, {})[account_id] = user return user if not isinstance(data, dict): return user = dict() self.merge(user, data) self.users.setdefault(db, {})[account_id] = user return user def merge(self, a: dict, b: dict): """ 将b 合并到 a :param a: :param b: :return: """ for k, v in b.items(): if isinstance(v, dict): self.merge(a, v) else: a[k] = v def merge_once(self, a: dict, b: dict): """ a 存在的字段不接受b的合并 :param a: :param b: :return: """ for k, v in b.items(): if isinstance(v, dict): self.merge_once(a, v) else: a[k] = v if a.get(k) is None else a[k] def merge_add(self, a: dict, b: dict): """ b 的properties 属性累加到a :param a: :param b: :return: """ if 'properties' not in b or not isinstance(b['properties'], dict): return for k, v in b['properties'].items(): if not isinstance(v, int): raise ValueError('需要提供数值类型累加') a[k] = a.setdefault(k, 0) + v def merge_unset(self, a: dict, b: dict): """ 清除 a 中 b的properties :param db: :param data: :return: """ if 'properties' not in b or not isinstance(b['properties'], list): return for k in b['properties']: if k in a: del a[k] def user_set(self, db, data: dict): """ 注意 data 结构包含 properties user 为一层 k v 将data 合并到 user :param db: :param data: :return: """ account_id = data[self.user_key] user = self.get_user(db, account_id, data) self.merge(user, data) def user_setOnce(self, db: str, data: dict): account_id = data[self.user_key] user = self.get_user(db, account_id, data) self.merge_once(user, data) def user_add(self, db: str, data: dict): account_id = data[self.user_key] user = self.get_user(db, account_id, data) self.merge_add(user, data) def user_unset(self, db: str, data: dict): account_id = data[self.user_key] user = self.get_user(db, account_id) self.merge_unset(user, data) def user_append(self, db: str, data: dict): pass def user_del(self, db: str, data: dict): pass @property def buffer_pool(self): return self.tb, self.users