From 8aa0021c3e5faafe99e054d41785688a6918d25c Mon Sep 17 00:00:00 2001
From: "Dmitry E. Oboukhov" <unera@debian.org>
Date: Tue, 4 Sep 2012 22:29:39 +0400
Subject: [PATCH] fix box.info by review

---
 mod/box/CMakeLists.txt          |   1 -
 mod/box/box_lua.m               |   3 -
 src/CMakeLists.txt              |  27 ++++++--
 {mod/box => src}/box_lua_info.h |   0
 {mod/box => src}/box_lua_info.m | 111 +++++++++++++++++++++-----------
 src/tarantool_lua.m             |   2 +
 test/box/info.result            |  25 ++++---
 test/box/info.test              |   8 ++-
 8 files changed, 121 insertions(+), 56 deletions(-)
 rename {mod/box => src}/box_lua_info.h (100%)
 rename {mod/box => src}/box_lua_info.m (71%)

diff --git a/mod/box/CMakeLists.txt b/mod/box/CMakeLists.txt
index 477404b273..9b3ec9b45f 100644
--- a/mod/box/CMakeLists.txt
+++ b/mod/box/CMakeLists.txt
@@ -39,5 +39,4 @@ set_source_files_properties(memcached.m
     PROPERTIES COMPILE_FLAGS "-Wno-uninitialized")
 
 tarantool_module("box" tuple.m index.m tree.m space.m port.m request.m
-    box_lua_info.m
     txn.m box.m box.lua.c box_lua.m memcached.m memcached-grammar.m)
diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m
index aac3cdab94..6fa47cf88f 100644
--- a/mod/box/box_lua.m
+++ b/mod/box/box_lua.m
@@ -46,7 +46,6 @@
 #include "tuple.h"
 #include "space.h"
 #include "port.h"
-#include "box_lua_info.h"
 
 /* contents of box.lua */
 extern const char box_lua[];
@@ -1049,8 +1048,6 @@ mod_lua_init(struct lua_State *L)
 	/* Load box.lua */
 	if (luaL_dostring(L, box_lua))
 		panic("Error loading box.lua: %s", lua_tostring(L, -1));
-	
-	lbox_info_init(L);
 
 	assert(lua_gettop(L) == 0);
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e3ec26d184..be13d9e146 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -79,10 +79,29 @@ set (recompiled_sources
      ${CMAKE_SOURCE_DIR}/src/replication.m
      ${CMAKE_SOURCE_DIR}/src/fiber.m PARENT_SCOPE)
 
-set (common_sources tbuf.m palloc.m util.m
-     salloc.m pickle.m coro.m stat.m log_io.m recovery.m cpu_feature.m
-     replica.m iproto.m object.m exception.m errcode.c errinj.m latch.m
-     nio.c crc32.c rope.c)
+set (common_sources
+	tbuf.m
+	palloc.m
+	util.m
+	salloc.m
+	pickle.m
+	coro.m
+	stat.m
+	log_io.m
+	recovery.m
+	cpu_feature.m
+	replica.m
+	iproto.m
+	object.m
+	exception.m
+	errcode.c
+	errinj.m
+	latch.m
+	nio.c
+	crc32.c
+	rope.c
+	box_lua_info.m
+)
 
 if (ENABLE_TRACE)
     set (common_sources ${common_sources} trace.m)
diff --git a/mod/box/box_lua_info.h b/src/box_lua_info.h
similarity index 100%
rename from mod/box/box_lua_info.h
rename to src/box_lua_info.h
diff --git a/mod/box/box_lua_info.m b/src/box_lua_info.m
similarity index 71%
rename from mod/box/box_lua_info.m
rename to src/box_lua_info.m
index be6b9dd7c7..da0f859b31 100644
--- a/mod/box/box_lua_info.m
+++ b/src/box_lua_info.m
@@ -38,41 +38,52 @@
 #include <recovery.h>
 
 
-static int lbox_info_index_get_recovery_lag(struct lua_State *L) {
+static int
+lbox_info_index_get_recovery_lag(struct lua_State *L)
+{
 	if (recovery_state->remote)
 		lua_pushnumber(L, recovery_state->remote->recovery_lag);
 	else
-		lua_pushnil(L);
+		lua_pushnumber(L, 0);
 	return 1;
 }
 
 static int
-lbox_info_index_get_recovery_last_update_tstamp(struct lua_State *L) {
+lbox_info_index_get_recovery_last_update_tstamp(struct lua_State *L)
+{
 	if (recovery_state->remote)
 		lua_pushnumber(L,
 			recovery_state->remote->recovery_last_update_tstamp);
 	else
-		lua_pushnil(L);
+		lua_pushnumber(L, 0);
 	return 1;
 }
 
-static int lbox_info_get_lsn(struct lua_State *L) {
+static int
+lbox_info_get_lsn(struct lua_State *L)
+{
 	luaL_pushnumber64(L, recovery_state->confirmed_lsn);
 	return 1;
 }
 
 
-static int lbox_info_get_status(struct lua_State *L) {
+static int
+lbox_info_get_status(struct lua_State *L)
+{
 	lua_pushstring(L, mod_status());
 	return 1;
 }
 
-static int lbox_info_uptime(struct lua_State *L) {
-	lua_pushnumber(L, (unsigned)tarantool_uptime() + 1); 
+static int
+lbox_info_uptime(struct lua_State *L)
+{
+	lua_pushnumber(L, (unsigned)tarantool_uptime() + 1);
 	return 1;
 }
 
-static const struct luaL_reg lbox_info_dynamic_meta [] = {
+static const struct luaL_reg
+lbox_info_dynamic_meta [] =
+{
 	{"recovery_lag", lbox_info_index_get_recovery_lag},
 	{"recovery_last_update",
 		lbox_info_index_get_recovery_last_update_tstamp},
@@ -82,40 +93,26 @@ static const struct luaL_reg lbox_info_dynamic_meta [] = {
 	{NULL, NULL}
 };
 
-static int lbox_info_index(struct lua_State *L) {
-
-	const char *key = lua_tolstring(L, -1, NULL);
-	unsigned i;
+static int
+lbox_info_index(struct lua_State *L)
+{
 
-	for (i = 0; lbox_info_dynamic_meta[i].name; i++) {
-		if (strcmp(key, lbox_info_dynamic_meta[i].name) == 0) {
-			return lbox_info_dynamic_meta[i].func(L);
-		}
+	lua_pushvalue(L, lua_upvalueindex(1));	/* table */
+	lua_pushvalue(L, -2);			/* key */
+	lua_gettable(L, -2);			/* table[key] */
+	lua_remove(L, -2);			/* remove table */
 
-	}
+	if (!lua_isfunction(L, -1))
+		return 1;
 
-	lua_pushnil(L);
+	lua_call(L, 0, 1);
+	lua_remove(L, -2);
 	return 1;
 }
 
 
-static const struct luaL_reg lbox_info_meta [] = {
-	{"__index", lbox_info_index},
-	{NULL, NULL}
-};
-
-void lbox_info_init(struct lua_State *L) {
-
-	lua_getfield(L, LUA_GLOBALSINDEX, "box");
-
-	lua_pushstring(L, "info");
-	lua_newtable(L);
-
-	lua_newtable(L);
-	luaL_register(L, NULL, lbox_info_meta);
-	lua_setmetatable(L, -2);
-
-
+static void
+lbox_info_staticvalues(struct lua_State *L) {
 	/* tarantool version */
 	lua_pushstring(L, "version");
 	lua_pushstring(L, tarantool_version());
@@ -162,6 +159,48 @@ void lbox_info_init(struct lua_State *L) {
 	lua_settable(L, -3);
 
 	lua_settable(L, -3);    /* box.info.build */
+}
+
+static int
+lbox_info_call(struct lua_State *L)
+{
+	unsigned i;
+	lua_newtable(L);
+	lbox_info_staticvalues(L);
+	for (i = 0; lbox_info_dynamic_meta[i].name; i++) {
+		lua_pushstring(L, lbox_info_dynamic_meta[i].name);
+		lbox_info_dynamic_meta[i].func(L);
+		lua_settable(L, -3);
+	}
+	return 1;
+}
+
+void
+lbox_info_init(struct lua_State *L)
+{
+
+	lua_getfield(L, LUA_GLOBALSINDEX, "box");
+
+	lua_pushstring(L, "info");
+	lua_newtable(L);		/* box.info table */
+
+	lua_newtable(L);		/* metatable for box.info */
+
+	lua_pushstring(L, "__index");
+
+	lua_newtable(L);
+	luaL_register(L, NULL, lbox_info_dynamic_meta); /* table for __index */
+	lua_pushcclosure(L, lbox_info_index, 1);
+	lua_settable(L, -3);
+
+	lua_pushstring(L, "__call");
+	lua_pushcfunction(L, lbox_info_call);
+	lua_settable(L, -3);
+
+
+	lua_setmetatable(L, -2);
+
+	lbox_info_staticvalues(L);		/* fill table */
 
 	lua_settable(L, -3);    /* box.info = created table */
 	lua_pop(L, 1);          /* cleanup stack */
diff --git a/src/tarantool_lua.m b/src/tarantool_lua.m
index c5509930e6..4474523544 100644
--- a/src/tarantool_lua.m
+++ b/src/tarantool_lua.m
@@ -42,6 +42,7 @@
 #include "pickle.h"
 #include "fiber.h"
 #include <ctype.h>
+#include "box_lua_info.h"
 #include TARANTOOL_CONFIG
 
 /**
@@ -1160,6 +1161,7 @@ tarantool_lua_init()
 	lua_register(L, "pcall", lbox_pcall);
 	lua_register(L, "tonumber64", lbox_tonumber64);
 	L = mod_lua_init(L);
+	lbox_info_init(L);
 	/* clear possible left-overs of init */
 	lua_settop(L, 0);
 	return L;
diff --git a/test/box/info.result b/test/box/info.result
index 2d0066599c..4350f7d8eb 100644
--- a/test/box/info.result
+++ b/test/box/info.result
@@ -1,11 +1,3 @@
-lua
----
-unknown command. try typing help.
-...
-lua 1
----
- - 1
-...
 lua box.info.unknown_variable
 ---
  - nil
@@ -36,11 +28,11 @@ lua box.info.lsn > 0
 ...
 lua box.info.recovery_lag
 ---
- - nil
+ - 0
 ...
 lua box.info.recovery_last_update
 ---
- - nil
+ - 0
 ...
 lua box.info.status
 ---
@@ -74,3 +66,16 @@ lua string.match(box.info.uptime, '^[1-9][0-9]*$') ~= nil
 ---
  - true
 ...
+lua for k, v in pairs(box.info()) do print(k) end
+---
+version
+status
+pid
+lsn
+recovery_last_update
+recovery_lag
+uptime
+build
+logger_pid
+config
+...
diff --git a/test/box/info.test b/test/box/info.test
index 639b95c0c6..8041ae1605 100644
--- a/test/box/info.test
+++ b/test/box/info.test
@@ -3,14 +3,16 @@ import os
 import sys
 # Test Lua from admin console. Whenever producing output,
 # make sure it's a valid YAML.
-exec admin "lua"
-exec admin "lua 1"
 exec admin "lua box.info.unknown_variable"
 exec admin "lua box.info[23]"
 exec admin "lua box.info['unknown_variable']"
 exec admin "lua string.match(box.info.version, '^[1-9]') ~= nil"
 exec admin "lua string.match(box.info.pid, '^[1-9][0-9]*$') ~= nil"
 exec admin "lua string.match(box.info.logger_pid, '^[1-9][0-9]*$') ~= nil"
+# exec admin "lua box.info.lsn() > 0"
+# exec admin "lua box.info.recovery_lag()"
+# exec admin "lua box.info.recovery_last_update()"
+# exec admin "lua box.info.status()"
 exec admin "lua box.info.lsn > 0"
 exec admin "lua box.info.recovery_lag"
 exec admin "lua box.info.recovery_last_update"
@@ -22,3 +24,5 @@ exec admin "lua string.len(box.info.build.flags) > 0"
 exec admin "lua string.len(box.info.build.options) > 0"
 exec admin "lua string.len(box.info.uptime) > 0"
 exec admin "lua string.match(box.info.uptime, '^[1-9][0-9]*$') ~= nil"
+
+exec admin "lua for k, v in pairs(box.info()) do print(k) end"
-- 
GitLab