#include <libgda/libgda.h>
#include <sql-parser/gda-sql-parser.h>
#include <glib.h>

GdaConnection *open_connection (void);
void display_products_contents (GdaConnection *cnc);
void create_table (GdaConnection *cnc);
void run_sql_non_select (GdaConnection *cnc, const gchar *sql);
GdaConnection *cnc;
GdaSqlParser *sql_parser;

static void
execute_statement ()
{
	GdaStatement *stmt;
	GdaSet *plist;
	GdaHolder *param;
	gint i;
	gchar* sql = "SELECT * from products where ref =  ## /* name:'foopar' type:gchararray */ ";
	
	sql_parser = gda_connection_create_parser (cnc);
	
	stmt = gda_sql_parser_parse_string (sql_parser, sql, NULL, NULL);	
	
	gda_statement_get_parameters (stmt,  &plist, NULL);

		
	for (i=0; i < 100000; i++) {
		gchar *curr_val;
		
		// even with GdaDataModelArray the leak is present.
		GdaDataModel *res;		
		
		GValue* value = gda_value_new (G_TYPE_STRING);
		curr_val = g_strdup_printf ("hey%d", i);
		g_value_set_string (value, curr_val);
		
		
		if ((param = gda_set_get_holder (plist, "foopar")) == NULL)
		{
			printf ("error");
			return ;
		}
		gda_holder_set_value(param, value);
		g_free (curr_val);
		gda_value_free (value);
		
		res = gda_connection_statement_execute_select (cnc, (GdaStatement*)stmt, 
														  (GdaSet*)plist, NULL);
		
		// unreffing res!
		g_object_unref (res);		
	}
}

int
main (int argc, char *argv[])
{
        gda_init ();



	/* open connections */
	cnc = open_connection ();
	create_table (cnc);
//	display_products_contents (cnc);
//        gda_connection_close (cnc);

	execute_statement ();
	sleep (10000);
        return 0;
}

/*
 * Open a connection to the example.db file
 */
GdaConnection *
open_connection ()
{
        GdaConnection *cnc;
        GError *error = NULL;
	GdaSqlParser *parser;

	/* open connection */
        cnc = gda_connection_open_from_string ("SQLite", "DB_DIR=.;DB_NAME=example_db", NULL,
					       GDA_CONNECTION_OPTIONS_NONE,
					       &error);
        if (!cnc) {
                g_print ("Could not open connection to SQLite database in example_db.db file: %s\n",
                         error && error->message ? error->message : "No detail");
                exit (1);
        }

	/* create an SQL parser */
	parser = gda_connection_create_parser (cnc);
	if (!parser) /* @cnc doe snot provide its own parser => use default one */
		parser = gda_sql_parser_new ();
	/* attach the parser object to the connection */
	g_object_set_data_full (G_OBJECT (cnc), "parser", parser, g_object_unref);

        return cnc;
}

/*
 * Create a "products" table
 */
void
create_table (GdaConnection *cnc)
{
	run_sql_non_select (cnc, "DROP table IF EXISTS products");
        run_sql_non_select (cnc, "CREATE table products (ref string not null primary key, "
                            "name string not null, price real)");
	run_sql_non_select (cnc, "INSERT INTO products VALUES ('p1', 'chair', 2.0)");
	run_sql_non_select (cnc, "INSERT INTO products VALUES ('p2', 'table', 5.0)");

	run_sql_non_select (cnc, "INSERT INTO products VALUES ('p3', 'glass', 1.1)");
	
	
}


/* 
 * display the contents of the 'products' table 
 */
void
display_products_contents (GdaConnection *cnc)
{
	GdaDataModel *data_model;
	GdaSqlParser *parser;
	GdaStatement *stmt;
	gchar *sql = "SELECT ref, name, price FROM products";
	GError *error = NULL;

	parser = g_object_get_data (G_OBJECT (cnc), "parser");
	stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
	data_model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
	g_object_unref (stmt);
        if (!data_model) 
                g_error ("Could not get the contents of the 'products' table: %s\n",
                         error && error->message ? error->message : "No detail");
	gda_data_model_dump (data_model, stdout);
	g_object_unref (data_model);
}

/*
 * run a non SELECT command and stops if an error occurs
 */
void
run_sql_non_select (GdaConnection *cnc, const gchar *sql)
{
        GdaStatement *stmt;
        GError *error = NULL;
        gint nrows;
	const gchar *remain;
	GdaSqlParser *parser;

	parser = g_object_get_data (G_OBJECT (cnc), "parser");
	stmt = gda_sql_parser_parse_string (parser, sql, &remain, &error);
	if (remain) 
		g_print ("REMAINS: %s\n", remain);

        nrows = gda_connection_statement_execute_non_select (cnc, stmt, NULL, NULL, &error);
        if (nrows == -1)
                g_error ("NON SELECT error: %s\n", error && error->message ? error->message : "no detail");
	g_object_unref (stmt);
}
