#include <mysql.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void show_error(MYSQL *mysql)
{
  printf("Error(%d) [%s] \"%s\"", mysql_errno(mysql),
                                  mysql_sqlstate(mysql),
                                  mysql_error(mysql));
  mysql_close(mysql);
  exit(-1);
}

void run(my_bool use_string, MYSQL* mysql, MYSQL_STMT *stmt)
{
	my_bool    is_null[3];
	int status;
    MYSQL_BIND ps_params[2];
  memset(ps_params, 0, sizeof (ps_params));

  char *sbuff = "AAAAAAAA";
  unsigned long slen = 8;
  long long val = 0x4433221111223344;
  if (use_string) {
	  ps_params[0].buffer_type = MYSQL_TYPE_VAR_STRING;
  } else {
	  ps_params[0].buffer_type = MYSQL_TYPE_LONGLONG;
	  ps_params[0].buffer = (char *) &val;
	  ps_params[0].buffer_length = 8;
	  ps_params[0].length = 0;
	  ps_params[0].is_null = 0;
  }

  status = mysql_stmt_bind_param(stmt, ps_params);
  if (use_string) {
  	status = mysql_stmt_send_long_data(stmt, 0, sbuff, slen);
  	if (status) printf("long data send error %d\n", status);
  }

  status = mysql_stmt_execute(stmt);

  do {
	  int i;
	  int num_fields;
	  MYSQL_FIELD *fields;
	  MYSQL_BIND *rs_bind;
	  long long *int_buf = malloc(sizeof(long long));
	  char *char_buf = malloc(16);
	  memset(char_buf, 0, 16);

	  num_fields = mysql_stmt_field_count(stmt);

	  if (num_fields > 0) {
		  printf("Number of columns in result: %d\n", (int) num_fields);
		  printf("Data: ");
		  if(mysql->server_status & SERVER_PS_OUT_PARAMS)
			  printf("this result set contains OUT/INOUT parameters\n");
		  else
			  printf("this result set is produced by the procedure\n");

		  MYSQL_RES *rs_metadata = mysql_stmt_result_metadata(stmt);

		  fields = mysql_fetch_fields(rs_metadata);

		  rs_bind = (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
		  if (!rs_bind)
		  {
			  printf("Cannot allocate output buffers\n");
			  exit(1);
		  }
		  memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);

		  /* set up and bind result set output buffers */
		  for (i = 0; i < num_fields; ++i)
		  {
			  rs_bind[i].buffer_type = fields[i].type;
			  rs_bind[i].is_null = &is_null[i];

			  switch (fields[i].type)
			  {
				  case MYSQL_TYPE_LONGLONG:
					  rs_bind[i].buffer = (char *) int_buf;
					  rs_bind[i].buffer_length = sizeof(long long);
					  break;

		                  case MYSQL_TYPE_VAR_STRING:
					  rs_bind[i].buffer = char_buf;
					  rs_bind[i].buffer_length = 15;
					  break;

				  default:
					  fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
					  exit(1);
			  }
		  }

		  status = mysql_stmt_bind_result(stmt, rs_bind);
		  printf("BIND RESULT STATUS %d\n", status);

		  /* fetch and display result set rows */
		  while (1)
		  {
			  status = mysql_stmt_fetch(stmt);

			  if (status == 1 || status == MYSQL_NO_DATA)
				  break;

			  for (i = 0; i < num_fields; ++i)
			  {
				  switch (rs_bind[i].buffer_type)
				  {
					  case MYSQL_TYPE_LONGLONG:
						  if (*rs_bind[i].is_null)
							  printf(" val[%d] = NULL;", i);
						  else
							  printf(" val[%d] = %ld;",
									  i, (long) *((int *) rs_bind[i].buffer));
						  break;

					  case MYSQL_TYPE_VAR_STRING:
						  if (*rs_bind[i].is_null)
							  printf(" val[%d] = NULL;", i);
						  else
							  printf(" val[%d] = '%s';", i, (char *) rs_bind[i].buffer);
						  break;

					  default:
						  printf("  unexpected type (%d)\n",
								  rs_bind[i].buffer_type);
				  }
			  }
			  printf("\n");
		  }

		  mysql_free_result(rs_metadata); /* free metadata */
		  free(rs_bind);                  /* free output buffers */
	  }
  } while (status == 0);
}

int main(int argc, char *argv[])
{
  MYSQL *mysql;
  const char *query;
  MYSQL_RES *result;
  

  mysql= mysql_init(NULL);
  if (!mysql_real_connect(mysql, "127.0.0.1", "root", "password", 
                          "mysql", 3306, 0, 0))
    show_error(mysql);

  MYSQL_STMT *stmt;
  stmt = mysql_stmt_init(mysql);
  if (!stmt)
	  show_error(mysql);

  int status;
  status = mysql_stmt_prepare(stmt, "SELECT ?", 8);



	run(0, mysql, stmt);
	run(1, mysql, stmt);

	mysql_stmt_close(stmt);
	mysql_close(mysql);
}

