Conversation
…mpleteness, add client check_offset attr, add swoole_mysql_coro_parse_end to tidy up, use event loop but instead loop recv.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
完整的MySQL存储过程支持
先贴上来, 还有一点细节问题, 说明我一会儿补
做了以下几件事:
fetch mode
一开始先想着和PDO一样给Swoole做一个fetch模式
分离client和statement
加了一个
MYSQL_RESPONSE_BUFFER宏, 处理了一些代码分离了client和statement的buffer并给statement结构上也挂了一个result的zval指针
这样就可以实现以下代码:
因为现在result是挂在statement上的, 和client分离干净, 就不会因为这样的写法产生错误
当然这并没有多大用, 主要还是为了后面处理多响应多结果集
分离mysql_parse_response
这样就就可以在除了
onRead回调之外的别的地方复用这个方法, 处理多结果集了存储过程
存储过程会返回多个响应, 如果和swoole之前的设计一样, 一次性全返回是不太现实的
PDO和MySQLi的设计都是用一个 next 方法来切换到下一个响应
刚开始是想做一个链表存储多个响应, 很快就发现并不需要
所以首先做了一个
mysql_is_over方法它用来校验MySQL包的完整性, 这是swoole以前没有的, 所以在之前的PR后虽然可以使用存储过程, 但是并不能每次都收到完整的响应包, 第一次没收到的包会被丢弃
然后说一下几个注意点
MYSQL_SERVER_MORE_RESULTS_EXISTS的标志位并不准确, 不可采信, 只有eof和ok包中的是准确的 (这里一定要注意)校验包的完整性直到所有数据接收完毕
(分离了client和statement后, execute获取的数据是被存在
statement->buffer里而不是client->buffer)这时候onRead中只会解析第一个响应的结果, 并置到statement对象上, 而剩下的数据仍在buffer中, 并等待nextResult来推动offset解析下一个, 可以说是懒解析了, 有时候会比一次性解析所有响应划算, 而且我们可以清楚的知道每一次nextResult切换前后, 对应的affected_rows和insert_id的值(如果一次性读完, 只能知道最后的)
最后效果就是以下代码
非fetch_mode模式下这么写
比较巧妙的是nextResult推到最后一个response_ok包的时候会返回null, while循环终止, 我们就可以在循环后读取ok包的affected_rows, 如果最后存储过程最后一个语句是insert成功, 这里会显示1
25个单元测试都通过了, 但是这个单元测试数量感觉还不够, 后续会补