gmyth/src/gmyth_query.c
author melunko
Wed Jan 10 21:47:24 2007 +0000 (2007-01-10)
branchtrunk
changeset 257 86e15690a104
parent 256 7776e35d59d4
child 313 f8d246310650
permissions -rw-r--r--
[svn r258] Added gmyth_query and gmyth_scheduler connection methods with timeout. Besides, configura.ac now checks libmysqlclient in the right way
     1 /**
     2  * GMyth Library
     3  *
     4  * @file gmyth/gmyth_query.c
     5  * 
     6  * @brief <p> GMythQuery class provides a wrapper for accessing
     7  * the libmysqlclient funtions.
     8  *
     9  * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    10  * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
    11  *
    12  *//*
    13  * 
    14  * This program is free software; you can redistribute it and/or modify
    15  * it under the terms of the GNU Lesser General Public License as published by
    16  * the Free Software Foundation; either version 2 of the License, or
    17  * (at your option) any later version.
    18  *
    19  * This program is distributed in the hope that it will be useful,
    20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    22  * GNU General Public License for more details.
    23  *
    24  * You should have received a copy of the GNU Lesser General Public License
    25  * along with this program; if not, write to the Free Software
    26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    27  */
    28  
    29 #ifdef HAVE_CONFIG_H
    30 #include "config.h"
    31 #endif
    32 
    33 #include <stdlib.h>
    34 #include <stdio.h>
    35 #include <assert.h>
    36 
    37 #include "gmyth_query.h"
    38 #include "gmyth_debug.h"
    39 
    40 static void gmyth_query_class_init          (GMythQueryClass *klass);
    41 static void gmyth_query_init                (GMythQuery *object);
    42 
    43 static void gmyth_query_dispose  (GObject *object);
    44 static void gmyth_query_finalize (GObject *object);
    45 
    46 static void gmyth_query_print_error (MYSQL *conn, char *message);
    47 
    48 G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
    49     
    50 static void
    51 gmyth_query_class_init (GMythQueryClass *klass)
    52 {
    53     GObjectClass *gobject_class;
    54 
    55     gobject_class = (GObjectClass *) klass;
    56 	
    57     gobject_class->dispose  = gmyth_query_dispose;
    58     gobject_class->finalize = gmyth_query_finalize;	
    59 }
    60 
    61 static void
    62 gmyth_query_init (GMythQuery *gmyth_query)
    63 {
    64     gmyth_query->backend_info = NULL;
    65 
    66     /* initialize connection handler */
    67     gmyth_query->conn = mysql_init (NULL);
    68 
    69     
    70     if (!(gmyth_query->conn))
    71     	g_warning ("[%s] MSQL structure not initialized", __FUNCTION__);
    72 
    73 }
    74 
    75 static void
    76 gmyth_query_dispose  (GObject *object)
    77 {
    78     GMythQuery *gmyth_query = GMYTH_QUERY (object);
    79     
    80     if (gmyth_query->backend_info) {
    81         g_object_unref (gmyth_query->backend_info);
    82 	//gmyth_query->backend_info = NULL;
    83     }
    84     
    85     G_OBJECT_CLASS (gmyth_query_parent_class)->dispose (object);
    86 }
    87 
    88 static void
    89 gmyth_query_finalize (GObject *object)
    90 {
    91     g_signal_handlers_destroy (object);
    92 
    93     G_OBJECT_CLASS (gmyth_query_parent_class)->finalize (object);
    94 }
    95 
    96 /** Creates a new instance of GMythQuery.
    97  * 
    98  * @return a new instance of GMythQuery.
    99  */
   100 GMythQuery*
   101 gmyth_query_new ()
   102 {
   103     GMythQuery *sql_query = GMYTH_QUERY (g_object_new(GMYTH_QUERY_TYPE, NULL));
   104 
   105     return sql_query;
   106 }
   107 
   108 gboolean
   109 gmyth_query_connect_with_timeout (GMythQuery *gmyth_query, 
   110 		GMythBackendInfo *backend_info, guint timeout)
   111 {
   112     assert(gmyth_query);
   113     g_return_val_if_fail (gmyth_query->conn != NULL, FALSE);
   114 printf ("XXXXXXXXX timeout %d\n", timeout);
   115     if (timeout != 0) {
   116         /* sets connection timeout */
   117         mysql_options (gmyth_query->conn, MYSQL_OPT_CONNECT_TIMEOUT, (gchar*) &timeout);
   118     }
   119 
   120     return gmyth_query_connect (gmyth_query, backend_info);
   121 }
   122 
   123 /** Connects to the Mysql database in the backend. The backend address
   124  * is loaded from the GMythBackendInfo instance.
   125  * 
   126  * @param gmyth_query the GMythEPG instance to be connected.
   127  * @return true if connection was success, false if failed.
   128  */
   129 gboolean
   130 gmyth_query_connect (GMythQuery *gmyth_query, GMythBackendInfo *backend_info) 
   131 {
   132     assert(gmyth_query);
   133     g_return_val_if_fail (backend_info != NULL, FALSE);
   134     g_return_val_if_fail (backend_info->hostname != NULL, FALSE);
   135     g_return_val_if_fail (backend_info->username != NULL, FALSE);
   136     g_return_val_if_fail (backend_info->password != NULL, FALSE);
   137     g_return_val_if_fail (backend_info->db_name != NULL, FALSE);
   138     
   139     g_object_ref (backend_info);
   140     gmyth_query->backend_info = backend_info;
   141 
   142     if (gmyth_query->conn == NULL) {
   143         gmyth_query_print_error (NULL, "mysql_init() failed (probably out of memory)");
   144         return FALSE;
   145     }
   146     
   147     /* connect to server */
   148     if (mysql_real_connect (gmyth_query->conn, 
   149 	    gmyth_query->backend_info->hostname, 
   150             gmyth_query->backend_info->username,
   151 	    gmyth_query->backend_info->password,
   152 	    gmyth_query->backend_info->db_name, 
   153             0, NULL, 0) == NULL) {
   154             	
   155         gmyth_query_print_error (gmyth_query->conn, "mysql_real_connect() failed");
   156 		return FALSE;
   157     }
   158 
   159     gmyth_debug ("[%s] Connection to Mysql server succeeded! (host = %s, user = %s, "\
   160     			"password = %s, db name = %s)", __FUNCTION__, 
   161     			gmyth_query->backend_info->hostname, gmyth_query->backend_info->username,
   162 	    		gmyth_query->backend_info->password, gmyth_query->backend_info->db_name );
   163     
   164     return TRUE;
   165 }
   166 
   167 /** Disconnects from the Mysql database in the backend.
   168  * 
   169  * @param gmyth_query the GMythQuery instance to be disconnected
   170  * @return true if disconnection was success, false if failed.
   171  */
   172 gboolean
   173 gmyth_query_disconnect (GMythQuery *gmyth_query) 
   174 {
   175     assert(gmyth_query);
   176     
   177     /* TODO: Check how to return error */
   178     gmyth_debug ("[%s] Closing gmyth_query->conn", __FUNCTION__);
   179     mysql_close (gmyth_query->conn);
   180 
   181 	return TRUE;	
   182 }
   183 
   184 static void
   185 gmyth_query_print_error (MYSQL *conn, char *message)
   186 {
   187     g_debug ("%s", message);
   188     
   189     if (conn != NULL) {
   190 #if MYSQL_VERSION_ID >= 40101
   191         g_debug ("Error %u (%s): %s\n",
   192                 mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn));
   193 #else
   194         g_debug ("Error %u: %s\n",
   195                mysql_errno (conn), mysql_error (conn));
   196 #endif
   197     }
   198 }
   199 
   200 /** Sends the given query to the backend returning the query result as
   201  * MYSQL_RES pointer.
   202  * 
   203  * FIXME: this function is returning NULL whether any error happens
   204  * or no rows are returned (e.g. UPDATE or REPLACE).
   205  * 
   206  * @param gmyth_query the GMythQuery instance.
   207  * @param stmt_str the query text.
   208  * @return the MYSQL_RES result pointer or NULL if any error happens.
   209  */
   210 MYSQL_RES*
   211 gmyth_query_process_statement (GMythQuery *gmyth_query, char *stmt_str)
   212 {
   213     MYSQL_RES *res_set;
   214     
   215     assert(gmyth_query);
   216     
   217     gmyth_debug ("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
   218 
   219     if (gmyth_query == NULL)
   220     	return NULL;
   221     
   222     /* the statement failed */
   223     if (mysql_query (gmyth_query->conn, stmt_str) != 0) {
   224         gmyth_query_print_error (gmyth_query->conn, "Could not execute statement");
   225         return NULL;
   226     }
   227 
   228     /* the statement succeeded; determine whether it returned data */
   229     res_set = mysql_store_result (gmyth_query->conn);
   230     if (res_set) {
   231         return res_set;
   232     } else if (mysql_field_count (gmyth_query->conn) == 0) {
   233         gmyth_debug ("%lu rows affected\n",
   234                 (unsigned long) mysql_affected_rows (gmyth_query->conn));
   235     } else {
   236         gmyth_query_print_error (gmyth_query->conn, "Could not retrieve result set");
   237     }
   238     
   239     return NULL;
   240 }