From a5459ee55432775e47d4ee1e1d126aa88c373d6b Mon Sep 17 00:00:00 2001 From: Edward Rudd Date: Wed, 19 Mar 2008 05:01:05 +0000 Subject: updated API to support mod_log_sql_dbd APR DBD driver. --- .project | 60 +++++++++++------------- Makefile.in | 28 +++++++++-- TODO.in | 3 +- configure.ac | 12 +++++ mod_log_sql.c | 26 +++++------ mod_log_sql.h | 4 +- mod_log_sql_dbd.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mod_log_sql_dbi.c | 2 +- mod_log_sql_mysql.c | 2 +- 9 files changed, 211 insertions(+), 58 deletions(-) create mode 100644 mod_log_sql_dbd.c diff --git a/.project b/.project index db2ba74..9af17e9 100644 --- a/.project +++ b/.project @@ -3,19 +3,16 @@ mod_log_sql + includes - org.eclipse.cdt.make.core.makeBuilder + org.eclipse.cdt.managedbuilder.core.genmakebuilder clean,full,incremental, - org.eclipse.cdt.make.core.build.arguments - - - - org.eclipse.cdt.core.errorOutputParser - org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.VCErrorParser; + org.eclipse.cdt.make.core.fullBuildTarget + all org.eclipse.cdt.make.core.enableAutoBuild @@ -26,47 +23,47 @@ - org.eclipse.cdt.make.core.enableFullBuild - true + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/mod_log_sql/Linux GCC} - org.eclipse.cdt.make.core.build.target.inc - all + ?name? + - org.eclipse.cdt.make.core.enabledIncrementalBuild + org.eclipse.cdt.make.core.enableFullBuild true - org.eclipse.cdt.make.core.build.location - + org.eclipse.cdt.make.core.enableCleanBuild + true - org.eclipse.cdt.make.core.build.target.clean + org.eclipse.cdt.make.core.cleanBuildTarget clean - - org.eclipse.cdt.make.core.build.command - sshmake - - - org.eclipse.cdt.make.core.enableCleanBuild - true - org.eclipse.cdt.make.core.append_environment true - org.eclipse.cdt.make.core.build.target.full - clean all + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings org.eclipse.cdt.make.core.useDefaultBuildCmd false - org.eclipse.cdt.make.core.build.target.auto + org.eclipse.cdt.make.core.buildArguments + ${project_name} make -k + + + org.eclipse.cdt.make.core.buildCommand + ${HOME}/bin/sshmake + + + org.eclipse.cdt.make.core.autoBuildTarget all @@ -76,19 +73,14 @@ - org.eclipse.cdt.make.core.ScannerConfigBuilder - - - - - de.loskutov.FileSync.FSBuilder + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder org.eclipse.cdt.core.cnature - org.eclipse.cdt.make.core.makeNature - org.eclipse.cdt.make.core.ScannerConfigNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature diff --git a/Makefile.in b/Makefile.in index 2865d5f..2647d2e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -77,6 +77,16 @@ ifeq (@WANT_DBI_MOD@,1) TARGETS += $(dbiTARGET) endif +dbdSOURCES = @PACKAGE_NAME@_dbd.c +dbdTARGET = @PACKAGE_NAME@_dbd@APXS_EXTENSION@ +dbdLDADD = +dbdCFLAGS = +dbdNAME = log_sql_dbd + +ifeq (@WANT_DBD_MOD@,1) +TARGETS += $(dbdTARGET) +endif + #Don't modify anything below here PROVIDERS_SUBDIRS = @subdirs@ @@ -85,13 +95,13 @@ srcdir = @abs_srcdir@ builddir = @abs_builddir@ OBJ = $(coreSOURCES:.c=.o) $(logioSOURCES:.c=.o) $(sslSOURCES:.c=.o) $(mysqlSOURCES:.c=.o) \ - $(dbiSOURCES:.c=.o) $(pgsqlSOURCES:.c=.o) + $(dbiSOURCES:.c=.o) $(pgsqlSOURCES:.c=.o) $(dbdSOURCES:.c=.o) LO = $(coreSOURCES:.c=.lo) $(logioSOURCES:.c=.lo) $(sslSOURCES:.c=.lo) $(mysqlSOURCES:.c=.lo) \ - $(dbiSOURCES:.c=.lo) $(pgsqlSOURCES:.c=.lo) + $(dbiSOURCES:.c=.lo) $(pgsqlSOURCES:.c=.lo) $(dbdSOURCES:.c=.lo) SLO = $(coreSOURCES:.c=.slo) $(logioSOURCES:.c=.slo) $(sslSOURCES:.c=.slo) $(mysqlSOURCES:.c=.slo) \ - $(dbiSOURCES:.c=.slo) $(pgsqlSOURCES:.c=.slo) + $(dbiSOURCES:.c=.slo) $(pgsqlSOURCES:.c=.slo) $(dbdSOURCES:.c=.slo) STD_DIST = install-sh \ config.sub \ @@ -104,7 +114,7 @@ STD_DIST = install-sh \ config.h.in DISTFILES = $(STD_DIST) $(EXTRA_DIST) $(coreSOURCES) $(HEADERS) \ - $(sslSOURCES) $(logioSOURCES) $(mysqlSOURCES) $(pgsqlSOURCES) $(dbiSOURCES) + $(sslSOURCES) $(logioSOURCES) $(mysqlSOURCES) $(pgsqlSOURCES) $(dbiSOURCES) $(dbdSOURCES) all: $(TARGETS) all-subdirs @@ -150,6 +160,11 @@ $(dbiTARGET): $(dbiSOURCES) $(HEADERS) @@APXS_BIN@ -c -o $(dbiTARGET) $(dbiCFLAGS) $(CFLAGS) \ @DEFS@ @AP_DEFS@ $(dbiLDADD) $(dbiSOURCES) +$(dbdTARGET): $(dbdSOURCES) $(HEADERS) + @@APXS_BIN@ -c -o $(dbdTARGET) $(dbdCFLAGS) $(CFLAGS) \ + @DEFS@ @AP_DEFS@ $(dbdLDADD) $(dbdSOURCES) + + install: $(TARGETS) install-subdirs @@APXS_BIN@ -n $(coreNAME) -i $(coreTARGET); \ if test @WANT_MYSQL_MOD@ -eq 1; then \ @@ -160,6 +175,9 @@ install: $(TARGETS) install-subdirs fi; \ if test @WANT_DBI_MOD@ -eq 1; then \ @APXS_BIN@ -n $(dbiNAME) -i $(dbiTARGET); \ + fi; \ + if test @WANT_DBD_MOD@ -eq 1; then \ + @APXS_BIN@ -n $(dbdNAME) -i $(dbdTARGET); \ fi; \ if test @WANT_SSL_MOD@ -eq 1; then \ @APXS_BIN@ -n $(sslNAME) -i $(sslTARGET); \ @@ -241,7 +259,7 @@ stamp-h: config.h.in config.status ./config.status $(srcdir)/configure: configure.ac aclocal.m4 - cd $(srcdir) && autoconf-2.53 + cd $(srcdir) && autoconf Makefile: Makefile.in config.status ./config.status diff --git a/TODO.in b/TODO.in index 0d871f6..bf6b624 100644 --- a/TODO.in +++ b/TODO.in @@ -1,5 +1,5 @@ TODO: -* verify a db driver has been loaded. +* restructure to be more friendly toward DBD pooling * validate table names before trying to log them. * write alternate DB driver (PostgreSQL, libDBI, mod_*_pool) * look at forcing table name to ServerName instead of on of the names in @@ -7,7 +7,6 @@ TODO: * LogSQLRotateLogs directive with daily/monthly/weekly/etc. * socket-based middleman daemon with configurable conns, or connect/disconnect. * DBI connection pooling. -* apr_dbd backend driver * ignore by cookie * investigate thread safety issues Use libmysqlclient_r for threaded MPM (or always?) diff --git a/configure.ac b/configure.ac index 8a348dc..55de120 100644 --- a/configure.ac +++ b/configure.ac @@ -26,8 +26,17 @@ if test $AP_VERSION = "2.0"; then else WANT_LOGIO_MOD=0 fi + AC_SUBST(WANT_LOGIO_MOD) +if test $AP_VERSION = "2.0"; then + WANT_DBD_MOD=1 +else + WANT_DBD_MOD=0 +fi + +AC_SUBST(WANT_DBD_MOD) + CHECK_MYSQL( WANT_MYSQL_MOD=1, AC_MSG_WARN([*** Mysql client libraries not found!]) @@ -105,6 +114,9 @@ fi if test $WANT_DBI_MOD -eq 1; then AC_MSG_RESULT([ libDBI Driver]) fi +if test $WANT_DBD_MOD -eq 1; then + AC_MSG_RESULT([ APR DBD Driver]) +fi if test $OOO_MAINTAIN -eq 1; then AC_MSG_RESULT([Maintainer mode is on. -Werror is in effect]) fi diff --git a/mod_log_sql.c b/mod_log_sql.c index b6a5c83..d319e97 100644 --- a/mod_log_sql.c +++ b/mod_log_sql.c @@ -1201,7 +1201,7 @@ static int log_sql_transaction(request_rec *orig) fields = apr_pstrcat(r->pool, fields, (showcomma ? "," : ""), item->sql_field_name, NULL); values = apr_pstrcat(r->pool, values, (showcomma ? "," : ""), - global_config.driver->escape(formatted_item, r->pool,&global_config.db), NULL); + global_config.driver->escape(r, formatted_item, r->pool,&global_config.db), NULL); showcomma = 1; } @@ -1216,11 +1216,11 @@ static int log_sql_transaction(request_rec *orig) itemsets = apr_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "(", - global_config.driver->escape(unique_id, r->pool, &global_config.db), + global_config.driver->escape(r, unique_id, r->pool, &global_config.db), ",", - global_config.driver->escape(*ptrptr, r->pool,&global_config.db), + global_config.driver->escape(r, *ptrptr, r->pool,&global_config.db), ",", - global_config.driver->escape(theitem, r->pool,&global_config.db), + global_config.driver->escape(r, theitem, r->pool,&global_config.db), ")", NULL); i++; @@ -1244,11 +1244,11 @@ static int log_sql_transaction(request_rec *orig) itemsets = apr_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "(", - global_config.driver->escape(unique_id, r->pool, &global_config.db), + global_config.driver->escape(r,unique_id, r->pool, &global_config.db), ",", - global_config.driver->escape(*ptrptr, r->pool,&global_config.db), + global_config.driver->escape(r,*ptrptr, r->pool,&global_config.db), ",", - global_config.driver->escape(theitem, r->pool,&global_config.db), + global_config.driver->escape(r,theitem, r->pool,&global_config.db), ")", NULL); i++; @@ -1273,11 +1273,11 @@ static int log_sql_transaction(request_rec *orig) itemsets = apr_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "(", - global_config.driver->escape(unique_id, r->pool, &global_config.db), + global_config.driver->escape(r,unique_id, r->pool, &global_config.db), ",", - global_config.driver->escape(*ptrptr, r->pool,&global_config.db), + global_config.driver->escape(r,*ptrptr, r->pool,&global_config.db), ",", - global_config.driver->escape(theitem, r->pool,&global_config.db), + global_config.driver->escape(r,theitem, r->pool,&global_config.db), ")", NULL); i++; @@ -1302,11 +1302,11 @@ static int log_sql_transaction(request_rec *orig) itemsets = apr_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "(", - global_config.driver->escape(unique_id, r->pool, &global_config.db), + global_config.driver->escape(r,unique_id, r->pool, &global_config.db), ",", - global_config.driver->escape(*ptrptr, r->pool,&global_config.db), + global_config.driver->escape(r,*ptrptr, r->pool,&global_config.db), ",", - global_config.driver->escape(theitem, r->pool,&global_config.db), + global_config.driver->escape(r,theitem, r->pool,&global_config.db), ")", NULL); i++; diff --git a/mod_log_sql.h b/mod_log_sql.h index 2d20374..c1d9bff 100644 --- a/mod_log_sql.h +++ b/mod_log_sql.h @@ -24,7 +24,7 @@ #define LOGSQL_DECLARE_DATA __declspec(dllimport) #endif -#define LOG_SQL_PLUGIN_VERSION 20070704 +#define LOG_SQL_PLUGIN_VERSION 20080318 /* Registration function for extract functions */ @@ -115,7 +115,7 @@ typedef struct { /* disconnect from the underlying database layer */ void (*disconnect)(logsql_dbconnection *db); /* escape the SQL statement according to database rules */ - const char *(*escape)(const char *from_str, apr_pool_t *p, + const char *(*escape)(request_rec *r,const char *from_str, apr_pool_t *p, logsql_dbconnection *db); /* insert a SQL query statement */ logsql_query_ret (*insert)(request_rec *r,logsql_dbconnection *db, diff --git a/mod_log_sql_dbd.c b/mod_log_sql_dbd.c new file mode 100644 index 0000000..c78a128 --- /dev/null +++ b/mod_log_sql_dbd.c @@ -0,0 +1,132 @@ +/* $Id: mod_log_sql_dbi.c 120 2004-04-17 15:14:12Z urkle@drip.ws $ */ + +#if defined(WITH_APACHE20) +# include "apache20.h" +#else +# error Unsupported Apache version +#endif + + +#ifdef HAVE_CONFIG_H +/* Undefine these to prevent conflicts between Apache ap_config_auto.h and + * my config.h. Only really needed for Apache < 2.0.48, but it can't hurt. + */ +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION + +#include "config.h" +#endif + +#include "mod_log_sql.h" + +#include "apr_dbd.h" +#include "mod_dbd.h" + +typedef struct { + ap_dbd_t *dbd; +} request_config_t; + +LOGSQL_MODULE_FORWARD(dbd); + +static ap_dbd_t *(*dbd_acquire_fn)(request_rec*) = NULL; + +static ap_dbd_t *log_sql_dbd_getconnection(request_rec *r) +{ + request_config_t *rconf = ap_get_module_config(r->request_config, &LOGSQL_MODULE(dbd)); + if (!rconf) { + rconf = apr_pcalloc(r->pool, sizeof(request_config_t)); + ap_set_module_config(r->request_config, &LOGSQL_MODULE(dbd), (void *)rconf); + rconf->dbd = dbd_acquire_fn(r); + } + return rconf->dbd; +} + +/* Connect to the database */ +static logsql_opendb_ret log_sql_dbd_connect(server_rec *s, logsql_dbconnection *db) +{ + // We are using mod_dbd so we don't do anything here + if (!dbd_acquire_fn) { + // no mod_dbd return failure + log_error(APLOG_MARK,APLOG_ERR,0, s,"mod_log_sql_dbd: mod_dbd is not loaded or available"); + return LOGSQL_OPENDB_FAIL; + } else { + return LOGSQL_OPENDB_SUCCESS; + } +} + +/* Close the DB link */ +static void log_sql_dbd_close(logsql_dbconnection *db) +{ + // mod_dbd handles this, so do nothing +} + +/* Routine to escape the 'dangerous' characters that would otherwise + * corrupt the INSERT string: ', \, and " + */ +static const char *log_sql_dbd_escape(request_rec *r, const char *from_str, apr_pool_t *p, + logsql_dbconnection *db) +{ + // Acquire a DBD connection from mod_dbd + ap_dbd_t *dbd = log_sql_dbd_getconnection(r); + if (!dbd) return NULL; + + if (!from_str) + return NULL; + + return apr_pstrcat(p, "'",apr_dbd_escape(dbd->driver, p, from_str, dbd->handle),"'",NULL); +} + +/* Run an insert query and return a categorized error or success */ +static logsql_query_ret log_sql_dbd_query(request_rec *r,logsql_dbconnection *db, + const char *query) +{ + int ret; + const char *err; + int affected; + // Acquire a DBD connection from mod_dbd + ap_dbd_t *dbd = log_sql_dbd_getconnection(r); + if (!dbd) return LOGSQL_QUERY_NOLINK; + + // Run the query + ret = apr_dbd_query(dbd->driver, dbd->handle, &affected, query); + if (ret == 0) { + return LOGSQL_QUERY_SUCCESS; + } else { + // attempt to detect error message + err = apr_dbd_error(dbd->driver, dbd->handle, ret); + log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "DB Returned error: (%d) %s", ret, err); + // Unable to check if "NO SUCH TABLE" due to apr_dbd not mapping error codes to a standard set. + return LOGSQL_QUERY_FAIL; + } +} + +/* Create table table_name of type table_type. */ +static logsql_table_ret log_sql_dbd_create(request_rec *r, logsql_dbconnection *db, + logsql_tabletype table_type, const char *table_name) +{ + return LOGSQL_TABLE_FAIL; +} + +static const char *supported_drivers[] = {"dbd",NULL}; +static logsql_dbdriver log_sql_dbd_driver = { + "dbd", + supported_drivers, + log_sql_dbd_connect,/* open DB connection */ + log_sql_dbd_close, /* close DB connection */ + log_sql_dbd_escape, /* escape query */ + log_sql_dbd_query, /* insert query */ + log_sql_dbd_create /* create table */ +}; + +LOGSQL_REGISTER(dbd) { + dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire); + if (dbd_acquire_fn == NULL) { + log_error(APLOG_MARK,APLOG_ERR,0,s,"You must load mod_dbd to enable AuthDBD functions"); + } + + log_sql_register_driver(p,&log_sql_dbd_driver); + LOGSQL_REGISTER_RETURN; +} diff --git a/mod_log_sql_dbi.c b/mod_log_sql_dbi.c index 8afd844..40a972b 100644 --- a/mod_log_sql_dbi.c +++ b/mod_log_sql_dbi.c @@ -90,7 +90,7 @@ static void log_sql_dbi_close(logsql_dbconnection *db) /* Routine to escape the 'dangerous' characters that would otherwise * corrupt the INSERT string: ', \, and " */ -static const char *log_sql_dbi_escape(const char *from_str, apr_pool_t *p, +static const char *log_sql_dbi_escape(request_rec *r,const char *from_str, apr_pool_t *p, logsql_dbconnection *db) { dbi_conn_rec *dblink = db->handle; diff --git a/mod_log_sql_mysql.c b/mod_log_sql_mysql.c index 8202672..942c03a 100644 --- a/mod_log_sql_mysql.c +++ b/mod_log_sql_mysql.c @@ -74,7 +74,7 @@ static void log_sql_mysql_close(logsql_dbconnection *db) /* Routine to escape the 'dangerous' characters that would otherwise * corrupt the INSERT string: ', \, and " */ -static const char *log_sql_mysql_escape(const char *from_str, apr_pool_t *p, +static const char *log_sql_mysql_escape(request_rec *r, const char *from_str, apr_pool_t *p, logsql_dbconnection *db) { /* Return "NULL" for empty strings */ -- cgit