Browse Source

1、md5封装函数:获取文本md5、获取文件md5;
2、使用批量插入数据时,如果插入失败,补充:rollback,回滚事务;(缺少会使得下次调用事务时报错)

Jeff 5 years ago
parent
commit
a937668851

+ 32 - 0
scbc.tools/MD5/MD5.cpp

@@ -292,3 +292,35 @@ CONST TCHAR* CMD5::GetMD5Digest()
 
 	return NULL;
 }
+
+std::string GetTextMD5(std::string text)
+{
+	CMD5 md5;
+	md5.SetBYTEText((const byte*)text.c_str(), text.size());
+	return std::string(md5.GetMD5Digest());
+}
+
+std::string GetFileMD5(std::string file)
+{
+	CMD5 md5;
+	FILE *pf = NULL;
+	if ( _tfopen_s(&pf, file.c_str(), "rb") == 0 )
+	{
+		fseek(pf, 0, SEEK_END);
+		size_t fsize = ftell(pf);
+		fseek(pf, 0, SEEK_SET);
+
+		byte* pdata = new byte[fsize];
+		fread(pdata, 1, fsize, pf);
+		md5.SetBYTEText(pdata, fsize);
+
+		delete []pdata;
+		pdata = NULL;
+
+		fclose(pf);
+
+		return std::string(md5.GetMD5Digest());
+	}
+
+	return std::string();
+}

+ 4 - 0
scbc.tools/MD5/MD5.h

@@ -52,4 +52,8 @@ public:
 	CONST TCHAR* GetMD5Digest();
 };
 
+extern std::string GetTextMD5(std::string text);
+
+extern std::string GetFileMD5(std::string file);
+
 #endif

+ 39 - 1
scbc.tools/scbc.tools/DataImpl.cpp

@@ -20,7 +20,7 @@ BOOL CDataImpl::Open()
 {
 	Close();
 	CHAR szpath[MAX_PATH] = {0};
-	_stprintf_s(szpath, _T("%ssms.db"), Global::g_szCurModuleDir);
+	_stprintf_s(szpath, _T("%sscbc.db"), Global::g_szCurModuleDir);
 	std::string strPath;
 	if ( !CharEncoding::ASCII2UTF8(szpath,strPath))
 	{
@@ -445,6 +445,8 @@ INT CDataImpl::BatchInsertKeyInfo(std::vector<STKeys> &vtdata)
 	nRet = sqlite3_finalize(stmt); 
 	if ( nRet != SQLITE_OK )
 	{
+		// »Ø¹öÊÂÎñ;
+		nRet = sqlite3_exec(m_psqlite3, "rollback;", 0, 0, &psqlite_error);
 		return -1;
 	}
 
@@ -458,6 +460,42 @@ INT CDataImpl::BatchInsertKeyInfo(std::vector<STKeys> &vtdata)
 	return vtdata.size();
 }
 
+BOOL CDataImpl::UpdateMidInfo(STMid &data)
+{
+	if(m_psqlite3 == NULL)
+		return FALSE;
+
+	std::string strInsert = "UPDATE mid SET pid ='";
+	strInsert.append(data.pid);
+	strInsert.append("', ctype='");
+	strInsert.append(data.ctype);
+	strInsert.append("', version='");
+	strInsert.append(data.version);
+	strInsert.append("', purl='");
+	strInsert.append(data.purl);
+	strInsert.append("', psize='");
+	strInsert.append(data.psize);
+	strInsert.append("', pmd5='");
+	strInsert.append(data.pmd5);
+	strInsert.append("', number='");
+	strInsert.append(data.number);
+	strInsert.append("'");
+	strInsert.append(" WHERE bid ='");
+	strInsert.append(data.order);
+	strInsert.append("';");
+
+	char* psqlite_error = NULL;
+	int sqlite_error = sqlite3_exec(m_psqlite3, strInsert.c_str(), NULL, 0, &psqlite_error);
+	if(SQLITE_OK != sqlite_error)
+	{
+		//Global::WriteTextLog(_T("UpdateContactsType:%s"), psqlite_error);
+		FREE_MSG2
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 BOOL CDataImpl::UpdateDownloadStatus(std::string order, int status, std::string des /* = "" */ )
 {
 	if(m_psqlite3 == NULL)

+ 26 - 4
scbc.tools/scbc.tools/DataImpl.h

@@ -55,15 +55,35 @@ public:
 	// begin;
 	BOOL TransactionBegin()
 	{
-		INT nRet = sqlite3_exec(m_psqlite3, "begin;", 0, 0, &m_pszErrmsg);
-		return ( nRet == 0 ) ? TRUE : FALSE;
+		char* psqlite_error = NULL;
+		INT nRet = sqlite3_exec(m_psqlite3, "begin;", 0, 0, &psqlite_error);
+		if ( nRet != SQLITE_OK)
+		{
+			if ( psqlite_error ) 
+			{ 
+				sqlite3_free(psqlite_error); 
+				psqlite_error = NULL;
+			}
+			return FALSE;
+		}
+		return TRUE;
 	}
 
 	// commit;
 	BOOL TransactionCommit()
 	{
-		INT nRet = sqlite3_exec(m_psqlite3, "commit;", 0, 0, &m_pszErrmsg);
-		return ( nRet == 0 ) ? TRUE : FALSE;
+		char* psqlite_error = NULL;
+		INT nRet = sqlite3_exec(m_psqlite3, "commit;", 0, 0, &psqlite_error);
+		if ( nRet != SQLITE_OK)
+		{
+			if ( psqlite_error ) 
+			{ 
+				sqlite3_free(psqlite_error); 
+				psqlite_error = NULL;
+			}
+			return FALSE;
+		}
+		return TRUE;
 	}
 
 	// 执行语句;
@@ -88,6 +108,8 @@ public:
 	// 批量插入keys;
 	INT BatchInsertKeyInfo(std::vector<STKeys> &vtdata);
 
+	// 更新MID表;
+	BOOL UpdateMidInfo(STMid &data);
 	// 更新下载状态;(成功时,更新完成时间)
 	BOOL UpdateDownloadStatus(std::string order, int status, std::string des = "" /*失败描述*/);
 	// 更新抄写状态;

+ 12 - 0
scbc.tools/scbc.tools/Global.h

@@ -16,6 +16,18 @@
 namespace Global
 {
 	//////////////////////////////////////////////////////////////////////////
+	typedef struct __MIDINFO__
+	{
+		std::string order;		// 땐데뵀;
+		std::string quantity;	// 땐데鑒좆;
+		std::string pid;		// 
+		std::string ctype;
+		std::string version;
+		std::string purl;
+		std::string psize;
+		std::string pmd5;
+	}STMidInfo, *pSTMidInfo;
+
 	// �섬관럿쀼竟;
 	typedef struct
 	{

+ 107 - 0
scbc.tools/scbc.tools/SDK.cpp

@@ -1,6 +1,10 @@
 #include "StdAfx.h"
 #include "SDK.h"
 #include "CritSection.h"
+#include "Global.h"
+
+ThreadSection g_csTask;
+std::list<STMid> CSDK::m_vtMidTask;
 
 CSDK::CSDK(void)
 {
@@ -9,3 +13,106 @@ CSDK::CSDK(void)
 CSDK::~CSDK(void)
 {
 }
+
+int CSDK::QueryMidInfo(std::string order)
+{
+	return 0;
+}
+
+int CSDK::DownloadMidData(std::string order)
+{
+	return 0;
+}
+
+int CSDK::QueryKeyInfo(std::string sn)
+{
+	return 0;
+}
+
+int CSDK::UpdateKeyCopyStatus(std::string sn)
+{
+	return 0;
+}
+
+int CSDK::UpdateKeyReportStatus(std::string sn)
+{
+	return 0;
+}
+
+int CSDK::ReportKeyCopyResults(std::string sn /* = "" */)
+{
+	return 0;
+}
+
+void CSDK::AddDownloadTask(STMid &mid)
+{
+	AutoThreadSection ats(&g_csTask);
+	bool has = false;
+	std::list<STMid>::iterator it = m_vtMidTask.begin();
+	for (; it != m_vtMidTask.end(); it++ )
+	{
+		if ( _tcsicmp(it->order.c_str(), mid.order.c_str()) == 0 )
+		{
+			has = true;
+			*it = mid; // 更新;
+			break;
+		}
+	}
+
+	if ( !has )
+	{
+		m_vtMidTask.push_back(mid);
+	}
+}
+
+BOOL CSDK::PopDownloadTask(STMid &mid)
+{
+	AutoThreadSection ats(&g_csTask);
+	if ( m_vtMidTask.size() )
+	{
+		mid = m_vtMidTask.front();
+		m_vtMidTask.pop_front();
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+DWORD CSDK::ThreadDownload(LPVOID lpParam)
+{
+	CSDK *that = (CSDK*)lpParam;
+	// key包文件路径;
+	TCHAR szKeyPacket[MAX_PATH] = {0};
+	do 
+	{
+		// 取出任务;
+		STMid mid;
+		if ( PopDownloadTask(mid) )
+		{
+			// 判断文件是否存在,并检验md5值;
+			_stprintf_s(szKeyPacket, _T("%s%s.json"), Global::g_szCurModuleDir, mid.order.c_str());
+			if ( _taccess(szKeyPacket, 0) != -1 )
+			{
+				// 校验文件md5值;
+			}
+			else
+			{
+				// 文件不存在,开始下载;
+			}
+		}
+	} while (WaitForSingleObject(that->m_hDownloadEvent, 3000) == WAIT_TIMEOUT );
+
+	return 0L;
+}
+
+DWORD CSDK::ThreadReport(LPVOID lpParam)
+{
+	CSDK *that = (CSDK*)lpParam;
+	do 
+	{
+		// 自动上报;
+
+	} while (WaitForSingleObject(that->m_hReportEvent, 3000) == WAIT_TIMEOUT );
+
+	return 0L;
+}

+ 24 - 0
scbc.tools/scbc.tools/SDK.h

@@ -3,11 +3,35 @@
 
 #pragma once
 
+#include "TableInfo.h"
+
 class CSDK
 {
 public:
 	CSDK(void);
 	~CSDK(void);
+
+public:
+	int QueryMidInfo(std::string order);
+	int DownloadMidData(std::string order);
+	int QueryKeyInfo(std::string sn);
+	int UpdateKeyCopyStatus(std::string sn);
+	int UpdateKeyReportStatus(std::string sn);
+	int ReportKeyCopyResults(std::string sn = "");
+
+private:
+	static std::list<STMid> m_vtMidTask;
+	static void AddDownloadTask(STMid &mid);
+	static BOOL PopDownloadTask(STMid &mid);
+
+	
+	HANDLE m_hDownloadEvent;
+	HANDLE m_hThreadDownload;
+	static DWORD WINAPI ThreadDownload(LPVOID lpParam);
+
+	HANDLE m_hReportEvent;
+	HANDLE m_hThreadReport;
+	static DWORD WINAPI ThreadReport(LPVOID lpParam);
 };
 
 #endif

+ 23 - 0
scbc.tools/scbc.tools/TableInfo.h

@@ -61,6 +61,29 @@ typedef struct	__ST_MID__
 	std::string		dsize;							// 已下载大小;
 	std::string		file;							// 文件路径;
 	std::string		des;							// 状态描述:下载失败原因;
+
+	__ST_MID__& operator=(const __ST_MID__& that)
+	{
+		if ( this != &that )
+		{
+			number = that.number;
+			pid = that.pid;
+			ctype = that.ctype;
+			version = that.version;
+			purl = that.purl;
+			psize = that.psize;
+			pmd5 = that.pmd5;
+			status = that.status;
+			start_date = that.start_date;
+			finish_date = that.finish_date;
+			dsize = that.dsize;
+			file = that.file;
+			des = that.des;
+		}
+
+		return *this;
+	}
+
 }STMid, *pSTMid;
 
 // 抄写表;

+ 31 - 0
scbc.tools/scbc.tools/scbc.tools.cpp

@@ -32,6 +32,7 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 	}
 	else
 	{
+		std::string md5 = GetFileMD5("D:\\bin\\scbc.tools\\scbc.tools.pdb");
 		// TODO: 在此处为应用程序的行为编写代码。
 		CDataImpl db;
 		if ( db.Open() )
@@ -190,11 +191,41 @@ int DownloadMidData(const char* lpOrder)
 	if ( lpOrder == NULL || lpOrder[0] == '\0' )
 		return -1;
 	
+	STMid host_mid;
 	// 1、直接http请求数据mid data;
+	// ...
 
 	// 2、查询数据库是否有该批次,有则更新,无则插入;
+	CDataImpl db;
+	if ( !db.Open() )
+		return -2;
+
+	STMid local_mid;
+	int nRow = db.QueryMidInfo(lpOrder, local_mid);
+	if ( nRow == -1)
+		return -3;
+
+	if ( nRow == 0 )
+	{
+		// 新增;
+		db.InsertMidInfo(host_mid);
+	}
+	else if ( nRow == 1 )
+	{
+		// 已下载完成,退出;
+		if ( _tcsicmp(local_mid.status.c_str(), "1") == 0 )
+			return 0;
+
+		// 更新;
+		db.UpdateMidInfo(host_mid);
+	}
 
 	// 3、key文件包是否存在,存在判断md5值,相同则下载成功;否则启动后台线程开始下载;
+	if ( _tcsicmp(host_mid.pmd5.c_str(), local_mid.pmd5.c_str()) != 0 )
+	{
+		// 线程是否正在下载,如果是删除该任务;同时删除文件;
+		
+	}
 
 	return 0;
 }

+ 16 - 3
scbc.tools/scbc.tools/scbc.tools.vcproj

@@ -42,7 +42,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\cJson;..\filehelper;..\Include;..\Log4C"
+				AdditionalIncludeDirectories="..\cJson;..\filehelper;..\Include;..\Log4C;..\MD5"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SCBCTOOLS_EXPORTS;LOG4C_ENABLE;CURL_STATICLIB"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
@@ -65,6 +65,7 @@
 				AdditionalDependencies="crypt32.lib ws2_32.lib winmm.lib wldap32.lib log4C.lib libcurld.lib libeay32.lib ssleay32.lib sqlite3d.lib"
 				LinkIncremental="2"
 				AdditionalLibraryDirectories="..\lib"
+				IgnoreDefaultLibraryNames=""
 				GenerateDebugInformation="true"
 				SubSystem="2"
 				TargetMachine="1"
@@ -119,7 +120,7 @@
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\cJson;..\filehelper;..\Include;..\Log4C"
+				AdditionalIncludeDirectories="..\cJson;..\filehelper;..\Include;..\Log4C;..\MD5"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SCBCTOOLS_EXPORTS;LOG4C_ENABLE;CURL_STATICLIB"
 				RuntimeLibrary="2"
 				EnableFunctionLevelLinking="true"
@@ -195,7 +196,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\cJson;..\filehelper;..\Include;..\Log4C"
+				AdditionalIncludeDirectories="..\cJson;..\filehelper;..\Include;..\Log4C;..\MD5"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SCBCTOOLS_EXPORTS;LOG4C_ENABLE;CURL_STATICLIB;TEST_MODE"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
@@ -474,6 +475,18 @@
 				>
 			</File>
 		</Filter>
+		<Filter
+			Name="MD5"
+			>
+			<File
+				RelativePath="..\MD5\MD5.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\MD5\MD5.h"
+				>
+			</File>
+		</Filter>
 		<File
 			RelativePath=".\ReadMe.txt"
 			>

+ 4 - 0
scbc.tools/scbc.tools/stdafx.h

@@ -27,9 +27,13 @@
 #include <iostream>
 // Windows 头文件:
 #include <windows.h>
+#include <vector>
+#include <string>
+#include <list>
 
 // log4c头文件;
 #include "log4c.h"
 // sqlite3头;
 #include "sqlite3.h"
 // TODO: 在此处引用程序需要的其他头文件
+#include "MD5.h"