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