implement the SQL logs table and the INSERT-logging code for mod_irc_log
authorTero Marttila <terom@fixme.fi>
Mon, 16 Mar 2009 20:22:51 +0200
changeset 67 aa94bf2b5f9b
parent 66 ef8c9d7daf62
child 68 591a574f390e
implement the SQL logs table and the INSERT-logging code for mod_irc_log
src/CMakeLists.txt
src/irc_chan.c
src/irc_log.c
--- a/src/CMakeLists.txt	Mon Mar 16 01:14:36 2009 +0200
+++ b/src/CMakeLists.txt	Mon Mar 16 20:22:51 2009 +0200
@@ -1,9 +1,11 @@
 # dependancies
 find_package (LibEvent REQUIRED)
 find_package (GnuTLS REQUIRED)
+find_package (LibPQ REQUIRED)
+find_package (Evsql REQUIRED)
 
 # add our include path
-include_directories (${LibEvent_INCLUDE_DIRS} ${GnuTLS_INCLUDE_DIRS})
+include_directories (${LibEvent_INCLUDE_DIRS} ${GnuTLS_INCLUDE_DIRS} ${Evsql_INCLUDE_DIRS})
 
 # define our source code modules
 set (CORE_SOURCES error.c log.c)
@@ -31,6 +33,7 @@
 # set libraries
 target_link_libraries (nexus ${NEXUS_LIBRARIES})
 target_link_libraries (test ${NEXUS_LIBRARIES})
+target_link_libraries (irc_log ${Evsql_LIBRARIES})
 
 # global target properties
 set_target_properties (nexus test irc_log PROPERTIES
@@ -44,6 +47,7 @@
 
 # modules have weird names
 set_target_properties (irc_log PROPERTIES
+    PREFIX                      "mod_"
     LIBRARY_OUTPUT_DIRECTORY    "modules"
 )
 
--- a/src/irc_chan.c	Mon Mar 16 01:14:36 2009 +0200
+++ b/src/irc_chan.c	Mon Mar 16 20:22:51 2009 +0200
@@ -41,13 +41,13 @@
 {
     struct irc_chan *chan = arg;
     char prefix_buf[IRC_PREFIX_MAX];
-    struct irc_nm *nm;
+    struct irc_nm nm;
     err_t err;
 
     const char *msg = line->args[1];
 
     // parse nickmask
-    if ((err = irc_nm_parse(nm, prefix_buf, line->prefix))) {
+    if ((err = irc_nm_parse(&nm, prefix_buf, line->prefix))) {
         log_warn("invalid prefix: %s", line->prefix);
         
         // invoke callback with NULL prefix
@@ -55,7 +55,7 @@
 
     } else {
         // invoke callback (prefix, message)
-        IRC_CHAN_INVOKE_CALLBACK(chan, on_msg, nm, msg);
+        IRC_CHAN_INVOKE_CALLBACK(chan, on_msg, &nm, msg);
     }
 }
 
--- a/src/irc_log.c	Mon Mar 16 01:14:36 2009 +0200
+++ b/src/irc_log.c	Mon Mar 16 20:22:51 2009 +0200
@@ -6,12 +6,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-/*
 #include <event2/event.h>
-// XXX: fix this err_t crap
-#define LIB_ERR_H
 #include <evsql.h>
-*/
 
 /**
  * The irc_log module state
@@ -20,21 +16,77 @@
     /** The nexus this module is loaded for */
     struct nexus *nexus;
 
-#if 0
     /** The database connection */
     struct evsql *db;
-#endif
 
 };
 
+static void irc_log_on_sql_result (struct evsql_result *res, void *arg)
+{
+    struct irc_log_ctx *ctx = arg;
+    err_t err;
+
+    (void) ctx;
+
+    if ((err = evsql_result_check(res)))
+        log_error("irc_log_event: %s", evsql_result_error(res));
+
+    // ok
+    evsql_result_free(res);
+}
+
+static void irc_log_event (struct irc_log_ctx *ctx, struct irc_chan *chan, const struct irc_nm *source,
+        const char *type, const char *target, const char *message)
+{
+    struct evsql_query *query;
+
+    // our SQL query
+    static struct evsql_query_info sql = {
+        "INSERT INTO logs ("
+        "  network, channel, nickname, username, hostname, type, target, message"
+        " ) VALUES ("
+        "  $1::varchar, $2::varchar, $3::varchar, $4::varchar, $5::varchar, $6::varchar, $7::varchar, $8::varchar"
+        " )", { 
+            EVSQL_TYPE(STRING),     // network
+            EVSQL_TYPE(STRING),     // channel
+            EVSQL_TYPE(STRING),     // nickname
+            EVSQL_TYPE(STRING),     // username
+            EVSQL_TYPE(STRING),     // hostname
+            EVSQL_TYPE(STRING),     // type
+            EVSQL_TYPE(STRING),     // target
+            EVSQL_TYPE(STRING),     // message
+            EVSQL_TYPE_END
+        }
+    };
+
+    // run the INSERT
+    if ((query = evsql_query_exec(ctx->db, NULL, &sql, &irc_log_on_sql_result, ctx,
+        chan->net->info.network, irc_chan_name(chan),
+        source->nickname, source->username, source->hostname,
+        type, target, message
+    )) == NULL) {
+        // XXX: get evsql_query error info somehow...
+        log_error("evsql_query_exec failed for %s:%s - %s!%s@%s - %s -> %s - %s", 
+            chan->net->info.network, irc_chan_name(chan),
+            source->nickname, source->username, source->hostname,
+            type, target, message
+        );
+
+    } else {
+        log_debug("%s:%s - %s!%s@%s - %s -> %s - %s", 
+            chan->net->info.network, irc_chan_name(chan),
+            source->nickname, source->username, source->hostname,
+            type, target, message
+        );
+
+    }
+}
+
 static void on_chan_msg (struct irc_chan *chan, const struct irc_nm *source, const char *message, void *arg)
 {
     struct irc_log_ctx *ctx = arg;
 
-    (void) ctx;
-
-    // log it! :P
-    log_debug("%s: %s: %s", source ? source->nickname : "???", irc_chan_name(chan), message);
+    irc_log_event(ctx, chan, source, "PRIVMSG", NULL, message);
 }
 
 static struct irc_chan_callbacks _chan_callbacks = {
@@ -66,14 +118,14 @@
 static err_t irc_log_conf (void *mod_ctx, const char *name, char *value, struct error_info *err)
 {
     struct irc_log_ctx *ctx = mod_ctx;
-/*
+
     if (strcmp(name, "db_info") == 0) {
         log_info("connect to database: %s", value);
 
         if ((ctx->db = evsql_new_pq(ctx->nexus->ev_base, value, NULL, NULL)) == NULL)
            return ERR_EVSQL_NEW_PQ;
 
-    } else */ if (strcmp(name, "channel") == 0) {
+    } else if (strcmp(name, "channel") == 0) {
         const char *network = strsep(&value, ":");
         const char *channel = value;