Exemple #1
0
int mod_okioki_view_execute(request_rec *http_request, mod_okioki_dir_config *cfg, view_t *view, apr_hash_t *arguments, const apr_dbd_driver_t **db_driver, apr_dbd_results_t **db_result, char **error)
{
    apr_pool_t         *pool = http_request->pool;
    ap_dbd_t           *db_conn;
    apr_dbd_prepared_t *db_statement;
    char               *arg;
    int                argc = view->nr_sql_params;
    char               *argv[argc + 1];
    off_t              i;
    int                ret;

    // Copy the pointers parameters in the right order for the SQL statement.
    for (i = 0; i < argc; i++) {
        ASSERT_NOT_NULL(
            arg = (char *)apr_hash_get(arguments, view->sql_params[i], view->sql_params_len[i]),
            HTTP_INTERNAL_SERVER_ERROR, "Could not find parameter '%s' in request.", view->sql_params[i]
        )

        argv[i] = arg;
    }
    argv[i] = NULL;

    // Retrieve a database connection from the resource pool.
    ASSERT_NOT_NULL(
        db_conn = ap_dbd_acquire(http_request),
        HTTP_INTERNAL_SERVER_ERROR, "Can not get database connection."
    )
    *db_driver = db_conn->driver;

    // Get the prepared statement.
    ASSERT_NOT_NULL(
        db_statement = apr_hash_get((db_conn)->prepared, view->sql, view->sql_len),
        HTTP_INTERNAL_SERVER_ERROR, "Can not find '%s'", view->sql
    )

    // Execute the statement.
    *db_result = NULL;

    // Execute a select statement. We allow random access here as it allows easier configuration because the number
    // of columns and the name of the columns are known when random access is enabled.
    // Also because we use buckets and brigades everything is done in memory already, so streaming data would not
    // have worked anyway.
    ASSERT_APR_SUCCESS(
        ret = apr_dbd_pselect(db_conn->driver, db_conn->pool, db_conn->handle, db_result, db_statement, 1, argc, (const char **)argv),
        HTTP_BAD_GATEWAY, "%s", apr_dbd_error(db_conn->driver, db_conn->handle, ret)
    )

    ASSERT_NOT_NULL(
        *db_result,
        HTTP_BAD_GATEWAY, "Result was not set by apr_dbd_pselect."
    )
    return HTTP_OK;
}
Exemple #2
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 prepped 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);
}
static int authz_dbd_query(request_rec *r, authz_dbd_cfg *cfg,
			   const apr_array_header_t *query_parameters,
			   apr_array_header_t *query_result_rows)
{
    /* SELECT group FROM authz WHERE col = %s, col = %s, ... */
    int rv;
    const char *message;
    ap_dbd_t *dbd = dbd_handle(r);
    apr_dbd_prepared_t *query;
    apr_dbd_results_t *res = NULL;
    apr_dbd_row_t *row = NULL;
    const char **query_result_row;

    if (cfg->query == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
                      "No query configured for dbd-query!");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    if (dbd == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
                      "No db handle available for dbd-query! Check your database access");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING);
    if (query == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
                      "Error retrieving query for dbd-query!");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    rv = apr_dbd_pselect(dbd->driver, r->pool, dbd->handle, &res,
			 query, 0, 
			 query_parameters->nelts,
			 (const char **)query_parameters->elts);

    if (rv == 0) {
        for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
             rv != -1;
             rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
            if (rv == 0) {
                query_result_row = apr_array_push(query_result_rows);
                *query_result_row = apr_dbd_get_entry(dbd->driver, row, 0);
            }
            else {
                message = apr_dbd_error(dbd->driver, dbd->handle, rv);
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
                              "authz_dbd dbd_query in get_row; query for user=%s [%s]",
                              r->user, message?message:noerror);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
        }
    }
    else {
        message = apr_dbd_error(dbd->driver, dbd->handle, rv);
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
                      "authz_dbd, in dbd_query query for %s [%s]",
                      r->user, message?message:noerror);
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    return OK;
}