#include "CTable.h"

CTable::CTable(CMysqlManager *pMysqlManager,CString TableName,BOOL IfHasT_e_s_t){
	//´ÓÍâ²¿µ¼Èë¹ÜÀíÕßÖ¸Õë
	this->pMysqlManager = pMysqlManager;
	//ÏÈ°ÑÐÂ¿ªµÄÖ¸Õë·Åµ½ÈÝÆ÷Àï
	this->pMysqlManager->vecTable.push_back(this);

	this->TableName = TableName;
	this->IfHasT_e_s_t = IfHasT_e_s_t;
	mysql = mysql_init(NULL);
}

CTable::~CTable(){
	//ÒòÎªÔÚÀàÄÚ£¬ËùÒÔÎÞ·¨Ö±½Ódelete this£¬Ò²¾ÍÎÞ·¨Í¨¹ý¹ÜÀíÕßÉ¾³ý¿Õ¼äÁË£¬Ö»ÄÜÄÚ²¿ÊÖ¶¯ÊÍ·ÅmysqlÁ¬½ÓÏß£¬È»ºóÔÚÍâ²¿ÊÍ·Å±¾Àà
	//¹Ø±ÕÀàÄÚÁ¬½ÓÏß
	if(mysql != 0){
		mysql_close(mysql);
		mysql = 0;
	}
	//ÕÒµ½ÈÝÆ÷ÀïÕâ¸öÖ¸Õë²¢É¾³ý£¬É¾³ý¹ÜÀíÕßÖÐ±¾ÀàµÄµØÖ·£¬ÔÚÎö¹¹Ö´ÐÐÍê±ÏÖ®ºó±¾Àà¿Õ¼äÒ²±»ÊÍ·Å
	VecErase(&(pMysqlManager->vecTable),this);
}

BOOL CTable::AddRecord(CRecord* pSetRecord){
	if(pMysqlManager->MysqlSucceed != 1) return 0;

	//ÓÐÇ¿×ª£¬²»ÐèÒªÅÐ¶ÏÊÇ·ñÎªÉèÖÃ¼ÇÂ¼
	CString SQL = "insert into " + TableName + " set " + pSetRecord->ConditionToSet().RecordToCString();
	
	int nIsSucceed = mysql_query(mysql,SQL);
	CString error = mysql_error(mysql);
	
	if(nIsSucceed != 0){
		//½øÈëÕâ¸ö·ÖÖ§ËµÃ÷¿ÉÄÜÊÇÖ÷¼üÖØ¸´µÄ´íÎóºÍÕæµÄ´íÎó£¬¶¼Ó¦¸Ã·µ»Ø0
		//Èç¹ûÕÒ²»µ½primaryËµÃ÷²»ÊÇÖ÷¼üÖØ¸´µÄ´íÎó£¬ÔòÎªÕæµÄ´íÎó
		if(error.Find("'PRIMARY'") < 0) pMysqlManager->MysqlSucceed = 0;
		return 0;
	}
	return 1;
}

void CTable::DeleteRecord(CRecord* pConditionRecord){
	if(pMysqlManager->MysqlSucceed != 1) return;

	//Ê×ÏÈÒªÅÐ¶ÏÊÇ·ñÊÇÌõ¼þ¼ÇÂ¼£¬Èç¹û²»ÊÇÌõ¼þ¼ÇÂ¼ÔòÖ±½Ó·µ»Ø´íÎó
	if(pConditionRecord->IsConditionRecord() == 0){
		pMysqlManager->MysqlSucceed = 0;
		return;
	}

	CString SQL = "delete from " + TableName + " where " + pConditionRecord->RecordToCString();

	int nIsSucceed = mysql_query(mysql,SQL);
	const char *s = mysql_error(mysql);
	if(nIsSucceed != 0) pMysqlManager->MysqlSucceed = 0;
	return;
}

void CTable::ReviseRecord(CRecord* pSetRecord,CRecord* pConditionRecord){
	if(pMysqlManager->MysqlSucceed != 1) return;

	//Ê×ÏÈÒªÅÐ¶ÏÊÇ·ñÊÇÌõ¼þ¼ÇÂ¼£¬Èç¹û²»ÊÇÌõ¼þ¼ÇÂ¼ÔòÖ±½Ó·µ»Ø´íÎó£¬SetÓÐÇ¿×ª£¬²»ÐèÒªÅÐ¶ÏÁË
	if(pConditionRecord->IsConditionRecord() == 0){
		pMysqlManager->MysqlSucceed = 0;
		return;
	}

	CString SQL = "update " + TableName + " set " + pSetRecord->ConditionToSet().RecordToCString() + " where " + pConditionRecord->RecordToCString();

	int nIsSucceed = mysql_query(mysql,SQL);
	if(nIsSucceed != 0) pMysqlManager->MysqlSucceed = 0;
	return;
}

vector<CRecord> CTable::SelectRecord(CRecord* pCondition,int LineBegin,int LineEnd,CRecord* pSelectField,CRecord *pOrderField,int AscDesc){
	//ÓÃÓÚ´æ·Å²éÑ¯µ½µÄ¼ÇÂ¼
	vector<CRecord> vecRecord;
	if(pMysqlManager->MysqlSucceed != 1) return vecRecord;
	
	if(pCondition != NULL && pCondition->IsConditionRecord() == 0){
		pMysqlManager->MysqlSucceed = 0;
		return vecRecord;
	}
	//ÐÐÊý
	CString strBeginEndLine = "";
	if(LineEnd > LineBegin && LineBegin >= 0) strBeginEndLine.Format("%d,%d",LineBegin,LineEnd);
	//ÏÔÊ¾µÄÁÐ
	CString strSelectField = "";
	if(pSelectField == NULL) strSelectField = "*";
	else strSelectField = pSelectField->OutPutFieldName();
	//Éý½µÅÅÐòÒÀ¾ÝµÄÁÐ
	CString strOrderField = "";
	if(pOrderField != NULL) strOrderField = pOrderField->OutPutFieldName();
	//1±íÊ¾ÉýÐò£¬0±íÊ¾½µÐò
	CString strAscDesc = "";
	if(AscDesc == 1) strAscDesc = "asc";
	if(AscDesc == 0) strAscDesc = "desc";

	//CString SQL = "SELECT abc,bcd FROM abcdefg WHERE bcd='yi' AND cde='YI' ORDER BY def AND efg LIMIT 0,1";// order by strchar limit 0,2;";

	CString SQL = "select " + strSelectField + " from " + TableName;
	if(pCondition != NULL) SQL = SQL + " where " + pCondition->RecordToCString();

	if(strOrderField != "") SQL = SQL + " order by " + strOrderField + " " + strAscDesc;

	if(strBeginEndLine != "") SQL = SQL + " limit " + strBeginEndLine;
	
	int nIsSucceed = mysql_query(mysql,SQL);

	const char *s = mysql_error(mysql);
	//´æ´¢µÃµ½µÄ½á¹û
	MYSQL_RES* result = mysql_store_result(mysql);
	
	int i = -1;
	//ÐÐÊý
	while(i++ != result->row_count - 1){
		int j = -1;
		//ÏÈÕÒµ½µÚÒ»ÐÐµÄÖµ£¬È»ºó¸ù¾Ýµ±Ç°ÐÐÊý×ªnextÕÒµ½¶ÔÓ¦µÄÐÐ
		MYSQL_ROWS* pRow = result->data->data;
		int temp = i;
		while(temp-- != 0) pRow = pRow->next;
		//×¼±¸Ò»¸ö¿Õ¼ÇÂ¼
		CRecord record;
		//ÁÐÊýÑ­»·£¬°ÑÓÐÐ§ÖµÑ­»·¼Óµ½¼ÇÂ¼ÖÐ
		while(j++ != result->field_count - 1){
			//×Ö¶ÎºÍ×Ö¶ÎÖµÊÇ¸ù¾ÝÁÐÊýÀ´Ñ­»·µÄ£¬ËùÒÔÍ¬ÓÃÒ»¸ö±äÁ¿
			CString FieldName = ((result->fields) + j)->name; //·Ö±ð»ñµÃÃ¿ÐÐµÄ×Ö¶ÎÃû
			int nType = ((result->fields) + j)->type; //ÀàÐÍ
			int length = ((result->fields) + j)->length; //³¤¶È
			CField field(FieldName,nType,length);
			CString strValue = pRow->data[j];
			CFieldValue FieldValue(field,strValue);
			record = record + FieldValue;
		}
		vecRecord.push_back(record);
	}

	if(nIsSucceed != 0) pMysqlManager->MysqlSucceed = 0;
	return vecRecord;
}

vector<CRecord> CTable::SearchKey(CString FieldName,CString KeyName){
	//ÓÃÓÚ´æ·Å²éÑ¯µ½µÄ¼ÇÂ¼
	vector<CRecord> vecRecord;
	if(pMysqlManager->MysqlSucceed != 1) return vecRecord;

	CString SQL = "select * from " + TableName + " where " + FieldName + " like '" + KeyName + "'";

	int nIsSucceed = mysql_query(mysql,SQL);

	//´æ´¢µÃµ½µÄ½á¹û
	MYSQL_RES* result = mysql_store_result(mysql);

	int i = -1;
	//ÐÐÊý
	while(i++ != result->row_count - 1){
		int j = -1;
		//ÏÈÕÒµ½µÚÒ»ÐÐµÄÖµ£¬È»ºó¸ù¾Ýµ±Ç°ÐÐÊý×ªnextÕÒµ½¶ÔÓ¦µÄÐÐ
		MYSQL_ROWS* pRow = result->data->data;
		int temp = i;
		while(temp-- != 0) pRow = pRow->next;
		//×¼±¸Ò»¸ö¿Õ¼ÇÂ¼
		CRecord record;
		//ÁÐÊýÑ­»·£¬°ÑÓÐÐ§ÖµÑ­»·¼Óµ½¼ÇÂ¼ÖÐ
		while(j++ != result->field_count - 1){
			//×Ö¶ÎºÍ×Ö¶ÎÖµÊÇ¸ù¾ÝÁÐÊýÀ´Ñ­»·µÄ£¬ËùÒÔÍ¬ÓÃÒ»¸ö±äÁ¿
			CString FieldName = ((result->fields) + j)->name; //·Ö±ð»ñµÃÃ¿ÐÐµÄ×Ö¶ÎÃû
			int nType = ((result->fields) + j)->type; //ÀàÐÍ
			int length = ((result->fields) + j)->length; //³¤¶È
			CField field(FieldName,nType,length);
			CString strValue = pRow->data[j];
			CFieldValue FieldValue(field,strValue);
			record = record + FieldValue;
		}
		vecRecord.push_back(record);
	}

	if(nIsSucceed != 0) pMysqlManager->MysqlSucceed = 0;
	return vecRecord;
}

void CTable::AddField(CField *pField,BOOL ifExists){
	if(pMysqlManager->MysqlSucceed != 1) return;

	CString SQL = "alter table " + TableName + " add " + pField->FieldName + " " + pField->Type + "(" + pField->strLength + ")";
	//Èç¹ûÓÐÄ¬ÈÏÖµ
	if(pField->Default != 0) SQL = SQL + " not null default " + pField->strDefault;
	//Èç¹ûÊÇÖ÷¼ü
	if(pField->ifPrimaryKey == 1) SQL = SQL + " primary key";

	//Ö´ÐÐ
	int nIsSucceed = mysql_query(mysql,SQL);
	const char*s = mysql_error(mysql);

	//Èç¹ûÌí¼Ó×Ö¶Î³É¹¦£¬ÇÒÊÇÐÂ¿ªµÄ±íµÚÒ»´Î¼ÓÍê×Ö¶ÎÊ±ÐèÒªÉ¾³ý×Ö¶ÎT_e_s_t
	if(nIsSucceed == 0 && IfHasT_e_s_t == 1){
		DropField(&CField("T_e_s_t"));
		IfHasT_e_s_t = 0;
	}

	//Èç¹û²»ÊÇ±Ø¶¨¼ÓÈë£¬ÇÒmysql·µ»Ø´íÎó£¬ÔòÐèÒª°ÑÖ´ÐÐÌõ¼þ¸ÄÎª0
	if(ifExists == 0 && nIsSucceed != 0) pMysqlManager->MysqlSucceed = 0;
	return;
}

BOOL CTable::DropField(CField *pField,BOOL ifExists){
	if(pMysqlManager->MysqlSucceed != 1) return 0;

	vector<CField> vecField = GetField();
	BOOL ifExist = 0;
	int i = -1;
	while(i++ != vecField.size() - 1){
		ifExist = ifExist || (vecField.at(i).FieldName == pField->FieldName);
	}
	
	int nIsSucceed = -1;
	//Èç¹û±íÖÐ²»´æÔÚ¸Ã×Ö¶Î£¬ÇÒ²»ÊÇ±Ø¶¨É¾³ý£¬ËµÃ÷¼´½«ÒªÉ¾Ò»¸ö²»´æÔÚµÄ×Ö¶Î£¬Ö±½Ó·µ»Ø´íÎóºÍ0
	if(ifExist == 0 && ifExists == 0){
		pMysqlManager->MysqlSucceed = 0;
		return 0;
	}
	//Èç¹û±íÖÐ²»´æÔÚ¸Ã×Ö¶Î£¬ÇÒÊÇ±Ø¶¨É¾³ý£¬ËµÃ÷±Ø¶¨ÒªÉ¾³ýÕâ¸ö×Ö¶Î£¬ËùÒÔ²»ÐèÒªÖ´ÐÐmysql£¬ÔòÖ±½Ó·µ»Ø1
	if(ifExist == 0 && ifExists == 1) return 1;
	//Èç¹û±íÖÐ´æÔÚ¸Ã×Ö¶Î£¬²»¹ÜÊÇ²»ÊÇ±Ø¶¨É¾³ý¶¼ÐèÒªÖ´ÐÐmysqlÀ´ÅÐ¶ÏÊÇ·ñÒÑ¾­É¾³ý³É¹¦£¬É¾³ý³É¹¦·µ»Ø1£¬Ê§°Ü·µ»Ø´íÎóºÍ0
	nIsSucceed = mysql_query(mysql,"alter table " + TableName + " drop column " + pField->FieldName);
	if(nIsSucceed == 0) return 1;
	else{
		pMysqlManager->MysqlSucceed = 0;
		return 0;
	}
}

vector<CField> CTable::GetField(){
	if(pMysqlManager->MysqlSucceed != 1){
		vector<CField> error;
		return error;
	}

	//ÏÈËÑË÷ÕûÕÅ±í
	mysql_query(mysql,"select * from " + TableName);
	//´æ´¢µÃµ½µÄ½á¹û
	MYSQL_RES* result = mysql_store_result(mysql);
	
	vector<CField> vecField;
	int i = -1;
	while(i++ != result->field_count - 1){
		CField Field(((result->fields) + i)->name,((result->fields) + i)->type,((result->fields) + i)->length);
		vecField.push_back(Field);
	}
	return vecField;
}

void CTable::ImportTable(CString mysql_exe_path,CString sqlpath){
	if(pMysqlManager->MysqlSucceed != 1) return;

	CString para = "";
	CString strPasswd = mysql->passwd;
	//Ê×ÏÈÊÇÖ÷»úºÍÓÃ»§Ãû
	para = para + " -h" + mysql->host + " -u" + mysql->user;
	//Èç¹ûÓÐÃÜÂë¼ÓÉÏÃÜÂë
	if(strPasswd != "")  para = para + " -p" + strPasswd;
	//×îºóÊÇÐèÒªµ¼ÈëµÄÊý¾Ý¿âÃû
	para = para + " " + mysql->db + " < " + sqlpath;

	//Ö´ÐÐ³ÌÐò£¬ShellExecute²»ÐÐ
	system("\"" + mysql_exe_path + "\"" + para);
	//ShellExecute(NULL,_T("open"),_T(mysql_exe_path),para,NULL,SW_SHOWNORMAL);
	return;
}

void CTable::ExportTable(CString mysqldump_exe_path,CString sqlpath){
	if(pMysqlManager->MysqlSucceed != 1) return;
	
	CString para = "";
	CString strPasswd = mysql->passwd;
	//Ê×ÏÈÊÇÖ÷»úºÍÓÃ»§Ãû
	para = para + " -h" + mysql->host + " -u" + mysql->user;
	//Èç¹ûÓÐÃÜÂë¼ÓÉÏÃÜÂë
	if(strPasswd != "")  para = para + " -p" + strPasswd;
	//×îºóÊÇÐèÒªµ¼³öµÄÊý¾Ý¿âºÍ±íÃû
	para = para + " " + mysql->db + " " + TableName + " > " + sqlpath;
	
	//Ö´ÐÐ³ÌÐò£¬ShellExecute²»ÐÐ
	system("\"" + mysqldump_exe_path + "\"" + para);
	//ShellExecute(NULL,_T("open"),_T(mysqldump_exe_path),para,NULL,SW_SHOWNORMAL);
	return;
}