/*
** CBLM v3
** $Id: db.c,v 1.18 2008/07/14 00:25:08 sella Exp $
** Copyright (c) 2004-2007 James M. Sella. All Rights Reserved.
** Released under the GPL Version 2 License.
** http://www.digitalgenesis.com
** 
** Cheap Bastard Latency Monitor v3
*/

static const char rcsid[] = "$Id: db.c,v 1.18 2008/07/14 00:25:08 sella Exp $";

#include "db.h"
#include "prefs.h"

#include <string.h>

/* Global Variables */
MYSQL mysql;
int connected = 0;
time_t last_connect = 0;

/* External Global Variables */
extern struct args_t args;
extern struct prefs_t prefs;

extern pthread_mutex_t db_mutex;

int db_connect() {
	unsigned int timeout = DEF_DBTIMO;
	unsigned int reconnect = 0;

	db_sanity();

	mysql_init(&mysql);
	/* Read my.cnf pulling in options from [cblmd] section */
	mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, PROGRAM_NAME);
	mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *) &timeout);
#ifdef MYSQL_OPT_RECONNECT
	mysql_options(&mysql, MYSQL_OPT_RECONNECT, (const char *) &reconnect);
#endif

	if (!mysql_real_connect(&mysql, args.db_host, args.db_user, args.db_pass, args.db_name, args.db_port, args.db_sock, args.db_comp)) {
		syslog(LOG_CRIT, "mysql_real_connect(%d): %s", mysql_errno(&mysql), mysql_error(&mysql));
		return 1;
	}

	connected = 1;
	last_connect = time(NULL);

	return 0;
}

void db_disconnect() {
	db_sanity();

	if (connected == 1) {
		connected = 0;
		last_connect = 0;
		mysql_close(&mysql);
	}
}

int db_check() {
	int error;

	db_sanity();

	if (connected != 1) { /* Skip if no connection */
		return 1;
	}

	if ((error = mysql_ping(&mysql)) != 0) {
		syslog(LOG_CRIT, "mysql_ping(%d): %s", mysql_errno(&mysql), mysql_error(&mysql));
	}

	return error;
}

int db_isconnected() {
	db_sanity();

	return connected;
}

int db_query(MYSQL_RES** res, char* sql) {
	int len;

	assert(res != NULL);
	assert(sql != NULL);

	db_sanity();

	len = strlen(sql);

	if (args.debug >= DEBUG_SQL) {
		syslog(LOG_DEBUG, "SQL: %s", sql);
	}

	if (connected != 1) {
		if (args.debug >= DEBUG_INTERNAL) {
			syslog(LOG_WARNING, "skipping db_query() - no connection to database");
		}

		return 1;
	}

	if (mysql_real_query(&mysql, sql, len) != 0) {
		syslog(LOG_CRIT, "mysql_real_query(%d): %s", mysql_errno(&mysql), mysql_error(&mysql));

		return 1;
	}

	*res = mysql_store_result(&mysql);
	if (mysql_errno(&mysql) != 0) {
		syslog(LOG_CRIT, "mysql_store_result(%d): %s", mysql_errno(&mysql), mysql_error(&mysql));

		return 1;
	}

	return 0;
}

int db_sanity() {
	if (pthread_mutex_trylock(&db_mutex) == 0) {
		syslog(LOG_DEBUG, "DEBUG: db_mutex_sanity() failed - db_mutex was not locked on call to db function");
		
		pthread_mutex_unlock(&db_mutex);

		return 1;
	}

	return 0;
}

time_t db_last_connect() {
	return last_connect;
}

/*
** Local Variables:
** c-basic-offset: 3
** tab-width: 3
** End:
** vim: noet ts=3 sw=3
*/
