#if defined(_NT)
#include <windows.h>
#else
#define TRUE	1
#define FALSE	0
#endif

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>

#include <mysql.h>



#define QUERY_DROP_TABLE			"DROP TABLE xxx"
#define QUERY_CREATE_TABLE			"CREATE TABLE xxx (id INTEGER NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB"
#define QUERY_INSERT_INTO_TABLE	"insert into xxx (id) values (%d)"
MYSQL			*mysql = NULL;


void print_mysql_error(MYSQL *mysql)
{
	fprintf(stderr, "%d:%s\n", mysql_errno(mysql), mysql_error(mysql));
}


void print_mysql_stmt_error(MYSQL_STMT *stmt)
{
	fprintf(stderr, "stmt error=%s\n", mysql_stmt_error(stmt));
}


void exec_query(const char *query, const int IgnoreError)
{
	if (mysql_query(mysql, query))
	{
		if (IgnoreError == FALSE)
		{
			fprintf(stderr, "mysql_query(), failed\n");
			fprintf(stderr, "query=%s\n", query);
			goto ErrorExit;
		}
	}
	return;

ErrorExit:
	print_mysql_error(mysql);
	return;
}


int select_statement()
{
#define QUERY		"select id from xxx order by 1"
	MYSQL_STMT		*stmt;
	MYSQL_BIND		bind_array[10];
	char			name[256];
	int				rc;
	const unsigned long type= CURSOR_TYPE_READ_ONLY;
	unsigned long	name_len;

	stmt = mysql_stmt_init(mysql);
	if (!stmt)
	{
		fprintf(stderr, " mysql_stmt_init(), out of memory\n");
		goto ErrorExit;
	}

	mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *) &type);

	if (mysql_stmt_prepare(stmt, QUERY, strlen(QUERY)))
	{
		fprintf(stderr, " mysql_stmt_prepare(), failed\n");
		print_mysql_stmt_error(stmt);
		goto ErrorExit;
	}

	/* output bind */
	memset(bind_array, 0, sizeof(bind_array));
	bind_array[0].buffer_type= MYSQL_TYPE_STRING;
	bind_array[0].buffer= (char *) name;
	bind_array[0].buffer_length= sizeof(name);
	bind_array[0].length= &name_len;
	if (mysql_stmt_bind_result(stmt, bind_array))
	{
		fprintf(stderr, " mysql_stmt_bind_result(), failed\n");
		print_mysql_stmt_error(stmt);
		goto ErrorExit;
	}


	if (mysql_stmt_execute(stmt))
	{
		fprintf(stderr, " mysql_stmt_execute(), failed\n");
		print_mysql_stmt_error(stmt);
		goto ErrorExit;
	}

	/* fetch a row */
	rc = mysql_stmt_fetch(stmt);
	if (rc == MYSQL_NO_DATA)
	{
		printf("no rows found\n");
	}
	else
	{
		if (rc == 0)
		{
			name[name_len]= '\0';
			printf("%s\n",  name);
		}
		else
		{
			printf("error\n");
		}
	}

	if ( mysql_rollback( mysql ))
	{
		fprintf(stderr, " mysql_rollback(), failed\n");
		print_mysql_error(mysql);
	}
	else
	{
		fprintf(stderr, "mysql_rollback(), succeeded\n");
	}


	/* fetch a row after the rollback */
	rc = mysql_stmt_fetch(stmt);
	if (rc == MYSQL_NO_DATA)
	{
		printf("no rows found\n");
	}
	else
	{
		if (rc == 0)
		{
			name[name_len]= '\0';
			printf("%s\n",  name);
		}
		else
		{
			printf("error\n");
		}
	}


	if (mysql_stmt_close(stmt))
	{
		fprintf(stderr, " mysql_stmt_close(), failed\n");
		print_mysql_stmt_error(stmt);
		goto ErrorExit;
	}

	return(TRUE);

ErrorExit:
	print_mysql_error(mysql);
	return(FALSE);
}


int main(void)
{
	int		i = 0;
	char		buf[100];

	if ((mysql = mysql_init((MYSQL *) 0)) == NULL) goto ErrorExit;

	if (mysql_real_connect(mysql, "", "root", "root", "mysql", 0, NULL, 0) == NULL) goto ErrorExit;

	exec_query(QUERY_DROP_TABLE, TRUE);
	exec_query(QUERY_CREATE_TABLE, FALSE);
	for (i = 10; i <= 340; i = i + 10)
	{
		sprintf(buf, QUERY_INSERT_INTO_TABLE, i);
		exec_query(buf, FALSE);
	}

	mysql_autocommit( mysql, FALSE );
	exec_query("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED", FALSE );

	/*  */
	(void) select_statement();
	
	mysql_close(mysql);

	return(0);

ErrorExit:
	print_mysql_error(mysql);
	return(1);
}


