1 /*
2 * BDB Database Driver for SER
3 *
4 * Copyright (C) 2008 iptelorg GmbH
5 *
6 * This file is part of Kamailio, a free SIP server.
7 *
8 * Kamailio is free software; you can redistribute it and/or modify it under the
9 * terms of the GNU General Public License as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option) any later
11 * version.
12 *
13 * Kamailio is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 /** \addtogroup bdb
24 * @{
25 */
26
27 /*! \file
28 * Functions related to connections to BDB.
29 *
30 * \ingroup database
31 */
32
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "../../core/mem/mem.h"
37 #include "../../core/dprint.h"
38 #include "../../core/ut.h"
39
40 #include "bdb_con.h"
41 #include "bdb_uri.h"
42 #include "bdb_lib.h"
43
44 /** Free all memory allocated for a bdb_con structure.
45 * This function function frees all memory that is in use by
46 * a bdb_con structure.
47 * @param con A generic db_con connection structure.
48 * @param payload BDB specific payload to be freed.
49 */
bdb_con_free(db_con_t * con,bdb_con_t * payload)50 static void bdb_con_free(db_con_t *con, bdb_con_t *payload)
51 {
52 if(!payload)
53 return;
54
55 /* Delete the structure only if there are no more references
56 * to it in the connection pool
57 */
58 if(db_pool_remove((db_pool_entry_t *)payload) == 0)
59 return;
60
61 db_pool_entry_free(&payload->gen);
62
63 /* destroy and free BDB env */
64 pkg_free(payload);
65 }
66
67
bdb_con(db_con_t * con)68 int bdb_con(db_con_t *con)
69 {
70 bdb_con_t *bcon;
71 bdb_uri_t *buri;
72
73 buri = DB_GET_PAYLOAD(con->uri);
74
75 /* First try to lookup the connection in the connection pool and
76 * re-use it if a match is found
77 */
78 bcon = (bdb_con_t *)db_pool_get(con->uri);
79 if(bcon) {
80 DBG("bdb: Connection to %s found in connection pool\n", buri->uri);
81 goto found;
82 }
83
84 bcon = (bdb_con_t *)pkg_malloc(sizeof(bdb_con_t));
85 if(!bcon) {
86 ERR("bdb: No memory left\n");
87 goto error;
88 }
89 memset(bcon, '\0', sizeof(bdb_con_t));
90 if(db_pool_entry_init(&bcon->gen, bdb_con_free, con->uri) < 0)
91 goto error;
92
93 DBG("bdb: Preparing new connection to %s\n", buri->uri);
94 if(bdb_is_database(buri->path.s) != 0) {
95 ERR("bdb: database [%.*s] does not exists!\n", buri->path.len,
96 buri->path.s);
97 goto error;
98 }
99
100 /* Put the newly created BDB connection into the pool */
101 db_pool_put((struct db_pool_entry *)bcon);
102 DBG("bdb: Connection stored in connection pool\n");
103
104 found:
105 /* Attach driver payload to the db_con structure and set connect and
106 * disconnect functions
107 */
108 DB_SET_PAYLOAD(con, bcon);
109 con->connect = bdb_con_connect;
110 con->disconnect = bdb_con_disconnect;
111 return 0;
112
113 error:
114 if(bcon) {
115 db_pool_entry_free(&bcon->gen);
116 pkg_free(bcon);
117 }
118 return -1;
119 }
120
121
bdb_con_connect(db_con_t * con)122 int bdb_con_connect(db_con_t *con)
123 {
124 bdb_con_t *bcon;
125 bdb_uri_t *buri;
126
127 bcon = DB_GET_PAYLOAD(con);
128 buri = DB_GET_PAYLOAD(con->uri);
129
130 /* Do not reconnect already connected connections */
131 if(bcon->flags & BDB_CONNECTED)
132 return 0;
133
134 DBG("bdb: Connecting to %s\n", buri->uri);
135
136 /* create BDB environment */
137 bcon->dbp = bdblib_get_db(&buri->path);
138 if(bcon->dbp == NULL) {
139 ERR("bdb: error binding to DB %s\n", buri->uri);
140 return -1;
141 }
142
143 DBG("bdb: Successfully bound to %s\n", buri->uri);
144 bcon->flags |= BDB_CONNECTED;
145 return 0;
146 }
147
148
bdb_con_disconnect(db_con_t * con)149 void bdb_con_disconnect(db_con_t *con)
150 {
151 bdb_con_t *bcon;
152 bdb_uri_t *buri;
153
154 bcon = DB_GET_PAYLOAD(con);
155 buri = DB_GET_PAYLOAD(con->uri);
156
157 if((bcon->flags & BDB_CONNECTED) == 0)
158 return;
159
160 DBG("bdb: Unbinding from %s\n", buri->uri);
161 if(bcon->dbp == NULL) {
162 bcon->flags &= ~BDB_CONNECTED;
163 return;
164 }
165
166 bdblib_close(bcon->dbp, &buri->path);
167 bcon->dbp = 0;
168
169 bcon->flags &= ~BDB_CONNECTED;
170 }
171
172
173 /** @} */
174