11

I'm running a MySQL query which always returns 4 rows:

row->name, row->date, row->ip, row->custom

What I want to achieve is create a simple table basing on the above results so it would look like:

{
     "name" = result of row->name,
     "date" = result of row->date,
     "ip"   = result of row->ip,
     "custom" = result of row->custom
}

I have tried multiple possibilities, but the examples posted are really varied and I got a problems making it working.

My last unsuccessful try:

lua_createtable(L, 0, 4);
top = lua_gettop(L);
lua_pushstring(L, "name");
lua_pushstring(L, row->name);
lua_pushstring(L, "date");
lua_pushnumber(L, row->date);
lua_pushstring(L, "ip");
lua_pushstring(L, row->ip);
lua_pushstring(L, "custom");
lua_pushstring(L, row->custom);
lua_settable(L, top);
1
  • 4
    lua_settable() sets only 1 value and pops only 1 pair of key, value from stack. Repeat it 4. Commented Nov 22, 2013 at 14:58

1 Answer 1

22

As I mentioned in comment, lua_settable() takes care only of one key, value pair. Must repeat that if You need more.

I'd prefer saving the Lua stack space like this:

lua_createtable(L, 0, 4);

lua_pushstring(L, "name");
lua_pushstring(L, row->name);
lua_settable(L, -3);  /* 3rd element from the stack top */

lua_pushstring(L, "date");
lua_pushstring(L, row->date);
lua_settable(L, -3);

lua_pushstring(L, "ip");
lua_pushstring(L, row->ip);
lua_settable(L, -3);

lua_pushstring(L, "custom");
lua_pushstring(L, row->custom);
lua_settable(L, -3);

/* We still have table left on top of the Lua stack. */

Also, You could write some kind of C struct iterator or something.

NOTE: if this is for some kind of Lua wrapper - You should do it the standard way. In the following example applied @lhf comment about shortening it a bit:

int 
l_row_push(lua_State *L)
{
    lua_createtable(L, 0, 4); /* creates and pushes new table on top of Lua stack */

    lua_pushstring(L, row->name); /* Pushes table value on top of Lua stack */
    lua_setfield(L, -2, "name");  /* table["name"] = row->name. Pops key value */

    lua_pushstring(L, row->date);
    lua_setfield(L, -2, "date");

    lua_pushstring(L, row->ip);
    lua_setfield(L, -2, "ip");

    lua_pushstring(L, row->custom);
    lua_setfield(L, -2, "custom");

    /* Returning one table which is already on top of Lua stack. */
    return 1;
}

EDIT: Fixes usage of lua_setfield() by @lhf note. Thanks!

Sign up to request clarification or add additional context in comments.

7 Comments

@Lucas yeah, it might look tricky at the beginning. Overall - it's not that bad at all.
Can I use the lua_newtable instead of the lua_createtable ?
@Lucas definitely. lua_createtable() saves some time of increasing memory allocated for the table each time inserting stuff. And recommended to be used. If size of table is not known, You're free to use lua_newtable.
The code is compiling itself, but in Lua when I do print(variable["name"]); nothing is being printed.
Nevermind, return 1 worked for it, just seen that its not going to return 4 tables, lol. Thank you very much!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.