freebsd-ports/databases/mysql-proxy/files/patch-lib-admin.lua
Cheng-Lung Sung f8680edbe5 - Update to 0.7.1
PR:		ports/134042
2009-07-09 02:49:52 +00:00

208 lines
6 KiB
Lua

--- lib/admin.lua.orig 2009-05-05 16:55:08.000000000 +0600
+++ lib/admin.lua 2009-05-05 16:56:11.000000000 +0600
@@ -0,0 +1,205 @@
+--[[ $%BEGINLICENSE%$
+ Copyright (C) 2009 MySQL AB, 2008 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ $%ENDLICENSE%$ --]]
+
+-- admin-1.lua
+
+--[[
+
+ See http://forge.mysql.com/tools/tool.php?id=78
+ (Thanks to Jan Kneschke)
+ See http://www.chriscalender.com/?p=41
+ (Thanks to Chris Calender)
+ See http://datacharmer.blogspot.com/2009/01/mysql-proxy-is-back.html
+ (Thanks Giuseppe Maxia)
+
+--]]
+
+
+function set_error(errmsg)
+ proxy.response = {
+ type = proxy.MYSQLD_PACKET_ERR,
+ errmsg = errmsg or "error"
+ }
+end
+
+function read_query(packet)
+ if packet:byte() ~= proxy.COM_QUERY then
+ set_error("[admin] we only handle text-based queries (COM_QUERY)")
+ return proxy.PROXY_SEND_RESULT
+ end
+
+ local query = packet:sub(2)
+ local rows = { }
+ local fields = { }
+
+ -- try to match the string up to the first non-alphanum
+ local f_s, f_e, command = string.find(packet, "^%s*(%w+)", 2)
+ local option
+
+ if f_e then
+ -- if that match, take the next sub-string as option
+ f_s, f_e, option = string.find(packet, "^%s+(%w+)", f_e + 1)
+ end
+
+ -- we got our commands, execute it
+ if command == "show" and option == "querycounter" then
+ ---
+ -- proxy.PROXY_SEND_RESULT requires
+ --
+ -- proxy.response.type to be either
+ -- * proxy.MYSQLD_PACKET_OK or
+ -- * proxy.MYSQLD_PACKET_ERR
+ --
+ -- for proxy.MYSQLD_PACKET_OK you need a resultset
+ -- * fields
+ -- * rows
+ --
+ -- for proxy.MYSQLD_PACKET_ERR
+ -- * errmsg
+ proxy.response.type = proxy.MYSQLD_PACKET_OK
+ proxy.response.resultset = {
+ fields = {
+ { type = proxy.MYSQL_TYPE_LONG, name = "query_counter", },
+ },
+ rows = {
+ { proxy.global.query_counter }
+ }
+ }
+
+ -- we have our result, send it back
+ return proxy.PROXY_SEND_RESULT
+ elseif command == "show" and option == "myerror" then
+ proxy.response.type = proxy.MYSQLD_PACKET_ERR
+ proxy.response.errmsg = "my first error"
+
+ return proxy.PROXY_SEND_RESULT
+
+ elseif string.sub(packet, 2):lower() == 'select help' then
+ return show_process_help()
+
+ elseif string.sub(packet, 2):lower() == 'show proxy processlist' then
+ return show_process_table()
+
+ elseif query == "SELECT * FROM backends" then
+ fields = {
+ { name = "backend_ndx",
+ type = proxy.MYSQL_TYPE_LONG },
+
+ { name = "address",
+ type = proxy.MYSQL_TYPE_STRING },
+ { name = "state",
+ type = proxy.MYSQL_TYPE_STRING },
+ { name = "type",
+ type = proxy.MYSQL_TYPE_STRING },
+ }
+
+ for i = 1, #proxy.global.backends do
+ local b = proxy.global.backends[i]
+
+ rows[#rows + 1] = {
+ i, b.dst.name, b.state, b.type
+ }
+ end
+ else
+ set_error()
+ return proxy.PROXY_SEND_RESULT
+ end
+
+ proxy.response = {
+ type = proxy.MYSQLD_PACKET_OK,
+ resultset = {
+ fields = fields,
+ rows = rows
+ }
+ }
+ return proxy.PROXY_SEND_RESULT
+end
+
+
+function make_dataset (header, dataset)
+ proxy.response.type = proxy.MYSQLD_PACKET_OK
+
+ proxy.response.resultset = {
+ fields = {},
+ rows = {}
+ }
+ for i,v in pairs (header) do
+ table.insert(proxy.response.resultset.fields, {type = proxy.MYSQL_TYPE_STRING, name = v})
+ end
+ for i,v in pairs (dataset) do
+ table.insert(proxy.response.resultset.rows, v )
+ end
+ return proxy.PROXY_SEND_RESULT
+end
+
+function show_process_table()
+ local dataset = {}
+ local header = { 'Id', 'IP Address', 'Time' }
+ local rows = {}
+ for t_i, t_v in pairs (proxy.global.process) do
+ for s_i, s_v in pairs ( t_v ) do
+ table.insert(rows, { t_i, s_v.ip, os.date('%c',s_v.ts) })
+ end
+ end
+ return make_dataset(header,rows)
+end
+
+function show_process_help()
+ local dataset = {}
+ local header = { 'command', 'description' }
+ local rows = {
+ {'SELECT HELP', 'This command.'},
+ {'SHOW PROXY PROCESSLIST', 'Show all connections and their true IP Address.'},
+ }
+ return make_dataset(header,rows)
+end
+
+function dump_process_table()
+ proxy.global.initialize_process_table()
+ print('current contents of process table')
+ for t_i, t_v in pairs (proxy.global.process) do
+ print ('session id: ', t_i)
+ for s_i, s_v in pairs ( t_v ) do
+ print ( '\t', s_i, s_v.ip, s_v.ts )
+ end
+ end
+ print ('---END PROCESS TABLE---')
+end
+
+
+
+
+--[[ Help
+
+we use a simple string-match to split commands are word-boundaries
+
+mysql> show querycounter
+
+is split into
+command = "show"
+option = "querycounter"
+
+spaces are ignored, the case has to be as is.
+
+mysql> show myerror
+
+returns a error-packet
+
+--]]
+
+