async def test_crud_simple(): db, MUsers, MTopics, MTopics2 = crud_db_init() info = QueryInfo(User) info.select = [User.id, User.username, User.password, User.nickname] info.conditions = QueryConditions([]) c = PeeweeCrud(None, { User: '******', Topic: 'topic', }, db) ret = await c.get_list(info) assert len(ret) == MUsers.select().count() for i in ret: assert isinstance(i, QueryResultRow) assert isinstance(i.id, int) info.conditions.items.append(ConditionExpr(User.id, QUERY_OP_COMPARE.EQ, 2)) ret = await c.get_list(info) assert len(ret) == 1 info.foreign_keys = { 'topic[]': QueryInfo(Topic, [Topic.id, Topic.title, Topic.user_id], conditions=QueryConditions([ ConditionExpr(Topic.user_id, QUERY_OP_RELATION.IN, [2, 3]), ])), 'topic': QueryInfo(Topic, [Topic.id, Topic.title, Topic.user_id], conditions=QueryConditions([ ConditionExpr(Topic.user_id, QUERY_OP_RELATION.IN, [2, 3]), ]), foreign_keys={ 'user': QueryInfo(User, [User.id, User.nickname], conditions=QueryConditions([ ConditionExpr(Topic.user_id, QUERY_OP_COMPARE.EQ, User.id), ])) }), } ret = await c.get_list_with_foreign_keys(info) assert ret[0].id == 2 d = ret[0].to_dict() assert d['$extra']['topic']['id'] == 3 assert d['$extra']['topic']['title'] == 'test3' assert d['$extra']['topic']['$extra']['user'] assert d['$extra']['topic']['$extra']['user']['id'] == 2 assert len(d['$extra']['topic[]']) == 2
async def test_bytes_read(): db, c, TestModel = crud_db_init() info = QueryInfo(ATest) info.select = [ATest.token] info.conditions = QueryConditions([]) ret = await c.get_list(info) assert ret[0].to_dict()['token'] == b'abcd' assert len(ret) == TestModel.select().count()
async def solve(ret_lst, main_table, fk_queries, depth=0): if fk_queries is None: return if depth == 0: pk_items = [x.id for x in ret_lst] else: pk_items = [x.raw_data[0] for x in ret_lst] for raw_name, query in fk_queries.items(): query: QueryInfo limit = -1 if raw_name.endswith('[]') else 1 # 上级ID,数据,查询条件 q = QueryInfo(main_table, [query.from_table.id, *query.select]) q.conditions = QueryConditions([ ConditionExpr(main_table.id, QUERY_OP_RELATION.IN, pk_items) ]) q.join = [ QueryJoinInfo(query.from_table, query.conditions, limit=limit) ] elist = [] for x in await self.get_list_with_perm(q, perm=perm): x.base = query.from_table elist.append(x) extra: Dict[Any, Union[List, QueryResultRow]] = {} if limit != 1: for x in elist: extra.setdefault(x.id, []) extra[x.id].append(x) else: for x in elist: extra[x.id] = x if depth == 0: for i in ret_lst: i.extra[raw_name] = extra.get(i.id) else: for i in ret_lst: i.extra[raw_name] = extra.get(i.raw_data[0]) if query.foreign_keys: await solve(elist, query.from_table, query.foreign_keys, depth + 1)
async def _solve_query(info: QueryInfo, perm: PermInfo): if perm.is_check: allow_query = perm.role.get_perm_avail(info.from_table, A.QUERY) allow_read = perm.role.get_perm_avail(info.from_table, A.READ) def sub_solve_items(items): if items: r = [solve_condition(x) for x in items if x is not None] # solve_condition 返回值仍有 None 的可能 return [x for x in r if x is not None] return [] def solve_condition(c): if isinstance(c, QueryConditions): return QueryConditions(sub_solve_items(c.items)) elif isinstance(c, ConditionLogicExpr): items = sub_solve_items(c.items) if items: return ConditionLogicExpr(c.type, items) return None elif isinstance(c, ConditionExpr): if c.column not in allow_query: # permission return None if isinstance(c.value, RecordMappingField): if c.value not in allow_query: # permission return None return c elif isinstance(c, UnaryExpr): return c select_new = [x for x in info.select if x in allow_read] info.select = select_new info.conditions = solve_condition(info.conditions) return info