/* Copyright (c) 2003, Rene Luria aka herel <rene@luria.ch>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice,
 *     * this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *     * notice, this list of conditions and the following disclaimer in the
 *     * documentation and/or other materials provided with the distribution.
 *     * Neither the name of the author nor the names of its
 *     * contributors may be used to endorse or promote products derived from
 *     * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE. */

/***
 * pour compiler:
 * gcc -o mysql mysql.c -lmysqlclient --std c99 -pedantic -Wall
 * pour utiliser:
 * ./mysql <user> <pass> <host> <db> <query>
 ***/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mysql/mysql.h>

#define QUERY_SIZE_MAX 128

int main (int argc, char **argv) 
{
	MYSQL *p_handle = NULL;
	char query[128];
	if (argc < 6)
	{
		fprintf (stderr, "usage: ./mysql <user> <pass> <host> <db> <query>\n");
		return EXIT_FAILURE;
	}
	/* Initialise l'objet de handle */
	if ((p_handle = mysql_init (NULL)) == NULL)
	{
		perror ("Init impossible");
		return EXIT_FAILURE;
	}
	/* établit la connexion */
	if (mysql_real_connect (p_handle, argv[3], argv[1], argv[2], argv[4], 0, NULL, 0) == NULL)
	{
		fprintf (stderr, 
			"Connection au serveur impossible.\nErreur: %s\n", 
			mysql_error (p_handle));
		mysql_close (p_handle);
		return EXIT_FAILURE;
	}
	/* créé la requête à partir des arguments en ligne de commande */
	{
		ssize_t longueur = 0;
		char *p_query = query;
		int i;
		for (i = 5; i < argc; i++)
		{
			longueur += strlen (argv[i] + 1);
			if (longueur > QUERY_SIZE_MAX)
			{
				fprintf (stderr, "query trop longue\n");
				mysql_close (p_handle);
				return EXIT_FAILURE;
			}
			strcpy (p_query, argv[i]);
			p_query += strlen (argv[i]);
			*p_query = ' ';
			p_query++;
		}
		*(--p_query) = '\0';
	}
	/* exécute la requête */
	if (mysql_query (p_handle, query) != 0)
	{
		fprintf (stderr, "Problème lors de la requête.\nErreur: %s\n", 
			mysql_error (p_handle));
		mysql_close (p_handle);
		return EXIT_FAILURE;
	}
	/* traite le résultat */
	{
		MYSQL_RES *p_res = mysql_store_result (p_handle);
		if ((p_res)) 
		{
			unsigned int num_champs = mysql_num_fields (p_res), i;
			my_ulonglong num_lignes = mysql_num_rows (p_res);
			MYSQL_FIELD *p_champs = mysql_fetch_fields (p_res);
			MYSQL_ROW ligne;
			printf ("%d collones et %llu lignes\n", num_champs, (unsigned long long) num_lignes);
			for (i = 0; i < num_champs; i++) 
			{
				printf("<%-20s> ", p_champs[i].name);
			}
			putchar('\n');
			while ((ligne = mysql_fetch_row (p_res))) 
			{
				unsigned long *tailles = mysql_fetch_lengths (p_res);
				for (i = 0; i < num_champs; i++) 
				{
					printf ("[%-20.*s] ", 
						(int) tailles[i], 
						ligne[i] ? ligne[i] : "NULL");
				}
				putchar ('\n');
			}
			mysql_free_result (p_res);
		}
	}
	mysql_close (p_handle);
	return EXIT_SUCCESS;
}
