summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-11-15 20:19:06 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2010-11-15 20:19:06 +0100
commit3ff195398245d187f0477ef6c83bd5ed5eb50b03 (patch)
tree8a3ce664c11df3e693dd4d0c18fcb87443490463
parent14e35e4d1f2f8927685b0c55bdc1f5d6bd5a2e9f (diff)
Added some ecpg stuff.
-rw-r--r--SConstruct7
-rw-r--r--config.c5
-rw-r--r--config.h2
-rw-r--r--main.c19
-rw-r--r--pg.h9
-rw-r--r--pg.pgc114
6 files changed, 154 insertions, 2 deletions
diff --git a/SConstruct b/SConstruct
index 97e885a..3e16eed 100644
--- a/SConstruct
+++ b/SConstruct
@@ -3,7 +3,7 @@ AddOption('--release', action = 'store_true')
env = Environment()
conf = Configure(env)
-for lib in ('config', 'pcre'):
+for lib in ('config', 'pcre', 'xml2', 'ecpg'):
if not conf.CheckLib(lib):
print 'Could not find %s' % lib
Exit(1)
@@ -19,6 +19,11 @@ else:
env.ParseConfig('pkg-config --cflags --libs libconfig')
env.ParseConfig('pcre-config --cflags --libs')
+build_ecpg = Builder(action = 'ecpg -o $TARGET $SOURCE')
+env['BUILDERS']['ecpg'] = build_ecpg
+
+env.ecpg('pg.c', 'pg.pgc')
+
env.Program('ircstats', Glob('*.c'))
# vim: syn=python
diff --git a/config.c b/config.c
index 9d465bd..8818cd8 100644
--- a/config.c
+++ b/config.c
@@ -43,6 +43,11 @@ int cfg_init() {
ircstats_config.day_date_format = NULL;
}
+ if(!config_lookup_string(&config, "db_connection_string", &ircstats_config.db_connection_string)) {
+ fprintf(stderr, "Missing setting \"db_connection_string\".\n");
+ return 0;
+ }
+
config_setting_t *regexes_setting = config_lookup(&config, "regexes");
if(!config_setting_is_aggregate(regexes_setting)) {
fprintf(stderr, "Setting \"regexes\" must be an aggregate type.\n");
diff --git a/config.h b/config.h
index ef2e3a4..7af3f8c 100644
--- a/config.h
+++ b/config.h
@@ -6,7 +6,7 @@ void cfg_free();
struct ircstats_config_t {
int monolog_min, wordlen_min;
- const char *log_date_format, *day_date_format;
+ const char *log_date_format, *day_date_format, *db_connection_string;
};
extern struct ircstats_config_t ircstats_config;
diff --git a/main.c b/main.c
index 5c34642..72a8848 100644
--- a/main.c
+++ b/main.c
@@ -7,6 +7,7 @@
#include "word.h"
#include "nick.h"
#include "parsing.h"
+#include "pg.h"
int main(int argc, char **argv) {
/* Set locale. */
@@ -24,8 +25,26 @@ int main(int argc, char **argv) {
return 1;
}
+ if(!pg_connect(ircstats_config.db_connection_string)) {
+ printf("failed to connect\n");
+ goto main_free;
+ }
+
+ if(argc == 2 && strcmp(argv[1], "-i") == 0) {
+ pg_init();
+ goto disconnect;
+ }
+ if(argc == 2 && strcmp(argv[1], "-u") == 0) {
+ pg_upgrade();
+ goto disconnect;
+ }
+
process();
+disconnect:
+ pg_disconnect();
+
+main_free:
nick_free();
cfg_free();
channel_free();
diff --git a/pg.h b/pg.h
new file mode 100644
index 0000000..150b5ef
--- /dev/null
+++ b/pg.h
@@ -0,0 +1,9 @@
+#ifndef PG_H
+#define PG_H
+
+int pg_connect(const char *string);
+void pg_disconnect();
+int pg_init();
+int pg_upgrade();
+
+#endif
diff --git a/pg.pgc b/pg.pgc
new file mode 100644
index 0000000..e004dc0
--- /dev/null
+++ b/pg.pgc
@@ -0,0 +1,114 @@
+EXEC SQL WHENEVER SQLERROR CONTINUE;
+
+static inline int iserror() {
+ return !(SQLSTATE[0] == '0' && SQLSTATE[1] == '0');
+}
+
+static inline void printerror() {
+ printf("%c%c%c%c%c\n", SQLSTATE[0], SQLSTATE[1], SQLSTATE[2], SQLSTATE[3], SQLSTATE[4]);
+}
+
+static inline int testerror(const char *code) {
+ for(int i = 0; i < 5; i++) {
+ if(code[i] != SQLSTATE[i])
+ return 0;
+ }
+ return 1;
+}
+
+int pg_connect(const char *string) {
+ EXEC SQL BEGIN DECLARE SECTION;
+ const char *target = string;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO :target;
+
+ if(iserror()) {
+ sqlprint();
+ printerror();
+ }
+
+ return !iserror();
+}
+
+void pg_disconnect() {
+ EXEC SQL DISCONNECT;
+}
+
+int pg_init() {
+ EXEC SQL WHENEVER SQLERROR GOTO pg_init_error;
+ EXEC SQL CREATE TABLE schema (version INTEGER);
+ EXEC SQL INSERT INTO schema (version) VALUES (1);
+
+ EXEC SQL CREATE TABLE channel (
+ id serial,
+ name varchar,
+ PRIMARY KEY (id)
+ );
+ EXEC SQL CREATE TABLE channel_hours (
+ channel_id integer,
+ time_index integer,
+ lines integer,
+ PRIMARY KEY (channel_id, time_index),
+ FOREIGN KEY (channel_id) REFERENCES channel (id)
+ );
+
+ /* "user" is a reserved word */
+ EXEC SQL CREATE TABLE users (
+ id serial,
+ nick varchar,
+ words integer,
+ characters integer,
+ kicks integer,
+ kicked integer,
+ monolog_lines integer,
+ monologs integer,
+ seen_first integer,
+ seen_last integer,
+ PRIMARY KEY (id)
+ );
+ EXEC SQL CREATE TABLE user_hours (
+ user_id integer,
+ time_index integer,
+ lines integer,
+ PRIMARY KEY (user_id, time_index),
+ FOREIGN KEY (user_id) REFERENCES users (id)
+ );
+
+ EXEC SQL CREATE TABLE word (
+ id serial PRIMARY KEY,
+ name varchar,
+ count integer
+ );
+
+ EXEC SQL COMMIT;
+
+ return 1;
+
+pg_init_error:
+
+ sqlprint();
+ return 0;
+}
+
+EXEC SQL WHENEVER SQLERROR CONTINUE;
+int pg_upgrade() {
+ EXEC SQL BEGIN DECLARE SECTION;
+ int version = 0;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL SELECT version INTO :version FROM schema;
+ if(testerror("02000")) {
+ EXEC SQL INSERT INTO schema (version) VALUES (1);
+ } else if(iserror()) {
+ sqlprint();
+ return 0;
+ }
+
+ printf("current schema version: %d\n", version);
+
+ EXEC SQL COMMIT;
+
+ return !iserror();
+}
+/* vim: set syn=c: */