km_my_con.c

Go to the documentation of this file.
00001 /* 
00002  * $Id$
00003  *
00004  * Copyright (C) 2001-2004 iptel.org
00005  * Copyright (C) 2008 1&1 Internet AG
00006  *
00007  * This file is part of Kamailio, a free SIP server.
00008  *
00009  * Kamailio is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version
00013  *
00014  * Kamailio is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License 
00020  * along with this program; if not, write to the Free Software 
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  */
00023 
00031 #include "km_my_con.h"
00032 #include "km_db_mysql.h"
00033 #include <mysql/mysql_version.h>
00034 #include "../../mem/mem.h"
00035 #include "../../dprint.h"
00036 #include "../../ut.h"
00037 #include "mysql_mod.h"
00038 
00043 struct my_con* db_mysql_new_connection(const struct db_id* id)
00044 {
00045         struct my_con* ptr;
00046         char *host, *grp;
00047 
00048         if (!id) {
00049                 LM_ERR("invalid parameter value\n");
00050                 return 0;
00051         }
00052 
00053         ptr = (struct my_con*)pkg_malloc(sizeof(struct my_con));
00054         if (!ptr) {
00055                 LM_ERR("no private memory left\n");
00056                 return 0;
00057         }
00058 
00059         memset(ptr, 0, sizeof(struct my_con));
00060         ptr->ref = 1;
00061         
00062         ptr->con = (MYSQL*)pkg_malloc(sizeof(MYSQL));
00063         if (!ptr->con) {
00064                 LM_ERR("no private memory left\n");
00065                 goto err;
00066         }
00067 
00068         mysql_init(ptr->con);
00069 
00070         if (id->host[0] == '[' && (host = strchr(id->host, ']')) != NULL) {
00071                 grp = id->host + 1;
00072                 *host = '\0';
00073                 if (host != id->host + strlen(id->host)-1) {
00074                         host += 1; // host found after closing bracket
00075                 }
00076                 else {
00077                         // let mysql read host info from my.cnf
00078                         // (defaults to "localhost")
00079                         host = NULL;
00080                 }
00081                 // read [client] and [<grp>] sections in the order
00082                 // given in my.cnf
00083                 mysql_options(ptr->con, MYSQL_READ_DEFAULT_GROUP, grp);
00084         }
00085         else {
00086                 host = id->host;
00087         }
00088 
00089         if (id->port) {
00090                 LM_DBG("opening connection: mysql://xxxx:xxxx@%s:%d/%s\n", ZSW(host),
00091                         id->port, ZSW(id->database));
00092         } else {
00093                 LM_DBG("opening connection: mysql://xxxx:xxxx@%s/%s\n", ZSW(host),
00094                         ZSW(id->database));
00095         }
00096 
00097         // set connect, read and write timeout, the value counts three times
00098         mysql_options(ptr->con, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&db_mysql_timeout_interval);
00099         mysql_options(ptr->con, MYSQL_OPT_READ_TIMEOUT, (const char *)&db_mysql_timeout_interval);
00100         mysql_options(ptr->con, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&db_mysql_timeout_interval);
00101 
00102 #if (MYSQL_VERSION_ID >= 40100)
00103         if (!mysql_real_connect(ptr->con, host, id->username, id->password,
00104                                 id->database, id->port, 0, CLIENT_MULTI_STATEMENTS)) {
00105 #else
00106         if (!mysql_real_connect(ptr->con, host, id->username, id->password,
00107                                 id->database, id->port, 0, 0)) {
00108 #endif
00109                 LM_ERR("driver error: %s\n", mysql_error(ptr->con));
00110                 /* increase error counter */
00111                 counter_inc(mysql_cnts_h.driver_err);
00112                 mysql_close(ptr->con);
00113                 goto err;
00114         }
00115         /* force reconnection if enabled */
00116         if (db_mysql_auto_reconnect)
00117                 ptr->con->reconnect = 1;
00118         else 
00119                 ptr->con->reconnect = 0;
00120 
00121         LM_DBG("connection type is %s\n", mysql_get_host_info(ptr->con));
00122         LM_DBG("protocol version is %d\n", mysql_get_proto_info(ptr->con));
00123         LM_DBG("server version is %s\n", mysql_get_server_info(ptr->con));
00124 
00125         ptr->timestamp = time(0);
00126         ptr->id = (struct db_id*)id;
00127         return ptr;
00128 
00129  err:
00130         if (ptr && ptr->con) pkg_free(ptr->con);
00131         if (ptr) pkg_free(ptr);
00132         return 0;
00133 }
00134 
00135 
00139 void db_mysql_free_connection(struct pool_con* con)
00140 {
00141         struct my_con * _c;
00142         
00143         if (!con) return;
00144 
00145         _c = (struct my_con*) con;
00146 
00147         if (_c->res) mysql_free_result(_c->res);
00148         if (_c->id) free_db_id(_c->id);
00149         if (_c->con) {
00150                 mysql_close(_c->con);
00151                 pkg_free(_c->con);
00152         }
00153         pkg_free(_c);
00154 }