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