/**
* Licensed to the Apache Software Foundation ( ASF ) under one or more
* contributor license agreements . See the NOTICE file distributed with
* this work for additional information regarding copyright ownership .
* The ASF licenses this file to You under the Apache License , Version 2 . 0
* ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
#include "mod_lua.h"
#include "lua_dbd.h"
APLOG_USE_MODULE(lua);
static APR_OPTIONAL_FN_TYPE(ap_dbd_close) *lua_ap_dbd_close = NULL;
static APR_OPTIONAL_FN_TYPE(ap_dbd_open) *lua_ap_dbd_open = NULL;
static request_rec *ap_lua_check_request_rec(lua_State *L, int index)
{
request_rec *r;
luaL_checkudata(L, index, "Apache2.Request" );
r = lua_unboxpointer(L, index);
return r;
}
static lua_db_handle *lua_get_db_handle(lua_State *L)
{
luaL_checktype(L, 1 , LUA_TTABLE);
lua_rawgeti(L, 1 , 0 );
luaL_checktype(L, -1 , LUA_TUSERDATA);
return (lua_db_handle *) lua_topointer(L, -1 );
}
static lua_db_result_set *lua_get_result_set(lua_State *L)
{
luaL_checktype(L, 1 , LUA_TTABLE);
lua_rawgeti(L, 1 , 0 );
luaL_checktype(L, -1 , LUA_TUSERDATA);
return (lua_db_result_set *) lua_topointer(L, -1 );
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
db : close ( ) : Closes an open database connection .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_close(lua_State *L)
{
/*~~~~~~~~~~~~~~~~~~~~*/
lua_db_handle *db;
apr_status_t rc = 0 ;
/*~~~~~~~~~~~~~~~~~~~~*/
db = lua_get_db_handle(L);
if (db && db->alive) {
if (db->type == LUA_DBTYPE_APR_DBD) {
rc = apr_dbd_close(db->driver, db->handle);
if (db->pool) apr_pool_destroy(db->pool);
}
else {
lua_ap_dbd_close = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_close);
if (lua_ap_dbd_close != NULL)
if (db->dbdhandle) lua_ap_dbd_close(db->server, db->dbdhandle);
}
db->driver = NULL;
db->handle = NULL;
db->alive = 0 ;
db->pool = NULL;
}
lua_settop(L, 0 );
lua_pushnumber(L, rc);
return 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
db : _ _ gc ( ) : Garbage collecting function .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_gc(lua_State *L)
{
/*~~~~~~~~~~~~~~~~*/
lua_db_handle *db;
/*~~~~~~~~~~~~~~~~~~~~*/
db = lua_touserdata(L, 1 );
if (db && db->alive) {
if (db->type == LUA_DBTYPE_APR_DBD) {
apr_dbd_close(db->driver, db->handle);
if (db->pool) apr_pool_destroy(db->pool);
}
else {
lua_ap_dbd_close = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_close);
if (lua_ap_dbd_close != NULL)
if (db->dbdhandle) lua_ap_dbd_close(db->server, db->dbdhandle);
}
db->driver = NULL;
db->handle = NULL;
db->alive = 0 ;
db->pool = NULL;
}
lua_settop(L, 0 );
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
db : active ( ) : Returns true if the connection to the db is still active .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_active(lua_State *L)
{
/*~~~~~~~~~~~~~~~~~~~~*/
lua_db_handle *db = 0 ;
apr_status_t rc = 0 ;
/*~~~~~~~~~~~~~~~~~~~~*/
db = lua_get_db_handle(L);
if (db && db->alive) {
rc = apr_dbd_check_conn(db->driver, db->pool, db->handle);
if (rc == APR_SUCCESS) {
lua_pushboolean(L, 1 );
return 1 ;
}
}
lua_pushboolean(L, 0 );
return 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
db : query ( statement ) : Executes the given database query and returns the
number of rows affected . If an error is encountered , returns nil as the
first parameter and the error message as the second .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_query(lua_State *L)
{
/*~~~~~~~~~~~~~~~~~~~~~~~*/
lua_db_handle *db = 0 ;
apr_status_t rc = 0 ;
int x = 0 ;
const char *statement;
/*~~~~~~~~~~~~~~~~~~~~~~~*/
luaL_checktype(L, 3 , LUA_TSTRING);
statement = lua_tostring(L, 3 );
db = lua_get_db_handle(L);
if (db && db->alive)
rc = apr_dbd_query(db->driver, db->handle, &x, statement);
else {
rc = 0 ;
x = -1 ;
}
if (rc == APR_SUCCESS)
lua_pushnumber(L, x);
else {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
const char *err = apr_dbd_error(db->driver, db->handle, rc);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_pushnil(L);
if (err) {
lua_pushstring(L, err);
return 2 ;
}
}
return 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
db : escape ( string ) : Escapes a string for safe use in the given database type .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_escape(lua_State *L)
{
/*~~~~~~~~~~~~~~~~~~~~~*/
lua_db_handle *db = 0 ;
const char *statement;
const char *escaped = 0 ;
request_rec *r;
/*~~~~~~~~~~~~~~~~~~~~~*/
r = ap_lua_check_request_rec(L, 2 );
if (r) {
luaL_checktype(L, 3 , LUA_TSTRING);
statement = lua_tostring(L, 3 );
db = lua_get_db_handle(L);
if (db && db->alive) {
apr_dbd_init(r->pool);
escaped = apr_dbd_escape(db->driver, r->pool, statement,
db->handle);
if (escaped) {
lua_pushstring(L, escaped);
return 1 ;
}
}
else {
lua_pushnil(L);
}
return (1 );
}
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
resultset ( N ) : Fetches one or more rows from a result set .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_get_row(lua_State *L)
{
int row_no,x,alpha = 0 ;
const char *entry, *rowname;
apr_dbd_row_t *row = 0 ;
lua_db_result_set *res = lua_get_result_set(L);
row_no = luaL_optinteger(L, 2 , 0 );
if (lua_isboolean(L, 3 )) {
alpha = lua_toboolean(L, 3 );
}
lua_settop(L,0 );
/* Fetch all rows at once? */
if (row_no == 0 ) {
row_no = 1 ;
lua_newtable(L);
while (apr_dbd_get_row(res->driver, res->pool, res->results,
&row, -1 ) != -1 )
{
lua_pushinteger(L, row_no);
lua_newtable(L);
for (x = 0 ; x < res->cols; x++) {
entry = apr_dbd_get_entry(res->driver, row, x);
if (entry) {
if (alpha == 1 ) {
rowname = apr_dbd_get_name(res->driver,
res->results, x);
lua_pushstring(L, rowname ? rowname : "(oob)" );
}
else {
lua_pushinteger(L, x + 1 );
}
lua_pushstring(L, entry);
lua_rawset(L, -3 );
}
}
lua_rawset(L, -3 );
row_no++;
}
return 1 ;
}
/* Just fetch a single row */
if (apr_dbd_get_row(res->driver, res->pool, res->results,
&row, row_no) != -1 )
{
lua_newtable(L);
for (x = 0 ; x < res->cols; x++) {
entry = apr_dbd_get_entry(res->driver, row, x);
if (entry) {
if (alpha == 1 ) {
rowname = apr_dbd_get_name(res->driver,
res->results, x);
lua_pushstring(L, rowname ? rowname : "(oob)" );
}
else {
lua_pushinteger(L, x + 1 );
}
lua_pushstring(L, entry);
lua_rawset(L, -3 );
}
}
return 1 ;
}
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
db : select ( statement ) : Queries the database for the given statement and
returns the rows / columns found as a table . If an error is encountered ,
returns nil as the first parameter and the error message as the second .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_select(lua_State *L)
{
/*~~~~~~~~~~~~~~~~~~~~~~~*/
lua_db_handle *db = 0 ;
apr_status_t rc = 0 ;
const char *statement;
request_rec *r;
/*~~~~~~~~~~~~~~~~~~~~~~~*/
r = ap_lua_check_request_rec(L, 2 );
if (r) {
luaL_checktype(L, 3 , LUA_TSTRING);
statement = lua_tostring(L, 3 );
db = lua_get_db_handle(L);
if (db && db->alive) {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int cols;
apr_dbd_results_t *results = 0 ;
lua_db_result_set* resultset = NULL;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
rc = apr_dbd_select(db->driver, db->pool, db->handle,
&results, statement, 0 );
if (rc == APR_SUCCESS) {
cols = apr_dbd_num_cols(db->driver, results);
if (cols > 0 ) {
lua_newtable(L);
resultset = lua_newuserdata(L, sizeof (lua_db_result_set));
resultset->cols = cols;
resultset->driver = db->driver;
resultset->pool = db->pool;
resultset->rows = apr_dbd_num_tuples(db->driver, results);
resultset->results = results;
luaL_newmetatable(L, "lua_apr.dbselect" );
lua_pushliteral(L, "__call" );
lua_pushcfunction(L, lua_db_get_row);
lua_rawset(L, -3 );
lua_setmetatable(L, -3 );
lua_rawseti(L, -2 , 0 );
return 1 ;
}
return 0 ;
}
else {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
const char *err = apr_dbd_error(db->driver, db->handle, rc);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_pushnil(L);
if (err) {
lua_pushstring(L, err);
return 2 ;
}
}
}
lua_pushboolean(L, 0 );
return 1 ;
}
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
statement : select ( var1 , var2 , var3 . . . ) : Injects variables into a prepared
statement and returns the number of rows matching the query .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_prepared_select(lua_State *L)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_db_prepared_statement *st = 0 ;
apr_status_t rc = 0 ;
const char **vars;
int x, have;
/*~~~~~~~~~~~~~~~~~~~~~~~*/
/* Fetch the prepared statement and the vars passed */
luaL_checktype(L, 1 , LUA_TTABLE);
lua_rawgeti(L, 1 , 0 );
luaL_checktype(L, -1 , LUA_TUSERDATA);
st = (lua_db_prepared_statement*) lua_topointer(L, -1 );
/* Check if we got enough variables passed on to us.
* This, of course, only works for prepared statements made through lua. */
have = lua_gettop(L) - 2 ;
if (st->variables != -1 && have < st->variables ) {
lua_pushboolean(L, 0 );
lua_pushfstring(L,
"Error in executing prepared statement: Expected %d arguments, got %d." ,
st->variables, have);
return 2 ;
}
vars = apr_pcalloc(st->db->pool, have*sizeof (char *));
for (x = 0 ; x < have; x++) {
vars[x] = lua_tostring(L, x + 2 );
}
/* Fire off the query */
if (st->db && st->db->alive) {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int cols;
apr_dbd_results_t *results = 0 ;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
rc = apr_dbd_pselect(st->db->driver, st->db->pool, st->db->handle,
&results, st->statement, 0 , have, vars);
if (rc == APR_SUCCESS) {
/*~~~~~~~~~~~~~~~~~~~~~*/
lua_db_result_set *resultset;
/*~~~~~~~~~~~~~~~~~~~~~*/
cols = apr_dbd_num_cols(st->db->driver, results);
lua_newtable(L);
resultset = lua_newuserdata(L, sizeof (lua_db_result_set));
resultset->cols = cols;
resultset->driver = st->db->driver;
resultset->pool = st->db->pool;
resultset->rows = apr_dbd_num_tuples(st->db->driver, results);
resultset->results = results;
luaL_newmetatable(L, "lua_apr.dbselect" );
lua_pushliteral(L, "__call" );
lua_pushcfunction(L, lua_db_get_row);
lua_rawset(L, -3 );
lua_setmetatable(L, -3 );
lua_rawseti(L, -2 , 0 );
return 1 ;
}
else {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
const char *err = apr_dbd_error(st->db->driver, st->db->handle, rc);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_pushnil(L);
if (err) {
lua_pushstring(L, err);
return 2 ;
}
return 1 ;
}
}
lua_pushboolean(L, 0 );
lua_pushliteral(L,
"Database connection seems to be closed, please reacquire it." );
return (2 );
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
statement : query ( var1 , var2 , var3 . . . ) : Injects variables into a prepared
statement and returns the number of rows affected .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_prepared_query(lua_State *L)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_db_prepared_statement *st = 0 ;
apr_status_t rc = 0 ;
const char **vars;
int x, have;
/*~~~~~~~~~~~~~~~~~~~~~~~*/
/* Fetch the prepared statement and the vars passed */
luaL_checktype(L, 1 , LUA_TTABLE);
lua_rawgeti(L, 1 , 0 );
luaL_checktype(L, -1 , LUA_TUSERDATA);
st = (lua_db_prepared_statement*) lua_topointer(L, -1 );
/* Check if we got enough variables passed on to us.
* This, of course, only works for prepared statements made through lua. */
have = lua_gettop(L) - 2 ;
if (st->variables != -1 && have < st->variables ) {
lua_pushboolean(L, 0 );
lua_pushfstring(L,
"Error in executing prepared statement: Expected %d arguments, got %d." ,
st->variables, have);
return 2 ;
}
vars = apr_pcalloc(st->db->pool, have*sizeof (char *));
for (x = 0 ; x < have; x++) {
vars[x] = lua_tostring(L, x + 2 );
}
/* Fire off the query */
if (st->db && st->db->alive) {
/*~~~~~~~~~~~~~~*/
int affected = 0 ;
/*~~~~~~~~~~~~~~*/
rc = apr_dbd_pquery(st->db->driver, st->db->pool, st->db->handle,
&affected, st->statement, have, vars);
if (rc == APR_SUCCESS) {
lua_pushinteger(L, affected);
return 1 ;
}
else {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
const char *err = apr_dbd_error(st->db->driver, st->db->handle, rc);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_pushnil(L);
if (err) {
lua_pushstring(L, err);
return 2 ;
}
return 1 ;
}
}
lua_pushboolean(L, 0 );
lua_pushliteral(L,
"Database connection seems to be closed, please reacquire it." );
return (2 );
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
db : prepare ( statement ) : Prepares a statement for later query / select .
Returns a table with a : query and : select function , same as the db funcs .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_prepare(lua_State* L)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_db_handle *db = 0 ;
apr_status_t rc = 0 ;
const char *statement, *at;
request_rec *r;
lua_db_prepared_statement* st;
int need = 0 ;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
r = ap_lua_check_request_rec(L, 2 );
if (r) {
apr_dbd_prepared_t *pstatement = NULL;
luaL_checktype(L, 3 , LUA_TSTRING);
statement = lua_tostring(L, 3 );
/* Count number of variables in statement */
at = ap_strchr_c(statement,'%' );
while (at != NULL) {
if (at[1 ] == '%' ) {
at++;
}
else {
need++;
}
at = ap_strchr_c(at+1 ,'%' );
}
db = lua_get_db_handle(L);
rc = apr_dbd_prepare(db->driver, r->pool, db->handle, statement,
NULL, &pstatement);
if (rc != APR_SUCCESS) {
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
const char *err = apr_dbd_error(db->driver, db->handle, rc);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_pushnil(L);
if (err) {
lua_pushstring(L, err);
return 2 ;
}
return 1 ;
}
/* Push the prepared statement table */
lua_newtable(L);
st = lua_newuserdata(L, sizeof (lua_db_prepared_statement));
st->statement = pstatement;
st->variables = need;
st->db = db;
lua_pushliteral(L, "select" );
lua_pushcfunction(L, lua_db_prepared_select);
lua_rawset(L, -4 );
lua_pushliteral(L, "query" );
lua_pushcfunction(L, lua_db_prepared_query);
lua_rawset(L, -4 );
lua_rawseti(L, -2 , 0 );
return 1 ;
}
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
db : prepared ( statement ) : Fetches a prepared statement made through
DBDPrepareSQL .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_prepared(lua_State* L)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lua_db_handle *db = 0 ;
const char *tag;
request_rec *r;
lua_db_prepared_statement* st;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~*/
r = ap_lua_check_request_rec(L, 2 );
if (r) {
apr_dbd_prepared_t *pstatement = NULL;
db = lua_get_db_handle(L);
luaL_checktype(L, 3 , LUA_TSTRING);
tag = lua_tostring(L, 3 );
/* Look for the statement */
pstatement = apr_hash_get(db->dbdhandle->prepared, tag,
APR_HASH_KEY_STRING);
if (pstatement == NULL) {
lua_pushnil(L);
lua_pushfstring(L,
"Could not find any prepared statement called %s!" , tag);
return 2 ;
}
/* Push the prepared statement table */
lua_newtable(L);
st = lua_newuserdata(L, sizeof (lua_db_prepared_statement));
st->statement = pstatement;
st->variables = -1 ; /* we don't know :( */
st->db = db;
lua_pushliteral(L, "select" );
lua_pushcfunction(L, lua_db_prepared_select);
lua_rawset(L, -4 );
lua_pushliteral(L, "query" );
lua_pushcfunction(L, lua_db_prepared_query);
lua_rawset(L, -4 );
lua_rawseti(L, -2 , 0 );
return 1 ;
}
return 0 ;
}
/* lua_push_db_handle: Creates a database table object with database functions
and a userdata at index 0 , which will call lua_dbgc when garbage collected .
*/
static lua_db_handle* lua_push_db_handle(lua_State *L, request_rec* r, int type,
apr_pool_t* pool)
{
lua_db_handle* db;
lua_newtable(L);
db = lua_newuserdata(L, sizeof (lua_db_handle));
db->alive = 1 ;
db->pool = pool;
db->type = type;
db->dbdhandle = 0 ;
db->server = r->server;
luaL_newmetatable(L, "lua_apr.dbacquire" );
lua_pushliteral(L, "__gc" );
lua_pushcfunction(L, lua_db_gc);
lua_rawset(L, -3 );
lua_setmetatable(L, -2 );
lua_rawseti(L, -2 , 0 );
lua_pushliteral(L, "escape" );
lua_pushcfunction(L, lua_db_escape);
lua_rawset(L, -3 );
lua_pushliteral(L, "close" );
lua_pushcfunction(L, lua_db_close);
lua_rawset(L, -3 );
lua_pushliteral(L, "select" );
lua_pushcfunction(L, lua_db_select);
lua_rawset(L, -3 );
lua_pushliteral(L, "query" );
lua_pushcfunction(L, lua_db_query);
lua_rawset(L, -3 );
lua_pushliteral(L, "active" );
lua_pushcfunction(L, lua_db_active);
lua_rawset(L, -3 );
lua_pushliteral(L, "prepare" );
lua_pushcfunction(L, lua_db_prepare);
lua_rawset(L, -3 );
lua_pushliteral(L, "prepared" );
lua_pushcfunction(L, lua_db_prepared);
lua_rawset(L, -3 );
return db;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
dbacquire ( dbType , dbString ) : Opens a new connection to a database of type
_ dbType_ and with the connection parameters _ dbString_ . If successful ,
returns a table with functions for using the database handle . If an error
occurs , returns nil as the first parameter and the error message as the
second . See the APR_DBD for a list of database types and connection strings
supported .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int lua_db_acquire(lua_State *L)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
const char *type;
const char *arguments;
const char *error = 0 ;
request_rec *r;
lua_db_handle *db = 0 ;
apr_status_t rc = 0 ;
ap_dbd_t *dbdhandle = NULL;
apr_pool_t *pool = NULL;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
r = ap_lua_check_request_rec(L, 1 );
if (r) {
type = luaL_optstring(L, 2 , "mod_dbd" ); /* Defaults to mod_dbd */
if (!strcmp(type, "mod_dbd" )) {
lua_settop(L, 0 );
lua_ap_dbd_open = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_open);
if (lua_ap_dbd_open)
dbdhandle = (ap_dbd_t *) lua_ap_dbd_open(
r->server->process->pool, r->server);
if (dbdhandle) {
db = lua_push_db_handle(L, r, LUA_DBTYPE_MOD_DBD, dbdhandle->pool);
db->driver = dbdhandle->driver;
db->handle = dbdhandle->handle;
db->dbdhandle = dbdhandle;
return 1 ;
}
else {
lua_pushnil(L);
if ( lua_ap_dbd_open == NULL )
lua_pushliteral(L,
"mod_dbd doesn't seem to have been loaded." );
else
lua_pushliteral(
L,
"Could not acquire connection from mod_dbd. If your database is running, this may indicate a permission problem." );
return 2 ;
}
}
else {
rc = apr_pool_create(&pool, NULL);
if (rc != APR_SUCCESS) {
lua_pushnil(L);
lua_pushliteral(L, "Could not allocate memory for database!" );
return 2 ;
}
apr_pool_tag(pool, "lua_dbd_pool" );
apr_dbd_init(pool);
dbdhandle = apr_pcalloc(pool, sizeof (ap_dbd_t));
rc = apr_dbd_get_driver(pool, type, &dbdhandle->driver);
if (rc == APR_SUCCESS) {
luaL_checktype(L, 3 , LUA_TSTRING);
arguments = lua_tostring(L, 3 );
lua_settop(L, 0 );
if (*arguments) {
rc = apr_dbd_open_ex(dbdhandle->driver, pool,
arguments, &dbdhandle->handle, &error);
if (rc == APR_SUCCESS) {
db = lua_push_db_handle(L, r, LUA_DBTYPE_APR_DBD, pool);
db->driver = dbdhandle->driver;
db->handle = dbdhandle->handle;
db->dbdhandle = dbdhandle;
return 1 ;
}
else {
lua_pushnil(L);
if (error) {
lua_pushstring(L, error);
return 2 ;
}
return 1 ;
}
}
lua_pushnil(L);
lua_pushliteral(L,
"No database connection string was specified." );
apr_pool_destroy(pool);
return (2 );
}
else {
lua_pushnil(L);
if (APR_STATUS_IS_ENOTIMPL(rc)) {
lua_pushfstring(L,
"driver for %s not available" , type);
}
else if (APR_STATUS_IS_EDSOOPEN(rc)) {
lua_pushfstring(L,
"can't find driver for %s" , type);
}
else if (APR_STATUS_IS_ESYMNOTFOUND(rc)) {
lua_pushfstring(L,
"driver for %s is invalid or corrupted" ,
type);
}
else {
lua_pushliteral(L,
"mod_lua not compatible with APR in get_driver" );
}
lua_pushinteger(L, rc);
apr_pool_destroy(pool);
return 3 ;
}
}
lua_pushnil(L);
return 1 ;
}
return 0 ;
}
Messung V0.5 in Prozent C=92 H=95 G=93
¤ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland