all: updated FSF address in GPL text
[sip-router] / modules / pipelimit / pl_db.c
1 /*
2  * $Id$
3  *
4  * pipelimit module
5  *
6  * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com)
7  *
8  * This file is part of Kamailio, a free SIP server.
9  *
10  * Kamailio is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * Kamailio is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License 
21  * along with this program; if not, write to the Free Software 
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  */
24
25 /*! \file
26  * \ingroup pipelimit
27  * \brief pipelimit :: pl_db
28  */
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33
34 #include "../../dprint.h"
35 #include "../../ut.h"
36 #include "../../lib/srdb1/db.h"
37 #include "../../lib/srdb1/db_res.h"
38 #include "../../str.h"
39
40 #include "pl_ht.h"
41
42 #if 0
43 INSERT INTO version (table_name, table_version) values ('pl_pipes','1');
44 CREATE TABLE pl_pipes (
45   id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
46   pipeid VARCHAR(64) DEFAULT '' NOT NULL,
47   algorithm VARCHAR(32) DEFAULT '' NOT NULL,
48   plimit INT DEFAULT 0 NOT NULL,
49   CONSTRAINT pipeid_idx UNIQUE (pipeid)
50 ) ENGINE=MyISAM;
51 #endif
52
53 #define RLP_PIPEID_COL                  "pipeid"
54 #define RLP_LIMIT_COL                   "plimit"
55 #define RLP_ALGORITHM_COL               "algorithm"
56 #define RLP_TABLE_NAME                  "pl_pipes"
57
58
59 #define RLP_TABLE_VERSION       1
60 static int _rlp_table_version = RLP_TABLE_VERSION;
61 static db_func_t  pl_dbf;
62 static db1_con_t* pl_db_handle=0;
63
64 /*db */
65 str pl_db_url          = {NULL, 0};
66 str rlp_pipeid_col     = str_init(RLP_PIPEID_COL);
67 str rlp_limit_col      = str_init(RLP_LIMIT_COL);
68 str rlp_algorithm_col  = str_init(RLP_ALGORITHM_COL);
69 str rlp_table_name     = str_init(RLP_TABLE_NAME);
70
71 int pl_load_db(void);
72
73 int pl_connect_db(void)
74 {
75         if(pl_db_url.s==NULL)
76                 return -1;
77
78         if (pl_db_handle!=NULL)
79         {
80                 LM_CRIT("BUG - db connection found already open\n");
81                 return -1;
82         }
83
84         if ((pl_db_handle = pl_dbf.init(&pl_db_url)) == 0){
85                 
86                         return -1;
87         }
88         return 0;
89 }
90
91 void pl_disconnect_db(void)
92 {
93         if(pl_db_handle!=NULL)
94         {
95                 pl_dbf.close(pl_db_handle);
96                 pl_db_handle = 0;
97         }
98 }
99
100
101 /*! \brief Initialize and verify DB stuff*/
102 int pl_init_db(void)
103 {
104         int ret;
105
106         if(pl_db_url.s==NULL)
107                 return 1;
108
109         pl_db_url.len         = strlen(pl_db_url.s);
110         rlp_table_name.len    = strlen(rlp_table_name.s);
111         rlp_pipeid_col.len    = strlen(rlp_pipeid_col.s);
112         rlp_limit_col.len     = strlen(rlp_limit_col.s);
113         rlp_algorithm_col.len = strlen(rlp_algorithm_col.s);
114
115         if(rlp_table_name.len <= 0 || pl_db_url.len<=0)
116         {
117                 LM_INFO("no table name or db url - skipping loading from db\n");
118                 return 0;
119         }
120
121         /* Find a database module */
122         if (db_bind_mod(&pl_db_url, &pl_dbf) < 0)
123         {
124                 LM_ERR("Unable to bind to a database driver\n");
125                 return -1;
126         }
127         
128         if(pl_connect_db()!=0){
129                 
130                 LM_ERR("unable to connect to the database\n");
131                 return -1;
132         }
133         
134         _rlp_table_version = db_table_version(&pl_dbf, pl_db_handle,
135                         &rlp_table_name);
136         if (_rlp_table_version < 0) 
137         {
138                 LM_ERR("failed to query pipes table version\n");
139                 return -1;
140         } else if (_rlp_table_version != RLP_TABLE_VERSION) {
141                 LM_ERR("invalid table version (found %d , required %d)\n"
142                         "(use kamdbctl reinit)\n",
143                         _rlp_table_version, RLP_TABLE_VERSION);
144                 return -1;
145         }
146
147         ret = pl_load_db();
148
149         pl_disconnect_db();
150
151         return ret;
152 }
153
154 /*! \brief load pipe descriptions from DB*/
155 int pl_load_db(void)
156 {
157         int i, nr_rows;
158         int nrcols;
159         str pipeid;
160         int limit;
161         str algorithm;
162         db1_res_t * res;
163         db_val_t * values;
164         db_row_t * rows;
165         
166         db_key_t query_cols[3] = {&rlp_pipeid_col, &rlp_limit_col,
167                                                                 &rlp_algorithm_col};
168         
169         nrcols = 3;
170
171         if(pl_db_handle == NULL) {
172                 LM_ERR("invalid DB handler\n");
173                 return -1;
174         }
175
176         if (pl_dbf.use_table(pl_db_handle, &rlp_table_name) < 0)
177         {
178                 LM_ERR("error in use_table\n");
179                 return -1;
180         }
181
182         if(pl_dbf.query(pl_db_handle,0,0,0,query_cols,0,nrcols,0,&res) < 0)
183         {
184                 LM_ERR("error while querying database\n");
185                 return -1;
186         }
187
188         nr_rows = RES_ROW_N(res);
189         rows    = RES_ROWS(res);
190         if(nr_rows == 0)
191         {
192                 LM_WARN("no ratelimit pipes data in the db\n");
193                 pl_dbf.free_result(pl_db_handle, res);
194                 return 0;
195         }
196
197         for(i=0; i<nr_rows; i++)
198         {
199                 values = ROW_VALUES(rows+i);
200
201                 pipeid.s      = VAL_STR(values).s;
202                 pipeid.len    = strlen(pipeid.s);
203                 limit         = VAL_INT(values+1);
204                 algorithm.s   = VAL_STR(values+2).s;
205                 algorithm.len = strlen(algorithm.s);
206
207                 if(pl_pipe_add(&pipeid, &algorithm, limit) != 0)
208                         goto error;
209
210         }
211         pl_dbf.free_result(pl_db_handle, res);
212
213         pl_print_pipes();
214
215         return 0;
216
217 error:
218         pl_dbf.free_result(pl_db_handle, res);
219
220         return -1;
221 }
222
223