branches/gmyth-0.1b/src/gmyth_query.c
branchtrunk
changeset 365 28c358053693
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/branches/gmyth-0.1b/src/gmyth_query.c	Wed Feb 14 23:06:17 2007 +0000
     1.3 @@ -0,0 +1,239 @@
     1.4 +/**
     1.5 + * GMyth Library
     1.6 + *
     1.7 + * @file gmyth/gmyth_query.c
     1.8 + * 
     1.9 + * @brief <p> GMythQuery class provides a wrapper for accessing
    1.10 + * the libmysqlclient funtions.
    1.11 + *
    1.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    1.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
    1.14 + *
    1.15 + *//*
    1.16 + * 
    1.17 + * This program is free software; you can redistribute it and/or modify
    1.18 + * it under the terms of the GNU Lesser General Public License as published by
    1.19 + * the Free Software Foundation; either version 2 of the License, or
    1.20 + * (at your option) any later version.
    1.21 + *
    1.22 + * This program is distributed in the hope that it will be useful,
    1.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.25 + * GNU General Public License for more details.
    1.26 + *
    1.27 + * You should have received a copy of the GNU Lesser General Public License
    1.28 + * along with this program; if not, write to the Free Software
    1.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.30 + */
    1.31 + 
    1.32 +#ifdef HAVE_CONFIG_H
    1.33 +#include "config.h"
    1.34 +#endif
    1.35 +
    1.36 +#include <stdlib.h>
    1.37 +#include <stdio.h>
    1.38 +#include <assert.h>
    1.39 +
    1.40 +#include "gmyth_query.h"
    1.41 +#include "gmyth_debug.h"
    1.42 +
    1.43 +static void gmyth_query_class_init          (GMythQueryClass *klass);
    1.44 +static void gmyth_query_init                (GMythQuery *object);
    1.45 +
    1.46 +static void gmyth_query_dispose  (GObject *object);
    1.47 +static void gmyth_query_finalize (GObject *object);
    1.48 +
    1.49 +static void gmyth_query_print_error (MYSQL *conn, char *message);
    1.50 +
    1.51 +G_DEFINE_TYPE(GMythQuery, gmyth_query, G_TYPE_OBJECT)
    1.52 +    
    1.53 +static void
    1.54 +gmyth_query_class_init (GMythQueryClass *klass)
    1.55 +{
    1.56 +    GObjectClass *gobject_class;
    1.57 +
    1.58 +    gobject_class = (GObjectClass *) klass;
    1.59 +	
    1.60 +    gobject_class->dispose  = gmyth_query_dispose;
    1.61 +    gobject_class->finalize = gmyth_query_finalize;	
    1.62 +}
    1.63 +
    1.64 +static void
    1.65 +gmyth_query_init (GMythQuery *gmyth_query)
    1.66 +{
    1.67 +    gmyth_query->backend_info = NULL;
    1.68 +
    1.69 +    /* initialize connection handler */
    1.70 +    gmyth_query->conn = mysql_init (NULL);
    1.71 +
    1.72 +    
    1.73 +    if (!(gmyth_query->conn))
    1.74 +    	g_warning ("[%s] MSQL structure not initialized", __FUNCTION__);
    1.75 +
    1.76 +}
    1.77 +
    1.78 +static void
    1.79 +gmyth_query_dispose  (GObject *object)
    1.80 +{
    1.81 +    GMythQuery *gmyth_query = GMYTH_QUERY (object);
    1.82 +    
    1.83 +    if (gmyth_query->backend_info) {
    1.84 +        g_object_unref (gmyth_query->backend_info);
    1.85 +	//gmyth_query->backend_info = NULL;
    1.86 +    }
    1.87 +    
    1.88 +    G_OBJECT_CLASS (gmyth_query_parent_class)->dispose (object);
    1.89 +}
    1.90 +
    1.91 +static void
    1.92 +gmyth_query_finalize (GObject *object)
    1.93 +{
    1.94 +    g_signal_handlers_destroy (object);
    1.95 +
    1.96 +    G_OBJECT_CLASS (gmyth_query_parent_class)->finalize (object);
    1.97 +}
    1.98 +
    1.99 +/** Creates a new instance of GMythQuery.
   1.100 + * 
   1.101 + * @return a new instance of GMythQuery.
   1.102 + */
   1.103 +GMythQuery*
   1.104 +gmyth_query_new ()
   1.105 +{
   1.106 +    GMythQuery *sql_query = GMYTH_QUERY (g_object_new(GMYTH_QUERY_TYPE, NULL));
   1.107 +
   1.108 +    return sql_query;
   1.109 +}
   1.110 +
   1.111 +gboolean
   1.112 +gmyth_query_connect_with_timeout (GMythQuery *gmyth_query, 
   1.113 +		GMythBackendInfo *backend_info, guint timeout)
   1.114 +{
   1.115 +    assert(gmyth_query);
   1.116 +    g_return_val_if_fail (gmyth_query->conn != NULL, FALSE);
   1.117 +    if (timeout != 0) {
   1.118 +        /* sets connection timeout */
   1.119 +        mysql_options (gmyth_query->conn, MYSQL_OPT_CONNECT_TIMEOUT, (gchar*) &timeout);
   1.120 +    }
   1.121 +
   1.122 +    return gmyth_query_connect (gmyth_query, backend_info);
   1.123 +}
   1.124 +
   1.125 +/** Connects to the Mysql database in the backend. The backend address
   1.126 + * is loaded from the GMythBackendInfo instance.
   1.127 + * 
   1.128 + * @param gmyth_query the GMythEPG instance to be connected.
   1.129 + * @return true if connection was success, false if failed.
   1.130 + */
   1.131 +gboolean
   1.132 +gmyth_query_connect (GMythQuery *gmyth_query, GMythBackendInfo *backend_info) 
   1.133 +{
   1.134 +    assert(gmyth_query);
   1.135 +    g_return_val_if_fail (backend_info != NULL, FALSE);
   1.136 +    g_return_val_if_fail (backend_info->hostname != NULL, FALSE);
   1.137 +    g_return_val_if_fail (backend_info->username != NULL, FALSE);
   1.138 +    g_return_val_if_fail (backend_info->password != NULL, FALSE);
   1.139 +    g_return_val_if_fail (backend_info->db_name != NULL, FALSE);
   1.140 +    
   1.141 +    g_object_ref (backend_info);
   1.142 +    gmyth_query->backend_info = backend_info;
   1.143 +
   1.144 +    if (gmyth_query->conn == NULL) {
   1.145 +        gmyth_query_print_error (NULL, "mysql_init() failed (probably out of memory)");
   1.146 +        return FALSE;
   1.147 +    }
   1.148 +    
   1.149 +    /* connect to server */
   1.150 +    if (mysql_real_connect (gmyth_query->conn, 
   1.151 +	    gmyth_query->backend_info->hostname, 
   1.152 +            gmyth_query->backend_info->username,
   1.153 +	    gmyth_query->backend_info->password,
   1.154 +	    gmyth_query->backend_info->db_name, 
   1.155 +            0, NULL, 0) == NULL) {
   1.156 +            	
   1.157 +        gmyth_query_print_error (gmyth_query->conn, "mysql_real_connect() failed");
   1.158 +		return FALSE;
   1.159 +    }
   1.160 +
   1.161 +    g_debug ("[%s] Connection to Mysql server succeeded! (host = %s, user = %s, "\
   1.162 +    			"password = %s, db name = %s)", __FUNCTION__, 
   1.163 +    			gmyth_query->backend_info->hostname, gmyth_query->backend_info->username,
   1.164 +	    		gmyth_query->backend_info->password, gmyth_query->backend_info->db_name );
   1.165 +    
   1.166 +    return TRUE;
   1.167 +}
   1.168 +
   1.169 +/** Disconnects from the Mysql database in the backend.
   1.170 + * 
   1.171 + * @param gmyth_query the GMythQuery instance to be disconnected
   1.172 + * @return true if disconnection was success, false if failed.
   1.173 + */
   1.174 +gboolean
   1.175 +gmyth_query_disconnect (GMythQuery *gmyth_query) 
   1.176 +{
   1.177 +    assert(gmyth_query);
   1.178 +    
   1.179 +    /* TODO: Check how to return error */
   1.180 +    g_debug ("[%s] Closing gmyth_query->conn", __FUNCTION__);
   1.181 +    mysql_close (gmyth_query->conn);
   1.182 +
   1.183 +	return TRUE;	
   1.184 +}
   1.185 +
   1.186 +static void
   1.187 +gmyth_query_print_error (MYSQL *conn, char *message)
   1.188 +{
   1.189 +    g_debug ("%s", message);
   1.190 +    
   1.191 +    if (conn != NULL) {
   1.192 +#if MYSQL_VERSION_ID >= 40101
   1.193 +        g_debug ("Error %u (%s): %s\n",
   1.194 +                mysql_errno (conn), mysql_sqlstate(conn), mysql_error (conn));
   1.195 +#else
   1.196 +        g_debug ("Error %u: %s\n",
   1.197 +               mysql_errno (conn), mysql_error (conn));
   1.198 +#endif
   1.199 +    }
   1.200 +}
   1.201 +
   1.202 +/** Sends the given query to the backend returning the query result as
   1.203 + * MYSQL_RES pointer.
   1.204 + * 
   1.205 + * FIXME: this function is returning NULL whether any error happens
   1.206 + * or no rows are returned (e.g. UPDATE or REPLACE).
   1.207 + * 
   1.208 + * @param gmyth_query the GMythQuery instance.
   1.209 + * @param stmt_str the query text.
   1.210 + * @return the MYSQL_RES result pointer or NULL if any error happens.
   1.211 + */
   1.212 +MYSQL_RES*
   1.213 +gmyth_query_process_statement (GMythQuery *gmyth_query, char *stmt_str)
   1.214 +{
   1.215 +    MYSQL_RES *res_set;
   1.216 +    
   1.217 +    assert(gmyth_query);
   1.218 +    
   1.219 +    g_debug ("[%s] Running mysql query %s", __FUNCTION__, stmt_str);
   1.220 +
   1.221 +    if (gmyth_query == NULL)
   1.222 +    	return NULL;
   1.223 +    
   1.224 +    /* the statement failed */
   1.225 +    if (mysql_query (gmyth_query->conn, stmt_str) != 0) {
   1.226 +        gmyth_query_print_error (gmyth_query->conn, "Could not execute statement");
   1.227 +        return NULL;
   1.228 +    }
   1.229 +
   1.230 +    /* the statement succeeded; determine whether it returned data */
   1.231 +    res_set = mysql_store_result (gmyth_query->conn);
   1.232 +    if (res_set) {
   1.233 +        return res_set;
   1.234 +    } else if (mysql_field_count (gmyth_query->conn) == 0) {
   1.235 +        g_debug ("%lu rows affected\n",
   1.236 +                (unsigned long) mysql_affected_rows (gmyth_query->conn));
   1.237 +    } else {
   1.238 +        gmyth_query_print_error (gmyth_query->conn, "Could not retrieve result set");
   1.239 +    }
   1.240 +    
   1.241 +    return NULL;
   1.242 +}