read_query_result() 函數僅在你之前手動向 query 隊列中添加了 query 的情況下,有結果集從伺服器端傳回的時候被調用。如果你沒有對 query 隊列進行過操作,該函數不會被調用。該函數僅具有一個入參,即結果包(在 lua 腳本中可以認為該包對應的是 injection 結構),其中包含了一系列屬性:
id: 結果集 id ,其對應于 當 query 包被用戶端向伺服器送出時使用 append(id) 函數對 query 隊列操作時設定的 id 值。你必須設定 resultset_is_needed 标志,以便當攔截到來自于伺服器的傳回結果集時,進行相應處理,之後再傳回給用戶端。參閱 proxy.queries 。
query: 原始 query 的文本内容。
query_time: 從 query 被發送到伺服器,到接收到結果集的第一行時,所需要的微秒數。
response_time: 從 query 被發送到伺服器,到接收到結果集的最後一行時,所需要的微秒數。
resultset: 結果集資料的内容。
通過對來自 mysql 伺服器的傳回結果資訊的分析處理,可以提取出與你之前注入的 query 語句比對的結果,并傳回修改後的結果集(例如傳回一個經過修改的 query 産生的結果),甚至建立屬于你自己的結果集。
下面的 lua 腳本,将輸出每一個發送到伺服器的 query 對應的文本内容,以及 query 時間和 response 時間(即開始執行 query 的時刻和傳回該 query 結果的時刻):
你可以通過 read_query_result() 函數獲得傳回結果中的 resultset 屬性的 row 屬性。例如,你可以使用下面的 lua 代碼段來遞歸顯示傳回結果中所有行的第一列内容:
正如 read_query() 函數一樣,read_query_result() 函數能夠根據傳回結果的内容,按需傳回結果的不同值。例如,如果你之前注入了額外的 query 到 query 隊列中,然後在擷取傳回的結果集後,移除與額外 query 對應的結果,僅傳回與用戶端發送的原始 query 對應的結果。
下面的例子注入額外的 select now() 語句到 query 隊列中,并設定了一個與原始 query 不同的 id 值。在 read_query_result() 函數中,如果發現了與我們自己注入的 query 的 id 相比對的結果,我們将顯示結果的行内容,然後通過 return proxy.proxy_ignore_result 語句使該結果不會被傳回給用戶端。如果結果是由任何其他 query 産生,則列印出 query 相應的時間資訊,并傳回預設值,即傳回不做任何修改的結果集給用戶端。我們同樣可以顯式地使用 return proxy.proxy_ignore_result 來将結果傳回給 mysql 用戶端。