diff -r 000000000000 -r 60bfeabc0af6 branches/gmyth-0.1b/src/gmyth_query.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/branches/gmyth-0.1b/src/gmyth_query.c Thu Feb 08 20:57:31 2007 +0000 @@ -0,0 +1,239 @@ +/** + * GMyth Library + * + * @file gmyth/gmyth_query.c + * + * @brief

GMythQuery class provides a wrapper for accessing + * the libmysqlclient funtions. + * + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. + * @author Leonardo Sobral Cunha + * + *//* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "gmyth_query.h" +#include "gmyth_debug.h" + +static void gmyth_query_class_init (GMythQueryClass *klass); +static void gmyth_query_init (GMythQuery *object); + +static void gmyth_query_dispose (GObject *object); +static void gmyth_query_finalize (GObject *object); + +static void gmyth_query_print_error (MYSQL *conn, char *message); + +G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT) + +static void +gmyth_query_class_init (GMythQueryClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = (GObjectClass *) klass; + + gobject_class->dispose = gmyth_query_dispose; + gobject_class->finalize = gmyth_query_finalize; +} + +static void +gmyth_query_init (GMythQuery *gmyth_query) +{ + gmyth_query->backend_info = NULL; + + /* initialize connection handler */ + gmyth_query->conn = mysql_init (NULL); + + + if (!(gmyth_query->conn)) + g_warning ("[%s] MSQL structure not initialized", __FUNCTION__); + +} + +static void +gmyth_query_dispose (GObject *object) +{ + GMythQuery *gmyth_query = GMYTH_QUERY (object); + + if (gmyth_query->backend_info) { + g_object_unref (gmyth_query->backend_info); + //gmyth_query->backend_info = NULL; + } + + G_OBJECT_CLASS (gmyth_query_parent_class)->dispose (object); +} + +static void +gmyth_query_finalize (GObject *object) +{ + g_signal_handlers_destroy (object); + + G_OBJECT_CLASS (gmyth_query_parent_class)->finalize (object); +} + +/** Creates a new instance of GMythQuery. + * + * @return a new instance of GMythQuery. + */ +GMythQuery* +gmyth_query_new () +{ + GMythQuery *sql_query = GMYTH_QUERY (g_object_new(GMYTH_QUERY_TYPE, NULL)); + + return sql_query; +} + +gboolean +gmyth_query_connect_with_timeout (GMythQuery *gmyth_query, + GMythBackendInfo *backend_info, guint timeout) +{ + assert(gmyth_query); + g_return_val_if_fail (gmyth_query->conn != NULL, FALSE); + if (timeout != 0) { + /* sets connection timeout */ + mysql_options (gmyth_query->conn, MYSQL_OPT_CONNECT_TIMEOUT, (gchar*) &timeout); + } + + return gmyth_query_connect (gmyth_query, backend_info); +} + +/** Connects to the Mysql database in the backend. The backend address + * is loaded from the GMythBackendInfo instance. + * + * @param gmyth_query the GMythEPG instance to be connected. + * @return true if connection was success, false if failed. + */ +gboolean +gmyth_query_connect (GMythQuery *gmyth_query, GMythBackendInfo *backend_info) +{ + assert(gmyth_query); + g_return_val_if_fail (backend_info != NULL, FALSE); + g_return_val_if_fail (backend_info->hostname != NULL, FALSE); + g_return_val_if_fail (backend_info->username != NULL, FALSE); + g_return_val_if_fail (backend_info->password != NULL, FALSE); + g_return_val_if_fail (backend_info->db_name != NULL, FALSE); + + g_object_ref (backend_info); + gmyth_query->backend_info = backend_info; + + if (gmyth_query->conn == NULL) { + gmyth_query_print_error (NULL, "mysql_init() failed (probably out of memory)"); + return FALSE; + } + + /* connect to server */ + if (mysql_real_connect (gmyth_query->conn, + gmyth_query->backend_info->hostname, + gmyth_query->backend_info->username, + gmyth_query->backend_info->password, + gmyth_query->backend_info->db_name, + 0, NULL, 0) == NULL) { + + gmyth_query_print_error (gmyth_query->conn, "mysql_real_connect() failed"); + return FALSE; + } + + g_debug ("[%s] Connection to Mysql server succeeded! (host = %s, user = %s, "\ + "password = %s, db name = %s)", __FUNCTION__, + gmyth_query->backend_info->hostname, gmyth_query->backend_info->username, + gmyth_query->backend_info->password, gmyth_query->backend_info->db_name ); + + return TRUE; +} + +/** Disconnects from the Mysql database in the backend. + * + * @param gmyth_query the GMythQuery instance to be disconnected + * @return true if disconnection was success, false if failed. + */ +gboolean +gmyth_query_disconnect (GMythQuery *gmyth_query) +{ + assert(gmyth_query); + + /* TODO: Check how to return error */ + g_debug ("[%s] Closing gmyth_query->conn", __FUNCTION__); + mysql_close (gmyth_query->conn); + + return TRUE; +} + +static void +gmyth_query_print_error (MYSQL *conn, char *message) +{ + g_debug ("%s", message); + + if (conn != NULL) { +#if MYSQL_VERSION_ID >= 40101 + g_debug ("Error %u (%s): %s\n", + mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn)); +#else + g_debug ("Error %u: %s\n", + mysql_errno (conn), mysql_error (conn)); +#endif + } +} + +/** Sends the given query to the backend returning the query result as + * MYSQL_RES pointer. + * + * FIXME: this function is returning NULL whether any error happens + * or no rows are returned (e.g. UPDATE or REPLACE). + * + * @param gmyth_query the GMythQuery instance. + * @param stmt_str the query text. + * @return the MYSQL_RES result pointer or NULL if any error happens. + */ +MYSQL_RES* +gmyth_query_process_statement (GMythQuery *gmyth_query, char *stmt_str) +{ + MYSQL_RES *res_set; + + assert(gmyth_query); + + g_debug ("[%s] Running mysql query %s", __FUNCTION__, stmt_str); + + if (gmyth_query == NULL) + return NULL; + + /* the statement failed */ + if (mysql_query (gmyth_query->conn, stmt_str) != 0) { + gmyth_query_print_error (gmyth_query->conn, "Could not execute statement"); + return NULL; + } + + /* the statement succeeded; determine whether it returned data */ + res_set = mysql_store_result (gmyth_query->conn); + if (res_set) { + return res_set; + } else if (mysql_field_count (gmyth_query->conn) == 0) { + g_debug ("%lu rows affected\n", + (unsigned long) mysql_affected_rows (gmyth_query->conn)); + } else { + gmyth_query_print_error (gmyth_query->conn, "Could not retrieve result set"); + } + + return NULL; +}