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 +}