diff options
| author | 2004-07-28 18:04:44 +0000 | |
|---|---|---|
| committer | 2004-07-28 18:04:44 +0000 | |
| commit | 17c8a5a5f7d79f44e5a05a96050673be566c4adf (patch) | |
| tree | 5993d8f546829b7da6e54a00d94cf10bdb05574e | |
| parent | 94c629f6f1ec92a77ee9c24f0fab28378c319b73 (diff) | |
added dbi provider
| -rw-r--r-- | mod_log_sql_dbi.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/mod_log_sql_dbi.c b/mod_log_sql_dbi.c new file mode 100644 index 0000000..8afd844 --- /dev/null +++ b/mod_log_sql_dbi.c | |||
| @@ -0,0 +1,263 @@ | |||
| 1 | /* $Id: mod_log_sql_dbi.c 120 2004-04-17 15:14:12Z urkle@drip.ws $ */ | ||
| 2 | |||
| 3 | #if defined(WITH_APACHE20) | ||
| 4 | # include "apache20.h" | ||
| 5 | #elif defined(WITH_APACHE13) | ||
| 6 | # include "apache13.h" | ||
| 7 | #else | ||
| 8 | # error Unsupported Apache version | ||
| 9 | #endif | ||
| 10 | |||
| 11 | |||
| 12 | #ifdef HAVE_CONFIG_H | ||
| 13 | /* Undefine these to prevent conflicts between Apache ap_config_auto.h and | ||
| 14 | * my config.h. Only really needed for Apache < 2.0.48, but it can't hurt. | ||
| 15 | */ | ||
| 16 | #undef PACKAGE_BUGREPORT | ||
| 17 | #undef PACKAGE_NAME | ||
| 18 | #undef PACKAGE_STRING | ||
| 19 | #undef PACKAGE_TARNAME | ||
| 20 | #undef PACKAGE_VERSION | ||
| 21 | |||
| 22 | #include "config.h" | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #include "mod_log_sql.h" | ||
| 26 | |||
| 27 | #include "dbi/dbi.h" | ||
| 28 | |||
| 29 | typedef struct { | ||
| 30 | dbi_conn conn; | ||
| 31 | } dbi_conn_rec; | ||
| 32 | |||
| 33 | /* Connect to the MYSQL database */ | ||
| 34 | static logsql_opendb_ret log_sql_dbi_connect(server_rec *s, logsql_dbconnection *db) | ||
| 35 | { | ||
| 36 | const char *driver = apr_table_get(db->parms,"driver"); | ||
| 37 | const char *host = apr_table_get(db->parms,"hostname"); | ||
| 38 | const char *user = apr_table_get(db->parms,"username"); | ||
| 39 | const char *passwd = apr_table_get(db->parms,"password"); | ||
| 40 | const char *database = apr_table_get(db->parms,"database"); | ||
| 41 | const char *s_tcpport = apr_table_get(db->parms,"port"); | ||
| 42 | unsigned int tcpport = (s_tcpport)?atoi(s_tcpport):0; | ||
| 43 | const char *socketfile = apr_table_get(db->parms,"socketfile"); | ||
| 44 | //dbi_result result; | ||
| 45 | dbi_conn_rec *dblink = db->handle; | ||
| 46 | if (!dblink) { | ||
| 47 | dblink = apr_pcalloc(db->p, sizeof(*dblink)); | ||
| 48 | db->handle = (void *)dblink; | ||
| 49 | } | ||
| 50 | |||
| 51 | dblink->conn = dbi_conn_new(driver); | ||
| 52 | |||
| 53 | dbi_conn_set_option(dblink->conn, "host", host); | ||
| 54 | dbi_conn_set_option(dblink->conn, "username", user); | ||
| 55 | dbi_conn_set_option(dblink->conn, "password", passwd); | ||
| 56 | dbi_conn_set_option(dblink->conn, "dbname", database); | ||
| 57 | if (tcpport) { | ||
| 58 | dbi_conn_set_option_numeric(dblink->conn, "port", tcpport); | ||
| 59 | } | ||
| 60 | |||
| 61 | if (socketfile && !strcmp(driver,"mysql")) { | ||
| 62 | dbi_conn_set_option(dblink->conn, "mysql_unix_socket", socketfile); | ||
| 63 | } | ||
| 64 | |||
| 65 | if (!dbi_conn_connect(dblink->conn)) { | ||
| 66 | log_error(APLOG_MARK, APLOG_DEBUG, 0, s, | ||
| 67 | "HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'", | ||
| 68 | host, tcpport, database, user, socketfile); | ||
| 69 | return LOGSQL_OPENDB_SUCCESS; | ||
| 70 | } else { | ||
| 71 | const char *error; | ||
| 72 | dbi_conn_error(dblink->conn, &error); | ||
| 73 | log_error(APLOG_MARK, APLOG_ERR, 0, s, | ||
| 74 | "DBI Error: %s", error); | ||
| 75 | log_error(APLOG_MARK, APLOG_DEBUG, 0, s, | ||
| 76 | "HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'", | ||
| 77 | host, tcpport, database, user, socketfile); | ||
| 78 | return LOGSQL_OPENDB_FAIL; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | /* Close the DB link */ | ||
| 83 | static void log_sql_dbi_close(logsql_dbconnection *db) | ||
| 84 | { | ||
| 85 | dbi_conn_rec *dblink = db->handle; | ||
| 86 | dbi_conn_close(dblink->conn); | ||
| 87 | dblink->conn = NULL; | ||
| 88 | } | ||
| 89 | |||
| 90 | /* Routine to escape the 'dangerous' characters that would otherwise | ||
| 91 | * corrupt the INSERT string: ', \, and " | ||
| 92 | */ | ||
| 93 | static const char *log_sql_dbi_escape(const char *from_str, apr_pool_t *p, | ||
| 94 | logsql_dbconnection *db) | ||
| 95 | { | ||
| 96 | dbi_conn_rec *dblink = db->handle; | ||
| 97 | |||
| 98 | if (!from_str) | ||
| 99 | return NULL; | ||
| 100 | else { | ||
| 101 | char *to_str = strdup(from_str); | ||
| 102 | char *retval; | ||
| 103 | dbi_driver_quote_string(dbi_conn_get_driver(dblink->conn), &to_str); | ||
| 104 | retval = apr_pstrdup(p, to_str); | ||
| 105 | free(to_str); | ||
| 106 | return retval; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | /* Run a mysql insert query and return a categorized error or success */ | ||
| 111 | static logsql_query_ret log_sql_dbi_query(request_rec *r,logsql_dbconnection *db, | ||
| 112 | const char *query) | ||
| 113 | { | ||
| 114 | const char *error; | ||
| 115 | dbi_result result; | ||
| 116 | dbi_conn_rec *dblink = db->handle; | ||
| 117 | |||
| 118 | if (!dblink->conn) { | ||
| 119 | return LOGSQL_QUERY_NOLINK; | ||
| 120 | } | ||
| 121 | |||
| 122 | /* Run the query */ | ||
| 123 | if ((result = dbi_conn_query(dblink->conn, query))) { | ||
| 124 | return LOGSQL_QUERY_SUCCESS; | ||
| 125 | } | ||
| 126 | /* Check to see if the error is "nonexistent table" */ | ||
| 127 | dbi_conn_error(dblink->conn, &error); | ||
| 128 | log_error(APLOG_MARK, APLOG_ERR, 0, r->server, | ||
| 129 | "DBI Error: %s", error); | ||
| 130 | /* if (real_error == ER_NO_SUCH_TABLE) { | ||
| 131 | log_error(APLOG_MARK,APLOG_ERR,0, r->server,"table does not exist, preserving query"); | ||
| 132 | return LOGSQL_QUERY_NOTABLE; | ||
| 133 | }*/ | ||
| 134 | return LOGSQL_QUERY_FAIL; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* Create table table_name of type table_type. */ | ||
| 138 | static logsql_table_ret log_sql_dbi_create(request_rec *r, logsql_dbconnection *db, | ||
| 139 | logsql_tabletype table_type, const char *table_name) | ||
| 140 | { | ||
| 141 | dbi_result result; | ||
| 142 | const char *driver = apr_table_get(db->parms,"driver"); | ||
| 143 | const char *tabletype = apr_table_get(db->parms,"tabletype"); | ||
| 144 | char *type_suffix = NULL; | ||
| 145 | |||
| 146 | char *create_prefix = "create table if not exists `"; | ||
| 147 | char *create_suffix = NULL; | ||
| 148 | char *create_sql; | ||
| 149 | |||
| 150 | dbi_conn_rec *dblink = db->handle; | ||
| 151 | |||
| 152 | /* if (!global_config.createtables) { | ||
| 153 | return APR_SUCCESS; | ||
| 154 | }*/ | ||
| 155 | |||
| 156 | switch (table_type) { | ||
| 157 | case LOGSQL_TABLE_ACCESS: | ||
| 158 | create_suffix = | ||
| 159 | "` (id char(19),\ | ||
| 160 | agent varchar(255),\ | ||
| 161 | bytes_sent int unsigned,\ | ||
| 162 | child_pid smallint unsigned,\ | ||
| 163 | cookie varchar(255),\ | ||
| 164 | machine_id varchar(25),\ | ||
| 165 | request_file varchar(255),\ | ||
| 166 | referer varchar(255),\ | ||
| 167 | remote_host varchar(50),\ | ||
| 168 | remote_logname varchar(50),\ | ||
| 169 | remote_user varchar(50),\ | ||
| 170 | request_duration smallint unsigned,\ | ||
| 171 | request_line varchar(255),\ | ||
| 172 | request_method varchar(10),\ | ||
| 173 | request_protocol varchar(10),\ | ||
| 174 | request_time char(28),\ | ||
| 175 | request_uri varchar(255),\ | ||
| 176 | request_args varchar(255),\ | ||
| 177 | server_port smallint unsigned,\ | ||
| 178 | ssl_cipher varchar(25),\ | ||
| 179 | ssl_keysize smallint unsigned,\ | ||
| 180 | ssl_maxkeysize smallint unsigned,\ | ||
| 181 | status smallint unsigned,\ | ||
| 182 | time_stamp int unsigned,\ | ||
| 183 | virtual_host varchar(255))"; | ||
| 184 | break; | ||
| 185 | case LOGSQL_TABLE_COOKIES: | ||
| 186 | case LOGSQL_TABLE_HEADERSIN: | ||
| 187 | case LOGSQL_TABLE_HEADERSOUT: | ||
| 188 | case LOGSQL_TABLE_NOTES: | ||
| 189 | create_suffix = | ||
| 190 | "` (id char(19),\ | ||
| 191 | item varchar(80),\ | ||
| 192 | val varchar(80))"; | ||
| 193 | break; | ||
| 194 | } | ||
| 195 | |||
| 196 | if (tabletype && !strcmp(driver,"mysql")) { | ||
| 197 | type_suffix = apr_pstrcat(r->pool, " TYPE=", | ||
| 198 | tabletype, NULL); | ||
| 199 | } | ||
| 200 | /* Find memory long enough to hold the whole CREATE string + \0 */ | ||
| 201 | create_sql = apr_pstrcat(r->pool, create_prefix, table_name, create_suffix, | ||
| 202 | type_suffix, NULL); | ||
| 203 | |||
| 204 | log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"create string: %s", create_sql); | ||
| 205 | |||
| 206 | if (!dblink) { | ||
| 207 | return LOGSQL_QUERY_NOLINK; | ||
| 208 | } | ||
| 209 | |||
| 210 | /* Run the create query */ | ||
| 211 | if (!(result = dbi_conn_query(dblink, create_sql))) { | ||
| 212 | const char *error; | ||
| 213 | dbi_conn_error(dblink->conn, &error); | ||
| 214 | log_error(APLOG_MARK, APLOG_ERR, 0, r->server, | ||
| 215 | "DBI Error: %s", error); | ||
| 216 | return LOGSQL_TABLE_FAIL; | ||
| 217 | } | ||
| 218 | |||
| 219 | return LOGSQL_TABLE_SUCCESS; | ||
| 220 | } | ||
| 221 | |||
| 222 | static logsql_dbdriver log_sql_dbi_driver = { | ||
| 223 | "dbi", | ||
| 224 | NULL, | ||
| 225 | log_sql_dbi_connect, /* open DB connection */ | ||
| 226 | log_sql_dbi_close, /* close DB connection */ | ||
| 227 | log_sql_dbi_escape, /* escape query */ | ||
| 228 | log_sql_dbi_query, /* insert query */ | ||
| 229 | log_sql_dbi_create /* create table */ | ||
| 230 | }; | ||
| 231 | |||
| 232 | static apr_status_t log_sql_dbi_cleanup(void *data) | ||
| 233 | { | ||
| 234 | dbi_shutdown(); | ||
| 235 | #if defined(WITH_APACHE20) | ||
| 236 | return APR_SUCCESS; | ||
| 237 | #endif | ||
| 238 | } | ||
| 239 | |||
| 240 | LOGSQL_REGISTER(dbi) { | ||
| 241 | dbi_driver driver; | ||
| 242 | const char **driver_list; | ||
| 243 | int count = 1; | ||
| 244 | |||
| 245 | dbi_initialize(NULL); | ||
| 246 | |||
| 247 | for (driver = dbi_driver_list(NULL); | ||
| 248 | driver; | ||
| 249 | driver = dbi_driver_list(driver)) { | ||
| 250 | count++; | ||
| 251 | } | ||
| 252 | driver_list = apr_pcalloc(p, sizeof(char *) * (count)); | ||
| 253 | count = 0; | ||
| 254 | for (driver = dbi_driver_list(NULL); | ||
| 255 | driver; | ||
| 256 | driver = dbi_driver_list(driver)) { | ||
| 257 | driver_list[count++] = dbi_driver_get_name(driver); | ||
| 258 | } | ||
| 259 | log_sql_dbi_driver.provided_drivers = driver_list; | ||
| 260 | log_sql_register_driver(p,&log_sql_dbi_driver); | ||
| 261 | apr_pool_cleanup_register(p, NULL, log_sql_dbi_cleanup, NULL); | ||
| 262 | LOGSQL_REGISTER_RETURN; | ||
| 263 | } | ||
