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

#define HOST "127.0.0.1"
#define USERNAME "root"
#define PASSWORD ""
#define DATABASE "test"
#define QUERY "SELECT ? AS test_string"
#define PARAM "non-empty-string"
#define RESULT_BUFFER_LEN 128

int main(int argc, char *argv[])
{
  MYSQL *link = NULL;
  MYSQL_STMT *ps = NULL;
  MYSQL_BIND params[1];
  MYSQL_BIND results[1];
  unsigned long param_length;
  unsigned long result_length;
  char *result_string = NULL;

  printf("status: Init\n");
  link = mysql_init(NULL);

  printf("status: Connect\n");
  mysql_real_connect(link, HOST, USERNAME, PASSWORD, DATABASE, 0, NULL, 0);
  if(mysql_errno(link)) goto error;

  printf("status: init prepared statement\n");
  ps = mysql_stmt_init(link);
  if(mysql_errno(link)) goto error;

  printf("status: prepare statement\n");
  mysql_stmt_prepare(ps, QUERY, strlen(QUERY));
  if(mysql_errno(link)) goto error;

  printf("status: bind parameters\n");
  memset(params, 0, sizeof(params));
  params[0].buffer_type = MYSQL_TYPE_VAR_STRING;
  params[0].buffer = PARAM;
  param_length = strlen(PARAM);
  params[0].length = &param_length;
  printf("status: set param string to '%s'\n", (char*)params[0].buffer);
  mysql_stmt_bind_param(ps, params);
  if(mysql_errno(link)) goto error;

  printf("status: executing statement\n");
  mysql_stmt_execute(ps);
  if(mysql_errno(link)) goto error;

  printf("status: binding result to buffers\n");
  result_string = (char*)calloc(RESULT_BUFFER_LEN, sizeof(char));
  memset(results, 0, sizeof(results));
  results[0].buffer_type = MYSQL_TYPE_VAR_STRING;
  results[0].buffer = result_string;
  results[0].buffer_length = RESULT_BUFFER_LEN * sizeof(char);
  results[0].length = &result_length;
  mysql_stmt_bind_result(ps, results);
  if(mysql_errno(link)) goto error;

  printf("status: fetch row\n");
  mysql_stmt_fetch(ps);
  if(mysql_errno(link)) goto error;

  printf("RESULTS\n");
  printf("Expected one result ('" PARAM "'). Got:\n");
  printf("'%s'\n", (char*)results[0].buffer);

 cleanup:
  if(NULL != ps) {
    printf("status: close statement\n");
    mysql_stmt_close(ps);
    if(mysql_errno(link)) goto error;
  }
  
  printf("status: Disconnect\n");
  mysql_close(link);

  return 0;

 error:
  printf("ERROR: %s\n", mysql_error(link));

  if(NULL != ps) {
    mysql_stmt_close(ps);
    if(mysql_errno(link)) {
      printf("Error closing statement: %s\n", mysql_error(link));
    }
  }

  if(NULL != result_string) {
    free(result_string);
  }

  mysql_close(link);

  return 1;
}
