diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a7284e10a9cdf462f678ee3a3601b3c4697987d..fed52629c6555b9ee86c5036b9a3161e7e426f21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ find_program(CONFETTI confetti) find_program(LD ld) find_program(POD2MAN pod2man) + # # This instructs the rest of the build system what product # and what modules to produce. @@ -266,6 +267,11 @@ else() endif() endif() +# +# MySQL & PgSQL +# +include(BuildSQL) + # # LibEV diff --git a/cmake/BuildSQL.cmake b/cmake/BuildSQL.cmake new file mode 100644 index 0000000000000000000000000000000000000000..ee17721efa9b2650c32095447d2ff2e0d85ca820 --- /dev/null +++ b/cmake/BuildSQL.cmake @@ -0,0 +1,41 @@ +option(ENABLE_PSQL "Enable postgresql client for box.net.sql" OFF) +option(ENABLE_MYSQL "Enable mysql client for box.net.sql" OFF) + + + +if(ENABLE_PSQL) + include(FindPostgreSQL) + if (PostgreSQL_FOUND) + message(STATUS + "box.net.sql(pg): INC=${PostgreSQL_INCLUDE_DIR}") + message(STATUS + "box.net.sql(pg): LIBDIR=${PostgreSQL_LIBRARY_DIR}") + message(STATUS + "box.net.sql(pg): LIBS=${PostgreSQL_LIBRARIES}") + + add_compile_flags("C;CXX" "-I${PostgreSQL_INCLUDE_DIR}") + add_compile_flags("C;CXX" "-L${PostgreSQL_LIBRARY_DIR}") + add_compile_flags("C;CXX" "-l${PostgreSQL_LIBRARIES}") + + else() + message(STATUS "PostgreSQL client not found") + set(ENABLE_PSQL OFF) + endif() +endif() + +if(ENABLE_PSQL) + set(USE_PSQL_CLIENT "1") +else() + set(USE_PSQL_CLIENT "0") +endif() + + +if(ENABLE_MYSQL) + +endif() + +if (ENABLE_MYSQL) + set(USE_MYSQL_CLIENT "1") +else() + set(USE_MYSQL_CLIENT "0") +endif() diff --git a/include/config.h.cmake b/include/config.h.cmake index d253758e2ee2bb3a79649f00df2d2b8ac7ab00e4..bc3505171aff9a9f3af8f7cee5f9486933cfbcd8 100644 --- a/include/config.h.cmake +++ b/include/config.h.cmake @@ -98,6 +98,12 @@ #cmakedefine ENABLE_BUNDLED_LIBEIO 1 #cmakedefine ENABLE_BUNDLED_LIBCORO 1 +/* + * SQL clients + */ +#define USE_PSQL_CLIENT @USE_PSQL_CLIENT@ +#define USE_MYSQL_CLIENT @USE_MYSQL_CLIENT@ + /* * predefined /etc directory prefix. */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8028d32837b35d330a3a76099fd94adccb84270d..a403fd9f3193366ab58726ef580c0482951c56ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,8 +106,13 @@ set (common_sources lua/lua_socket.m lua/session.m lua/cjson.m + lua/lua_sql.m ) +if (ENABLE_PSQL) + set (common_sources ${common_sources} lua/pg.m) +endif() + if (ENABLE_TRACE) set (common_sources ${common_sources} trace.m) endif() diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index a01ab0354125f4a9e7ed31c58a046cd98adf76d9..8e88a0a16c44410d56894ae019ccb66b40ccd3b2 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -22,6 +22,7 @@ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/src/box/lua) lua_source(lua/box.lua) lua_source(lua/box_net.lua) lua_source(lua/misc.lua) +lua_source(lua/sql.lua) add_custom_target(generate_lua_sources} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src/box diff --git a/src/box/box_lua.m b/src/box/box_lua.m index 4ad80347f1ecab90f6056f2d763ab78fa0b5f2d5..2eedde66b4edc126c7f75faf9b6271cc9ef3b5fc 100644 --- a/src/box/box_lua.m +++ b/src/box/box_lua.m @@ -48,8 +48,8 @@ #include "tbuf.h" /* contents of box.lua, misc.lua, box.net.lua respectively */ -extern char box_lua[], box_net_lua[], misc_lua[]; -const char *lua_sources[] = { box_lua, box_net_lua, misc_lua, NULL }; +extern char box_lua[], box_net_lua[], misc_lua[], sql_lua[]; +const char *lua_sources[] = { box_lua, box_net_lua, misc_lua, sql_lua, NULL }; /** * All box connections share the same Lua state. We use diff --git a/src/box/lua/sql.lua b/src/box/lua/sql.lua new file mode 100644 index 0000000000000000000000000000000000000000..f14fb435e56a3b0c60120c63acfb37f4b78d6a3f --- /dev/null +++ b/src/box/lua/sql.lua @@ -0,0 +1,55 @@ +box.net.sql = { + connect = function(driver, host, port, user, login, db, ...) + + if type(driver) == 'table' then + driver = driver.driver + end + + local self = { + driver = driver, + host = host, + port = port, + login = login, + password = password, + db = db + } + + local init = { ... } + + setmetatable(self, box.net.sql) + + -- do_connect is written in C + -- it add 'raw' field in the table + local c = box.net.sql.do_connect( self ) + + -- perform init statements + for i, s in pairs(init) do + c:execute(unpack(s)) + end + return c + end, + + + __index = { + -- main method + -- do query and returns: status, resultset + execute = function(self, sql, ...) + if self.raw == nil then + error("Connection was not established") + end + error("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + return self.raw.execute(self, sql, ...) + end, + + -- quote identifiers + ident_quote = function(self, ident) + return self.raw.ident_quote(ident) + end, + + -- quote variables + quote = function(self, value) + return self.raw.quote(value) + end, + } + +} diff --git a/src/lua/init.m b/src/lua/init.m index 0f39799f8cc1581e2e2f9eadf1dc5d960d3fc064..2ec936b8ea01c3c98c2b874b31d7067dc5db96c4 100644 --- a/src/lua/init.m +++ b/src/lua/init.m @@ -45,6 +45,7 @@ #include "fiber.h" #include "lua_ipc.h" #include "lua_socket.h" +#include "lua_sql.h" #include "lua/info.h" #include "lua/slab.h" #include "lua/stat.h" @@ -1124,6 +1125,9 @@ tarantool_lua_init() mod_lua_init(L); + /* init after internal luas are processed */ + tarantool_lua_sql_init(L); + /* clear possible left-overs of init */ lua_settop(L, 0); return L; diff --git a/src/lua/lua_pg.h b/src/lua/lua_pg.h new file mode 100644 index 0000000000000000000000000000000000000000..6e1a20d37a9b44cdd1b584179baab6d2d5a13093 --- /dev/null +++ b/src/lua/lua_pg.h @@ -0,0 +1,6 @@ +#ifndef TARANTOOL_LUA_SQL_PG_H_INCLUDED + +struct lua_State; +int lbox_net_pg_connect(struct lua_State *L); + +#endif /* TARANTOOL_LUA_SQL_PG_H_INCLUDED */ diff --git a/src/lua/lua_sql.h b/src/lua/lua_sql.h new file mode 100644 index 0000000000000000000000000000000000000000..e94946b2936e9132e4805d8e357c0d836e4b8868 --- /dev/null +++ b/src/lua/lua_sql.h @@ -0,0 +1,7 @@ +#ifndef TARANTOOL_LUA_SQL_H_INCLUDED + +struct lua_State; +void tarantool_lua_sql_init(struct lua_State *L); + +#endif + diff --git a/src/lua/lua_sql.m b/src/lua/lua_sql.m new file mode 100644 index 0000000000000000000000000000000000000000..100ebea7561abdc1417c176472689f5fa8b87327 --- /dev/null +++ b/src/lua/lua_sql.m @@ -0,0 +1,68 @@ +#include "lua_sql.h" +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +#include <string.h> + +#include <config.h> + +#if USE_PSQL_CLIENT + #include "lua_pg.h" +#endif + +#if USE_MYSQL_CLIENT + #include "lua_mysql.h" +#endif + +int +lbox_net_sql_do_connect(struct lua_State *L) +{ + lua_pushstring(L, "driver"); + lua_rawget(L, -2); + + const char *drv = lua_tostring(L, -1); + lua_pop(L, 1); + + + if (strcmp(drv, "pg") == 0 || strcmp(drv, "postgresql") == 0) + #if USE_PSQL_CLIENT + return lbox_net_pg_connect(L); + #else + luaL_error(L, + "Tarantool was not compiled with postgresql. " + "Use cmake with '-DENABLE_PSQL=ON' option." + ); + #endif + + if (strcmp(drv, "mysql") == 0) + #if USE_MYSQL_CLIENT + return lbox_net_mysql_connect(L); + #else + luaL_error(L, + "Tarantool was not compiled with mysqlclient. " + "Use cmake with '-DENABLE_MYSQL=ON' option." + ); + #endif + return 0; +} + + +void +tarantool_lua_sql_init(struct lua_State *L) +{ + lua_getfield(L, LUA_GLOBALSINDEX, "box"); /* stack: box */ + + lua_pushstring(L, "net"); /* stack: box.net */ + lua_rawget(L, -2); + + lua_pushstring(L, "sql"); /* stack: box.net.sql */ + lua_rawget(L, -2); + + /* stack: box, box.net.sql */ + lua_pushstring(L, "do_connect"); + lua_pushcfunction(L, lbox_net_sql_do_connect); + lua_rawset(L, -3); + + /* cleanup stack */ + lua_pop(L, 3); +} diff --git a/src/lua/pg.m b/src/lua/pg.m new file mode 100644 index 0000000000000000000000000000000000000000..3ff477c507da60efa59b8e05fa2b423966bfebc0 --- /dev/null +++ b/src/lua/pg.m @@ -0,0 +1,12 @@ +#include "lua_pg.h" +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" + + +int +lbox_net_pg_connect(struct lua_State *L) +{ + lua_pushstring(L, "aaaaaaaaaaaaaaaaaaa"); + return 1; +} diff --git a/test/box/net_sql.result b/test/box/net_sql.result new file mode 100644 index 0000000000000000000000000000000000000000..5e5fe3ef33397233a3c13966b6661efd03d37693 --- /dev/null +++ b/test/box/net_sql.result @@ -0,0 +1,4 @@ +lua 1 +--- + - 1 +... diff --git a/test/box/net_sql.test b/test/box/net_sql.test new file mode 100644 index 0000000000000000000000000000000000000000..caafa1bc38e8cf30d8ec10da66cf381cdfb4e77f --- /dev/null +++ b/test/box/net_sql.test @@ -0,0 +1,4 @@ +# encoding: tarantool + +exec admin "lua c = box.net.sql.connect('pg', 'localhost', 5432, 'tarantool', 'tarantool', 'tarantool')" +exec admin "lua c"