00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #include "gwlib.h"
00069 #include "dbpool.h"
00070 #include "dbpool_p.h"
00071
00072 #ifdef HAVE_DBPOOL
00073
00074 #include "dbpool_mysql.c"
00075 #include "dbpool_oracle.c"
00076 #include "dbpool_sqlite.c"
00077 #include "dbpool_sqlite3.c"
00078 #include "dbpool_sdb.c"
00079 #include "dbpool_pgsql.c"
00080
00081
00082 static void dbpool_conn_destroy(DBPoolConn *conn)
00083 {
00084 gw_assert(conn != NULL);
00085
00086 if (conn->conn != NULL)
00087 conn->pool->db_ops->close(conn->conn);
00088
00089 gw_free(conn);
00090 }
00091
00092
00093
00094
00095
00096
00097 DBPool *dbpool_create(enum db_type db_type, DBConf *conf, unsigned int connections)
00098 {
00099 DBPool *p;
00100
00101 if (conf == NULL)
00102 return NULL;
00103
00104 p = gw_malloc(sizeof(DBPool));
00105 gw_assert(p != NULL);
00106 p->pool = gwlist_create();
00107 gwlist_add_producer(p->pool);
00108 p->max_size = connections;
00109 p->curr_size = 0;
00110 p->conf = conf;
00111 p->db_type = db_type;
00112
00113 switch(db_type) {
00114 #ifdef HAVE_MYSQL
00115 case DBPOOL_MYSQL:
00116 p->db_ops = &mysql_ops;
00117 break;
00118 #endif
00119 #ifdef HAVE_ORACLE
00120 case DBPOOL_ORACLE:
00121 p->db_ops = &oracle_ops;
00122 break;
00123 #endif
00124 #ifdef HAVE_SQLITE
00125 case DBPOOL_SQLITE:
00126 p->db_ops = &sqlite_ops;
00127 break;
00128 #endif
00129 #ifdef HAVE_SQLITE3
00130 case DBPOOL_SQLITE3:
00131 p->db_ops = &sqlite3_ops;
00132 break;
00133 #endif
00134 #ifdef HAVE_SDB
00135 case DBPOOL_SDB:
00136 p->db_ops = &sdb_ops;
00137 break;
00138 #endif
00139 #ifdef HAVE_PGSQL
00140 case DBPOOL_PGSQL:
00141 p->db_ops = &pgsql_ops;
00142 break;
00143 #endif
00144 default:
00145 panic(0, "Unknown dbpool type defined.");
00146 }
00147
00148
00149
00150
00151
00152 dbpool_increase(p, connections);
00153
00154 return p;
00155 }
00156
00157
00158 void dbpool_destroy(DBPool *p)
00159 {
00160
00161 if (p == NULL)
00162 return;
00163
00164 gw_assert(p->pool != NULL && p->db_ops != NULL);
00165
00166 gwlist_remove_producer(p->pool);
00167 gwlist_destroy(p->pool, (void*) dbpool_conn_destroy);
00168
00169 p->db_ops->conf_destroy(p->conf);
00170 gw_free(p);
00171 }
00172
00173
00174 unsigned int dbpool_increase(DBPool *p, unsigned int count)
00175 {
00176 unsigned int i, opened = 0;
00177
00178 gw_assert(p != NULL && p->conf != NULL && p->db_ops != NULL && p->db_ops->open != NULL);
00179
00180
00181
00182 gwlist_lock(p->pool);
00183
00184
00185 for (i=0; i < count && p->curr_size < p->max_size; i++) {
00186 void *conn = p->db_ops->open(p->conf);
00187 if (conn != NULL) {
00188 DBPoolConn *pc = gw_malloc(sizeof(DBPoolConn));
00189 gw_assert(pc != NULL);
00190
00191 pc->conn = conn;
00192 pc->pool = p;
00193
00194 p->curr_size++;
00195 opened++;
00196 gwlist_produce(p->pool, pc);
00197 }
00198 }
00199
00200
00201 gwlist_unlock(p->pool);
00202
00203 return opened;
00204 }
00205
00206
00207 unsigned int dbpool_decrease(DBPool *p, unsigned int c)
00208 {
00209 unsigned int i;
00210
00211 gw_assert(p != NULL && p->pool != NULL && p->db_ops != NULL && p->db_ops->close != NULL);
00212
00213
00214 gwlist_lock(p->pool);
00215
00216
00217
00218
00219 for (i = 0; i < c; i++) {
00220 DBPoolConn *pc;
00221
00222
00223 pc = gwlist_extract_first(p->pool);
00224
00225
00226 if (pc == NULL)
00227 break;
00228
00229
00230 dbpool_conn_destroy(pc);
00231 p->curr_size--;
00232 }
00233
00234
00235 gwlist_unlock(p->pool);
00236
00237 return i;
00238 }
00239
00240
00241 long dbpool_conn_count(DBPool *p)
00242 {
00243 gw_assert(p != NULL && p->pool != NULL);
00244
00245 return gwlist_len(p->pool);
00246 }
00247
00248
00249 DBPoolConn *dbpool_conn_consume(DBPool *p)
00250 {
00251 DBPoolConn *pc;
00252
00253 gw_assert(p != NULL && p->pool != NULL);
00254
00255
00256 if (p->max_size < 1)
00257 return NULL;
00258
00259
00260 while (p->curr_size < 1) {
00261 debug("dbpool", 0, "DBPool has no connections, reconnecting up to maximum...");
00262
00263 dbpool_increase(p, p->max_size - p->curr_size);
00264 if (p->curr_size < 1)
00265 gwthread_sleep(0.1);
00266 }
00267
00268
00269 while ((pc = gwlist_consume(p->pool)) != NULL) {
00270
00271
00272
00273
00274
00275 if (!pc->conn || (p->db_ops->check && p->db_ops->check(pc->conn) != 0)) {
00276
00277
00278 gwlist_lock(p->pool);
00279 dbpool_conn_destroy(pc);
00280 p->curr_size--;
00281
00282 gwlist_unlock(p->pool);
00283
00284
00285
00286
00287
00288 while (p->curr_size < 1) {
00289 debug("dbpool", 0, "DBPool has too few connections, reconnecting up to maximum...");
00290
00291 dbpool_increase(p, p->max_size - p->curr_size);
00292 if (p->curr_size < 1)
00293 gwthread_sleep(0.1);
00294 }
00295
00296 } else {
00297 break;
00298 }
00299 }
00300
00301 return (pc->conn != NULL ? pc : NULL);
00302 }
00303
00304
00305 void dbpool_conn_produce(DBPoolConn *pc)
00306 {
00307 gw_assert(pc != NULL && pc->conn != NULL && pc->pool != NULL && pc->pool->pool != NULL);
00308
00309 gwlist_produce(pc->pool->pool, pc);
00310 }
00311
00312
00313 unsigned int dbpool_check(DBPool *p)
00314 {
00315 long i, len, n = 0, reinit = 0;
00316
00317 gw_assert(p != NULL && p->pool != NULL && p->db_ops != NULL);
00318
00319
00320
00321
00322
00323
00324 if (p->db_ops->check == NULL)
00325 return gwlist_len(p->pool);
00326
00327 gwlist_lock(p->pool);
00328 len = gwlist_len(p->pool);
00329 for (i = 0; i < len; i++) {
00330 DBPoolConn *pconn;
00331
00332 pconn = gwlist_get(p->pool, i);
00333 if (p->db_ops->check(pconn->conn) != 0) {
00334
00335 gwlist_delete(p->pool, i, 1);
00336 dbpool_conn_destroy(pconn);
00337 p->curr_size--;
00338 reinit++;
00339 len--;
00340 i--;
00341 } else {
00342 n++;
00343 }
00344 }
00345 gwlist_unlock(p->pool);
00346
00347
00348 if (reinit > 0)
00349 n += dbpool_increase(p, reinit);
00350
00351
00352 return n;
00353 }
00354
00355
00356 int dbpool_conn_select(DBPoolConn *conn, const Octstr *sql, List *binds, List **result)
00357 {
00358 if (sql == NULL || conn == NULL)
00359 return -1;
00360
00361 if (conn->pool->db_ops->select == NULL)
00362 return -1;
00363
00364 return conn->pool->db_ops->select(conn->conn, sql, binds, result);
00365 }
00366
00367
00368 int dbpool_conn_update(DBPoolConn *conn, const Octstr *sql, List *binds)
00369 {
00370 if (sql == NULL || conn == NULL)
00371 return -1;
00372
00373 if (conn->pool->db_ops->update == NULL)
00374 return -1;
00375
00376 return conn->pool->db_ops->update(conn->conn, sql, binds);
00377 }
00378
00379 #endif
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.