#include <cstdlib>
#include <cstdio>
#include <process.h>
#include <my_global.h>
#include <m_string.h>
#include <mysql.h>

#define uint unsigned int

typedef void * (__cdecl *p_func)(void *);

#define TH_COUNT 30

struct handle_conn
{
  MYSQL p_mysql;
  char* p_host;
  char* p_user;
  char* p_pwd;
  char* p_db;
  uint  p_port;
  uint  p_th;
  uint  p_start;
  uint  p_end;
  char p_query1[255];
  char p_query2[255];
  char p_query3[255];
  char p_query4[255];
 }; 

p_func f_query(void* pParam);
CRITICAL_SECTION l_lock;

int main()
{
  struct handle_conn ws_th[TH_COUNT];
  HANDLE wh_th[TH_COUNT];
  int wi_lp;
  uint wx_lp = 1;
  
  InitializeCriticalSection(&l_lock);

  for ( wi_lp = 0; wi_lp < TH_COUNT; wi_lp++)
  {
    ws_th[wi_lp].p_host = "localhost";
    ws_th[wi_lp].p_user = "root";
    ws_th[wi_lp].p_pwd  = "";
    ws_th[wi_lp].p_db   = "test";
    ws_th[wi_lp].p_port = 3510;
    ws_th[wi_lp].p_th   = wi_lp;
    ws_th[wi_lp].p_start= wx_lp;
    ws_th[wi_lp].p_end  = wx_lp + 69999;
    wx_lp+= 70000;

    EnterCriticalSection(&l_lock);

    wh_th[wi_lp] = reinterpret_cast<HANDLE>(_beginthread((void( __cdecl *)(void*))f_query,0,&ws_th[wi_lp]));

    LeaveCriticalSection(&l_lock);
    Sleep(50);
  }
  
  DWORD wd = WaitForMultipleObjects(TH_COUNT,wh_th,TRUE,INFINITE);

  switch( wd )
  {
  case WAIT_FAILED:
    printf("Something was wrong :(\n");
    return(-1);
    break;

  }
  
  return(0);
}

p_func f_query(void* pParam)
{
  mysql_init(&((struct handle_conn *) pParam)->p_mysql);
  
  if (!mysql_real_connect(&((struct handle_conn *) pParam)->p_mysql,
                           ((struct handle_conn *) pParam)->p_host,
                           ((struct handle_conn *) pParam)->p_user,
                           ((struct handle_conn *) pParam)->p_pwd,
                           ((struct handle_conn *) pParam)->p_db,
						   ((struct handle_conn *) pParam)->p_port,
						   NULL,
                           0))
  {
    printf("Error: %s\n",mysql_error(&((struct handle_conn *) pParam)->p_mysql));
    return(0);
  }
  else
	printf("Server Thread ID: %d\n",mysql_thread_id(&((struct handle_conn *)pParam)->p_mysql));

  for ( uint x = ((struct handle_conn *) pParam)->p_start; x <= ((struct handle_conn *) pParam)->p_end;x++)
  {
    
    int10_to_str((int) x, strmov(((struct handle_conn *) pParam)->p_query1,""), 10);
	int10_to_str((int) x+1, strmov(((struct handle_conn *) pParam)->p_query3,""), 10);
      
    strxnmov(((struct handle_conn *) pParam)->p_query2,
               sizeof(((struct handle_conn *) pParam)->p_query2)-1,
               "INSERT IGNORE INTO t1 SET a =",
               ((struct handle_conn *) pParam)->p_query1,
               ",b =",
               ((struct handle_conn *) pParam)->p_query3,
               NullS);
	strxnmov(((struct handle_conn *) pParam)->p_query4,
               sizeof(((struct handle_conn *) pParam)->p_query4)-1,
               "INSERT IGNORE INTO t2 SET a =",
               ((struct handle_conn *) pParam)->p_query1,
               ",b =",
               ((struct handle_conn *) pParam)->p_query3,
               NullS);
    if (mysql_query( &((struct handle_conn *) pParam)->p_mysql, 
                      ((struct handle_conn *) pParam)->p_query2 ))
    {
	   printf("Error (query): %s\n", mysql_error( &((struct handle_conn *)pParam)->p_mysql));
       return(0);
    }

	if (mysql_query( &((struct handle_conn *) pParam)->p_mysql, 
                      ((struct handle_conn *) pParam)->p_query4 ))
    {
	   printf("Error (query): %s\n", mysql_error( &((struct handle_conn *)pParam)->p_mysql));
       return(0);
    }
  }
  mysql_close(&((struct handle_conn *) pParam)->p_mysql);
 
  return(0);
}