Re: mod_dbd and prepared statements (httpd-2.2.9)

2008-10-19 Thread Tom Donovan

Andrej van der Zee wrote:

* apr_dbd_pvquery is only for string values.
 You must use apr_dbd_pvbquery (with a b) for binary values.

 see:
http://apr.apache.org/docs/apr-util/1.3/group___a_p_r___util___d_b_d.html


I tried both versions, but without success. But that was because I did not
pass pointers to float obviously.


* You don't pass a float value directly - %f takes a *pointer* to a float.


O yes, thank you! That did the trick. I definitely missed this in the
documentation. Is it there?


http://apr.apache.org/docs/apr-util/1.3/group___a_p_r___util___d_b_d.html#g19608fa5d518a5121bee23daacc5c230 
describes the binary datatypes.  Note that they all take pointers, e.g.

  APR_DBD_TYPE_FLOAT  %f : in, out: float*



* It is best not to call ap_dbd_prepare and ap_dbd_acquire directly.
 You should populate your own function pointers at config time using
APR_RETRIEVE_OPTIONAL_FN.

 If APR_RETRIEVE_OPTIONAL_FN gives you NULL pointers, that means that
mod_dbd is not loaded.


I have no problems with calling these function directly. If mod_dbd is not
loaded, Apache simply does not start. But it does impose a restriction on
the order that the modules are loaded.


True, these functions still work when your module links directly to mod_dbd - but 
APR_RETRIEVE_OPTIONAL_FN is worth using for several reasons:

1) You won't need to load modules in a specific order (as you observed)
2) It lets you return meaningful error messages while processing config 
directives, e.g.
if (dbd_acquire_fn == NULL)
return this directive requires mod_dbd;
-tom-


Re: mod_dbd and prepared statements (httpd-2.2.9)

2008-10-19 Thread Andrej van der Zee
Hi Tom,

Thanks a lot for your help! Everything works as expected...

Cheers,
Andrej


Re: mod_dbd and prepared statements (httpd-2.2.9)

2008-10-18 Thread Sorin Manolache
On Sat, Oct 18, 2008 at 15:20, Andrej van der Zee
[EMAIL PROTECTED] wrote:
 Hi,

 I did not find a solution, I just stopped using prepared statements
 altogether. But I tried to isolate the problem just now, and found somehow
 that I cannot use FLOAT in prepared statement somehow (when I tried INT
 columns it even segfaults). Below the source code of a mini-module to
 illustrate this. This is the table I created in MySQL:

 CREATE TABLE simple_table (duration FLOAT NOT NULL) ENGINE=INNODEDB;

 And this is what appears in the MySQL log:

 PrepareINSERT INTO simple_table (duration) VALUES (?)
 ExecuteINSERT INTO simple_table (duration) VALUES ('')

 If you want to reproduce it, dont forget to put this in httpd.conf:
 LoadModule prep_stmt_module   modules/mod_prep_stmt.so
 PrepStmt on

Hello,

I have not reproduced it, it's Saturday :-). I have never worked with
mod_dbd but I might have a clue though, although I am not sure.

You call ap_dbd_prepare from prep_stmt_config_set_prep_stmt_on. This
function is called during the conf parsing phase when there are no
apache children processes. cmd-server refers to the server structure
of the root apache process (the parent of all future apache children).
Then the apr_dbd_pvquery is called from an apache child process, in
which the server structure is not the same as the one you passed to
ap_dbd_prepare. As I have never worked with mod_dbd, I do not know if
this can cause a crash. If your mini-module is inspired from a
text-book or some working example, then my hunch is wrong.

Try the following: Leave cfg-prep_stmt_on = flag but move the
ap_dbd_prepare from the config hook to the child_init hook.

S


Re: mod_dbd and prepared statements (httpd-2.2.9)

2008-10-18 Thread Andrej van der Zee
Hi,

I did not find a solution, I just stopped using prepared statements
altogether. But I tried to isolate the problem just now, and found somehow
that I cannot use FLOAT in prepared statement somehow (when I tried INT
columns it even segfaults). Below the source code of a mini-module to
illustrate this. This is the table I created in MySQL:

CREATE TABLE simple_table (duration FLOAT NOT NULL) ENGINE=INNODEDB;

And this is what appears in the MySQL log:

PrepareINSERT INTO simple_table (duration) VALUES (?)
ExecuteINSERT INTO simple_table (duration) VALUES ('')

If you want to reproduce it, dont forget to put this in httpd.conf:
LoadModule prep_stmt_module   modules/mod_prep_stmt.so
PrepStmt on


-  Complete mini-module -



#include httpd.h
#include http_config.h
#include http_core.h
#include http_log.h
#include http_protocol.h
#include http_connection.h
#include apr_file_info.h
#include apr_file_io.h
#include apr_dbd.h
#include mod_dbd.h

module AP_MODULE_DECLARE_DATA prep_stmt_module;

static int prep_stmt_write(request_rec *r);

typedef struct prep_stmt_config
{
  int prep_stmt_on;
} prep_stmt_config;

static const char * prep_stmt_config_set_prep_stmt_on(cmd_parms *cmd, void
*dummy, int flag)
{
ap_dbd_prepare(cmd-server, INSERT INTO simple_table (duration) VALUES
(%f), insert_row);

  prep_stmt_config *cfg = ap_get_module_config(cmd-server-module_config,
prep_stmt_module);
  cfg-prep_stmt_on = flag;
  return NULL;
}

static int prep_stmt_write(request_rec *r)
{
prep_stmt_config *cfg = ap_get_module_config(r-server-module_config,
prep_stmt_module);
if (!cfg-prep_stmt_on)
return DECLINED;

ap_dbd_t * dbd = ap_dbd_acquire(r);

apr_dbd_prepared_t *prepared = apr_hash_get(dbd-prepared, insert_row,
APR_HASH_KEY_STRING);
if (!prepared) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r-server,
DBD Log: Failed to get prepared statement:
update_request);
return DECLINED;
}

int rv, nrows;
if (rv = apr_dbd_pvquery(dbd-driver, r-pool, dbd-handle, nrows,
prepared, 10.2, NULL)) {
const char *errmsg = apr_dbd_error(dbd-driver, dbd-handle, rv);
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r-server,
DBD Log: Failed to execute prepared statement:
insert_row);
return DECLINED;
}
}

static const command_rec prep_stmt_cmds[] = {
AP_INIT_FLAG(PrepStmt, prep_stmt_config_set_prep_stmt_on,
NULL, RSRC_CONF, Enable DBD Log),
{ NULL }
};

static void prep_stmt_register_hooks(apr_pool_t *p)
{
ap_hook_log_transaction(prep_stmt_write, NULL, NULL, APR_HOOK_MIDDLE);
}

static void * prep_stmt_create_config(apr_pool_t *pool, server_rec *s)
{
  prep_stmt_config *cfg = apr_pcalloc(pool, sizeof(prep_stmt_config));
  return cfg;
}

module AP_MODULE_DECLARE_DATA prep_stmt_module =
{
STANDARD20_MODULE_STUFF,/* stuff that needs to be declared in every
2.0 mod */
NULL,   /* create per-directory config structure*/
NULL,   /* merge per-directory config
structures*/
prep_stmt_create_config,   /* create per-server
config structure   */
NULL,   /* merge per-server config
structures   */
prep_stmt_cmds,   /* command
apr_table_t  */
prep_stmt_register_hooks  /* register
hooks   */
};