• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

return table from C++

gugu15

Well-Known Member
Joined
Dec 15, 2014
Messages
99
Reaction score
63
Hello guys!
I'm building a interface with SQLITE3 and Lua on the otclient. But I want return a table with the results of the SELECT for use in Lua.
A table like:
Code:
local selected = db:exec("SELECT * FROM PERSON")
--[
what I wanted:
selected = {{name = "Scot", age = 18, id = 1}, {name = "Louis", age = 21, id = 2}}
]]

I do not know how to do a function in c ++ to return a lua table

This is my code if somebody needs
C++:
//header
#ifndef __SQLAPI_H__
#define __SQLAPI_H__


#include <sqlite3.h>
#include "sqlitedeclaration.h"
#include <framework/luaengine/luaobject.h>
#include <framework/luaengine/luainterface.h>

class DatabaseSqlite : public LuaObject
{

public:
  static int callback(void *data, int argc, char **argv, char **columnName);
  bool exec(const std::string& query);
  bool open(const std::string& name);
  void onExec(std::string column, std::string value, int count, int total);
  void close();

protected:
  sqlite3 *database;
};

#endif

C++:
#include "sqlapi.h"


int DatabaseSqlite::callback(void *p, int argc, char **argv, char **columnName){
  DatabaseSqlite* pthis = (DatabaseSqlite*)(p);

  for(int i = 0; i<argc; i++){
      pthis->onExec(std::string(columnName[i]), std::string(argv[i] ? argv[i] : "NULL"), i+1, argc);
  }
  return 0;
}

void DatabaseSqlite::onExec(std::string column, std::string value, int count, int total){
  callLuaField("onExec", column, value, count, total);
}

bool DatabaseSqlite::exec(const std::string& query){
  char *errorMsg = 0;
  int ret;

  ret = sqlite3_exec(database, query.c_str(), DatabaseSqlite::callback, (void*)this, &errorMsg);
  if (ret == SQLITE_OK){
    return true;
  }else{
    sqlite3_free(errorMsg);
    return false;
  }
}

bool DatabaseSqlite::open(const std::string& name){ // .db name file is the paramter
    int ret;
    ret = sqlite3_open(name.c_str(), &database);
    if (ret == SQLITE_OK){
        return true;
    }else{
        return false;
    }
}


void DatabaseSqlite::close(){
    sqlite3_close(database);
}
Running:
qYrgaCl.png
 
Stackoverflow said:
Here's a quick helper function to push strings to the table:
C++:
void l_pushtablestring(lua_State* L , char* key , char* value) {
    lua_pushstring(L, key);
    lua_pushstring(L, value);
    lua_settable(L, -3);
}
Here is the helper function to create the table and pass it to a function:
C++:
// create a lua function
luaL_loadstring(L, "function fullName(t) print(t.fname,t.lname) end");
lua_pcall(L, 0, 0, 0);

// push the function to the stack
lua_getglobal(L, "fullName");

// create a table in c (it will be at the top of the stack)
lua_newtable(L);
l_pushtablestring(L, "fname", "john");
l_pushtablestring(L, "lname", "stewart");

// call the function with one argument
lua_pcall(L, 1, 0, 0);

You can also do the same for lua_pushnumber, but that's probably obvious.

Kind regards,
Adrik
 
Thank you so much, I'll try make that

Edit:
I got it!
I saw the callLuaField code and lua_pushvalue code and made this code:
C++:
void DatabaseSqlite::onExec(std::vector<std::string> &columns, std::vector<std::string> &values){
  //callLuaField("onExec", columns, values);

  g_lua.pushObject(asLuaObject());
  g_lua.getField("onExec");
  if(!g_lua.isNil()){
    g_lua.insert(-2);
    g_lua.createTable(0, columns.size());
    for(int i = 0; i < columns.size(); i++){
      g_lua.pushString(values[i]);
      g_lua.setField(columns[i]);
    }
    g_lua.signalCall(1+1);
  }else{
    g_lua.pop(2);
  }
}
 
Last edited:
Back
Top