From 3ff195398245d187f0477ef6c83bd5ed5eb50b03 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Mon, 15 Nov 2010 20:19:06 +0100 Subject: Added some ecpg stuff. --- SConstruct | 7 +++- config.c | 5 +++ config.h | 2 +- main.c | 19 +++++++++++ pg.h | 9 +++++ pg.pgc | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 pg.h create mode 100644 pg.pgc 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: */ -- cgit v1.2.3