diff options
author | Edward Rudd | 2005-02-09 01:25:40 +0000 |
---|---|---|
committer | Edward Rudd | 2005-02-09 01:25:40 +0000 |
commit | 367599e034c97b9f4a353ae4362f32709a0eb286 (patch) | |
tree | cd9c991ff3f34bcbf33aa83286db277e3658aca2 | |
parent | 7ffd531ccb6c1a56d2b2b82cbb66c3d16b9a289b (diff) |
merged in PgSQL code contributed by Manfred Haelters
-rw-r--r-- | mod_log_sql_pgsql.c | 108 |
1 files changed, 52 insertions, 56 deletions
diff --git a/mod_log_sql_pgsql.c b/mod_log_sql_pgsql.c index 7ac4053..4e12920 100644 --- a/mod_log_sql_pgsql.c +++ b/mod_log_sql_pgsql.c | |||
@@ -26,12 +26,7 @@ | |||
26 | 26 | ||
27 | #include "libpq-fe.h" | 27 | #include "libpq-fe.h" |
28 | 28 | ||
29 | typedef struct { | 29 | /* Connect to the PGSQL database */ |
30 | PGconn *PG; | ||
31 | char *connectioninfo; | ||
32 | } pg_conn_rec; | ||
33 | |||
34 | /* Connect to the MYSQL database */ | ||
35 | static logsql_opendb_ret log_sql_pgsql_connect(server_rec *s, logsql_dbconnection *db) | 30 | static logsql_opendb_ret log_sql_pgsql_connect(server_rec *s, logsql_dbconnection *db) |
36 | { | 31 | { |
37 | const char *host = apr_table_get(db->parms,"hostname"); | 32 | const char *host = apr_table_get(db->parms,"hostname"); |
@@ -39,28 +34,18 @@ static logsql_opendb_ret log_sql_pgsql_connect(server_rec *s, logsql_dbconnectio | |||
39 | const char *passwd = apr_table_get(db->parms,"password"); | 34 | const char *passwd = apr_table_get(db->parms,"password"); |
40 | const char *database = apr_table_get(db->parms,"database"); | 35 | const char *database = apr_table_get(db->parms,"database"); |
41 | const char *s_tcpport = apr_table_get(db->parms,"port"); | 36 | const char *s_tcpport = apr_table_get(db->parms,"port"); |
42 | unsigned int tcpport = (s_tcpport)?atoi(s_tcpport):3306; | 37 | |
43 | const char *socketfile = apr_table_get(db->parms,"socketfile"); | 38 | db->handle = PQsetdbLogin(host, s_tcpport, NULL, NULL, database, user, passwd); |
44 | pg_conn_rec *dblink = db->handle; | ||
45 | |||
46 | dblink = mysql_init(dblink); | ||
47 | db->handle = (void *)dblink; | ||
48 | |||
49 | |||
50 | if (!socketfile) { | ||
51 | socketfile = "/var/lib/mysql/mysql.sock"; | ||
52 | } | ||
53 | 39 | ||
54 | if (PQconnectdb(dblink, host, user, passwd, database, tcpport, | 40 | if (PQstatus(db->handle) == CONNECTION_OK) { |
55 | socketfile, 0)) { | 41 | log_error(APLOG_MARK,APLOG_DEBUG,0, s,"HOST: '%s' PORT: '%s' DB: '%s' USER: '%s'", |
56 | log_error(APLOG_MARK,APLOG_DEBUG,0, s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'", | 42 | host, s_tcpport, database, user); |
57 | host, tcpport, database, user, socketfile); | ||
58 | return LOGSQL_OPENDB_SUCCESS; | 43 | return LOGSQL_OPENDB_SUCCESS; |
59 | } else { | 44 | } else { |
60 | log_error(APLOG_MARK,APLOG_DEBUG,0, s,"mod_log_sql: database connection error: %s", | 45 | log_error(APLOG_MARK,APLOG_DEBUG,0, s,"mod_log_sql: database connection error: %s", |
61 | MYSQL_ERROR(dblink)); | 46 | PQerrorMessage(db->handle)); |
62 | log_error(APLOG_MARK,APLOG_DEBUG, 0, s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'", | 47 | log_error(APLOG_MARK,APLOG_DEBUG, 0, s,"HOST: '%s' PORT: '%s' DB: '%s' USER: '%s'", |
63 | host, tcpport, database, user, socketfile); | 48 | host, s_tcpport, database, user); |
64 | return LOGSQL_OPENDB_FAIL; | 49 | return LOGSQL_OPENDB_FAIL; |
65 | } | 50 | } |
66 | } | 51 | } |
@@ -68,15 +53,18 @@ static logsql_opendb_ret log_sql_pgsql_connect(server_rec *s, logsql_dbconnectio | |||
68 | /* Close the DB link */ | 53 | /* Close the DB link */ |
69 | static void log_sql_pgsql_close(logsql_dbconnection *db) | 54 | static void log_sql_pgsql_close(logsql_dbconnection *db) |
70 | { | 55 | { |
71 | PQfinish(((pg_conn_rec *)db->handle)->PG); | 56 | PQfinish((PGconn*)(db->handle)); |
72 | } | 57 | } |
73 | 58 | ||
74 | /* Routine to escape the 'dangerous' characters that would otherwise | 59 | /* Routine to escape the 'dangerous' characters that would otherwise |
75 | * corrupt the INSERT string: ', \, and " | 60 | * corrupt the INSERT string: ', \, and " |
61 | * Also PQescapeString does not place the ' around the string. So we have | ||
62 | * to do this manually | ||
76 | */ | 63 | */ |
77 | static const char *log_sql_pgsql_escape(const char *from_str, apr_pool_t *p, | 64 | static const char *log_sql_pgsql_escape(const char *from_str, apr_pool_t *p, |
78 | logsql_dbconnection *db) | 65 | logsql_dbconnection *db) |
79 | { | 66 | { |
67 | char *temp; | ||
80 | if (!from_str) | 68 | if (!from_str) |
81 | return NULL; | 69 | return NULL; |
82 | else { | 70 | else { |
@@ -85,67 +73,72 @@ static const char *log_sql_pgsql_escape(const char *from_str, apr_pool_t *p, | |||
85 | unsigned long retval; | 73 | unsigned long retval; |
86 | 74 | ||
87 | /* Pre-allocate a new string that could hold twice the original, which would only | 75 | /* Pre-allocate a new string that could hold twice the original, which would only |
88 | * happen if the whole original string was 'dangerous' characters. | 76 | * happen if the whole original string was 'dangerous' characters. |
77 | * And forsee the space for the 2 ' | ||
89 | */ | 78 | */ |
90 | to_str = (char *) apr_palloc(p, length * 2 + 1); | 79 | temp = to_str = (char *) apr_palloc(p, length * 2 + 3); |
91 | if (!to_str) { | 80 | if (!to_str) { |
92 | return from_str; | 81 | return from_str; |
93 | } | 82 | } |
94 | 83 | ||
95 | if (!db->connected) { | 84 | *temp = '\''; |
96 | /* Well, I would have liked to use the current database charset. mysql is | 85 | temp++; |
97 | * unavailable, however, so I fall back to the slightly less respectful | 86 | |
98 | * mysql_escape_string() function that uses the default charset. | 87 | retval = PQescapeString(temp, from_str, length); |
99 | */ | 88 | |
100 | retval = mysql_escape_string(to_str, from_str, length); | 89 | /* avoid the string to be tolong for the sql database*/ |
101 | } else { | 90 | if (retval > 250) retval = 250; |
102 | /* MySQL is available, so I'll go ahead and respect the current charset when | 91 | |
103 | * I perform the escape. | 92 | *(temp+retval) = '\''; |
104 | */ | 93 | *(temp+retval+1) = '\0'; |
105 | retval = mysql_real_escape_string((MYSQL *)db->handle, to_str, from_str, length); | 94 | |
106 | } | 95 | /* We must always return the to_str, because we always need the ' added */ |
107 | 96 | // if (retval) | |
108 | if (retval) | ||
109 | return to_str; | 97 | return to_str; |
110 | else | 98 | // else |
111 | return from_str; | 99 | // return from_str; |
112 | } | 100 | } |
113 | } | 101 | } |
114 | 102 | ||
115 | /* Run a mysql insert query and return a categorized error or success */ | 103 | /* Run a sql insert query and return a categorized error or success */ |
116 | static logsql_query_ret log_sql_pgsql_query(request_rec *r,logsql_dbconnection *db, | 104 | static logsql_query_ret log_sql_pgsql_query(request_rec *r,logsql_dbconnection *db, |
117 | const char *query) | 105 | const char *query) |
118 | { | 106 | { |
119 | int retval; | 107 | PGresult *result; |
120 | void (*handler) (int); | 108 | void (*handler) (int); |
121 | unsigned int real_error = 0; | 109 | unsigned int real_error = 0; |
122 | /*const char *real_error_str = NULL;*/ | 110 | /*const char *real_error_str = NULL;*/ |
123 | 111 | ||
124 | pg_conn_rec *dblink = db->handle; | 112 | PGconn *conn = db->handle; |
125 | 113 | ||
126 | if (!dblink) { | 114 | if (PQstatus(conn) != CONNECTION_OK) { |
127 | return LOGSQL_QUERY_NOLINK; | 115 | return LOGSQL_QUERY_NOLINK; |
128 | } | 116 | } |
129 | /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ | 117 | /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ |
118 | /* Does postgresql do this also ??? */ | ||
130 | handler = signal(SIGPIPE, SIG_IGN); | 119 | handler = signal(SIGPIPE, SIG_IGN); |
131 | 120 | ||
121 | result = PQexec(conn, query); | ||
132 | /* Run the query */ | 122 | /* Run the query */ |
133 | if (!(retval = mysql_query(dblink, query))) { | 123 | if (PQresultStatus(result) == PGRES_COMMAND_OK) { |
134 | signal(SIGPIPE, handler); | 124 | signal(SIGPIPE, handler); |
125 | PQclear(result); | ||
135 | return LOGSQL_QUERY_SUCCESS; | 126 | return LOGSQL_QUERY_SUCCESS; |
136 | } | 127 | } |
137 | /* Check to see if the error is "nonexistent table" */ | 128 | /* Check to see if the error is "nonexistent table" */ |
129 | /* removed ... don't know how ! (sorry) | ||
138 | real_error = mysql_errno(dblink); | 130 | real_error = mysql_errno(dblink); |
139 | 131 | ||
140 | if (real_error == ER_NO_SUCH_TABLE) { | 132 | if (real_error == ER_NO_SUCH_TABLE) { |
141 | log_error(APLOG_MARK,APLOG_ERR,0, r->server,"table does not exist, preserving query"); | 133 | log_error(APLOG_MARK,APLOG_ERR,0, r->server,"table does not exist, preserving query"); |
142 | /* Restore SIGPIPE to its original handler function */ | ||
143 | signal(SIGPIPE, handler); | 134 | signal(SIGPIPE, handler); |
135 | PQclear(result); | ||
144 | return LOGSQL_QUERY_NOTABLE; | 136 | return LOGSQL_QUERY_NOTABLE; |
145 | } | 137 | }*/ |
146 | 138 | ||
147 | /* Restore SIGPIPE to its original handler function */ | 139 | /* Restore SIGPIPE to its original handler function */ |
148 | signal(SIGPIPE, handler); | 140 | signal(SIGPIPE, handler); |
141 | PQclear(result); | ||
149 | return LOGSQL_QUERY_FAIL; | 142 | return LOGSQL_QUERY_FAIL; |
150 | } | 143 | } |
151 | 144 | ||
@@ -153,7 +146,7 @@ static logsql_query_ret log_sql_pgsql_query(request_rec *r,logsql_dbconnection * | |||
153 | static logsql_table_ret log_sql_pgsql_create(request_rec *r, logsql_dbconnection *db, | 146 | static logsql_table_ret log_sql_pgsql_create(request_rec *r, logsql_dbconnection *db, |
154 | logsql_tabletype table_type, const char *table_name) | 147 | logsql_tabletype table_type, const char *table_name) |
155 | { | 148 | { |
156 | int retval; | 149 | PGresult *result; |
157 | const char *tabletype = apr_table_get(db->parms,"tabletype"); | 150 | const char *tabletype = apr_table_get(db->parms,"tabletype"); |
158 | void (*handler) (int); | 151 | void (*handler) (int); |
159 | char *type_suffix = NULL; | 152 | char *type_suffix = NULL; |
@@ -162,7 +155,7 @@ static logsql_table_ret log_sql_pgsql_create(request_rec *r, logsql_dbconnection | |||
162 | char *create_suffix = NULL; | 155 | char *create_suffix = NULL; |
163 | char *create_sql; | 156 | char *create_sql; |
164 | 157 | ||
165 | pg_conn_rec *dblink = db->handle; | 158 | PGconn *conn = db->handle; |
166 | 159 | ||
167 | /* if (!global_config.createtables) { | 160 | /* if (!global_config.createtables) { |
168 | return APR_SUCCESS; | 161 | return APR_SUCCESS; |
@@ -218,20 +211,23 @@ static logsql_table_ret log_sql_pgsql_create(request_rec *r, logsql_dbconnection | |||
218 | 211 | ||
219 | log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"create string: %s", create_sql); | 212 | log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"create string: %s", create_sql); |
220 | 213 | ||
221 | if (!dblink) { | 214 | if (PQstatus(conn) != CONNECTION_OK) { |
222 | return LOGSQL_QUERY_NOLINK; | 215 | return LOGSQL_QUERY_NOLINK; |
223 | } | 216 | } |
224 | /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ | 217 | /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ |
225 | handler = signal(SIGPIPE, SIG_IGN); | 218 | handler = signal(SIGPIPE, SIG_IGN); |
226 | 219 | ||
227 | /* Run the create query */ | 220 | /* Run the create query */ |
228 | if ((retval = mysql_query(dblink, create_sql))) { | 221 | result = PQexec(conn, create_sql); |
222 | if (PQresultStatus(result) != PGRES_COMMAND_OK) { | ||
229 | log_error(APLOG_MARK,APLOG_ERR,0, r->server,"failed to create table: %s", | 223 | log_error(APLOG_MARK,APLOG_ERR,0, r->server,"failed to create table: %s", |
230 | table_name); | 224 | table_name); |
231 | signal(SIGPIPE, handler); | 225 | signal(SIGPIPE, handler); |
226 | PQclear(result); | ||
232 | return LOGSQL_TABLE_FAIL; | 227 | return LOGSQL_TABLE_FAIL; |
233 | } | 228 | } |
234 | signal(SIGPIPE, handler); | 229 | signal(SIGPIPE, handler); |
230 | PQclear(result); | ||
235 | return LOGSQL_TABLE_SUCCESS; | 231 | return LOGSQL_TABLE_SUCCESS; |
236 | } | 232 | } |
237 | 233 | ||