async def test_value_write_bind_with_empty(): write = SQLValuesToWrite({'$num': 123}) view: PeeweeView = await make_mocked_view_instance(app, ATestView, 'POST', '/api/list/1') write.bind(view, None, None) assert len(write) == 0
async def before_update(self, raw_post: Dict, values: SQLValuesToWrite, records: List[DataRecord]): if 'password' in raw_post: ret = User.gen_password_and_salt(raw_post['password']) values.update(ret) if 'key' in raw_post: values.update(User.gen_key())
async def before_update(self, values: SQLValuesToWrite, records: List[DataRecord]): raw_post = await self.post_data() if 'password' in raw_post: ret = User.gen_password_and_salt(self.new_pass) values.update(ret)
async def _base_insert(self, raw_values_lst, ignore_exists): with ErrorCatchContext(self): if isinstance(raw_values_lst, str): try: values_lst = json.loads(raw_values_lst) assert isinstance(values_lst, list) except (json.JSONDecodeError, AssertionError): return self.finish(RETCODE.INVALID_POSTDATA, "`value_lst` is not validated") values_lst = [ SQLValuesToWrite(x, self, A.CREATE) for x in raw_values_lst ] if logger.isEnabledFor(logging.DEBUG): logger.debug('insert record(s): %s' % values_lst) await self._call_handle(self.before_insert, values_lst) for values in values_lst: values.validate_before_execute_insert(self) records = await self._sql.insert(values_lst, returning=True, ignore_exists=ignore_exists) await self.check_records_permission(None, records) await self._call_handle(self.after_insert, values_lst, records) return records
async def set(self): """ 更新数据接口 查询规则参考 https://fy0.github.io/slim/#/quickstart/query_and_modify 赋值规则参考 https://fy0.github.io/slim/#/quickstart/query_and_modify?id=修改新建 """ self.current_interface = InnerInterfaceName.SET with ErrorCatchContext(self): info = SQLQueryInfo(self.params, self) await self._call_handle(self.before_query, info) records, count = await self._sql.select_page(info, size=self.bulk_num()) if records: # 确保 before_update 时得到list records = list(records) values = SQLValuesToWrite(await self.post_data()) values.bind(self, A.WRITE, records) await self._call_handle(self.before_update, values, records) # 如果 before_update 之后,不再有values,那么抛出invalid_postdata if len(values) == 0: raise InvalidPostData("No value to set for table: %s" % self.table_name) if logger.isEnabledFor(logging.DEBUG): logger.debug('update record(s): %s' % values) # 注:此处returning为true是因为后续要检查数据的权限,和前端要求无关 new_records = await self._sql.update(records, values, returning=True) await self.check_records_permission(None, new_records) await self._call_handle(self.after_update, values, records, new_records) if await self.is_returning(): self.finish(RETCODE.SUCCESS, new_records) else: self.finish(RETCODE.SUCCESS, len(new_records)) else: self.finish(RETCODE.NOT_FOUND)
async def before_insert(self, raw_post: Dict, values: SQLValuesToWrite): form = WikiNewForm(**raw_post) if not form.validate(): return self.finish(RETCODE.FAILED, form.errors) values['time'] = int(time.time()) values['user_id'] = self.current_user.id ref = values.get('ref', '').strip() if not ref: ref = values['title'] values['ref'] = quote(ref).replace('/', '')
async def before_insert(self, raw_post: Dict, values: SQLValuesToWrite): relate_type = values.get('related_type', None) if not (relate_type and relate_type in POST_TYPES.values()): return self.finish(RETCODE.INVALID_POSTDATA, "被评论的内容不存在") try: cid = config.POST_ID_GENERATOR(values['related_id']) post = POST_TYPES.get_post(relate_type, cid) if not post: return self.finish(RETCODE.INVALID_POSTDATA, "被评论的内容不存在") if relate_type == POST_TYPES.TOPIC: if post.state == POST_STATE.CLOSE: return self.finish(RETCODE.INVALID_POSTDATA, "无法评论指定内容") elif post.visible in (POST_VISIBLE.HIDE, ): return self.finish(RETCODE.INVALID_POSTDATA, "被评论的内容不存在") except TypeError: return self.finish(RETCODE.INVALID_POSTDATA, "被评论的内容不存在") if 'content' not in values or not values['content']: return self.finish(RETCODE.INVALID_POSTDATA, "评论内容不能为空") if 'reply_to_cmt_id' in values: try: rtid = config.POST_ID_GENERATOR(values['reply_to_cmt_id']) except TypeError: return self.finish(RETCODE.INVALID_POSTDATA, "指定被回复的内容不存在") c: Comment = Comment.get_by_pk(rtid.to_bin()) if not c: return self.finish(RETCODE.INVALID_POSTDATA, "指定被回复的内容不存在") if c.related_id != post.id: return self.finish(RETCODE.INVALID_POSTDATA, "指定被回复的内容不存在") values['reply_to_cmt_id'] = rtid.to_bin() if not isinstance(config.LONG_ID_GENERATOR, config.AutoGenerator): values['id'] = config.LONG_ID_GENERATOR().to_bin() values['related_id'] = cid.to_bin() values['related_type'] = int(values['related_type']) values['user_id'] = self.current_user.id values['time'] = int(time.time()) values['content'], self.do_mentions = check_content_mention( values['content']) if relate_type == POST_TYPES.TOPIC: post: Topic await post.weight_inc()
async def before_insert(self, raw_post: Dict, values: SQLValuesToWrite): # 必须存在以下值: # email password nickname # 自动填充或改写以下值: # id password salt group state key key_time time if not config.USER_ALLOW_SIGNUP: return self.finish(RETCODE.FAILED, '注册未开放') form = SignupFormLegacy(**raw_post) if not form.validate(): return self.finish(RETCODE.FAILED, form.errors) if not config.POST_ID_GENERATOR == config.AutoGenerator: uid = User.gen_id().to_bin() values['id'] = uid values['email'] = values['email'].lower() ret = User.gen_password_and_salt(raw_post['password']) values.update(ret) if 'group' not in values: # 如果无权限,那此时即使带着 group 参数也被刷掉了,直接设为 normal 即可 values['group'] = USER_GROUP.NORMAL if 'state' not in values: values['state'] = POST_STATE.NORMAL # 注册IP地址 values['ip_registered'] = await get_fuzz_ip(self) values['is_new_user'] = False # 目前的代表了是否重设过昵称,但在legacy模式中注册时即设置好了昵称 values['change_nickname_chance'] = 0 values.update(User.gen_key()) values['time'] = int(time.time()) self._key = values['key']
async def test_value_write_invalid(): write = SQLValuesToWrite({'num1': 123, 'str1': {}}) view: PeeweeView = await make_mocked_view_instance(app, ATestView, 'POST', '/api/list/1') with pytest.raises(InvalidPostData) as e: write.bind(view, None, None)
async def test_value_write_normal2(): write = SQLValuesToWrite({'num1': 123, 'str1': 456}) view: PeeweeView = await make_mocked_view_instance(app, ATestView, 'POST', '/api/list/1') write.bind(view, None, None) assert write['str1'] == '456'
async def test_value_write_normal(): write = SQLValuesToWrite({'num1': 123, 'str1': 'whatever'}) view: PeeweeView = await make_mocked_view_instance(app, ATestView, 'POST', '/api/list/1') write.bind(view, None, None)