/* ** Creates a cursor table and leave it on the top of the stack. */ static int create_cursor (lua_State *L, int o, conn_data *conn, const SQLHSTMT hstmt, const SQLSMALLINT numcols) { cur_data *cur = (cur_data *) lua_newuserdata(L, sizeof(cur_data)); luasql_setmeta (L, LUASQL_CURSOR_ODBC); conn->cur_counter++; /* fill in structure */ cur->closed = 0; cur->conn = LUA_NOREF; cur->numcols = numcols; cur->colnames = LUA_NOREF; cur->coltypes = LUA_NOREF; cur->hstmt = hstmt; lua_pushvalue (L, o); cur->conn = luaL_ref (L, LUA_REGISTRYINDEX); /* make and store column information table */ if(create_colinfo (L, cur) < 0) { lua_pop(L, 1); return fail(L, hSTMT, cur->hstmt); } return 1; }
/* ** Pushes a column information table on top of the stack. ** If the table isn't built yet, call the creator function and stores ** a reference to it on the cursor structure. */ static void _pushtable (lua_State *L, cur_data *cur, size_t off) { int *ref = (int *)((char *)cur + off); /* If colnames or coltypes do not exist, create both. */ if (*ref == LUA_NOREF) create_colinfo(L, cur); /* Pushes the right table (colnames or coltypes) */ lua_rawgeti (L, LUA_REGISTRYINDEX, *ref); }
/* ** Get another row of the given cursor. */ static int cur_fetch (lua_State *L) { cur_data *cur = getcursor (L); MYSQL_RES *res = cur->my_res; unsigned long *lengths; MYSQL_ROW row = mysql_fetch_row(res); if (row == NULL) { lua_pushnil(L); /* no more results */ return 1; } lengths = mysql_fetch_lengths(res); if (lua_istable (L, 2)) { const char *opts = luaL_optstring (L, 3, "n"); if (strchr (opts, 'n') != NULL) { /* Copy values to numerical indices */ int i; for (i = 0; i < cur->numcols; i++) { pushvalue (L, row[i], lengths[i]); lua_rawseti (L, 2, i+1); } } if (strchr (opts, 'a') != NULL) { int i; /* Check if colnames exists */ if (cur->colnames == LUA_NOREF) create_colinfo(L, cur); lua_rawgeti (L, LUA_REGISTRYINDEX, cur->colnames);/* Push colnames*/ /* Copy values to alphanumerical indices */ for (i = 0; i < cur->numcols; i++) { lua_rawgeti(L, -1, i+1); /* push the field name */ /* Actually push the value */ pushvalue (L, row[i], lengths[i]); lua_rawset (L, 2); } /* lua_pop(L, 1); Pops colnames table. Not needed */ } lua_pushvalue(L, 2); return 1; /* return table */ } else { int i; luaL_checkstack (L, cur->numcols, LUASQL_PREFIX"too many columns"); for (i = 0; i < cur->numcols; i++) pushvalue (L, row[i], lengths[i]); return cur->numcols; /* return #numcols values */ } }