[tarantool-patches] [PATCH v1 09/10] lua: create vstream implementation for Lua

imeevma at tarantool.org imeevma at tarantool.org
Sat Nov 17 17:04:07 MSK 2018


Thas patch creates vstream implementation for Lua and function
box.sql.new_execute() that uses this implementation.

Part of #3505
---
 src/box/lua/sql.c |  36 +++++++++++++
 src/box/vstream.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/box/vstream.h |   3 ++
 3 files changed, 187 insertions(+)

diff --git a/src/box/lua/sql.c b/src/box/lua/sql.c
index 17e2694..b5e428d 100644
--- a/src/box/lua/sql.c
+++ b/src/box/lua/sql.c
@@ -6,6 +6,8 @@
 #include "box/info.h"
 #include "lua/utils.h"
 #include "info.h"
+#include "box/execute.h"
+#include "box/vstream.h"
 
 static void
 lua_push_column_names(struct lua_State *L, struct sqlite3_stmt *stmt)
@@ -111,6 +113,39 @@ sqlerror:
 }
 
 static int
+lbox_execute(struct lua_State *L)
+{
+	struct sqlite3 *db = sql_get();
+	if (db == NULL)
+		return luaL_error(L, "not ready");
+
+	size_t length;
+	const char *sql = lua_tolstring(L, 1, &length);
+	if (sql == NULL)
+		return luaL_error(L, "usage: box.execute(sqlstring)");
+
+	struct sql_request request = {};
+	struct sql_response response = {};
+	request.sql_text = sql;
+	request.sql_text_len = length;
+	if (sql_prepare_and_execute(&request, &response, &fiber()->gc) != 0)
+		goto sqlerror;
+
+	int keys;
+	struct vstream vstream;
+	lua_vstream_init(&vstream, L);
+	lua_newtable(L);
+	if (sql_response_dump(&response, &keys, &vstream) != 0) {
+		lua_pop(L, 1);
+		goto sqlerror;
+	}
+	return 1;
+sqlerror:
+	lua_pushstring(L, sqlite3_errmsg(db));
+	return lua_error(L);
+}
+
+static int
 lua_sql_debug(struct lua_State *L)
 {
 	struct info_handler info;
@@ -124,6 +159,7 @@ box_lua_sqlite_init(struct lua_State *L)
 {
 	static const struct luaL_Reg module_funcs [] = {
 		{"execute", lua_sql_execute},
+		{"new_execute", lbox_execute},
 		{"debug", lua_sql_debug},
 		{NULL, NULL}
 	};
diff --git a/src/box/vstream.c b/src/box/vstream.c
index d43c352..9d446ee 100644
--- a/src/box/vstream.c
+++ b/src/box/vstream.c
@@ -34,6 +34,8 @@
 #include "iproto_constants.h"
 #include "port.h"
 #include "xrow.h"
+#include "lua/utils.h"
+#include "lua/tuple.h"
 
 void
 mp_vstream_encode_array(struct vstream *stream, uint32_t size)
@@ -198,3 +200,149 @@ mp_vstream_init(struct vstream *vstream, struct mpstream *mpstream)
 	vstream->mpstream = mpstream;
 	vstream->is_flatten = false;
 }
+
+void
+lua_vstream_encode_array(struct vstream *stream, uint32_t size)
+{
+	lua_createtable(stream->L, size, 0);
+}
+
+void
+lua_vstream_encode_map(struct vstream *stream, uint32_t size)
+{
+	(void)size;
+	lua_newtable(stream->L);
+}
+
+void
+lua_vstream_encode_uint(struct vstream *stream, uint64_t num)
+{
+	luaL_pushuint64(stream->L, num);
+}
+
+void
+lua_vstream_encode_int(struct vstream *stream, int64_t num)
+{
+	luaL_pushint64(stream->L, num);
+}
+
+void
+lua_vstream_encode_float(struct vstream *stream, float num)
+{
+	lua_pushnumber(stream->L, num);
+}
+
+void
+lua_vstream_encode_double(struct vstream *stream, double num)
+{
+	lua_pushnumber(stream->L, num);
+}
+
+void
+lua_vstream_encode_strn(struct vstream *stream, const char *str, uint32_t len)
+{
+	lua_pushlstring(stream->L, str, len);
+}
+
+void
+lua_vstream_encode_nil(struct vstream *stream)
+{
+	lua_pushnil(stream->L);
+}
+
+void
+lua_vstream_encode_bool(struct vstream *stream, bool val)
+{
+	lua_pushboolean(stream->L, val);
+}
+
+int
+lua_vstream_encode_port(struct vstream *stream, struct port *port)
+{
+	if (port_dump_lua(port, stream->L) < 0)
+		return -1;
+	return 0;
+}
+
+int
+lua_vstream_encode_reply_array(struct vstream *stream, uint32_t size,
+			      uint8_t key, const char *str)
+{
+	(void)key;
+	if (stream->is_flatten)
+		return 0;
+	lua_createtable(stream->L, size, 0);
+	lua_setfield(stream->L, -2, str);
+	lua_getfield(stream->L, -1, str);
+	return 0;
+}
+
+int
+lua_vstream_encode_reply_map(struct vstream *stream, uint32_t size, uint8_t key,
+			    const char *str)
+{
+	(void)size;
+	(void)key;
+	if (stream->is_flatten)
+		return 0;
+	lua_newtable(stream->L);
+	lua_setfield(stream->L, -2, str);
+	lua_getfield(stream->L, -1, str);
+	return 0;
+}
+
+void
+lua_vstream_encode_enum(struct vstream *stream, int64_t num, const char *str)
+{
+	(void)num;
+	lua_pushlstring(stream->L, str, strlen(str));
+}
+
+void
+lua_vstream_encode_reply_commit(struct vstream *stream)
+{
+	if(!stream->is_flatten)
+		lua_pop(stream->L, 1);
+}
+
+void
+lua_vstream_encode_map_commit(struct vstream *stream)
+{
+	size_t length;
+	const char *key = lua_tolstring(stream->L, -2, &length);
+	lua_setfield(stream->L, -3, key);
+	lua_pop(stream->L, 1);
+}
+
+void
+lua_vstream_encode_array_commit(struct vstream *stream, uint32_t id)
+{
+	lua_rawseti(stream->L, -2, id + 1);
+}
+
+const struct vstream_vtab lua_vstream_vtab = {
+	/** encode_array = */ lua_vstream_encode_array,
+	/** encode_map = */ lua_vstream_encode_map,
+	/** encode_uint = */ lua_vstream_encode_uint,
+	/** encode_int = */ lua_vstream_encode_int,
+	/** encode_float = */ lua_vstream_encode_float,
+	/** encode_double = */ lua_vstream_encode_double,
+	/** encode_strn = */ lua_vstream_encode_strn,
+	/** encode_nil = */ lua_vstream_encode_nil,
+	/** encode_bool = */ lua_vstream_encode_bool,
+	/** encode_enum = */ lua_vstream_encode_enum,
+	/** encode_port = */ lua_vstream_encode_port,
+	/** encode_reply_array = */ lua_vstream_encode_reply_array,
+	/** encode_reply_map = */ lua_vstream_encode_reply_map,
+	/** encode_array_commit = */ lua_vstream_encode_array_commit,
+	/** encode_reply_commit = */ lua_vstream_encode_reply_commit,
+	/** encode_map_commit = */ lua_vstream_encode_map_commit,
+};
+
+void
+lua_vstream_init(struct vstream *vstream, struct lua_State *L)
+{
+	vstream->vtab = &lua_vstream_vtab;
+	vstream->L = L;
+	vstream->is_flatten = false;
+}
diff --git a/src/box/vstream.h b/src/box/vstream.h
index 42f9813..d5c18b8 100644
--- a/src/box/vstream.h
+++ b/src/box/vstream.h
@@ -80,6 +80,9 @@ struct vstream {
 void
 mp_vstream_init(struct vstream *vstream, struct mpstream *mpstream);
 
+void
+lua_vstream_init(struct vstream *vstream, struct lua_State *L);
+
 static inline void
 vstream_encode_array(struct vstream *stream, uint32_t size)
 {
-- 
2.7.4





More information about the Tarantool-patches mailing list