modules/db_mysql/km_my_con.c
4f778298
 /* 
  * Copyright (C) 2001-2004 iptel.org
  * Copyright (C) 2008 1&1 Internet AG
  *
31f52f1d
  * This file is part of Kamailio, a free SIP server.
4f778298
  *
31f52f1d
  * Kamailio is free software; you can redistribute it and/or modify
4f778298
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
31f52f1d
  * Kamailio is distributed in the hope that it will be useful,
4f778298
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
9e1ff448
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
4f778298
  */
 
083502f8
 /*! \file
  *  \brief DB_MYSQL :: Connections
  *  \ingroup db_mysql
  *  Module: \ref db_mysql
  */
 
 
96121273
 #include "km_my_con.h"
 #include "km_db_mysql.h"
2bd85c6b
 #include <mysql_version.h>
4f778298
 #include "../../mem/mem.h"
 #include "../../dprint.h"
 #include "../../ut.h"
7ca3941c
 #include "mysql_mod.h"
4f778298
 
083502f8
 /*! \brief
4f778298
  * Create a new connection structure,
  * open the MySQL connection and set reference count to 1
  */
 struct my_con* db_mysql_new_connection(const struct db_id* id)
 {
 	struct my_con* ptr;
1d3b89b1
 	char *host, *grp, *egrp;
bb30c83e
 	unsigned int connection_flag = 0;
e89c77f6
 #if MYSQL_VERSION_ID > 50012
 	my_bool rec;
 #endif
4f778298
 
 	if (!id) {
 		LM_ERR("invalid parameter value\n");
 		return 0;
 	}
 
 	ptr = (struct my_con*)pkg_malloc(sizeof(struct my_con));
 	if (!ptr) {
 		LM_ERR("no private memory left\n");
 		return 0;
 	}
 
1d3b89b1
 	egrp = 0;
4f778298
 	memset(ptr, 0, sizeof(struct my_con));
 	ptr->ref = 1;
 	
 	ptr->con = (MYSQL*)pkg_malloc(sizeof(MYSQL));
 	if (!ptr->con) {
 		LM_ERR("no private memory left\n");
 		goto err;
 	}
 
 	mysql_init(ptr->con);
 
1d3b89b1
 	if (id->host[0] == '[' && (egrp = strchr(id->host, ']')) != NULL) {
89215f17
 		grp = id->host + 1;
1d3b89b1
 		*egrp = '\0';
 		host = egrp;
89215f17
 		if (host != id->host + strlen(id->host)-1) {
 			host += 1; // host found after closing bracket
 		}
 		else {
 			// let mysql read host info from my.cnf
 			// (defaults to "localhost")
 			host = NULL;
 		}
 		// read [client] and [<grp>] sections in the order
 		// given in my.cnf
 		mysql_options(ptr->con, MYSQL_READ_DEFAULT_GROUP, grp);
 	}
 	else {
 		host = id->host;
 	}
 
4f778298
 	if (id->port) {
89215f17
 		LM_DBG("opening connection: mysql://xxxx:xxxx@%s:%d/%s\n", ZSW(host),
4f778298
 			id->port, ZSW(id->database));
 	} else {
89215f17
 		LM_DBG("opening connection: mysql://xxxx:xxxx@%s/%s\n", ZSW(host),
4f778298
 			ZSW(id->database));
 	}
 
 	// set connect, read and write timeout, the value counts three times
 	mysql_options(ptr->con, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&db_mysql_timeout_interval);
 	mysql_options(ptr->con, MYSQL_OPT_READ_TIMEOUT, (const char *)&db_mysql_timeout_interval);
 	mysql_options(ptr->con, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&db_mysql_timeout_interval);
e89c77f6
 #if MYSQL_VERSION_ID > 50012
 	/* set reconnect flag if enabled */
 	if (db_mysql_auto_reconnect) {
 		rec = 1;
 		mysql_options(ptr->con, MYSQL_OPT_RECONNECT, &rec);
 	}
 #endif
4f778298
 
bb30c83e
 	if (db_mysql_update_affected_found) { 
 	    connection_flag |= CLIENT_FOUND_ROWS;
 	}
 	
4f778298
 #if (MYSQL_VERSION_ID >= 40100)
89215f17
 	if (!mysql_real_connect(ptr->con, host, id->username, id->password,
bb30c83e
 				id->database, id->port, 0, connection_flag|CLIENT_MULTI_STATEMENTS)) {
4f778298
 #else
89215f17
 	if (!mysql_real_connect(ptr->con, host, id->username, id->password,
bb30c83e
 				id->database, id->port, 0, connection_flag)) {
4f778298
 #endif
 		LM_ERR("driver error: %s\n", mysql_error(ptr->con));
7ca3941c
 		/* increase error counter */
 		counter_inc(mysql_cnts_h.driver_err);
4f778298
 		mysql_close(ptr->con);
 		goto err;
 	}
 	/* force reconnection if enabled */
 	if (db_mysql_auto_reconnect)
 		ptr->con->reconnect = 1;
 	else 
 		ptr->con->reconnect = 0;
 
 	LM_DBG("connection type is %s\n", mysql_get_host_info(ptr->con));
 	LM_DBG("protocol version is %d\n", mysql_get_proto_info(ptr->con));
 	LM_DBG("server version is %s\n", mysql_get_server_info(ptr->con));
 
 	ptr->timestamp = time(0);
 	ptr->id = (struct db_id*)id;
1d3b89b1
 	if(egrp) *egrp = ']';
4f778298
 	return ptr;
 
  err:
 	if (ptr && ptr->con) pkg_free(ptr->con);
 	if (ptr) pkg_free(ptr);
1d3b89b1
 	if(egrp) *egrp = ']';
4f778298
 	return 0;
 }
 
 
083502f8
 /*! \brief
4f778298
  * Close the connection and release memory
  */
 void db_mysql_free_connection(struct pool_con* con)
 {
030ed0e6
 	struct my_con * _c;
 	
4f778298
 	if (!con) return;
 
 	_c = (struct my_con*) con;
 
 	if (_c->id) free_db_id(_c->id);
 	if (_c->con) {
 		mysql_close(_c->con);
 		pkg_free(_c->con);
 	}
 	pkg_free(_c);
 }