/* * $Id: mysql.c,v 1.10 2000/07/22 06:13:16 danny Exp $ * * This file is part of Oleo, the GNU spreadsheet. * * Copyright © 1999-2000 by the Free Software Foundation, Inc. * Written by Danny Backx . * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ static char rcsid[] = "$Id: mysql.c,v 1.10 2000/07/22 06:13:16 danny Exp $"; #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WITH_DMALLOC #include #endif #include "global.h" #include "oleosql.h" #include "cmd.h" #include "io-term.h" #include "mysql.h" #ifdef HAVE_LIBMYSQLCLIENT #include #include #include /* * Define some MySQL access functions for Oleo */ #include "funcdef.h" #include "sysdef.h" #include "global.h" #include "cell.h" #include "eval.h" #include "errors.h" /* * Declarations necessary for defining an Oleo function */ struct value { int type; union vals x; }; #define Float x.c_d #define String x.c_s #define Int x.c_l #define Value x.c_i #define Rng x.c_r /* * Forward declarations */ static void do_mysql_query(struct value *); static void do_mysql_read(struct value *); static void do_mysql_write(struct value *); /* * Define Oleo functions */ struct function mysql_functions[] = { { C_FN1, X_A1, "S", do_mysql_query, "mysql_query" }, { C_FN1, X_A1, "S", do_mysql_read, "mysql_read" }, { C_FN1, X_A1, "S", do_mysql_write, "mysql_write" }, { 0, 0, "", 0, 0 } }; int init_mysql_function_count(void) { return sizeof(mysql_functions) / sizeof(struct function) - 1; } /* * This function should just retrieve a single value from the dbms. */ static void do_mysql_query(struct value *p) { char *sql = p[0].String; MYSQL db; MYSQL_RES *res; MYSQL_ROW row; MYSQL_FIELD *field; int r, i, j, nrows; char *result; double d; AllocateDatabaseGlobal(); if (Global->DatabaseGlobal == NULL) { io_error_msg("Need to initialize database"); return; } if (Global->DatabaseGlobal->name == 0 || Global->DatabaseGlobal->user == 0) { io_error_msg("Database Access requires db name and user name"); return; } if (mysql_connect(&db, Global->DatabaseGlobal->host, Global->DatabaseGlobal->user, "") == NULL) { io_error_msg("MySQL error '%s'\n", mysql_error(&db)); return; /* FIX ME */ } r = mysql_select_db(&db, Global->DatabaseGlobal->name); if (r != 0) { io_error_msg("MySQL error '%s'\n", mysql_error(&db)); return; /* FIX ME */ } r = mysql_query(&db, sql); if (r != 0) { io_error_msg("MySQL error '%s'\n", mysql_error(&db)); return; /* FIX ME */ } res = mysql_store_result(&db); if (mysql_num_fields(res) != 1) { /* There's more than one, or less than one, result. */ io_error_msg("MySQLQuery: number of results (%d) should be one\n", nrows); return; /* FIX ME */ } field = mysql_fetch_field(res); nrows = mysql_num_rows(res); if (nrows != 1) { /* There's more than one, or less than one, result. */ io_error_msg("MySQLQuery: number of results (%d) should be one\n", nrows); return; /* FIX ME */ } row = mysql_fetch_row(res); switch (field->type) { case FIELD_TYPE_CHAR: case FIELD_TYPE_NULL: case FIELD_TYPE_TIMESTAMP: case FIELD_TYPE_DATE: case FIELD_TYPE_TIME: case FIELD_TYPE_DATETIME: case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_STRING: p->type = TYP_STR; p->String = strdup(row[0]); break; case FIELD_TYPE_DECIMAL: case FIELD_TYPE_FLOAT: case FIELD_TYPE_DOUBLE: case FIELD_TYPE_LONGLONG: case FIELD_TYPE_INT24: default: p->type = TYP_FLT; d = atof(row[0]); p->Float = d; break; case FIELD_TYPE_SHORT: case FIELD_TYPE_LONG: p->type = TYP_INT; sscanf(row[0], "%d", &i); p->Int = i; break; case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_MEDIUM_BLOB: case FIELD_TYPE_LONG_BLOB: case FIELD_TYPE_BLOB: break; } mysql_free_result(res); mysql_close(&db); return; } static void do_mysql_read(struct value *p) { /* * This doesn't do a thing. * * A database query is only triggered on request from the user. */ } static void do_mysql_write(struct value *p) { /* * This doesn't do a thing. * * A database query is only triggered on request from the user. */ } /* * This function reads a block of data from an SQL statement * into the spreadsheet. */ void MySQLRead(void) { MYSQL db; MYSQL_RES *res; MYSQL_ROW row; MYSQL_FIELD *field; int r, i, j, nrows; enum enum_field_types *types_list; char *sql = "select * from koers"; int in_row = curow, in_col = cucol; if (mysql_connect(&db, "localhost", "danny", "") == NULL) { fprintf(stderr, "MySQL error '%s'\n", mysql_error(&db)); return; } r = mysql_select_db(&db, "test"); if (r != 0) { fprintf(stderr, "MySQL error '%s'\n", mysql_error(&db)); return; } r = mysql_query(&db, sql); if (r != 0) { fprintf(stderr, "MySQL error '%s'\n", mysql_error(&db)); return; } res = mysql_store_result(&db); types_list = malloc(mysql_num_fields(res)); for (j=0; jname); types_list[j] = field->type; } nrows = mysql_num_rows(res); for (i=0; imodified = 1; recalculate(1); return; } #endif /* HAVE_LIBMYSQLCLIENT */ /* * The functions below need to exist even if we don't have MySQL */ void AllocateDatabaseGlobal(void) { if (Global->DatabaseGlobal == NULL) { Global->DatabaseGlobal = (struct DatabaseGlobalType *) malloc(sizeof(struct DatabaseGlobalType)); memset(Global->DatabaseGlobal, 0, sizeof(struct DatabaseGlobalType)); } } void DatabaseSetName(const char *name) { if (Global->DatabaseGlobal->name) free(Global->DatabaseGlobal->name); Global->DatabaseGlobal->name = strdup(name); } void DatabaseSetHost(const char *host) { if (Global->DatabaseGlobal->host) free(Global->DatabaseGlobal->host); Global->DatabaseGlobal->host = strdup(host); } void DatabaseSetUser(const char *user) { if (Global->DatabaseGlobal->user) free(Global->DatabaseGlobal->user); Global->DatabaseGlobal->user = strdup(user); } int DatabaseInitialised(void) { if (Global->DatabaseGlobal) return 1; return 0; } char * DatabaseGetName(void) { if (Global->DatabaseGlobal) return Global->DatabaseGlobal->name; return NULL; } char * DatabaseGetHost(void) { if (Global->DatabaseGlobal) return Global->DatabaseGlobal->host; return NULL; } char * DatabaseGetUser(void) { if (Global->DatabaseGlobal) return Global->DatabaseGlobal->user; return NULL; } #ifndef HAVE_LIBMYSQLCLIENT #include "eval.h" /* * Define Oleo functions */ struct function mysql_functions[] = { { 0, 0, "", 0, 0 } }; int init_mysql_function_count(void) { return sizeof(mysql_functions) / sizeof(struct function) - 1; } #endif /* HAVE_LIBMYSQLCLIENT */