diff options
author | Edward Rudd <urkle@outoforder.cc> | 2009-03-14 22:07:56 (GMT) |
---|---|---|
committer | Edward Rudd <urkle@outoforder.cc> | 2009-03-14 22:07:56 (GMT) |
commit | b8790b1b48c238f2ba266e34625b8e8f5db0ad6e (patch) | |
tree | a9c7b08bc4ed3ee59aaf574f5f1738efa915fadc /utility/database.c | |
parent | 99867e8a2eca4421075900e44f24cfd749db7dcb (diff) |
refactoroed to allo wdb connections to be per-thread
added initial threading implementation using apr_queues and apr_thread_pools
Diffstat (limited to 'utility/database.c')
-rw-r--r-- | utility/database.c | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/utility/database.c b/utility/database.c index 98c203b..ff81caa 100644 --- a/utility/database.c +++ b/utility/database.c | |||
@@ -19,15 +19,16 @@ void database_init(apr_pool_t *p) | |||
19 | apr_dbd_init(p); | 19 | apr_dbd_init(p); |
20 | } | 20 | } |
21 | 21 | ||
22 | apr_status_t database_connect(config_t *cfg) | 22 | /** @todo split this into load and connect */ |
23 | apr_status_t database_connect(config_t *cfg, config_dbd_t **dbconn) | ||
23 | { | 24 | { |
24 | apr_status_t rv; | 25 | apr_status_t rv; |
25 | if (!cfg->dbdriver || !cfg->dbparams) | 26 | if (!cfg->dbdriver || !cfg->dbparams) |
26 | return APR_EINVAL; | 27 | return APR_EINVAL; |
27 | if (!cfg->dbconn) { | 28 | if (!*dbconn) { |
28 | cfg->dbconn = apr_pcalloc(cfg->pool, sizeof(config_dbd_t)); | 29 | *dbconn = apr_pcalloc(cfg->pool, sizeof(config_dbd_t)); |
29 | } | 30 | } |
30 | rv = apr_dbd_get_driver(cfg->pool, cfg->dbdriver, &(cfg->dbconn->driver)); | 31 | rv = apr_dbd_get_driver(cfg->pool, cfg->dbdriver, &((*dbconn)->driver)); |
31 | if (rv) { | 32 | if (rv) { |
32 | 33 | ||
33 | logging_log(cfg, LOGLEVEL_ERROR, | 34 | logging_log(cfg, LOGLEVEL_ERROR, |
@@ -36,8 +37,8 @@ apr_status_t database_connect(config_t *cfg) | |||
36 | return rv; | 37 | return rv; |
37 | } | 38 | } |
38 | 39 | ||
39 | rv = apr_dbd_open(cfg->dbconn->driver, cfg->pool, cfg->dbparams, | 40 | rv = apr_dbd_open((*dbconn)->driver, cfg->pool, cfg->dbparams, |
40 | &(cfg->dbconn->dbd)); | 41 | &((*dbconn)->dbd)); |
41 | if (rv) { | 42 | if (rv) { |
42 | logging_log(cfg, LOGLEVEL_ERROR, | 43 | logging_log(cfg, LOGLEVEL_ERROR, |
43 | "DB: Could not connect to database. Error (%d)%s", rv, | 44 | "DB: Could not connect to database. Error (%d)%s", rv, |
@@ -48,12 +49,13 @@ apr_status_t database_connect(config_t *cfg) | |||
48 | return APR_SUCCESS; | 49 | return APR_SUCCESS; |
49 | } | 50 | } |
50 | 51 | ||
51 | apr_status_t database_disconnect(config_t *cfg) | 52 | apr_status_t database_disconnect(config_dbd_t *dbconn) |
52 | { | 53 | { |
53 | return apr_dbd_close(cfg->dbconn->driver, cfg->dbconn->dbd); | 54 | return apr_dbd_close(dbconn->driver, dbconn->dbd); |
54 | } | 55 | } |
55 | 56 | ||
56 | static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, apr_pool_t *p) | 57 | static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, |
58 | config_dbd_t *dbconn, apr_pool_t *p) | ||
57 | { | 59 | { |
58 | apr_status_t rv; | 60 | apr_status_t rv; |
59 | char *sql; | 61 | char *sql; |
@@ -93,19 +95,20 @@ static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, apr_pool_t *p) | |||
93 | 95 | ||
94 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Generated SQL: %s", sql); | 96 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Generated SQL: %s", sql); |
95 | 97 | ||
96 | rv = apr_dbd_prepare(cfg->dbconn->driver, cfg->pool, cfg->dbconn->dbd, sql, | 98 | rv = apr_dbd_prepare(dbconn->driver, cfg->pool, dbconn->dbd, sql, |
97 | "INSERT", &stmt); | 99 | "INSERT", &stmt); |
98 | 100 | ||
99 | if (rv) { | 101 | if (rv) { |
100 | logging_log(cfg, LOGLEVEL_NOISE, | 102 | logging_log(cfg, LOGLEVEL_NOISE, |
101 | "DB: Unable to Prepare SQL insert: %s", apr_dbd_error( | 103 | "DB: Unable to Prepare SQL insert: %s", apr_dbd_error( |
102 | cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | 104 | dbconn->driver, dbconn->dbd, rv)); |
103 | return NULL; | 105 | return NULL; |
104 | } | 106 | } |
105 | return stmt; | 107 | return stmt; |
106 | } | 108 | } |
107 | 109 | ||
108 | apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | 110 | apr_status_t database_insert(config_t *cfg, config_dbd_t *dbconn, |
111 | apr_pool_t *p, apr_table_t *data) | ||
109 | { | 112 | { |
110 | apr_status_t rv; | 113 | apr_status_t rv; |
111 | int f, nfs; | 114 | int f, nfs; |
@@ -113,93 +116,95 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | |||
113 | ofields = (config_output_field_t *)cfg->output_fields->elts; | 116 | ofields = (config_output_field_t *)cfg->output_fields->elts; |
114 | nfs = cfg->output_fields->nelts; | 117 | nfs = cfg->output_fields->nelts; |
115 | // Prepare statement | 118 | // Prepare statement |
116 | if (!cfg->dbconn->stmt) { | 119 | if (!dbconn->stmt) { |
117 | cfg->dbconn->stmt = database_prepare_insert(cfg, p); | 120 | dbconn->stmt = database_prepare_insert(cfg, dbconn, p); |
118 | if (!cfg->dbconn->stmt) { | 121 | if (!dbconn->stmt) { |
119 | return APR_EINVAL; | 122 | return APR_EINVAL; |
120 | } | 123 | } |
121 | cfg->dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *)); | 124 | dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *)); |
122 | } | 125 | } |
123 | for (f=0; f<nfs; f++) { | 126 | for (f=0; f<nfs; f++) { |
124 | cfg->dbconn->args[f] = apr_table_get(data, ofields[f].field); | 127 | dbconn->args[f] = apr_table_get(data, ofields[f].field); |
125 | } | 128 | } |
126 | rv = apr_dbd_pquery(cfg->dbconn->driver, p, cfg->dbconn->dbd, &f, | 129 | rv = apr_dbd_pquery(dbconn->driver, p, dbconn->dbd, &f, |
127 | cfg->dbconn->stmt, nfs, cfg->dbconn->args); | 130 | dbconn->stmt, nfs, dbconn->args); |
128 | if (rv) { | 131 | if (rv) { |
129 | logging_log(cfg, LOGLEVEL_ERROR, "DB: Unable to Insert SQL: %s", | 132 | logging_log(cfg, LOGLEVEL_ERROR, "DB: Unable to Insert SQL: %s", |
130 | apr_dbd_error(cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | 133 | apr_dbd_error(dbconn->driver, dbconn->dbd, rv)); |
131 | return rv; | 134 | return rv; |
132 | } | 135 | } |
133 | return APR_SUCCESS; | 136 | return APR_SUCCESS; |
134 | } | 137 | } |
135 | 138 | ||
136 | apr_status_t database_trans_start(config_t *cfg, apr_pool_t *p) | 139 | apr_status_t database_trans_start(config_t *cfg, config_dbd_t *dbconn, |
140 | apr_pool_t *p) | ||
137 | { | 141 | { |
138 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | 142 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET |
139 | apr_status_t rv; | 143 | apr_status_t rv; |
140 | if (!cfg->transactions) | 144 | if (!cfg->transactions) |
141 | return APR_SUCCESS; | 145 | return APR_SUCCESS; |
142 | if (cfg->dbconn->txn) { | 146 | if (dbconn->txn) { |
143 | logging_log(cfg, LOGLEVEL_NOISE, | 147 | logging_log(cfg, LOGLEVEL_NOISE, |
144 | "Transaction Already Started. Something is BROKE"); | 148 | "Transaction Already Started. Something is BROKE"); |
145 | return APR_EINVAL; | 149 | return APR_EINVAL; |
146 | } | 150 | } |
147 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Starting Transaction"); | 151 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Starting Transaction"); |
148 | rv = apr_dbd_transaction_start(cfg->dbconn->driver, p, cfg->dbconn->dbd, | 152 | rv = apr_dbd_transaction_start(dbconn->driver, p, dbconn->dbd, |
149 | &cfg->dbconn->txn); | 153 | &dbconn->txn); |
150 | if (rv) | 154 | if (rv) |
151 | logging_log(cfg, LOGLEVEL_NOISE, | 155 | logging_log(cfg, LOGLEVEL_NOISE, |
152 | "DB: Error Starting Transaction: (%d)%s", rv, apr_dbd_error( | 156 | "DB: Error Starting Transaction: (%d)%s", rv, apr_dbd_error( |
153 | cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | 157 | dbconn->driver, dbconn->dbd, rv)); |
154 | return rv; | 158 | return rv; |
155 | #else | 159 | #else |
156 | return APR_SUCCESS; | 160 | return APR_SUCCESS; |
157 | #endif | 161 | #endif |
158 | } | 162 | } |
159 | 163 | ||
160 | apr_status_t database_trans_stop(config_t *cfg, apr_pool_t *p) | 164 | apr_status_t database_trans_stop(config_t *cfg, config_dbd_t *dbconn, |
165 | apr_pool_t *p) | ||
161 | { | 166 | { |
162 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | 167 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET |
163 | apr_status_t rv; | 168 | apr_status_t rv; |
164 | if (!cfg->transactions) | 169 | if (!cfg->transactions) |
165 | return APR_SUCCESS; | 170 | return APR_SUCCESS; |
166 | if (!cfg->dbconn->txn) { | 171 | if (!dbconn->txn) { |
167 | logging_log(cfg, LOGLEVEL_NOISE, | 172 | logging_log(cfg, LOGLEVEL_NOISE, |
168 | "No Transaction Started. Something is BROKE"); | 173 | "No Transaction Started. Something is BROKE"); |
169 | return APR_EINVAL; | 174 | return APR_EINVAL; |
170 | } | 175 | } |
171 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Stopping Transaction"); | 176 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Stopping Transaction"); |
172 | rv = apr_dbd_transaction_end(cfg->dbconn->driver, p, cfg->dbconn->txn); | 177 | rv = apr_dbd_transaction_end(dbconn->driver, p, dbconn->txn); |
173 | if (rv) | 178 | if (rv) |
174 | logging_log(cfg, LOGLEVEL_NOISE, | 179 | logging_log(cfg, LOGLEVEL_NOISE, |
175 | "DB: Error Stopping Transaction: (%d)%s", rv, apr_dbd_error( | 180 | "DB: Error Stopping Transaction: (%d)%s", rv, apr_dbd_error( |
176 | cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | 181 | dbconn->driver, dbconn->dbd, rv)); |
177 | 182 | ||
178 | cfg->dbconn->txn = NULL; | 183 | dbconn->txn = NULL; |
179 | return rv; | 184 | return rv; |
180 | #else | 185 | #else |
181 | return APR_SUCCESS; | 186 | return APR_SUCCESS; |
182 | #endif | 187 | #endif |
183 | } | 188 | } |
184 | 189 | ||
185 | apr_status_t database_trans_abort(config_t *cfg) | 190 | apr_status_t database_trans_abort(config_t *cfg, config_dbd_t *dbconn) |
186 | { | 191 | { |
187 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | 192 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET |
188 | apr_status_t rv; | 193 | apr_status_t rv; |
189 | if (!cfg->transactions) | 194 | if (!cfg->transactions) |
190 | return APR_SUCCESS; | 195 | return APR_SUCCESS; |
191 | if (!cfg->dbconn->txn) { | 196 | if (!dbconn->txn) { |
192 | logging_log(cfg, LOGLEVEL_NOISE, | 197 | logging_log(cfg, LOGLEVEL_NOISE, |
193 | "No Transaction Started. Something is BROKE"); | 198 | "No Transaction Started. Something is BROKE"); |
194 | return APR_EINVAL; | 199 | return APR_EINVAL; |
195 | } | 200 | } |
196 | logging_log(cfg, LOGLEVEL_NOTICE, "DB: Aborting Transaction"); | 201 | logging_log(cfg, LOGLEVEL_NOTICE, "DB: Aborting Transaction"); |
197 | rv = apr_dbd_transaction_mode_set(cfg->dbconn->driver, cfg->dbconn->txn, | 202 | rv = apr_dbd_transaction_mode_set(dbconn->driver, dbconn->txn, |
198 | APR_DBD_TRANSACTION_ROLLBACK); | 203 | APR_DBD_TRANSACTION_ROLLBACK); |
199 | if (rv) | 204 | if (rv) |
200 | logging_log(cfg, LOGLEVEL_NOISE, | 205 | logging_log(cfg, LOGLEVEL_NOISE, |
201 | "DB: Error Aborting Transaction: (%d)%s", rv, apr_dbd_error( | 206 | "DB: Error Aborting Transaction: (%d)%s", rv, apr_dbd_error( |
202 | cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | 207 | dbconn->driver, dbconn->dbd, rv)); |
203 | return rv; | 208 | return rv; |
204 | #else | 209 | #else |
205 | return APR_SUCCESS; | 210 | return APR_SUCCESS; |