renatofilho@320: /** renatofilho@320: * GMyth Library renatofilho@320: * renatofilho@320: * @file gmyth/gmyth_query.c renatofilho@320: * renatofilho@320: * @brief

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