- Spelling checked
[sip-router] / db / db.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27  /*
28   * History:
29   * --------
30   *  2004-06-06  bind_dbmod takes dbf as parameter (andrei)
31   */
32
33
34 #include "db.h"
35 #include "../dprint.h"
36 #include "../sr_module.h"
37 #include "../mem/mem.h"
38 #include "../str.h"
39 #include "../ut.h"
40
41
42
43 /* fills mydbf with the corresponding db module callbacks
44  * returns 0 on success, -1 on error
45  * on error mydbf will contain only 0s */
46 int bind_dbmod(char* mod, db_func_t* mydbf)
47 {
48         char* tmp, *p;
49         int len;
50         db_func_t dbf;
51
52         if (!mod) {
53                 LOG(L_CRIT, "BUG: bind_dbmod(): null database module name\n");
54                 return -1;
55         }
56         if (mydbf==0) {
57                 LOG(L_CRIT, "BUG: bind_dbmod(): null dbf parameter\n");
58                 return -1;
59         }
60         /* for safety we initialize mydbf with 0 (this will cause
61          *  a segfault immediately if someone tries to call a function
62          *  from it without checking the return code from bind_dbmod -- andrei */
63         memset((void*)mydbf, 0, sizeof(db_func_t));
64
65         p = strchr(mod, ':');
66         if (p) {
67                 len = p - mod;
68                 tmp = (char*)pkg_malloc(len + 1);
69                 if (!tmp) {
70                         LOG(L_ERR, "ERROR: bind_dbmod(): No memory left\n");
71                         return -1;
72                 }
73                 memcpy(tmp, mod, len);
74                 tmp[len] = '\0';
75         } else {
76                 tmp = mod;
77         }
78
79         dbf.use_table = (db_use_table_f)find_mod_export(tmp, "db_use_table", 2, 0);
80         if (dbf.use_table == 0) goto err;
81
82         dbf.init = (db_init_f)find_mod_export(tmp, "db_init", 1, 0);
83         if (dbf.init == 0) goto err;
84
85         dbf.close = (db_close_f)find_mod_export(tmp, "db_close", 2, 0);
86         if (dbf.close == 0) goto err;
87
88         dbf.query = (db_query_f)find_mod_export(tmp, "db_query", 2, 0);
89         if (dbf.query == 0) goto err;
90
91         dbf.raw_query = (db_raw_query_f)find_mod_export(tmp, "db_raw_query", 2, 0);
92         if (dbf.raw_query == 0) goto err;
93
94         dbf.free_result = (db_free_result_f)find_mod_export(tmp, "db_free_result", 2,
95                                                                                                                 0);
96         if (dbf.free_result == 0) goto err;
97
98         dbf.insert = (db_insert_f)find_mod_export(tmp, "db_insert", 2, 0);
99         if (dbf.insert == 0) goto err;
100
101         dbf.delete = (db_delete_f)find_mod_export(tmp, "db_delete", 2, 0);
102         if (dbf.delete == 0) goto err;
103
104         dbf.update = (db_update_f)find_mod_export(tmp, "db_update", 2, 0);
105         if (dbf.update == 0) goto err;
106
107         *mydbf=dbf; /* copy */
108         return 0;
109
110  err:
111         if (tmp != mod) pkg_free(tmp);
112         return -1;
113 }
114
115
116 /*
117  * Get version of a table
118  * If there is no row for the given table, return version 0
119  */
120 int table_version(db_func_t* dbf, db_con_t* connection, const str* table)
121 {
122         db_key_t key[1], col[1];
123         db_val_t val[1];
124         db_res_t* res;
125         int ret;
126
127         if (!dbf||!connection || !table) {
128                 LOG(L_CRIT, "BUG: table_version(): Invalid parameter value\n");
129                 return -1;
130         }
131
132         if (dbf->use_table(connection, VERSION_TABLE) < 0) {
133                 LOG(L_ERR, "table_version(): Error while changing table\n");
134                 return -1;
135         }
136
137         key[0] = TABLENAME_COLUMN;
138
139         VAL_TYPE(val) = DB_STR;
140         VAL_NULL(val) = 0;
141         VAL_STR(val) = *table;
142         
143         col[0] = VERSION_COLUMN;
144         
145         if (dbf->query(connection, key, 0, val, col, 1, 1, 0, &res) < 0) {
146                 LOG(L_ERR, "table_version(): Error in db_query\n");
147                 return -1;
148         }
149
150         if (RES_ROW_N(res) == 0) {
151                 DBG("table_version(): No row for table %.*s found\n", table->len, ZSW(table->s));
152                 return 0;
153         }
154
155         if (RES_ROW_N(res) != 1) {
156                 LOG(L_ERR, "table_version(): Invalid number of rows received: %d, %.*s\n", RES_ROW_N(res), table->len, ZSW(table->s));
157                 dbf->free_result(connection, res);
158                 return -1;
159         }
160
161         ret = VAL_INT(ROW_VALUES(RES_ROWS(res)));
162         dbf->free_result(connection, res);
163         return ret;
164 }