#include "stdafx.h"


char* DefaultHost="70.50.10.43";
const char* DefaultUser="root";
const char* DefaultPassword="202409";
const char* DefaultDatabase="nicktest";
const int DefaultPort=3306;

char* MySqlTools::buffer = NULL;
int MySqlTools::bufferSize = 0;
FILE* MySqlTools::log = NULL;
int MySqlTools::succeedCounter = 0;
int MySqlTools::failureCounter = 0;
MYSQL MySqlTools::mysql;



bool isPictureFile(TCHAR* namePtr)
{
	return      _tcsicmp(namePtr, _T("jpg"))==0||
				_tcsicmp(namePtr, _T("bmp"))==0 ;				
}


MySqlTools::~MySqlTools()
{
	mysql_close(&mysql);
	fclose(log);
}


bool MySqlTools::doSaveToFile(LPBYTE imagePtr, DWORD imageSize)
{
	bool result = false;
	int imageWidth;
	int imageHeight;
	int stretchedWidth;
	int stretchedHeight;
	LPBYTE thumbPtr;
	LPBYTE stretchedPtr;
	DWORD thumbDataSize;
	DWORD stretchedSize;
	ImageFileFormat fileFormat;	 

	fileFormat=imageFileFormat(imagePtr);
	if (imageProcess(imagePtr, imageSize, DefaultMaxHeight, DefaultThumbnailSize,
		imageWidth, imageHeight, stretchedWidth, stretchedHeight, thumbPtr, 
		stretchedPtr, thumbDataSize, stretchedSize) == JPEG_SUCCESS)
	{
		switch (fileFormat)
		{
		case Image_File_Format_BMP:
			saveJpgFile(_T("original.bmp"), imagePtr, imageSize);
			break;
		case Image_File_Format_JPG:	  			
			saveJpgFile(_T("original.jpg"), imagePtr, imageSize);
			break;
		}
		saveJpgFile(_T("stretched.jpg"), stretchedPtr, stretchedSize);
		saveJpgFile(_T("thumbnail.jpg"), thumbPtr, thumbDataSize);
		_ftprintf(log, _T("imageSize[%d], maxHeight[%d],thumbSize[%d],imageWidth[%d],\
		  imageHeight[%d], stretchedWidth[%d], stretchedHeight[%d], thumbDataSize[%d],\
		  stretchedSize[%d]\n"), imageSize, DefaultMaxHeight, DefaultThumbnailSize,
		  imageWidth, imageHeight,
		  stretchedWidth, stretchedHeight, thumbDataSize, stretchedSize);
		free(stretchedPtr);
		free(thumbPtr);
		result = true;
	}
	return result;	
}


bool MySqlTools::saveToFile(int offset)
{
	LPBYTE imagePtr;
	DWORD imageSize;
	bool result = false;

	int id;

	//id = minId + offset;
	id = offset;
	
	if (fetchData(id, imagePtr, imageSize))
	{
		result = doSaveToFile(imagePtr, imageSize);
		free(imagePtr);
	}
	return result;	
}


bool MySqlTools::init(char* ipAddress)
{
	char* host = ipAddress;
	if ((log = fopen("mysql.log", "a+"))==NULL)
	{
		return false;
	}

	mysql_init(&mysql);
	if (ipAddress == NULL)
	{
		host = DefaultHost;
	}
	if (mysql_init(&mysql)==NULL)
	{
		return false;
	}
	if (mysql_real_connect(&mysql, host, DefaultUser, DefaultPassword,
		DefaultDatabase, DefaultPort, NULL, 0)==NULL)
	{
		mysql_close(&mysql);
		return false;
	}
	if (!initDataRange(minId, maxId, count))
	{
		mysql_close(&mysql);
		return false;
	}

	return true;
}



bool MySqlTools::initDataRange( int& minId, int& maxId, int& count)
{
	char buffer[256];
	MYSQL_ROW row;
	MYSQL_RES* res=NULL;	  

	sprintf(buffer, "select min(id), max(id), count(id) from mypicture");

	if (doFetchResult(buffer, res))
	{	
		if ((row=mysql_fetch_row(res))==NULL)
		{
			_ftprintf(log, _T("row error %d\n"), mysql_error(&mysql));
			mysql_free_result(res);
			return false;
		}

		sscanf( row[0], "%d", &minId);
		sscanf( row[1], "%d", &maxId);
		sscanf( row[2], "%d", &count);

		mysql_free_result(res);	
		return true;
	}
	return false;
}

bool MySqlTools::doforeach(int id, const LPBYTE imagePtr, DWORD imageSize)
{
	bool isSucceed = false;
 	int imageWidth  = 0;
	int imageHeight = 0;
	int stretchedWidth = 0;;
	int stretchedHeight = 0;
	LPBYTE thumbPtr     = NULL;
	LPBYTE stretchedPtr = NULL;
	DWORD thumbDataSize = 0;
	DWORD stretchedDataSize = 0;

	if (imageProcess(imagePtr, imageSize, DefaultMaxHeight, DefaultThumbnailSize,
				imageWidth, imageHeight, stretchedWidth,  stretchedHeight, thumbPtr,
				stretchedPtr, thumbDataSize,stretchedDataSize) == JPEG_SUCCESS)
	{
		isSucceed = true;
		if (isSucceed)
		{
			isSucceed = updateInt(id, imageWidth, "picture_width");
		}
		if (isSucceed)
		{
			isSucceed = updateInt(id, imageHeight, "picture_height");
		}
		if (isSucceed)
		{
			isSucceed = updateInt(id, stretchedWidth, "picture_image_width");
		}
		if (isSucceed)
		{
			isSucceed = updateInt(id, stretchedHeight, "picture_image_Height");
		}

		if (isSucceed)
		{
			isSucceed = updateInt(id, thumbDataSize, "picture_thumb_size");
		}

		if (isSucceed)
		{
			isSucceed = updateInt(id, stretchedDataSize, "picture_image_size");
		}

		if (isSucceed)
		{
			isSucceed = updateBinary(id, stretchedPtr, stretchedDataSize, "picture_image");
		}
		if (isSucceed)
		{
			isSucceed = updateBinary(id, thumbPtr, thumbDataSize, "picture_thumb");
		}
		
		free(stretchedPtr); 
		free(thumbPtr);
	}
	return isSucceed;
}



bool MySqlTools::foreach(int offset)
{
	int succeeded = 0;
	int id = minId + offset;
	LPBYTE imagePtr  = NULL;
	DWORD  imageSize = 0;  

	while (id < maxId)
	{ 		
		if (fetchData(id, imagePtr, imageSize))
		{
			if (!doforeach(id, imagePtr, imageSize))
			{
				_ftprintf(log, _T("image process error of id[%d]\n"), id);
			}
			else
			{
				succeeded ++;
			}
			free(imagePtr); 
		} 
		id ++;
		if (id % 10 == 0)
		{
			_tprintf(_T("id = %d, succeeded = %d\n"), id, succeeded);
		}
		fflush(log);
	}
	_ftprintf(log, _T("expected [%d], actually [%d]\n"), count, succeeded);

	return succeeded == count;
}

bool MySqlTools::fetchData(int id, LPBYTE& imagePtr, DWORD& imageSize)
{
	char buffer[256];
	MYSQL_ROW row;
	unsigned long * lengths;
	MYSQL_RES* res=NULL;	  

	sprintf(buffer, "select picture_data from mypicture where id = %d", id);

	if (doFetchResult(buffer, res))
	{	
		if ((row=mysql_fetch_row(res))==NULL)
		{
			_ftprintf(log, _T("row error %s\n"), mysql_error(&mysql));
			mysql_free_result(res);
			return false;
		}  

		if ((lengths=mysql_fetch_lengths(res))==NULL)
		{
			_ftprintf(log, _T("row length error %s\n"), mysql_error(&mysql));
			mysql_free_result(res);	 
			return false;
		}
		imageSize = lengths[0];
		imagePtr = (LPBYTE)malloc(imageSize);
		if (imagePtr == NULL)
		{
			_ftprintf(log, _T("allocate memory faile for %d bytes\n"), imageSize);
			mysql_free_result(res);	 
			return false;  
		}
		memcpy(imagePtr, row[0], imageSize);
		mysql_free_result(res);	
		return true;
	}
	return false;	 	
}

bool MySqlTools::remakePicture(int id)
{
	LPBYTE imagePtr = NULL;
	DWORD  imageSize = 0;	
	bool result = false;

	if (fetchData(id, imagePtr, imageSize))
	{
		if (doforeach(id, imagePtr, imageSize))
		{
			_tprintf(_T("remake picture %d successful!\n"), id);
			result = true;
		}
		free(imagePtr);
	}
	return result;
}


bool MySqlTools::doFetchResult(const char* statement, MYSQL_RES*& res)
{
	if (mysql_real_query(&mysql, statement, strlen(statement)))
	{
		_ftprintf(log, _T("query error %s\n"), mysql_error(&mysql));	
		return false;
	}

	if ((res=mysql_store_result(&mysql))==NULL)
	{
		_ftprintf(log, _T("store result error %s\n"), mysql_error(&mysql));			
		return false;
	}
	return true;
}


bool MySqlTools::updateInt(int id, int data, char* field, char* table)
{
	char buffer[256];
	sprintf(buffer, "update %s set %s=%d where %s = %d", table, field, data, "id", id);

	if (mysql_real_query(&mysql, buffer, strlen(buffer)))
	{
		_ftprintf(log, _T("query error %s\n"), mysql_error(&mysql));	
		return false;
	}
	return true;
}

bool MySqlTools::updateBinary(int id, LPBYTE data, int size, char* field, char* table)
{
	char* buffer = NULL;
	int len, escapeLength;

	buffer = (char*)malloc(size*2 + 256);
	if (buffer == NULL)
	{
		return false;
	}
	sprintf(buffer, "update %s set %s =\"", table, field);
	len = strlen(buffer);
	if ((escapeLength = mysql_real_escape_string(&mysql, buffer + len, (char*)data, size))
		==0)
	{
		free(buffer);
		return false;
	}
	len += escapeLength;
	sprintf(buffer+len, "\" where id = %d", id);
	len += strlen(buffer+len);

	if (mysql_real_query(&mysql, buffer, len))
	{  
		_ftprintf(log, _T("query error %s\n"), mysql_error(&mysql)); 		
		free(buffer);
		return false;
	}
	
	free(buffer);
	return true;
}





void insertFile(TCHAR* fullName, TCHAR* fileName)
{
	int curBufferSize;
	_TCHAR* namePtr;
	unsigned char digest[16];
	int dataLength, firstLength, nameLength;

	static int counter = 0;

	LPBYTE imagePtr;
	DWORD imageSize;
	int imageWidth;
	int imageHeight;
	int stretchedWidth;
	int stretchedHeight;
	LPBYTE thumbPtr;
	LPBYTE stretchedPtr;
	DWORD thumbDataSize;
	DWORD stretchedSize; 
	bool hasError = false;

	//const char* insertFirst="insert into mymusic (music_time, music_size, music_name, music_signature, music_data) values (now()";
	const char* insertFirst="insert into mypicture (picture_time, \
		picture_name, picture_signature, picture_data, picture_thumb, picture_image,\
		picture_size,picture_width, picture_height,\
		picture_image_width, picture_image_height, \
		picture_image_size, picture_thumb_size, picture_thumb_datasize) values (now(),";
 
	counter ++;
   
	_tprintf(_T("[%d]\n"), counter);
	if (counter == 1029)
	{
		printf("stop\n");
	}


	nameLength=_tcsclen(fileName);
	
	namePtr=fileName + nameLength - 3;
	if (!isPictureFile(namePtr))
	{
		return;						
	}

	if (!mapFile(fullName, imagePtr, imageSize))
	{
		_ftprintf(MySqlTools::log, _T("fileMapping error %d fullName=%s fileName=%s\n"), GetLastError(),
			fullName, fileName);		
		MySqlTools::failureCounter++;
		return;
	}

	hasError = false;
	if (imageProcess(imagePtr, imageSize, DefaultMaxHeight, DefaultThumbnailSize,
		imageWidth, imageHeight, stretchedWidth, stretchedHeight, thumbPtr, 
		stretchedPtr, thumbDataSize, stretchedSize) == JPEG_SUCCESS)
	{ 
		curBufferSize = imageSize * 2 + stretchedSize * 2 + 1024;
		if (curBufferSize > MySqlTools::bufferSize)
		{
			if ((MySqlTools::buffer = (char*)realloc(MySqlTools::buffer, curBufferSize)) != NULL)
			{
				MySqlTools::bufferSize = curBufferSize;
			}
			else
			{
				_ftprintf(MySqlTools::log, _T("Allocate buffer failed\n"));
				MySqlTools::failureCounter++;
				hasError = true;
			}
		}

		//if (!hasError)
		if (!hasError)
		{
			sprintf(MySqlTools::buffer, "%s", insertFirst);
			firstLength=strlen(MySqlTools::buffer);	

			calculateMD5((unsigned char*)imagePtr, imageSize, digest);	 					

			MySqlTools::assembleEscapeStr(fullName, nameLength*sizeof(TCHAR), firstLength);
			MySqlTools::assembleEscapeStr((char*)digest, 16, firstLength);	
			
			MySqlTools::assembleEscapeStr((char*)imagePtr, imageSize, firstLength);

			MySqlTools::assembleEscapeStr((char*)thumbPtr, thumbDataSize, firstLength);

			MySqlTools::assembleEscapeStr((char*)stretchedPtr, stretchedSize, firstLength);
		
			sprintf(MySqlTools::buffer + firstLength, "%d,%d,%d,%d,%d,%d,%d,%d)", imageSize,
				imageWidth, imageHeight, stretchedWidth, stretchedHeight, 
				thumbDataSize, stretchedSize, DefaultThumbnailSize);
			dataLength = strlen(MySqlTools::buffer+firstLength);
			firstLength += dataLength;

			if (mysql_real_query(&MySqlTools::mysql, MySqlTools::buffer, firstLength))
			{
				_ftprintf(MySqlTools::log, _T("query error %s file name=%s filesize=%d\n"),
					mysql_error(&MySqlTools::mysql), fileName, imageSize);
				_ftprintf(MySqlTools::log, _T("fullName %s \n"), fullName);							
				fflush(MySqlTools::log);
				MySqlTools::failureCounter++;
				if (MySqlTools::failureCounter %10 ==0)
				{
					_tprintf(_T("failure count = %d\n"), MySqlTools::failureCounter);
				}				
			}
			else
			{
				MySqlTools::succeedCounter++;
				if (MySqlTools::succeedCounter % 10==0)
				{
					_tprintf(_T("succeed count = %d\n"), MySqlTools::succeedCounter);
				}	  
			} 							
		}
		free(thumbPtr);
		free(stretchedPtr);
	}  		
	unmapFile(imagePtr); 
	fflush(MySqlTools::log);
}

void MySqlTools::assembleEscapeStr(const char* src, int srcSize, int& firstLength)
{
	int dataLength;
	MySqlTools::buffer[firstLength++]='"';	

	dataLength = mysql_real_escape_string(&MySqlTools::mysql, 
		MySqlTools::buffer+firstLength, src, srcSize);

	firstLength += dataLength;
	MySqlTools::buffer[firstLength++]='"';  
	
	MySqlTools::buffer[firstLength++]=',';
}

		

		
bool MySqlTools::batchInsert(TCHAR* dir, char* ipAddress)
{
	bufferSize = DefaultBufferSize;
	char* host = ipAddress;

	if ((log = fopen("mysql.log", "a+"))==NULL)
	{
		return false;
	}

 	if (ipAddress == NULL)
	{
		host = DefaultHost;
	}
	if (mysql_init(&mysql)==NULL)
	{
		return false;
	}
	if (mysql_real_connect(&mysql, host, DefaultUser, DefaultPassword,
		DefaultDatabase, DefaultPort, NULL, 0)==NULL)
	{
		mysql_close(&mysql);
		return false;
	}
 
	if ((buffer = (char*)malloc(bufferSize)) == NULL)
	{
		_ftprintf(log, _T("query error %s\n"), mysql_error(&mysql));
		mysql_close(&mysql);
		return false;
	}

	genericFind(dir, insertFile);
	free(buffer);
	_ftprintf(MySqlTools::log, _T("succeed=%d, failure=%d\n"), succeedCounter, failureCounter);
	fclose(MySqlTools::log);
	_tprintf(_T("succeed=%d, failure=%d\n"), succeedCounter, failureCounter);
	return true;
}









