static int lua_sql(lua_State *L){
if(lua_isstring(L, 1) && mysql != NULL){
if(mysql_query(mysql, lua_tostring(L, 1))){
output(lua_tostring(L, 1));
}else{
MYSQL_RES *result = mysql_store_result(mysql);
MYSQL_ROW row;
lua_newtable(L);
int rowcount = 1;
while(row = mysql_fetch_row(result)){
lua_pushnumber(L, rowcount);
lua_newtable(L);
lua_settable(L, -3);
int i = 0;
while(row[i]){
lua_pushnumber(L, i + 1);
lua_pushstring(L, row[i]);
lua_settable(L, -3);
i++;
}
rowcount++;
}
}
}
lua_pop(L, 1);
return 0;
}
mysql is a MYSQL*, and will be NULL, if there''s no connection to the database. Basically, this function is supposed to execute the arguement as a sql query. Then return a lua table, which contains any result from the database. I know it doesn''t do that yet, because I''m just testing it so far.
Alrighty, let me explain what I think it does (or supposed to do). First checks there''s a connection to the database, and the arguement from Lua is a string. Then executes the arguement as sql query. If it fails, it outputs the query to my program window. If it works, it stores the result, and creates a Lua table on the stack. It loops over, fetching a row from the database. It pushes a number, which should be the key on the table. Then creates a new table, which should be the value of the first table. Then sets the table (that''s in the wrong place for a start, right?). Then loops through each field of the row, pushing the relevant key and value, and setting the table. Doesn''t bother returning it or anything, since it''s just a test.
Someone explain to me when to call lua_settable? I should only call it once, once the table is complete, right? If so, that''s obviously the problem, calling it in the loop. Does it place alternate stack values as keys and values of the table? Could really do with some help understanding it =) hehe...
lua_newtable / lua_settable
Hey guys =)
This function crashes my program, but I don''t totally understand how to do it properly >.< Would like some help understanding it =) I''m getting really confused over calling lua_settable.
You really need to grab the docs and give them a thorough read
newtable() creates a new table and pushes it onto the stack.
settable() stores a value into the table. The stack must be setup so that the value is at the top of the stack and the key is just underneath the value.
So if you index on numbers:
lua_newtable(L)
lua_pushnumber(L,key)
lua_pushnumber(L,value)
lua_settable(L,-3)
settable pops both the key and value off the stack so after the above fragment the stack just has the table on the top.
I think you are being bitten by that popping. You new table is being popped after being added to the top level table so when you come to populate the inner table, the reference is no longer there (or at least I think that's what you're trying to do). I'm not 100% sure why it is crashing, although the logic isn't quite right, theres nothing that leaps out as a crash bug.
You probably want this sequence:
newtable() creates a new table and pushes it onto the stack.
settable() stores a value into the table. The stack must be setup so that the value is at the top of the stack and the key is just underneath the value.
So if you index on numbers:
lua_newtable(L)
lua_pushnumber(L,key)
lua_pushnumber(L,value)
lua_settable(L,-3)
settable pops both the key and value off the stack so after the above fragment the stack just has the table on the top.
I think you are being bitten by that popping. You new table is being popped after being added to the top level table so when you come to populate the inner table, the reference is no longer there (or at least I think that's what you're trying to do). I'm not 100% sure why it is crashing, although the logic isn't quite right, theres nothing that leaps out as a crash bug.
You probably want this sequence:
lua_newtable() // top level tablefor each row r lua_newtable() // push new table lua_pushnumber(r) lua_pushvalue(-2) // get the new table and push a reference to the top lua_settable(-4) for each element i lua_pushnumber(i) lua_pushstring(element)<br> lua_settable(-3)<br><br> lua_pop(1)<br> </pre> <br><br><SPAN CLASS=editedby>[edited by - JuNC on August 2, 2003 9:48:58 AM]</SPAN>
Right... Hehe, thanks for reply. I have been reading the docs, but I''m still having trouble understanding what lua_settable does. I think I understand what you''re saying, I''ll try it out, thanks =)
It''s quite straight forward as long as you know how the stack works. Imagine it like this:
Step 1 (newtable)
stack top: TABLErest of ----- stack -----
Step 2 (pushnumber key)
stack top: key TABLE ----- -----
Step 3 (pushnumber value)
stack top: value key TABLE ----- -----
Step 4 (settable -3)
stack top: TABLE ----- -----
etc.
Ahh thanks, that helped a lot =)
It no longer crashes, but execution of the Lua script fails >.<
If I call lua_newtable again, before pushing the key, that seems to crash it =/
Ok, let me see. I labelled those functions, step 1 - 8. I''ll see if I can understand what the stack looks like each time...
1:
Table
2:
Key
Table
3:
Table (value)
Key
Table
4:
reference to Table (value)
Table (value)
Key
Table
5:
reference to Table (value)
Table
6:
Key
reference to Table (value)
Table
7:
Value
Key
reference to Table (value)
Table
8:
reference to Table (value)
Table
Hmm... Does lua_settable set the 1st 2 stack values after the table as key and value? Or does it take the last 2 stack values?
It no longer crashes, but execution of the Lua script fails >.<
MYSQL_RES *result = mysql_store_result(mysql);MYSQL_ROW row;lua_newtable(L); // 1int rowcount = 0;while(row = mysql_fetch_row(result)){ lua_pushnumber(L, rowcount); // 2 lua_newtable(L); // 3 lua_pushvalue(L, -1); // 4 lua_settable(L, -4); // 5 int i = 0; while(row[i]){ lua_pushnumber(L, i); // 6 lua_pushstring(L, row[i]); // 7 lua_settable(L, -3); // 8 i++; } rowcount++;}
If I call lua_newtable again, before pushing the key, that seems to crash it =/
Ok, let me see. I labelled those functions, step 1 - 8. I''ll see if I can understand what the stack looks like each time...
1:
Table
2:
Key
Table
3:
Table (value)
Key
Table
4:
reference to Table (value)
Table (value)
Key
Table
5:
reference to Table (value)
Table
6:
Key
reference to Table (value)
Table
7:
Value
Key
reference to Table (value)
Table
8:
reference to Table (value)
Table
Hmm... Does lua_settable set the 1st 2 stack values after the table as key and value? Or does it take the last 2 stack values?
settable always takes the top two values off the stack. Your step 4 needs to be rearranged because you are using two table references:
reference to Table (value)
Table (value)
Key <- this will remain after the settable call
Table
Whereas what you want is:
reference to Table (value)
Key
Table (value) <- this will remain after the settable call
Table
(which is how I originally wrote it). Your actual diagram of the stack is correct for your code, but the logic is still screwed up.
Note also that everytime you finish one of the inner tables you should pop the top of the stack.
This is how I would write the function, assuming I have understood correctly what you''re trying to do:
reference to Table (value)
Table (value)
Key <- this will remain after the settable call
Table
Whereas what you want is:
reference to Table (value)
Key
Table (value) <- this will remain after the settable call
Table
(which is how I originally wrote it). Your actual diagram of the stack is correct for your code, but the logic is still screwed up.
Note also that everytime you finish one of the inner tables you should pop the top of the stack.
This is how I would write the function, assuming I have understood correctly what you''re trying to do:
static int lua_sql(lua_State *L){ if(lua_isstring(L, 1) && mysql != NULL) { if(mysql_query(mysql, lua_tostring(L, 1))) { output(lua_tostring(L, 1)); } else { MYSQL_RES *result = mysql_store_result(mysql); MYSQL_ROW row; lua_newtable(L); int rowcount = 1; while(row = mysql_fetch_row(result)) { lua_newtable(L); // new inner table lua_pushnumber(L, rowcount); // key lua_pushvalue(L,-2); // value lua_settable(L, -4); // refer to the top level table int i = 0; while(row[i]) { lua_pushnumber(L, i + 1); // key in inner table lua_pushstring(L, row[i]); // value for inner table lua_settable(L, -3); // refer to inner table i++; } lua_pop(L,1); // done with inner table, remove it so top level table is on top of stack rowcount++; } } } lua_pop(L, 1); return 0;}
I''ll just make sure you understand what I''m trying to do...
I basically wanna export the row into Lua. But I''m trying to make an array of rows, or a 2 dimensional array of fields.
I basically wanna export the row into Lua. But I''m trying to make an array of rows, or a 2 dimensional array of fields.
I honestly can''t see why it should be crashing, although I haven''t tested the code I''m sure the Lua API isn''t at fault here, have you definitely narrowed it down to something being done in the Lua code? Could the MySQL code be crashing?
Yup, it was >.< sorry hehe. I just got out of the deep, and got back in via the shallow end. It kinda threw me off when I moved that lua_pushvalue, started to think it was my Lua code that was at fault. My function now looks like this:
It doesn't crash, and each field is definately being extracted from the database, because I'm outputting it there, as a test. Now it seems that the tables aren't created properly >.< The way it should work is like this:
Can you see where it's going wrong? I can't >.<
Edit - Just added in that other lua_pop. But now, the value it returns is a string, which is the arguement in the first place! Hehe, I think I might get it right in a minute.
[edited by - Ironica on August 2, 2003 8:28:56 PM]
static int lua_sql(lua_State *L){ if(lua_isstring(L, 1) && mysql != NULL){ if(mysql_query(mysql, lua_tostring(L, 1))){ output(lua_tostring(L, 1)); }else{ MYSQL_RES *result = mysql_store_result(mysql); MYSQL_ROW row; lua_newtable(L); int rowcount = 1; while(row = mysql_fetch_row(result)){ lua_newtable(L); lua_pushnumber(L, rowcount); lua_pushvalue(L, -2); lua_settable(L, -4); unsigned int fields = mysql_num_fields(result); for(int i = 0; i < fields; i++){ lua_pushnumber(L, i + 1); lua_pushstring(L, row[i]); output(row[i]); lua_settable(L, -3); } lua_pop(L, 1); rowcount++; } } } lua_pop(L, 1); return 1;}
It doesn't crash, and each field is definately being extracted from the database, because I'm outputting it there, as a test. Now it seems that the tables aren't created properly >.< The way it should work is like this:
db = sqlexec("SELECT * FROM tbl_mytable")db[1][1] -- row 1, field 1db[1][2] -- row 1, field 2-- etcdb[2][1] -- row 2, field 1-- etc etc
Can you see where it's going wrong? I can't >.<
Edit - Just added in that other lua_pop. But now, the value it returns is a string, which is the arguement in the first place! Hehe, I think I might get it right in a minute.
[edited by - Ironica on August 2, 2003 8:28:56 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement