用 C++ 封装一层 MySQL 接口,再通过 Lua 桥接函数暴露给脚本层调用。

SQLInterface.cpp

下面是 C++ 封装类及对应的 Lua 桥接函数实现。


                #include "mysql/mysql.h"
                
                
                #pragma comment(lib,"mysql/libmysql.lib")
                
                
                
                class SQLInterface
                {
                
                
                public:
                	SQLInterface()
                	{
                		this->res = nullptr;
                		this->mysql = nullptr;
                		cout << __FUNCTION__ << endl;
                	}
                	~SQLInterface()
                	{
                		cout << __FUNCTION__ << endl;
                	}
                	bool connect(string user, string pwd, string host, string db, int port)
                	{
                		mysql = new MYSQL;
                
                		MYSQL_RES *result;
                		MYSQL_ROW sql_row;
                		int res;
                		mysql_init(mysql);
                		//	if (!mysql)return false;
                		if (!mysql_real_connect(mysql, host.c_str(), user.c_str(), pwd.c_str(), db.c_str(), port, NULL, 0))
                		{
                			return false;
                		}
                		return true;
                	}
                
                	bool exec(string sql)
                	{
                		if (!mysql)return false;
                
                		int res11 = mysql_query(this->mysql, sql.c_str());//查询
                		if (!res11)
                		{
                			MYSQL_RES * result = mysql_store_result(mysql);
                			if (result)
                			{
                				this->res = result;
                			}
                		}
                		else
                		{
                			cout << "query sql failed!" << endl;
                		}
                
                		return true;
                	}
                
                	int pushParams(lua_State*l, int count)
                	{
                		if (!mysql)return 0;
                		int ret = 0;
                
                		MYSQL_ROW row;
                		while (row = mysql_fetch_row(res))//获取具体的数据
                		{
                			int i = count;
                
                			while (i)
                			{
                				char *str = row[--i];
                
                				lua_pushstring(l, str);
                				++ret;
                				cout << str << " ";
                			}
                			cout << endl;  //  << "     " << sql_row[2] << endl;
                		}
                
                
                		cout << endl; cout << endl; cout << endl;
                		return ret;
                	}
                	void release()
                	{
                		if (res)mysql_free_result(res);
                		if (mysql)mysql_close(mysql);
                	}
                private:
                	MYSQL *mysql  ;
                	MYSQL_RES *res ;
                
                };
                
                
                
                
                
                int SQL_Script_Bridge(lua_State *l)
                {
                	int top = lua_gettop(l);
                
                	const char * host = lua_tostring(l, top - 6);
                	int port = lua_tonumber(l, top - 5);
                	const char * user = lua_tostring(l, top - 4);
                	const char * pswd = lua_tostring(l, top - 3);
                	const char * table = lua_tostring(l, top - 2);
                	const char *  sql = lua_tostring(l, top - 1);
                	int count = lua_tonumber(l, top);
                
                	cout << sql << count << endl;
                
                
                	SQLInterface s;
                	s.connect(user, pswd, host, table, port);
                	s.exec(sql);
                	int n = s.pushParams(l, count);
                
                	return n;
                
                }
                
                
                
                
                int SQL_Script_create(lua_State*l)
                {
                
                	void * user = lua_newuserdata(l, sizeof SQLInterface);
                
                	SQLInterface* ins = (SQLInterface*)user;
                	ins->SQLInterface::SQLInterface();
                
                	return 1;
                }
                
                
                
                int SQL_Script_connect(lua_State*l)
                {
                
                	int top = lua_gettop(l);
                
                	void *  instance = lua_touserdata(l, top - 5);
                	const char * host = lua_tostring(l, top - 4);
                	int port = lua_tonumber(l, top - 3);
                	const char * user = lua_tostring(l, top - 2);
                	const char * pswd = lua_tostring(l, top - 1);
                	const char * table = lua_tostring(l, top);
                
                
                	SQLInterface* ins = (SQLInterface*)instance;
                	bool ret = ins->connect(user, pswd, host, table, port);
                
                	lua_pushboolean(l,ret);
                
                	return 1;
                }
                
                
                
                int SQL_Script_execute(lua_State*l)
                {
                
                	int top = lua_gettop(l);
                
                	void *  instance = lua_touserdata(l, top - 2);
                	const char * sql = lua_tostring(l, top - 1);
                	int  row_count = lua_tonumber(l, top);
                
                	SQLInterface* ins = (SQLInterface*)instance;
                
                	ins->exec(sql);
                	int n = ins->pushParams(l, row_count);
                
                	return n;
                }
                
                int SQL_Script_release(lua_State*l)
                {
                
                	int top = lua_gettop(l);
                
                	void *  instance = lua_touserdata(l, top);
                
                	SQLInterface* ins = (SQLInterface*)instance;
                
                
                
                	return 0;
                }
                

sql.lua

Lua 脚本侧的封装模块。后续可以在此基础上补充参数校验和错误处理,以提升健壮性。


                local t={};
                
                t.config=require("sql_config");
                
                
                --exec the sql
                --return the res table which is one by one
                function t:exec(sql,row_count)
                    local c=t.config;
                
                    local t={ SQL_Script_Bridge(c.host , c.port , c.user , c.pwd , c.db , sql,row_count)};
                
                
                    return t;
                
                
                
                end
                
                
                function t:create()
                    return  SQL_Script_create();
                
                end
                
                function t:connect(ins)
                    local c=t.config;
                
                    local bool = SQL_Script_connect(ins,c.host , c.port , c.user , c.pwd , c.db);
                
                
                end
                
                
                function t:release(ins)
                    SQL_Script_release(ins);
                end
                
                function t:execute(ins,sql,col_count)
                  local t={ SQL_Script_execute(ins, sql,col_count)};
                
                  return t;
                end
                
                
                return t;