lib/srdb1: db_use_table() more suggestive error messages
[kamailio] / src / lib / srdb1 / db.c
1 /*
2  * Copyright (C) 2001-2003 FhG Fokus
3  * Copyright (C) 2007-2008 1&1 Internet AG
4  * 
5  * This file is part of Kamailio, a free SIP server.
6  *
7  * Kamailio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version
11  *
12  * Kamailio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License 
18  * along with this program; if not, write to the Free Software 
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 /**
23  * \file lib/srdb1/db.c
24  * \ingroup db1
25  * \brief Generic Database Interface
26  *
27  */
28 /*! \defgroup db DB: The Kamailio generic database interface
29  * This is a generic database interface for modules that need to utilize a
30  * database. The interface should be used by all modules that access database.
31  * The interface will be independent of the underlying database server.
32  * Notes:
33  * If possible, use the predefined macros if you need to access any structure
34  * attributes.
35  * For additional description, see the comments in the sources of mysql module.
36  *
37  * If you want to see more complicated examples of how the API could be used,
38  * take a look at the sources of the usrloc or auth modules.
39  * - \ref usrloc
40  * - \ref auth
41  *
42  * Implemented modules
43  * - \ref ../modules/db_berkeley
44  * - \ref ../modules/db_flatstore
45  * - \ref ../modules/db_text
46  * - \ref ../modules/db_mysql
47  * - \ref ../modules/db_oracle
48  * - \ref ../modules/db_postgres
49  * - \ref ../modules/db_unixodbc
50  */
51
52 #include "../../core/dprint.h"
53 #include "../../core/sr_module.h"
54 #include "../../core/mem/mem.h"
55 #include "../../core/ut.h"
56 #include "../../core/globals.h"
57 #include "db_cap.h"
58 #include "db_id.h"
59 #include "db_pool.h"
60 #include "db_query.h"
61 #include "db.h"
62
63 static unsigned int MAX_URL_LENGTH = 1023;      /*!< maximum length of a SQL URL */
64
65
66 int db_check_api(db_func_t* dbf, char *mname)
67 {
68         if(dbf==NULL)
69                 return -1;
70
71         /* All modules must export db_use_table */
72         if (dbf->use_table == 0) {
73                 LM_ERR("module %s does not export db_use_table function. Please check if module is loaded.\n", mname);
74                 goto error;
75         }
76
77         /* All modules must export db_init */
78         if (dbf->init == 0) {
79                 LM_ERR("module %s does not export db_init function. Please check if module is loaded.\n", mname);
80                 goto error;
81         }
82
83         /* All modules must export db_close */
84         if (dbf->close == 0) {
85                 LM_ERR("module %s does not export db_close function. Please check if module is loaded.\n", mname);
86                 goto error;
87         }
88
89         if (dbf->query) {
90                 dbf->cap |= DB_CAP_QUERY;
91         }
92
93         if (dbf->fetch_result) {
94                 dbf->cap |= DB_CAP_FETCH;
95         }
96
97         if (dbf->raw_query) {
98                 dbf->cap |= DB_CAP_RAW_QUERY;
99         }
100
101         /* Free result must be exported if DB_CAP_QUERY or
102          * DB_CAP_RAW_QUERY is set */
103         if ((dbf->cap & (DB_CAP_QUERY|DB_CAP_RAW_QUERY)) && (dbf->free_result==0)) {
104                 LM_ERR("module %s supports queries but does not export free_result\n",
105                                 mname);
106                 goto error;
107         }
108
109         if (dbf->insert) {
110                 dbf->cap |= DB_CAP_INSERT;
111         }
112
113         if (dbf->delete) {
114                 dbf->cap |= DB_CAP_DELETE;
115         }
116
117         if (dbf->update) {
118                 dbf->cap |= DB_CAP_UPDATE;
119         }
120
121         if (dbf->replace) {
122                 dbf->cap |= DB_CAP_REPLACE;
123         }
124
125         if (dbf->last_inserted_id) {
126                 dbf->cap |= DB_CAP_LAST_INSERTED_ID;
127         }
128
129         if (dbf->insert_update) {
130                 dbf->cap |= DB_CAP_INSERT_UPDATE;
131         }
132
133         if (dbf->insert_delayed) {
134                 dbf->cap |= DB_CAP_INSERT_DELAYED;
135         }
136
137         if (dbf->affected_rows) {
138                 dbf->cap |= DB_CAP_AFFECTED_ROWS;
139         }
140
141         return 0;
142 error:
143         return -1;
144 }
145
146 /*! \brief fills mydbf with the corresponding db module callbacks
147  * \param mod
148  * \param mydbf
149  * \return returns 0 on success, -1 on error
150  * \note on error mydbf will contain only 0s */
151 int db_bind_mod(const str* mod, db_func_t* mydbf)
152 {
153         char *name, *tmp, *p;
154         int len;
155         db_func_t dbf;
156         db_bind_api_f dbind;
157
158         if (!mod || !mod->s) {
159                 LM_CRIT("null database module name\n");
160                 return -1;
161         }
162         if (mydbf==0) {
163                 LM_CRIT("null dbf parameter\n");
164                 return -1;
165         }
166
167         /* for safety we initialize mydbf with 0 (this will cause
168          *  a segfault immediately if someone tries to call a function
169          *  from it without checking the return code from bind_dbmod */
170         memset((void*)mydbf, 0, sizeof(db_func_t));
171
172         if (mod->len > MAX_URL_LENGTH)
173         {
174                 LM_ERR("SQL URL too long\n");
175                 return -1;
176         }
177         // add the prefix
178         name = pkg_malloc(mod->len + 4);
179         if (!name) {
180                 PKG_MEM_ERROR;
181                 return -1;
182         }
183         memcpy(name, "db_", 3);
184         memcpy(name+3, mod->s, mod->len);
185         name[mod->len+3] = 0;
186
187         p = strchr(name, ':');
188         if (p) {
189                 len = p - name;
190                 tmp = (char*)pkg_malloc(len + 4);
191                 if (!tmp) {
192                         PKG_MEM_ERROR;
193                         pkg_free(name);
194                         return -1;
195                 }
196                 memcpy(tmp, name, len);
197                 tmp[len] = '\0';
198                 pkg_free(name);
199         } else {
200                 tmp = name;
201         }
202
203         if (!find_module_by_name(tmp)) {
204                 LM_ERR("Module %s not found. Missing loadmodule? \n", tmp);
205                 goto error;
206         }
207         dbind = (db_bind_api_f)find_mod_export(tmp, "db_bind_api", 0, 0);
208         if(dbind != NULL)
209         {
210                 LM_DBG("using db bind api for %s\n", tmp);
211                 if(dbind(&dbf)<0)
212                 {
213                         LM_ERR("db_bind_api returned error for module %s\n", tmp);
214                         goto error;
215                 }
216         } else {
217                 memset(&dbf, 0, sizeof(db_func_t));
218                 LM_DBG("using export interface to bind %s\n", tmp);
219                 dbf.use_table = (db_use_table_f)find_mod_export(tmp,
220                         "db_use_table", 2, 0);
221                 dbf.init = (db_init_f)find_mod_export(tmp, "db_init", 1, 0);
222                 dbf.init2 = (db_init2_f)find_mod_export(tmp, "db_init2", 1, 0);
223                 dbf.close = (db_close_f)find_mod_export(tmp, "db_close", 2, 0);
224                 dbf.query = (db_query_f)find_mod_export(tmp, "db_query", 2, 0);
225                 dbf.fetch_result = (db_fetch_result_f)find_mod_export(tmp,
226                         "db_fetch_result", 2, 0);
227                 dbf.raw_query = (db_raw_query_f)find_mod_export(tmp,
228                         "db_raw_query", 2, 0);
229                 dbf.free_result = (db_free_result_f)find_mod_export(tmp,
230                         "db_free_result", 2, 0);
231                 dbf.insert = (db_insert_f)find_mod_export(tmp, "db_insert", 2, 0);
232                 dbf.delete = (db_delete_f)find_mod_export(tmp, "db_delete", 2, 0);
233                 dbf.update = (db_update_f)find_mod_export(tmp, "db_update", 2, 0);
234                 dbf.replace = (db_replace_f)find_mod_export(tmp, "db_replace", 2, 0);
235                 dbf.last_inserted_id= (db_last_inserted_id_f)find_mod_export(tmp,
236                         "db_last_inserted_id", 1, 0);
237                 dbf.affected_rows = (db_affected_rows_f)find_mod_export(tmp,
238                         "db_affected_rows", 1, 0);
239                 dbf.insert_update = (db_insert_update_f)find_mod_export(tmp,
240                         "db_insert_update", 2, 0);
241                 dbf.insert_delayed = (db_insert_delayed_f)find_mod_export(tmp,
242                         "db_insert_delayed", 2, 0);
243                 dbf.start_transaction = (db_start_transaction_f)find_mod_export(tmp,
244                         "db_start_transaction", 2, 0);
245                 dbf.end_transaction = (db_end_transaction_f)find_mod_export(tmp,
246                         "db_end_transaction", 1, 0);
247                 dbf.abort_transaction = (db_abort_transaction_f)find_mod_export(tmp,
248                         "db_abort_transaction", 1, 0);
249                 dbf.query_lock = (db_query_f)find_mod_export(tmp, "db_query_lock", 2, 0);
250         }
251         if(db_check_api(&dbf, tmp)!=0)
252                 goto error;
253
254         *mydbf=dbf; /* copy */
255         pkg_free(tmp);
256         return 0;
257
258 error:
259         pkg_free(tmp);
260         return -1;
261 }
262
263
264 /*! \brief
265  * Initialize database module
266  * \note No function should be called before this
267  */
268 db1_con_t* db_do_init(const str* url, void* (*new_connection)())
269 {
270         return db_do_init2(url, *new_connection, DB_POOLING_PERMITTED);
271 }
272
273
274 /*! \brief
275  * Initialize database module
276  * \note No function should be called before this
277  */
278 db1_con_t* db_do_init2(const str* url, void* (*new_connection)(), db_pooling_t pooling)
279 {
280         struct db_id* id;
281         void* con;
282         db1_con_t* res;
283
284         int con_size = sizeof(db1_con_t) + sizeof(void *);
285         id = 0;
286         res = 0;
287
288         if (!url || !url->s || !new_connection) {
289                 LM_ERR("invalid parameter value\n");
290                 return 0;
291         }
292         if (url->len > MAX_URL_LENGTH)
293         {
294                 LM_ERR("The configured db_url is too long\n");
295                 return 0;
296         }
297         
298         /* this is the root memory for this database connection. */
299         res = (db1_con_t*)pkg_malloc(con_size);
300         if (!res) {
301                 PKG_MEM_ERROR;
302                 return 0;
303         }
304         memset(res, 0, con_size);
305
306         id = new_db_id(url, pooling);
307         if (!id) {
308                 LM_ERR("cannot parse URL '%.*s'\n", url->len, url->s);
309                 goto err;
310         }
311
312         /* Find the connection in the pool */
313         con = pool_get(id);
314         if (!con) {
315                 LM_DBG("connection %p not found in pool\n", id);
316                 /* Not in the pool yet */
317                 con = new_connection(id);
318                 if (!con) {
319                         LM_ERR("could not add connection to the pool\n");
320                         goto err;
321                 }
322                 pool_insert((struct pool_con*)con);
323         } else {
324                 LM_DBG("connection %p found in pool\n", id);
325                 free_db_id(id); // free the new id, as we use the pool instead
326                 id = 0;
327         }
328
329         res->tail = (unsigned long)con;
330         return res;
331
332  err:
333         if (id) free_db_id(id);
334         if (res) pkg_free(res);
335         return 0;
336 }
337
338
339 /*! \brief
340  * Shut down database module
341  * \note No function should be called after this
342  */
343 void db_do_close(db1_con_t* _h, void (*free_connection)())
344 {
345         struct pool_con* con;
346
347         if (!_h || !_h->tail) {
348                 LM_ERR("invalid parameter value\n");
349                 return;
350         }
351
352         con = (struct pool_con*)_h->tail;
353         if (pool_remove(con) == 1) {
354                 free_connection(con);
355         }
356
357         pkg_free(_h);
358 }
359
360
361 /**
362  * \brief Get the version of a table.
363  *
364  * Returns the version number of a given table from the version table.
365  * Instead of this function you should use db_check_table_version!
366  * \see db_check_table_version
367  * \param dbf database module callbacks
368  * \param con database connection handle
369  * \param table checked table
370  * \return the version number if present, 0 if no version data available, < 0 on error
371  */
372 int db_table_version(const db_func_t* dbf, db1_con_t* connection, const str* table)
373 {
374         db_key_t key[1], col[1];
375         db_val_t val[1];
376         db1_res_t* res = NULL;
377         db_val_t* ver = 0;
378         str *version = &version_table;
379         str tmp1 = str_init(TABLENAME_COLUMN);
380         str tmp2 = str_init(VERSION_COLUMN);
381         int ret = 0;
382         int val_type;
383
384         if (!dbf||!connection || !table || !table->s) {
385                 LM_CRIT("invalid parameter value\n");
386                 return -1;
387         }
388
389         if (dbf->use_table(connection, version) < 0) {
390                 LM_ERR("error while changing table\n");
391                 return -1;
392         }
393         key[0] = &tmp1;
394
395         VAL_TYPE(val) = DB1_STR;
396         VAL_NULL(val) = 0;
397         VAL_STR(val) = *table;
398
399         col[0] = &tmp2;
400
401         if (dbf->query(connection, key, 0, val, col, 1, 1, 0, &res) < 0) {
402                 LM_ERR("error in db_query\n");
403                 return -1;
404         }
405
406         if (RES_ROW_N(res) == 0) {
407                 LM_DBG("no row for table %.*s found\n",
408                         table->len, ZSW(table->s));
409                 return 0;
410         }
411
412         if (RES_ROW_N(res) != 1) {
413                 LM_ERR("invalid number of rows received:"
414                         " %d, %.*s\n", RES_ROW_N(res), table->len, ZSW(table->s));
415                 dbf->free_result(connection, res);
416                 return -1;
417         }
418
419         ver = ROW_VALUES(RES_ROWS(res));
420         val_type = VAL_TYPE(ver);
421         if ( (val_type!=DB1_INT && val_type!=DB1_DOUBLE && val_type!=DB1_BIGINT
422                                 && val_type!=DB1_UINT && val_type!=DB1_UBIGINT)
423                         || VAL_NULL(ver) ) {
424                 LM_ERR("invalid type (%d) or nul (%d) version "
425                         "columns for %.*s\n", VAL_TYPE(ver), VAL_NULL(ver),
426                         table->len, ZSW(table->s));
427                 dbf->free_result(connection, res);
428                 return -1;
429         }
430
431         if (val_type == DB1_INT) {
432                 ret = VAL_INT(ver);
433         } else if (val_type == DB1_UINT) {
434                 ret = (int)VAL_UINT(ver);
435         } else if (val_type == DB1_BIGINT) {
436                 ret = (int)VAL_BIGINT(ver);
437         } else if (val_type == DB1_UBIGINT) {
438                 ret = (int)VAL_UBIGINT(ver);
439         } else if (val_type == DB1_DOUBLE) {
440                 ret = (int)VAL_DOUBLE(ver);
441         }
442
443         dbf->free_result(connection, res);
444
445         return ret;
446 }
447
448 /**
449  * \brief Check the table version, including user error logging.
450  *
451  * Small helper function to check the table version, including user error logging.
452  * \param dbf database module callbacks
453  * \param dbh database connection handle
454  * \param table checked table
455  * \param version checked version
456  * \return 0 means ok, -1 means an error occurred
457  */
458 int db_check_table_version(db_func_t* dbf, db1_con_t* dbh, const str* table,
459                 const unsigned int version)
460 {
461         int ver = db_table_version(dbf, dbh, table);
462         if (ver < 0) {
463                 LM_ERR("querying version for table %.*s\n", table->len, table->s);
464                 return -1;
465         } else if (ver != (int)version) {
466                 LM_ERR("invalid version %d for table %.*s found, expected %u"
467                                 " (check table structure and table \"version\")\n",
468                                 ver, table->len, table->s, version);
469                 return -1;
470         }
471         return 0;
472 }
473
474 /*! \brief
475  * Store name of table that will be used by
476  * subsequent database functions
477  */
478 int db_use_table(db1_con_t* _h, const str* _t)
479 {
480         if (!_h) {
481                 LM_ERR("invalid connection parameter\n");
482                 return -1;
483         }
484         if (!_t || !_t->s) {
485                 LM_ERR("invalid table parameter value\n");
486                 return -1;
487         }
488
489         CON_TABLE(_h) = _t;
490         return 0;
491 }
492
493
494 /*! \brief Generic query helper for load bulk data
495  *
496  * Generic query helper method for load bulk data, e.g. lcr tables
497  * \param binding database module binding
498  * \param handle database connection
499  * \param name database table name
500  * \param cols queried columns
501  * \param count number of queried columns
502  * \param strict if set to 1 an error is returned when no data could be loaded,
503     otherwise just a warning is logged
504  * \param res database result, unchanged on failure and if no data could be found
505  * \return 0 if the query was run successful, -1 otherwise
506  */
507 int db_load_bulk_data(db_func_t* binding, db1_con_t* handle, str* name, db_key_t* cols,
508                       unsigned int count, unsigned int strict, db1_res_t* res)
509 {
510         if (binding == NULL) {
511                 LM_ERR("invalid database module binding\n");
512                 return -1;
513         }
514
515         if(handle == NULL) {
516                 LM_ERR("invalid database handle\n");
517                 return -1;
518         }
519
520         if (binding->use_table(handle, name) < 0) {
521                 LM_ERR("error in use_table for database\n");
522                 return -1;
523         }
524
525         /* select the whole table and all the columns */
526         if(binding->query(handle, 0, 0, 0, cols, 0, count, 0, &res) < 0) {
527                 LM_ERR("error while querying database\n");
528                 return -1;
529         }
530
531         if(RES_ROW_N(res) == 0) {
532                 binding->free_result(handle, res);
533                 if (strict == 1) {
534                         LM_ERR("no data in the database table %.*s\n", name->len, name->s);
535                         return -1;
536                 } else {
537                         LM_WARN("no data in the database table %.*s, use an empty set\n", name->len, name->s);
538                         return 0;
539                 }
540         }
541
542         return 0;
543 }
544
545 /**
546  * \brief DB API init function.
547  *
548  * This function must be executed by DB connector modules at load time to
549  * initialize the internals of DB API library.
550  * \return returns 0 on successful initialization, -1 on error.
551  */
552 int db_api_init(void)
553 {
554         if(db_query_init()<0)
555                 return -1;
556         return 0;
557 }