summaryrefslogtreecommitdiffstatsabout
path: root/utility/database.c
diff options
context:
space:
mode:
Diffstat (limited to 'utility/database.c')
-rw-r--r--utility/database.c102
1 files changed, 66 insertions, 36 deletions
diff --git a/utility/database.c b/utility/database.c
index a979268..45022da 100644
--- a/utility/database.c
+++ b/utility/database.c
@@ -3,6 +3,8 @@
3#include "apr_dbd.h" 3#include "apr_dbd.h"
4#include "apr_strings.h" 4#include "apr_strings.h"
5 5
6#include "util.h"
7
6struct config_dbd_t { 8struct config_dbd_t {
7 const apr_dbd_driver_t *driver; 9 const apr_dbd_driver_t *driver;
8 apr_dbd_t *dbd; 10 apr_dbd_t *dbd;
@@ -18,17 +20,26 @@ void database_init(apr_pool_t *p)
18apr_status_t database_connect(config_t *cfg) 20apr_status_t database_connect(config_t *cfg)
19{ 21{
20 apr_status_t rv; 22 apr_status_t rv;
23 if (!cfg->dbdriver || !cfg->dbparams)
24 return APR_EINVAL;
21 if (!cfg->dbconn) { 25 if (!cfg->dbconn) {
22 cfg->dbconn = apr_pcalloc(cfg->pool, sizeof(config_dbd_t)); 26 cfg->dbconn = apr_pcalloc(cfg->pool, sizeof(config_dbd_t));
23 } 27 }
24 rv = apr_dbd_get_driver(cfg->pool, cfg->dbdriver, &(cfg->dbconn->driver)); 28 rv = apr_dbd_get_driver(cfg->pool, cfg->dbdriver, &(cfg->dbconn->driver));
25 if (rv) 29 if (rv) {
30 logging_log(cfg, LOGLEVEL_ERROR,
31 "Could not load database driver %s. Error %d", cfg->dbdriver,
32 rv);
26 return rv; 33 return rv;
34 }
27 35
28 rv = apr_dbd_open(cfg->dbconn->driver, cfg->pool, cfg->dbparams, 36 rv = apr_dbd_open(cfg->dbconn->driver, cfg->pool, cfg->dbparams,
29 &(cfg->dbconn->dbd)); 37 &(cfg->dbconn->dbd));
30 if (rv) 38 if (rv) {
39 logging_log(cfg, LOGLEVEL_ERROR,
40 "Could not connect to database. Error %d", rv);
31 return rv; 41 return rv;
42 }
32 43
33 return APR_SUCCESS; 44 return APR_SUCCESS;
34} 45}
@@ -38,6 +49,56 @@ apr_status_t database_disconnect(config_t *cfg)
38 return apr_dbd_close(cfg->dbconn->driver, cfg->dbconn->dbd); 49 return apr_dbd_close(cfg->dbconn->driver, cfg->dbconn->dbd);
39} 50}
40 51
52static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, apr_pool_t *p)
53{
54 apr_status_t rv;
55 char *sql;
56 int i, f;
57 struct iovec *vec;
58 apr_dbd_prepared_t *stmt;
59 int nfs = cfg->output_fields->nelts;
60 config_output_field_t *ofields;
61
62 ofields = (config_output_field_t *)cfg->output_fields->elts;
63
64 vec = apr_palloc(p, (nfs*2 + 5) * sizeof(struct iovec));
65 sql = apr_palloc(p, (nfs*3));
66
67 vec[0].iov_base = "INSERT INTO ";
68 vec[0].iov_len = 12;
69 vec[1].iov_base = (void *)cfg->table;
70 vec[1].iov_len = strlen(cfg->table);
71 vec[2].iov_base = " (";
72 vec[2].iov_len = 2;
73 for (i=3, f=0; f<nfs; f++, i+=2) {
74 vec[i].iov_base = (void *)ofields[f].field;
75 vec[i].iov_len = strlen(vec[i].iov_base);
76 vec[i+1].iov_base = ",";
77 vec[i+1].iov_len = 1;
78 memcpy(&sql[f*3], "%s,", 3);
79 }
80 sql[nfs*3-1] = '\0';
81 vec[i-1].iov_base = ") VALUES (";
82 vec[i-1].iov_len = 10;
83 vec[i].iov_base = sql;
84 vec[i].iov_len = nfs*3-1;
85 vec[i+1].iov_base = ")";
86 vec[i+1].iov_len = 1;
87
88 sql = apr_pstrcatv(p, vec, i+2, NULL);
89
90 printf("SQL: %s\n", sql);
91
92 rv = apr_dbd_prepare(cfg->dbconn->driver, cfg->pool, cfg->dbconn->dbd, sql,
93 "INSERT", &stmt);
94
95 if (rv) {
96 printf("DB Error: %s\n", apr_dbd_error(cfg->dbconn->driver,
97 cfg->dbconn->dbd, rv));
98 return NULL;
99 }
100 return stmt;
101}
41apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) 102apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data)
42{ 103{
43 apr_status_t rv; 104 apr_status_t rv;
@@ -47,41 +108,8 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data)
47 nfs = cfg->output_fields->nelts; 108 nfs = cfg->output_fields->nelts;
48 // Prepare statement 109 // Prepare statement
49 if (!cfg->dbconn->stmt) { 110 if (!cfg->dbconn->stmt) {
50 char *sql; 111 cfg->dbconn->stmt = database_prepare_insert(cfg, p);
51 int i;
52 struct iovec *vec;
53 vec = apr_palloc(p, (nfs*2 + 5) * sizeof(struct iovec));
54 sql = apr_palloc(p, (nfs*3));
55 vec[0].iov_base = "INSERT INTO ";
56 vec[0].iov_len = 12;
57 vec[1].iov_base = (void *)cfg->table;
58 vec[1].iov_len = strlen(cfg->table);
59 vec[2].iov_base = " (";
60 vec[2].iov_len = 2;
61 for (i=3, f=0; f<nfs; f++, i+=2) {
62 vec[i].iov_base = (void *)ofields[f].field;
63 vec[i].iov_len = strlen(vec[i].iov_base);
64 vec[i+1].iov_base = ",";
65 vec[i+1].iov_len = 1;
66 memcpy(&sql[f*3], "%s,", 3);
67 }
68 sql[nfs*3-1] = '\0';
69 vec[i-1].iov_base = ") VALUES (";
70 vec[i-1].iov_len = 10;
71 vec[i].iov_base = sql;
72 vec[i].iov_len = nfs*3-1;
73 vec[i+1].iov_base = ")";
74 vec[i+1].iov_len = 1;
75 sql = apr_pstrcatv(p, vec, i+2, NULL);
76 printf("SQL: %s\n", sql);
77 cfg->dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *)); 112 cfg->dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *));
78 rv = apr_dbd_prepare(cfg->dbconn->driver, cfg->pool, cfg->dbconn->dbd,
79 sql, "INSERT", &(cfg->dbconn->stmt));
80 if (rv) {
81 printf("DB Error: %s\n", apr_dbd_error(cfg->dbconn->driver,
82 cfg->dbconn->dbd, rv));
83 return rv;
84 }
85 } 113 }
86 for (f=0; f<nfs; f++) { 114 for (f=0; f<nfs; f++) {
87 cfg->dbconn->args[f] = apr_table_get(data, ofields[f].field); 115 cfg->dbconn->args[f] = apr_table_get(data, ofields[f].field);
@@ -95,3 +123,5 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data)
95 } 123 }
96 return APR_SUCCESS; 124 return APR_SUCCESS;
97} 125}
126
127/** @todo implement transactions */