summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2011-06-30 12:56:46 +0000
committerdeva <deva>2011-06-30 12:56:46 +0000
commit0a9bb105ff1534868886e68e3309aabc6c0315c0 (patch)
treea03ebb328f5c6492c75b6909e2adcbccda3804b8
parenta20c72026fe7871964eb2743f407658dc4c00173 (diff)
Use stack manipulation through c, rather than pragram text generation/parsing to create query result values in lua maps.
-rw-r--r--server/src/luaquerymapper.cc131
1 files changed, 98 insertions, 33 deletions
diff --git a/server/src/luaquerymapper.cc b/server/src/luaquerymapper.cc
index fcdce85..380960c 100644
--- a/server/src/luaquerymapper.cc
+++ b/server/src/luaquerymapper.cc
@@ -29,35 +29,78 @@
#include <sstream>
#include <string>
-static std::string loadresultstring(QueryResult &res, std::string group = "")
+static bool hasField(lua_State *L, int i, std::string name)
{
+ lua_getfield(L, i, name.c_str());
+ bool ret = lua_isnil(L, lua_gettop(L));
+ lua_pop(L, 1);
+ return ret;
+}
+
+static void loadResult(lua_State *L, QueryResult &res,
+ std::vector<std::string> group = std::vector<std::string>())
+{
+ int grp = 0;
+ std::vector<std::string>::iterator gi = group.begin();
+ while(gi != group.end()) {
+ const char *name = gi->c_str();
+ printf("[%d: %s]", grp, name); fflush(stdout);
+
+ if(grp == 0) grp = LUA_GLOBALSINDEX;
+ if(hasField(L, grp, name)) {
+ lua_newtable(L);
+ lua_setfield(L, grp, name);
+ lua_getfield(L, grp, name);
+ }
+
+ grp = lua_gettop(L);
+ gi++;
+ }
+ printf("\n"); fflush(stdout);
+
std::string s;
std::stringstream timestamp; timestamp << res.timestamp;
std::map< std::string, std::string >::iterator v = res.values.begin();
while(v != res.values.end()) {
- std::string grp = (*v).first;
- std::string::size_type idx = -1;
- while((idx = grp.find(".", idx + 1)) != std::string::npos) {
- s += group + grp.substr(0, idx) + " = {}\n";
+ const char *name = v->first.c_str();
+
+ if(grp == 0) grp = LUA_GLOBALSINDEX;
+ if(hasField(L, grp, name)) {
+ lua_newtable(L);
+ lua_setfield(L, grp, name);
}
- s += group + (*v).first + " = {}\n";
- s += group + (*v).first + ".value = \"" + (*v).second + "\"\n";
- s += group + (*v).first + ".timestamp = " + timestamp.str() + "\n";
- s += group + (*v).first + ".source = \"" + res.source + "\"\n";
+ int val;
+
+ lua_getfield(L, grp, name);
+ val = lua_gettop(L);
+ lua_pushstring(L, v->second.c_str());
+ lua_setfield(L, val, "value");
+
+ lua_getfield(L, grp, name);
+ val = lua_gettop(L);
+ lua_pushstring(L, timestamp.str().c_str());
+ lua_setfield(L, val, "timestamp");
+
+ lua_getfield(L, grp, name);
+ val = lua_gettop(L);
+ lua_pushstring(L, res.source.c_str());
+ lua_setfield(L, val, "source");
+
v++;
}
+ while(lua_gettop(L) > 1) lua_pop(L, 1);
+
std::map< std::string, QueryResult >::iterator g = res.groups.begin();
while(g != res.groups.end()) {
- s += group + (*g).first + " = {}\n";
- s += loadresultstring((*g).second, group + (*g).first + ".");
+ std::vector<std::string> subgrp = group;
+ subgrp.push_back(g->first);
+ loadResult(L, g->second, subgrp);
g++;
}
-
- return s;
}
LUAQueryMapper::LUAQueryMapper() throw(Exception)
@@ -82,21 +125,7 @@ LUAQueryMapper::~LUAQueryMapper()
void LUAQueryMapper::addQueryResult(QueryResult &result) throw(Exception)
{
- std::string preload = loadresultstring(result);
-
- DEBUG(querymapper, "Preload:\n%s\n", preload.c_str());
-
- if(luaL_loadbuffer(L, preload.c_str(), preload.size(), "preload")) {
- error(lua_tostring(L, lua_gettop(L)));
- return;
- }
-
- // Run program (init)
- if(lua_pcall(L, 0, LUA_MULTRET, 0)) {
- error(lua_tostring(L, lua_gettop(L)));
- return;
- }
-
+ loadResult(L, result);
clean_top = lua_gettop(L);
}
@@ -202,7 +231,6 @@ std::string LUAQueryMapper::automap(const std::string &name)
return automapstring;
}
-
#ifdef TEST_LUAQUERYMAPPER
//deps: exception.cc log.cc debug.cc
//cflags: -I.. ${LUA_CFLAGS}
@@ -211,22 +239,59 @@ std::string LUAQueryMapper::automap(const std::string &name)
TEST_BEGIN;
-QueryResult res;
-
time_t now = time(NULL);
+{
+ QueryResult res;
+ res.groups["test"].timestamp = now;
+ res.groups["test"].source = "test app";
+ res.groups["test"].values["somevalue"] = "hello world";
+ res.groups["test"].values["pi"] = "3.14";
+ res.groups["test"].groups["subtest"].source = "test app 2";
+ res.groups["test"].groups["subtest"].timestamp = now + 1;
+ res.groups["test"].groups["subtest"].values["somevalue"] = "hello world!";
+
+ LUAQueryMapper mapper;
+ mapper.addQueryResult(res);
+
+ // Test simple value forwarding with nesting
+ std::string luamap = "return test.subtest.somevalue.value, test.subtest.somevalue.timestamp, test.subtest.somevalue.source";
+
+ Value value = mapper.map(luamap);
+
+ TEST_EQUAL_STR(value.value, "hello world!", "Test value");
+ TEST_EQUAL_INT(value.timestamp, now + 1, "Test timestamp");
+ TEST_EQUAL_STR(value.source, "test app 2", "Test source");
+
+ luamap = "return test.somevalue.value, test.somevalue.timestamp, test.somevalue.source";
+
+ value = mapper.map(luamap);
+
+ TEST_EQUAL_STR(value.value, "hello world", "Test value");
+ TEST_EQUAL_INT(value.timestamp, now, "Test timestamp");
+ TEST_EQUAL_STR(value.source, "test app", "Test source");
+
+ luamap = "return test.pi.value, test.pi.timestamp, test.pi.source";
+
+ value = mapper.map(luamap);
+
+ TEST_EQUAL_STR(value.value, "3.14", "Test value");
+ TEST_EQUAL_INT(value.timestamp, now, "Test timestamp");
+ TEST_EQUAL_STR(value.source, "test app", "Test source");
+}
+
+QueryResult res;
res.groups["test"].timestamp = now;
res.groups["test"].source = "test app";
res.groups["test"].values["somevalue"] = "hello world";
res.groups["test"].values["pi"] = "3.1416";
-
-//printf("%s\n", loadresultstring(res).c_str());
LUAQueryMapper mapper;
mapper.addQueryResult(res);
// Test simple value forwarding
std::string luamap = "return test.somevalue.value, test.somevalue.timestamp, test.somevalue.source";
+
Value value = mapper.map(luamap);
TEST_EQUAL_STR(value.value, "hello world", "Test value");