Spec-Zone .ru
спецификации, руководства, описания, API
|
The read_query_result()
is called for each result set returned by the server only
if you have manually injected queries into the query queue. If you have not manipulated the query queue, this
function is not called. The function supports a single argument, the result packet, which provides a number of
properties:
id
: The ID of the result set, which corresponds to the
ID that was set when the query packet was submitted to the server when using append(id)
on the query queue. You must have set the resultset_is_needed
flag to append
to intercept the result set before it is returned to the client.
See proxy.queries.
query
: The text of the original query.
query_time
: The number of microseconds required to
receive the first row of a result set since the query was sent to the server.
response_time
: The number of microseconds required to
receive the last row of the result set since the query was sent to the server.
resultset
: The content of the result set data.
By accessing the result information from the MySQL server, you can extract the results that match the queries that you injected, return different result sets (for example, from a modified query), and even create your own result sets.
The following Lua script, for example, will output the query, followed by the query time and response time (that is, the time to execute the query and the time to return the data for the query) for each query sent to the server:
function read_query( packet ) if packet:byte() == proxy.COM_QUERY then print("we got a normal query: " .. packet:sub(2)) proxy.queries:append(1, packet ) return proxy.PROXY_SEND_QUERY endendfunction read_query_result(inj) print("query-time: " .. (inj.query_time / 1000) .. "ms") print("response-time: " .. (inj.response_time / 1000) .. "ms")end
You can access the rows of returned results from the result set by accessing the rows
property of the resultset
property of the result
that is exposed through read_query_result()
. For example, you can iterate over the
results showing the first column from each row using this Lua fragment:
for row in inj.resultset.rows do print("injected query returned: " .. row[1])end
Just like read_query()
, read_query_result()
can
return different values for each result according to the result returned. If you have injected additional
queries into the query queue, for example, remove the results returned from those additional queries and return
only the results from the query originally submitted by the client.
The following example injects additional SELECT NOW()
statements into the query
queue, giving them a different ID to the ID of the original query. Within read_query_result()
,
if the ID for the injected queries is identified, we display the result row, and return the proxy.PROXY_IGNORE_RESULT
from the function so that the result is not returned to
the client. If the result is from any other query, we print out the query time information for the query and
return the default, which passes on the result set unchanged. We could also have explicitly returned proxy.PROXY_IGNORE_RESULT
to the MySQL client.
function read_query( packet ) if packet:byte() == proxy.COM_QUERY then proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SELECT NOW()", {resultset_is_needed = true} ) proxy.queries:append(1, packet, {resultset_is_needed = true}) proxy.queries:append(2, string.char(proxy.COM_QUERY) .. "SELECT NOW()", {resultset_is_needed = true} ) return proxy.PROXY_SEND_QUERY endendfunction read_query_result(inj) if inj.id == 2 then for row in inj.resultset.rows do print("injected query returned: " .. row[1]) end return proxy.PROXY_IGNORE_RESULT else print("query-time: " .. (inj.query_time / 1000) .. "ms") print("response-time: " .. (inj.response_time / 1000) .. "ms") endend
For further examples, see Section 15.7.5, "Using MySQL Proxy".