bdb_con.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * BDB Database Driver for SER
00005  *
00006  * Copyright (C) 2008 iptelorg GmbH
00007  *
00008  * This file is part of SIP-router, a free SIP server.
00009  *
00010  * SIP-router is free software; you can redistribute it and/or modify it under the
00011  * terms of the GNU General Public License as published by the Free Software
00012  * Foundation; either version 2 of the License, or (at your option) any later
00013  * version.
00014  *
00015  * SIP-router is distributed in the hope that it will be useful, but WITHOUT ANY
00016  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00018  * details.
00019  *
00020  * You should have received a copy of the GNU General Public License along
00021  * with this program; if not, write to the Free Software Foundation, Inc.,
00022  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00023  */
00024 
00035 #include <stdlib.h>
00036 #include <string.h>
00037 
00038 #include "../../mem/mem.h"
00039 #include "../../dprint.h"
00040 #include "../../ut.h"
00041 
00042 #include "bdb_con.h"
00043 #include "bdb_uri.h"
00044 #include "bdb_lib.h"
00045 
00052 static void bdb_con_free(db_con_t* con, bdb_con_t *payload)
00053 {
00054         bdb_uri_t *buri;
00055         if (!payload)
00056                 return;
00057 
00058         buri = DB_GET_PAYLOAD(con->uri);
00059 
00060         /* Delete the structure only if there are no more references
00061          * to it in the connection pool
00062          */
00063         if (db_pool_remove((db_pool_entry_t*)payload) == 0) return;
00064 
00065         db_pool_entry_free(&payload->gen);
00066 
00067         /* destroy and free BDB env */
00068         pkg_free(payload);
00069 }
00070 
00071 
00072 int bdb_con(db_con_t* con)
00073 {
00074         bdb_con_t* bcon;
00075         bdb_uri_t* buri;
00076 
00077         buri = DB_GET_PAYLOAD(con->uri);
00078 
00079         /* First try to lookup the connection in the connection pool and
00080          * re-use it if a match is found
00081          */
00082         bcon = (bdb_con_t*)db_pool_get(con->uri);
00083         if (bcon) {
00084                 DBG("bdb: Connection to %s found in connection pool\n",
00085                         buri->uri);
00086                 goto found;
00087         }
00088 
00089         bcon = (bdb_con_t*)pkg_malloc(sizeof(bdb_con_t));
00090         if (!bcon) {
00091                 ERR("bdb: No memory left\n");
00092                 goto error;
00093         }
00094         memset(bcon, '\0', sizeof(bdb_con_t));
00095         if (db_pool_entry_init(&bcon->gen, bdb_con_free, con->uri) < 0) goto error;
00096 
00097         DBG("bdb: Preparing new connection to %s\n", buri->uri);
00098         if(bdb_is_database(buri->path.s)!=0)
00099         {       
00100                 ERR("bdb: database [%.*s] does not exists!\n",
00101                                 buri->path.len, buri->path.s);
00102                 goto error;
00103         }
00104 
00105         /* Put the newly created BDB connection into the pool */
00106         db_pool_put((struct db_pool_entry*)bcon);
00107         DBG("bdb: Connection stored in connection pool\n");
00108 
00109 found:
00110         /* Attach driver payload to the db_con structure and set connect and
00111          * disconnect functions
00112          */
00113         DB_SET_PAYLOAD(con, bcon);
00114         con->connect = bdb_con_connect;
00115         con->disconnect = bdb_con_disconnect;
00116         return 0;
00117 
00118 error:
00119         if (bcon) {
00120                 db_pool_entry_free(&bcon->gen);
00121                 pkg_free(bcon);
00122         }
00123         return -1;
00124 }
00125 
00126 
00127 
00128 int bdb_con_connect(db_con_t* con)
00129 {
00130         bdb_con_t *bcon;
00131         bdb_uri_t *buri;
00132 
00133         bcon = DB_GET_PAYLOAD(con);
00134         buri = DB_GET_PAYLOAD(con->uri);
00135 
00136         /* Do not reconnect already connected connections */
00137         if (bcon->flags & BDB_CONNECTED) return 0;
00138 
00139         DBG("bdb: Connecting to %s\n", buri->uri);
00140 
00141         /* create BDB environment */
00142         bcon->dbp = bdblib_get_db(&buri->path);
00143         if(bcon->dbp == NULL)
00144         {
00145                 ERR("bdb: error binding to DB %s\n", buri->uri);
00146                 return -1;
00147         }
00148 
00149         DBG("bdb: Successfully bound to %s\n", buri->uri);
00150         bcon->flags |= BDB_CONNECTED;
00151         return 0;
00152 
00153 }
00154 
00155 
00156 void bdb_con_disconnect(db_con_t* con)
00157 {
00158         bdb_con_t *bcon;
00159         bdb_uri_t *buri;
00160 
00161         bcon = DB_GET_PAYLOAD(con);
00162         buri = DB_GET_PAYLOAD(con->uri);
00163 
00164         if ((bcon->flags & BDB_CONNECTED) == 0) return;
00165 
00166         DBG("bdb: Unbinding from %s\n", buri->uri);
00167         if(bcon->dbp==NULL)
00168         {
00169                 bcon->flags &= ~BDB_CONNECTED;
00170                 return;
00171         }
00172 
00173         bdblib_close(bcon->dbp, &buri->path);
00174         bcon->dbp = 0;
00175 
00176         bcon->flags &= ~BDB_CONNECTED;
00177 }
00178 
00179