2 * Copyright (C) 2001-2003 FhG Fokus
3 * Copyright (C) 2007-2008 1&1 Internet AG
5 * This file is part of Kamailio, a free SIP server.
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
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.
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
23 * \file lib/srdb1/db.c
25 * \brief Generic Database Interface
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.
33 * If possible, use the predefined macros if you need to access any structure
35 * For additional description, see the comments in the sources of mysql module.
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.
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
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"
63 static unsigned int MAX_URL_LENGTH = 1023; /*!< maximum length of a SQL URL */
66 int db_check_api(db_func_t* dbf, char *mname)
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);
77 /* All modules must export db_init */
79 LM_ERR("module %s does not export db_init function. Please check if module is loaded.\n", mname);
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);
90 dbf->cap |= DB_CAP_QUERY;
93 if (dbf->fetch_result) {
94 dbf->cap |= DB_CAP_FETCH;
98 dbf->cap |= DB_CAP_RAW_QUERY;
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",
110 dbf->cap |= DB_CAP_INSERT;
114 dbf->cap |= DB_CAP_DELETE;
118 dbf->cap |= DB_CAP_UPDATE;
122 dbf->cap |= DB_CAP_REPLACE;
125 if (dbf->last_inserted_id) {
126 dbf->cap |= DB_CAP_LAST_INSERTED_ID;
129 if (dbf->insert_update) {
130 dbf->cap |= DB_CAP_INSERT_UPDATE;
133 if (dbf->insert_delayed) {
134 dbf->cap |= DB_CAP_INSERT_DELAYED;
137 if (dbf->affected_rows) {
138 dbf->cap |= DB_CAP_AFFECTED_ROWS;
146 /*! \brief fills mydbf with the corresponding db module callbacks
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)
153 char *name, *tmp, *p;
158 if (!mod || !mod->s) {
159 LM_CRIT("null database module name\n");
163 LM_CRIT("null dbf parameter\n");
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));
172 if (mod->len > MAX_URL_LENGTH)
174 LM_ERR("SQL URL too long\n");
178 name = pkg_malloc(mod->len + 4);
183 memcpy(name, "db_", 3);
184 memcpy(name+3, mod->s, mod->len);
185 name[mod->len+3] = 0;
187 p = strchr(name, ':');
190 tmp = (char*)pkg_malloc(len + 4);
196 memcpy(tmp, name, len);
203 if (!find_module_by_name(tmp)) {
204 LM_ERR("Module %s not found. Missing loadmodule? \n", tmp);
207 dbind = (db_bind_api_f)find_mod_export(tmp, "db_bind_api", 0, 0);
210 LM_DBG("using db bind api for %s\n", tmp);
213 LM_ERR("db_bind_api returned error for module %s\n", tmp);
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);
251 if(db_check_api(&dbf, tmp)!=0)
254 *mydbf=dbf; /* copy */
265 * Initialize database module
266 * \note No function should be called before this
268 db1_con_t* db_do_init(const str* url, void* (*new_connection)())
270 return db_do_init2(url, *new_connection, DB_POOLING_PERMITTED);
275 * Initialize database module
276 * \note No function should be called before this
278 db1_con_t* db_do_init2(const str* url, void* (*new_connection)(), db_pooling_t pooling)
284 int con_size = sizeof(db1_con_t) + sizeof(void *);
288 if (!url || !url->s || !new_connection) {
289 LM_ERR("invalid parameter value\n");
292 if (url->len > MAX_URL_LENGTH)
294 LM_ERR("The configured db_url is too long\n");
298 /* this is the root memory for this database connection. */
299 res = (db1_con_t*)pkg_malloc(con_size);
304 memset(res, 0, con_size);
306 id = new_db_id(url, pooling);
308 LM_ERR("cannot parse URL '%.*s'\n", url->len, url->s);
312 /* Find the connection in the pool */
315 LM_DBG("connection %p not found in pool\n", id);
316 /* Not in the pool yet */
317 con = new_connection(id);
319 LM_ERR("could not add connection to the pool\n");
322 pool_insert((struct pool_con*)con);
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
329 res->tail = (unsigned long)con;
333 if (id) free_db_id(id);
334 if (res) pkg_free(res);
340 * Shut down database module
341 * \note No function should be called after this
343 void db_do_close(db1_con_t* _h, void (*free_connection)())
345 struct pool_con* con;
347 if (!_h || !_h->tail) {
348 LM_ERR("invalid parameter value\n");
352 con = (struct pool_con*)_h->tail;
353 if (pool_remove(con) == 1) {
354 free_connection(con);
362 * \brief Get the version of a table.
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
372 int db_table_version(const db_func_t* dbf, db1_con_t* connection, const str* table)
374 db_key_t key[1], col[1];
376 db1_res_t* res = NULL;
378 str *version = &version_table;
379 str tmp1 = str_init(TABLENAME_COLUMN);
380 str tmp2 = str_init(VERSION_COLUMN);
384 if (!dbf||!connection || !table || !table->s) {
385 LM_CRIT("invalid parameter value\n");
389 if (dbf->use_table(connection, version) < 0) {
390 LM_ERR("error while changing table\n");
395 VAL_TYPE(val) = DB1_STR;
397 VAL_STR(val) = *table;
401 if (dbf->query(connection, key, 0, val, col, 1, 1, 0, &res) < 0) {
402 LM_ERR("error in db_query\n");
406 if (RES_ROW_N(res) == 0) {
407 LM_DBG("no row for table %.*s found\n",
408 table->len, ZSW(table->s));
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);
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)
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);
431 if (val_type == DB1_INT) {
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);
443 dbf->free_result(connection, res);
449 * \brief Check the table version, including user error logging.
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
458 int db_check_table_version(db_func_t* dbf, db1_con_t* dbh, const str* table,
459 const unsigned int version)
461 int ver = db_table_version(dbf, dbh, table);
463 LM_ERR("querying version for table %.*s\n", table->len, table->s);
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);
475 * Store name of table that will be used by
476 * subsequent database functions
478 int db_use_table(db1_con_t* _h, const str* _t)
481 LM_ERR("invalid connection parameter\n");
485 LM_ERR("invalid table parameter value\n");
494 /*! \brief Generic query helper for load bulk data
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
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)
510 if (binding == NULL) {
511 LM_ERR("invalid database module binding\n");
516 LM_ERR("invalid database handle\n");
520 if (binding->use_table(handle, name) < 0) {
521 LM_ERR("error in use_table for database\n");
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");
531 if(RES_ROW_N(res) == 0) {
532 binding->free_result(handle, res);
534 LM_ERR("no data in the database table %.*s\n", name->len, name->s);
537 LM_WARN("no data in the database table %.*s, use an empty set\n", name->len, name->s);
546 * \brief DB API init function.
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.
552 int db_api_init(void)
554 if(db_query_init()<0)