Feature #1747 ยป 0042-luasql-Update-to-version-2.7.0.patch
| dependencies/luasql/Version.txt | ||
|---|---|---|
|
Sources here are from luasql git tag 2.6.0
|
||
|
(https://github.com/lunarmodules/luasql/tree/2.6.0)
|
||
|
Some modifications have been done to them, but as of 08-Oct-22
|
||
|
all our modifications have been accepted to the upstream.
|
||
|
Sources here are from luasql git tag 2.7.0
|
||
|
(https://github.com/lunarmodules/luasql/tree/2.7.0)
|
||
|
Some modifications have been done to them:
|
||
|
- Commit 10ed75b36bf909f57b3c1a070dd87669c323cff0 backported
|
||
|
- Fixed compile error on ls_sqlite3.c raw_readparams_table()
|
||
|
Fix has been submitted to upstream.
|
||
|
Only the files needed by freeciv are included here, not entire luasql
|
||
|
source directory hierarchy.
|
||
| dependencies/luasql/src/ls_mysql.c | ||
|---|---|---|
|
luaL_argcheck (L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
|
||
|
if (cur->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring (L, "Cursor is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
cur_nullify (L, cur);
|
||
|
lua_pushboolean (L, 1);
|
||
| ... | ... | |
|
** Create a new Cursor object and push it on top of the stack.
|
||
|
*/
|
||
|
static int create_cursor (lua_State *L, MYSQL *my_conn, int conn, MYSQL_RES *result, int cols) {
|
||
|
cur_data *cur = (cur_data *)lua_newuserdata(L, sizeof(cur_data));
|
||
|
cur_data *cur = (cur_data *)LUASQL_NEWUD(L, sizeof(cur_data));
|
||
|
luasql_setmeta (L, LUASQL_CURSOR_MYSQL);
|
||
|
/* fill in structure */
|
||
| ... | ... | |
|
luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
|
||
|
if (conn->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring (L, "Connection is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
conn_gc (L);
|
||
|
/* Nullify structure fields. */
|
||
|
conn->closed = 1;
|
||
|
luaL_unref (L, LUA_REGISTRYINDEX, conn->env);
|
||
|
mysql_close (conn->my_conn);
|
||
|
lua_pushboolean (L, 1);
|
||
|
return 1;
|
||
|
}
|
||
| ... | ... | |
|
** Create a new Connection object and push it on top of the stack.
|
||
|
*/
|
||
|
static int create_connection (lua_State *L, int env, MYSQL *const my_conn) {
|
||
|
conn_data *conn = (conn_data *)lua_newuserdata(L, sizeof(conn_data));
|
||
|
conn_data *conn = (conn_data *)LUASQL_NEWUD(L, sizeof(conn_data));
|
||
|
luasql_setmeta (L, LUASQL_CONNECTION_MYSQL);
|
||
|
/* fill in structure */
|
||
| ... | ... | |
|
**
|
||
|
*/
|
||
|
static int env_gc (lua_State *L) {
|
||
|
env_data *env= (env_data *)luaL_checkudata (L, 1, LUASQL_ENVIRONMENT_MYSQL); if (env != NULL && !(env->closed))
|
||
|
env_data *env= (env_data *)luaL_checkudata (L, 1, LUASQL_ENVIRONMENT_MYSQL);
|
||
|
if (env != NULL && !(env->closed)) {
|
||
|
env->closed = 1;
|
||
|
mysql_library_end();
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
| ... | ... | |
|
luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected");
|
||
|
if (env->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring(L, "Environment is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
mysql_library_end();
|
||
|
env->closed = 1;
|
||
|
mysql_library_end();
|
||
|
lua_pushboolean (L, 1);
|
||
|
return 1;
|
||
|
}
|
||
| ... | ... | |
|
*/
|
||
|
static void create_metatables (lua_State *L) {
|
||
|
struct luaL_Reg environment_methods[] = {
|
||
|
{"__gc", env_gc},
|
||
|
{"close", env_close},
|
||
|
{"connect", env_connect},
|
||
|
{"__gc", env_gc},
|
||
|
{"__close", env_gc},
|
||
|
{"close", env_close},
|
||
|
{"connect", env_connect},
|
||
|
{NULL, NULL},
|
||
|
};
|
||
|
struct luaL_Reg connection_methods[] = {
|
||
|
{"__gc", conn_gc},
|
||
|
{"close", conn_close},
|
||
|
{"ping", conn_ping},
|
||
|
{"escape", escape_string},
|
||
|
{"execute", conn_execute},
|
||
|
{"commit", conn_commit},
|
||
|
{"rollback", conn_rollback},
|
||
|
{"setautocommit", conn_setautocommit},
|
||
|
{"__gc", conn_gc},
|
||
|
{"__close", conn_gc},
|
||
|
{"close", conn_close},
|
||
|
{"ping", conn_ping},
|
||
|
{"escape", escape_string},
|
||
|
{"execute", conn_execute},
|
||
|
{"commit", conn_commit},
|
||
|
{"rollback", conn_rollback},
|
||
|
{"setautocommit", conn_setautocommit},
|
||
|
{"getlastautoid", conn_getlastautoid},
|
||
|
{NULL, NULL},
|
||
|
};
|
||
|
struct luaL_Reg cursor_methods[] = {
|
||
|
{"__gc", cur_gc},
|
||
|
{"__close", cur_gc},
|
||
|
{"close", cur_close},
|
||
|
{"getcolnames", cur_getcolnames},
|
||
|
{"getcoltypes", cur_getcoltypes},
|
||
| ... | ... | |
|
** Creates an Environment and returns it.
|
||
|
*/
|
||
|
static int create_environment (lua_State *L) {
|
||
|
env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data));
|
||
|
env_data *env = (env_data *)LUASQL_NEWUD(L, sizeof(env_data));
|
||
|
luasql_setmeta (L, LUASQL_ENVIRONMENT_MYSQL);
|
||
|
/* fill in structure */
|
||
| dependencies/luasql/src/ls_odbc.c | ||
|---|---|---|
|
SQLHSTMT hstmt; /* statement handle */
|
||
|
SQLSMALLINT numparams; /* number of input parameters */
|
||
|
int paramtypes; /* reference to param type table */
|
||
|
param_data *params; /* array of parater data */
|
||
|
param_data *params; /* array of parameter data */
|
||
|
} stmt_data;
|
||
|
typedef struct {
|
||
| ... | ... | |
|
case SQL_DATE: case SQL_INTERVAL: case SQL_TIMESTAMP:
|
||
|
case SQL_LONGVARCHAR:
|
||
|
case SQL_WCHAR: case SQL_WVARCHAR: case SQL_WLONGVARCHAR:
|
||
|
#if (ODBCVER >= 0x0350)
|
||
|
case SQL_GUID:
|
||
|
#endif
|
||
|
return "string";
|
||
|
case SQL_BIGINT: case SQL_TINYINT:
|
||
|
case SQL_INTEGER: case SQL_SMALLINT:
|
||
| ... | ... | |
|
** hstmt: statement handle
|
||
|
** i: column number
|
||
|
** Returns:
|
||
|
** 0 if successfull, non-zero otherwise;
|
||
|
** 0 if successful, non-zero otherwise;
|
||
|
*/
|
||
|
static int push_column(lua_State *L, int coltypes, const SQLHSTMT hstmt,
|
||
|
SQLUSMALLINT i) {
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
/*
|
||
|
** Cursor object collector function
|
||
|
*/
|
||
|
static int cur_gc (lua_State *L) {
|
||
|
cur_data *cur = (cur_data *) luaL_checkudata (L, 1, LUASQL_CURSOR_ODBC);
|
||
|
if (cur != NULL && !(cur->closed))
|
||
|
cur_shut(L, cur);
|
||
|
return 0;
|
||
|
}
|
||
|
/*
|
||
|
** Closes a cursor.
|
||
|
*/
|
||
| ... | ... | |
|
if (cur->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring (L, "Cursor is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
if((res = cur_shut(L, cur)) != 0) {
|
||
| ... | ... | |
|
lock_obj(L, stmt_i, stmt);
|
||
|
cur = (cur_data *) lua_newuserdata(L, sizeof(cur_data));
|
||
|
cur = (cur_data *) LUASQL_NEWUD(L, sizeof(cur_data));
|
||
|
luasql_setmeta (L, LUASQL_CURSOR_ODBC);
|
||
|
/* fill in structure */
|
||
| ... | ... | |
|
luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
|
||
|
if (conn->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring (L, "Connection is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
if (conn->lock > 0) {
|
||
|
return luaL_error (L, LUASQL_PREFIX"there are open statements/cursors");
|
||
|
lua_pushboolean (L, 0);
|
||
|
lua_pushstring (L, "There are open cursors");
|
||
|
return 2;
|
||
|
}
|
||
|
/* Decrement connection counter on environment object */
|
||
| ... | ... | |
|
return ret;
|
||
|
}
|
||
|
stmt = (stmt_data *)lua_newuserdata(L, sizeof(stmt_data));
|
||
|
stmt = (stmt_data *)LUASQL_NEWUD(L, sizeof(stmt_data));
|
||
|
memset(stmt, 0, sizeof(stmt_data));
|
||
|
stmt->closed = 0;
|
||
| ... | ... | |
|
*/
|
||
|
static int create_connection (lua_State *L, int o, env_data *env, SQLHDBC hdbc)
|
||
|
{
|
||
|
conn_data *conn = (conn_data *)lua_newuserdata(L, sizeof(conn_data));
|
||
|
conn_data *conn = (conn_data *)LUASQL_NEWUD(L, sizeof(conn_data));
|
||
|
/* set auto commit mode */
|
||
|
SQLRETURN ret = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
|
||
| ... | ... | |
|
** source: data source
|
||
|
** user, pass: data source authentication information
|
||
|
** Lua Returns:
|
||
|
** connection object if successfull
|
||
|
** connection object if successful
|
||
|
** nil and error message otherwise.
|
||
|
*/
|
||
|
static int env_connect (lua_State *L) {
|
||
| ... | ... | |
|
return create_connection (L, 1, env, hdbc);
|
||
|
}
|
||
|
/*
|
||
|
** Environment object collector function
|
||
|
*/
|
||
|
static int env_gc (lua_State *L)
|
||
|
{
|
||
|
SQLRETURN ret;
|
||
|
env_data *env = (env_data *)luaL_checkudata(L, 1, LUASQL_ENVIRONMENT_ODBC);
|
||
|
if (env != NULL && !(env->closed)) {
|
||
|
env->closed = 1;
|
||
|
ret = SQLFreeHandle (hENV, env->henv);
|
||
|
if (error (ret)) {
|
||
|
int ret2 = fail (L, hENV, env->henv);
|
||
|
env->henv = NULL;
|
||
|
return ret2;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
/*
|
||
|
** Closes an environment object
|
||
|
*/
|
||
| ... | ... | |
|
luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected");
|
||
|
if (env->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring (L, "Environment is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
if (env->lock > 0) {
|
||
|
return luaL_error (L, LUASQL_PREFIX"there are open connections");
|
||
|
lua_pushboolean (L, 0);
|
||
|
lua_pushstring (L, "There are open connections");
|
||
|
return 2;
|
||
|
}
|
||
|
env->closed = 1;
|
||
| ... | ... | |
|
*/
|
||
|
static void create_metatables (lua_State *L) {
|
||
|
struct luaL_Reg environment_methods[] = {
|
||
|
{"__gc", env_close}, /* Should this method be changed? */
|
||
|
{"__gc", env_gc},
|
||
|
{"__close", env_gc},
|
||
|
{"close", env_close},
|
||
|
{"connect", env_connect},
|
||
|
{NULL, NULL},
|
||
|
};
|
||
|
struct luaL_Reg connection_methods[] = {
|
||
|
{"__gc", conn_close}, /* Should this method be changed? */
|
||
|
{"__close", conn_close},
|
||
|
{"close", conn_close},
|
||
|
{"prepare", conn_prepare},
|
||
|
{"execute", conn_execute},
|
||
| ... | ... | |
|
};
|
||
|
struct luaL_Reg statement_methods[] = {
|
||
|
{"__gc", stmt_close}, /* Should this method be changed? */
|
||
|
{"__close", stmt_close},
|
||
|
{"close", stmt_close},
|
||
|
{"execute", stmt_execute},
|
||
|
{"getparamtypes", stmt_paramtypes},
|
||
|
{NULL, NULL},
|
||
|
};
|
||
|
struct luaL_Reg cursor_methods[] = {
|
||
|
{"__gc", cur_close}, /* Should this method be changed? */
|
||
|
{"__gc", cur_gc}, /* Should this method be changed? */
|
||
|
{"__close", cur_gc},
|
||
|
{"close", cur_close},
|
||
|
{"fetch", cur_fetch},
|
||
|
{"getcoltypes", cur_coltypes},
|
||
| ... | ... | |
|
return ret;
|
||
|
}
|
||
|
env = (env_data *)lua_newuserdata (L, sizeof (env_data));
|
||
|
env = (env_data *)LUASQL_NEWUD (L, sizeof (env_data));
|
||
|
luasql_setmeta (L, LUASQL_ENVIRONMENT_ODBC);
|
||
|
/* fill in structure */
|
||
|
env->closed = 0;
|
||
| dependencies/luasql/src/ls_postgres.c | ||
|---|---|---|
|
luaL_argcheck (L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
|
||
|
if (cur->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring (L, "cursor is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
cur_nullify (L, cur); /* == cur_gc (L); */
|
||
|
cur_nullify (L, cur);
|
||
|
lua_pushboolean (L, 1);
|
||
|
return 1;
|
||
|
}
|
||
| ... | ... | |
|
** Create a new Cursor object and push it on top of the stack.
|
||
|
*/
|
||
|
static int create_cursor (lua_State *L, int conn, PGresult *result) {
|
||
|
cur_data *cur = (cur_data *)lua_newuserdata(L, sizeof(cur_data));
|
||
|
cur_data *cur = (cur_data *)LUASQL_NEWUD(L, sizeof(cur_data));
|
||
|
luasql_setmeta (L, LUASQL_CURSOR_PG);
|
||
|
/* fill in structure */
|
||
| ... | ... | |
|
luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
|
||
|
if (conn->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring(L, "Connection is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
conn_gc (L);
|
||
|
conn->closed = 1;
|
||
|
luaL_unref (L, LUA_REGISTRYINDEX, conn->env);
|
||
|
PQfinish (conn->pg_conn);
|
||
|
lua_pushboolean (L, 1);
|
||
|
return 1;
|
||
|
}
|
||
| ... | ... | |
|
** Create a new Connection object and push it on top of the stack.
|
||
|
*/
|
||
|
static int create_connection (lua_State *L, int env, PGconn *const pg_conn) {
|
||
|
conn_data *conn = (conn_data *)lua_newuserdata(L, sizeof(conn_data));
|
||
|
conn_data *conn = (conn_data *)LUASQL_NEWUD(L, sizeof(conn_data));
|
||
|
luasql_setmeta (L, LUASQL_CONNECTION_PG);
|
||
|
/* fill in structure */
|
||
| ... | ... | |
|
luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected");
|
||
|
if (env->closed) {
|
||
|
lua_pushboolean (L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring (L, "Environment is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
env_gc (L);
|
||
|
env->closed = 1;
|
||
|
lua_pushboolean (L, 1);
|
||
|
return 1;
|
||
|
}
|
||
| ... | ... | |
|
static void create_metatables (lua_State *L) {
|
||
|
struct luaL_Reg environment_methods[] = {
|
||
|
{"__gc", env_gc},
|
||
|
{"__close", env_gc},
|
||
|
{"close", env_close},
|
||
|
{"connect", env_connect},
|
||
|
{NULL, NULL},
|
||
|
};
|
||
|
struct luaL_Reg connection_methods[] = {
|
||
|
{"__gc", conn_gc},
|
||
|
{"__close", conn_gc},
|
||
|
{"close", conn_close},
|
||
|
{"escape", conn_escape},
|
||
|
{"execute", conn_execute},
|
||
| ... | ... | |
|
};
|
||
|
struct luaL_Reg cursor_methods[] = {
|
||
|
{"__gc", cur_gc},
|
||
|
{"__close", cur_gc},
|
||
|
{"close", cur_close},
|
||
|
{"getcolnames", cur_getcolnames},
|
||
|
{"getcoltypes", cur_getcoltypes},
|
||
| ... | ... | |
|
** Creates an Environment and returns it.
|
||
|
*/
|
||
|
static int create_environment (lua_State *L) {
|
||
|
env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data));
|
||
|
env_data *env = (env_data *)LUASQL_NEWUD(L, sizeof(env_data));
|
||
|
luasql_setmeta (L, LUASQL_ENVIRONMENT_PG);
|
||
|
/* fill in structure */
|
||
| dependencies/luasql/src/ls_sqlite3.c | ||
|---|---|---|
|
/*
|
||
|
** Finalizes the vm
|
||
|
** Return nil + errmsg or nil in case of sucess
|
||
|
** Return nil + errmsg or nil in case of success
|
||
|
*/
|
||
|
static int finalize(lua_State *L, cur_data *cur) {
|
||
|
const char *errmsg;
|
||
| ... | ... | |
|
cur_data *cur = (cur_data *)luaL_checkudata(L, 1, LUASQL_CURSOR_SQLITE);
|
||
|
luaL_argcheck(L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
|
||
|
if (cur->closed) {
|
||
|
lua_pushboolean(L, 0);
|
||
|
return 1;
|
||
|
lua_pushboolean (L, 0);
|
||
|
lua_pushstring(L, "cursor is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
cur->closed = 1;
|
||
|
sqlite3_finalize(cur->sql_vm);
|
||
|
cur_nullify(L, cur);
|
||
|
lua_pushboolean(L, 1);
|
||
| ... | ... | |
|
sqlite3_stmt *sql_vm, int numcols)
|
||
|
{
|
||
|
int i;
|
||
|
cur_data *cur = (cur_data*)lua_newuserdata(L, sizeof(cur_data));
|
||
|
cur_data *cur = (cur_data*)LUASQL_NEWUD(L, sizeof(cur_data));
|
||
|
luasql_setmeta (L, LUASQL_CURSOR_SQLITE);
|
||
|
/* increment cursor count for the connection creating this cursor */
|
||
| ... | ... | |
|
conn_data *conn = (conn_data *)luaL_checkudata(L, 1, LUASQL_CONNECTION_SQLITE);
|
||
|
if (conn != NULL && !(conn->closed))
|
||
|
{
|
||
|
if (conn->cur_counter > 0)
|
||
|
return luaL_error (L, LUASQL_PREFIX"there are open cursors");
|
||
|
/* Nullify structure fields. */
|
||
|
conn->closed = 1;
|
||
|
luaL_unref(L, LUA_REGISTRYINDEX, conn->env);
|
||
| ... | ... | |
|
conn_data *conn = (conn_data *)luaL_checkudata(L, 1, LUASQL_CONNECTION_SQLITE);
|
||
|
luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected");
|
||
|
if (conn->closed)
|
||
|
{
|
||
|
lua_pushboolean(L, 0);
|
||
|
return 1;
|
||
|
}
|
||
|
conn_gc(L);
|
||
|
{
|
||
|
lua_pushboolean(L, 0);
|
||
|
lua_pushstring(L, "Connection is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
if (conn->cur_counter > 0)
|
||
|
{
|
||
|
lua_pushboolean(L, 0);
|
||
|
lua_pushstring(L, "There are open cursors");
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
conn->closed = 1;
|
||
|
|
||
|
lua_pushboolean(L, 1);
|
||
|
return 1;
|
||
|
}
|
||
| ... | ... | |
|
return 1;
|
||
|
}
|
||
|
/*
|
||
|
** Bind one parameter.
|
||
|
** Supported are the data types nil, string, boolean, number.
|
||
|
*/
|
||
|
static int set_param(lua_State *L, sqlite3_stmt *vm, int param_nr, int arg)
|
||
|
{
|
||
|
int tt = lua_type(L, arg);
|
||
|
int rc = 0;
|
||
|
switch (tt) {
|
||
|
case LUA_TNIL:
|
||
|
rc = sqlite3_bind_null(vm, param_nr);
|
||
|
break;
|
||
|
case LUA_TSTRING: {
|
||
|
size_t s_len;
|
||
|
const char *s = lua_tolstring(L, arg, &s_len);
|
||
|
rc = sqlite3_bind_null(vm, param_nr);
|
||
|
rc = sqlite3_bind_text(vm, param_nr, s, s_len, SQLITE_TRANSIENT);
|
||
|
break;
|
||
|
}
|
||
|
case LUA_TBOOLEAN: {
|
||
|
int val = lua_tointeger(L, arg);
|
||
|
rc = sqlite3_bind_int(vm, param_nr, val);
|
||
|
break;
|
||
|
}
|
||
|
case LUA_TNUMBER: {
|
||
|
#if defined(lua_isinteger)
|
||
|
if (lua_isinteger(L, arg)) {
|
||
|
lua_Integer val = lua_tointeger(L, arg);
|
||
|
rc = sqlite3_bind_int64(vm, param_nr, val);
|
||
|
} else {
|
||
|
#endif
|
||
|
double val = lua_tonumber(L, arg);
|
||
|
rc = sqlite3_bind_double(vm, param_nr, val);
|
||
|
#if defined(lua_isinteger)
|
||
|
}
|
||
|
#endif
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
luaL_error(L, LUASQL_PREFIX"unhandled data type %s in parameter binding",
|
||
|
lua_typename(L, tt));
|
||
|
}
|
||
|
return rc;
|
||
|
}
|
||
|
static int raw_readparams_args(lua_State *L, sqlite3_stmt *vm, int arg, int ltop)
|
||
|
{
|
||
|
int param_count, param_nr, rc = 0;
|
||
|
param_count = sqlite3_bind_parameter_count(vm);
|
||
|
if (ltop - arg + 1 != param_count)
|
||
|
luaL_error(L, LUASQL_PREFIX"wrong number of parameters: expected=%d, given=%d",
|
||
|
param_count, ltop - arg + 1);
|
||
|
for (param_nr=1; param_nr <= param_count; param_nr ++, arg ++) {
|
||
|
rc = set_param(L, vm, param_nr, arg);
|
||
|
if (rc)
|
||
|
break;
|
||
|
}
|
||
|
return rc;
|
||
|
}
|
||
|
/*
|
||
|
** Bind all parameters from the given table.
|
||
|
** The table indices can be integers or strings.
|
||
|
** Unbound parameters, or duplicate bindings are not detected.
|
||
|
*/
|
||
|
static int raw_readparams_table(lua_State *L, sqlite3_stmt *vm, int arg)
|
||
|
{
|
||
|
int param_nr, rc = 0;
|
||
|
lua_pushnil(L);
|
||
|
while (lua_next(L, arg)) { // [arg]=table, [-2]=key, [-1]=val
|
||
|
#if defined(lua_isinteger)
|
||
|
int tt =
|
||
|
#endif
|
||
|
lua_type(L, -2);
|
||
|
#if defined(lua_isinteger)
|
||
|
if (tt == LUA_TNUMBER && lua_isinteger(L, -2)) {
|
||
|
param_nr = lua_tointeger(L, -2);
|
||
|
} else {
|
||
|
#endif
|
||
|
const char *param_name = lua_tostring(L, -2);
|
||
|
param_nr = sqlite3_bind_parameter_index(vm, param_name);
|
||
|
if (param_nr == 0)
|
||
|
luaL_error(L, LUASQL_PREFIX"binding to invalid parameter name %s\n",
|
||
|
param_name);
|
||
|
#if defined(lua_isinteger)
|
||
|
}
|
||
|
#endif
|
||
|
set_param(L, vm, param_nr, -1);
|
||
|
lua_pop(L, 1);
|
||
|
}
|
||
|
return rc;
|
||
|
}
|
||
|
/*
|
||
|
** Execute an SQL statement.
|
||
|
** Return a Cursor object if the statement is a query, otherwise
|
||
| ... | ... | |
|
return luasql_faildirect(L, errmsg);
|
||
|
}
|
||
|
/* process first result to retrive query information and type */
|
||
|
/* Bind parameters (if any) */
|
||
|
int ltop = lua_gettop(L);
|
||
|
if (ltop > 2) {
|
||
|
if (ltop == 3 && lua_type(L, 3) == LUA_TTABLE) {
|
||
|
res = raw_readparams_table(L, vm, 3);
|
||
|
} else if (ltop >= 3) {
|
||
|
res = raw_readparams_args(L, vm, 3, ltop);
|
||
|
} else {
|
||
|
luaL_error(L, LUASQL_PREFIX"parameters are either one table or positional");
|
||
|
}
|
||
|
if (res)
|
||
|
return res;
|
||
|
}
|
||
|
/* process first result to retrieve query information and type */
|
||
|
res = sqlite3_step(vm);
|
||
|
numcols = sqlite3_column_count(vm);
|
||
| ... | ... | |
|
*/
|
||
|
static int create_connection(lua_State *L, int env, sqlite3 *sql_conn)
|
||
|
{
|
||
|
conn_data *conn = (conn_data*)lua_newuserdata(L, sizeof(conn_data));
|
||
|
conn_data *conn = (conn_data*)LUASQL_NEWUD(L, sizeof(conn_data));
|
||
|
luasql_setmeta(L, LUASQL_CONNECTION_SQLITE);
|
||
|
/* fill in structure */
|
||
| ... | ... | |
|
luaL_argcheck(L, env != NULL, 1, LUASQL_PREFIX"environment expected");
|
||
|
if (env->closed) {
|
||
|
lua_pushboolean(L, 0);
|
||
|
return 1;
|
||
|
lua_pushstring(L, "env is already closed");
|
||
|
return 2;
|
||
|
}
|
||
|
env_gc(L);
|
||
|
|
||
|
env->closed = 1;
|
||
|
lua_pushboolean(L, 1);
|
||
|
return 1;
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
struct luaL_Reg environment_methods[] = {
|
||
|
{"__gc", env_gc},
|
||
|
{"__close", env_gc},
|
||
|
{"close", env_close},
|
||
|
{"connect", env_connect},
|
||
|
{NULL, NULL},
|
||
|
};
|
||
|
struct luaL_Reg connection_methods[] = {
|
||
|
{"__gc", conn_gc},
|
||
|
{"__close", conn_gc},
|
||
|
{"close", conn_close},
|
||
|
{"escape", conn_escape},
|
||
|
// {"prepare", conn_prepare},
|
||
|
{"execute", conn_execute},
|
||
|
{"commit", conn_commit},
|
||
|
{"rollback", conn_rollback},
|
||
| ... | ... | |
|
};
|
||
|
struct luaL_Reg cursor_methods[] = {
|
||
|
{"__gc", cur_gc},
|
||
|
{"__close", cur_gc},
|
||
|
{"close", cur_close},
|
||
|
{"getcolnames", cur_getcolnames},
|
||
|
{"getcoltypes", cur_getcoltypes},
|
||
| ... | ... | |
|
*/
|
||
|
static int create_environment (lua_State *L)
|
||
|
{
|
||
|
env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data));
|
||
|
env_data *env = (env_data *)LUASQL_NEWUD(L, sizeof(env_data));
|
||
|
luasql_setmeta(L, LUASQL_ENVIRONMENT_SQLITE);
|
||
|
/* fill in structure */
|
||
| dependencies/luasql/src/luasql.c | ||
|---|---|---|
|
*/
|
||
|
LUASQL_API void luasql_set_info (lua_State *L) {
|
||
|
lua_pushliteral (L, "_COPYRIGHT");
|
||
|
lua_pushliteral (L, "Copyright (C) 2003-2020 Kepler Project");
|
||
|
lua_pushliteral (L, "Copyright (C) 2003-2025 Kepler Project");
|
||
|
lua_settable (L, -3);
|
||
|
lua_pushliteral (L, "_DESCRIPTION");
|
||
|
lua_pushliteral (L, "LuaSQL is a simple interface from Lua to a DBMS");
|
||
|
lua_settable (L, -3);
|
||
|
lua_pushliteral (L, "_VERSION");
|
||
|
lua_pushliteral (L, "LuaSQL 2.6.0 (for "LUA_VERSION")");
|
||
|
lua_pushliteral (L, "LuaSQL 2.7.0 (for "LUA_VERSION")");
|
||
|
lua_settable (L, -3);
|
||
|
}
|
||
| dependencies/luasql/src/luasql.h | ||
|---|---|---|
|
#define LUASQL_CONNECTION "Each driver must have a connection metatable"
|
||
|
#define LUASQL_CURSOR "Each driver must have a cursor metatable"
|
||
|
// Macro to handle userdata creation across Lua versions
|
||
|
#if LUA_VERSION_NUM >= 504
|
||
|
#define LUASQL_NEWUD(L, size) lua_newuserdatauv(L, size, 0)
|
||
|
#else
|
||
|
#define LUASQL_NEWUD(L, size) lua_newuserdata(L, size)
|
||
|
#endif
|
||
|
LUASQL_API int luasql_faildirect (lua_State *L, const char *err);
|
||
|
LUASQL_API int luasql_failmsg (lua_State *L, const char *err, const char *m);
|
||
|
LUASQL_API int luasql_createmeta (lua_State *L, const char *name, const luaL_Reg *methods);
|
||