Bläddra i källkod

1、数据库变更,读写随着变更;
2、新增函数:ConvertBinaryToString将文件读出来,然后将二进制转换成mysql能保存的字符串数据;
3、新增mysql_stmt_init等相关的演示代码,是另一种更安全的数据库读写方法,防止被注入;

sat23 4 år sedan
förälder
incheckning
7f7c3f6c0a

+ 7 - 9
CTSManager/CTSManager/CTSManager.cpp

@@ -130,17 +130,15 @@ BOOL CCTSManagerApp::InitInstance()
 	CDatabase db;
 	if (db.Init(_STR_HOST_, _STR_USER_, _STR_PASSWD_, _STR_DBNAME_))
 	{
-		db.InserProvider(_T("RealTealk"), _T("RTK台湾"));
-		db.InserProvider(_T("RealTealk2"), _T("RTK台湾"));
-		std::vector<STProvider> vtprovider;
-		db.QueryProvider(vtprovider);
+		db.InserSoc(_T("RT2851C"), _T("RealTealk"), _T("RTK台湾"));
+		db.InserSoc(_T("RT2851M"), _T("RealTealk2"), _T("RTK台湾"));
+		std::vector<STSOC> vtSOC;
+		db.QuerySoc(vtSOC);
 
-		for (std::vector<STProvider>::iterator it = vtprovider.begin(); it != vtprovider.end(); it++ ) {
-			TRACE2(_T("name=%s, note=%s\n"), it->name.c_str(), it->note.c_str());
-
-			//(*it).note = _T("aaaaaa");
+		for (std::vector<STSOC>::iterator it = vtSOC.begin(); it != vtSOC.end(); it++ ) {
+			TRACE3(_T("name=%s, provider=%s, note=%s\n"), it->name.c_str(),it->provider.c_str(), it->note.c_str());
 			it->note = _T("xxxx1111xxx");
-			db.UpdateProvider(it->name, *it);
+			db.UpdateSoc(it->name, *it);
 		}
 	}
 #endif

+ 256 - 3
CTSManager/CTSManager/Database.cpp

@@ -3,6 +3,7 @@
 
 #define CHECKDB if (m_pConn == NULL || !m_bConnected) return FALSE
 
+char* CDatabase::pImage = NULL;
 CDatabase::CDatabase():m_pConn(NULL), m_pError(NULL), m_bConnected(FALSE)
 {
 	m_pConn = mysql_init(NULL);
@@ -14,6 +15,29 @@ CDatabase::~CDatabase()
 	mysql_library_end();
 }
 
+BOOL CDatabase::SetBinaryField(std::string strCondition, void* pDataIn, int nDataLen)
+{
+	CHECKDB;
+	MYSQL_STMT* stmt = NULL;
+	if (!mysql_stmt_prepare(stmt, strCondition.c_str(), strCondition.length()))
+	{
+		MYSQL_BIND bind;
+		memset(&bind, 0, sizeof(MYSQL_BIND));
+		bind.buffer_type = MYSQL_TYPE_BLOB;
+		(*bind.length) = nDataLen;
+		memcpy(bind.buffer, pDataIn, nDataLen);
+		if (!mysql_stmt_bind_param(stmt, (MYSQL_BIND*)&bind))
+		{
+			if (!mysql_stmt_execute(stmt))
+			{
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
 BOOL CDatabase::Init(std::string host, std::string user, std::string password, std::string db)
 {
 	if (!m_pConn)
@@ -156,6 +180,221 @@ BOOL CDatabase::QueryProvider(std::vector<STProvider>& vtProvider)
 	return TRUE;
 }
 
+BOOL CDatabase::InserSoc(const STSOC& soc)
+{
+	CHECKDB;
+#if 0
+	TCHAR szSql[MAX_PATH] = { 0 };
+	_stprintf_s(szSql, INSER_SOC, soc.name.c_str(), soc.provider.c_str(), soc.note.c_str());
+	if (0 != mysql_query(m_pConn, szSql)) {
+#ifdef _DEBUG
+		TRACE1(_T("InserSoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+
+	return TRUE;
+#else
+	MYSQL_STMT* stmt;
+	MYSQL_BIND bind[3];
+	TCHAR szQuery[MAX_PATH] = { 0 };
+	strcpy_s(szQuery, _T("INSERT INTO soc(name, provider, note) VALUES(?,?,?);"));
+	//初始化stmt
+	stmt = mysql_stmt_init(m_pConn);
+	//预处理语句
+	mysql_stmt_prepare(stmt, szQuery, strlen(szQuery));
+	//初始化参数
+	bind[0].buffer_type = MYSQL_TYPE_VARCHAR;
+	bind[0].buffer = (void*)soc.name.c_str();
+	bind[0].is_null = 0;
+	*bind[0].length = soc.name.size();
+
+	bind[1].buffer_type = MYSQL_TYPE_VARCHAR;
+	bind[1].buffer = (void*)soc.provider.c_str();
+	bind[1].is_null = 0;
+	*bind[1].length = soc.provider.size();
+
+	bind[2].buffer_type = MYSQL_TYPE_VARCHAR;
+	bind[2].buffer = (void*)soc.note.c_str();
+	bind[2].is_null = 0;
+	*bind[2].length = soc.note.size();
+
+	//绑定参数123
+	mysql_stmt_bind_param(stmt, bind);
+	//执行预处理mysql语句
+	if (0 != mysql_stmt_execute(stmt))
+	{
+#ifdef _DEBUG
+		TRACE1(_T("InserSoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+
+	return TRUE;
+#endif
+}
+
+BOOL CDatabase::InserSoc(std::string name, std::string provider, std::string note)
+{
+	CHECKDB;
+#if 0
+	TCHAR szSql[MAX_PATH] = { 0 };
+	_stprintf_s(szSql, INSER_SOC, name.c_str(), provider.c_str(), note.c_str());
+	if (0 != mysql_query(m_pConn, szSql)) {
+#ifdef _DEBUG
+		TRACE1(_T("InserSoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+
+	return TRUE;
+#else
+	//https://dev.mysql.com/doc/c-api/5.6/en/mysql-stmt-execute.html
+	MYSQL_STMT* stmt;
+	MYSQL_BIND bind[3];
+	TCHAR szQuery[MAX_PATH] = { 0 };
+	strcpy_s(szQuery, _T("INSERT INTO soc(name, provider, note) VALUES(?,?,?);"));
+	//初始化stmt
+	stmt = mysql_stmt_init(m_pConn);
+	if (!stmt)
+		return FALSE;
+
+	//预处理语句
+	if (mysql_stmt_prepare(stmt, szQuery, strlen(szQuery)))
+		return FALSE;
+
+	// 字段数量是否匹配;
+	int param_count = mysql_stmt_param_count(stmt);
+	if (param_count != 3)
+		return FALSE;
+
+	//初始化参数
+	memset(bind, 0, sizeof(bind));
+	bind[0].buffer_type = MYSQL_TYPE_VARCHAR;
+	bind[0].buffer = (void*)name.c_str();
+	bind[0].buffer_length = name.size();
+	bind[0].is_null = 0;
+	//bind[0].length = (unsigned long*)name.size();
+	bind[0].length = 0;
+
+	bind[1].buffer_type = MYSQL_TYPE_VARCHAR;
+	bind[1].buffer = (void*)provider.c_str();
+	bind[1].buffer_length = provider.size();
+	bind[1].is_null = 0;
+	//bind[1].length = (unsigned long*)provider.size();
+	bind[1].length = 0;
+
+	bind[2].buffer_type = MYSQL_TYPE_VARCHAR;
+	bind[2].buffer = (void*)note.c_str();
+	bind[2].buffer_length = note.size();
+	bind[2].is_null = 0;
+	//bind[2].length = (unsigned long*)note.size();
+	bind[2].length = 0;
+
+	//绑定参数123
+	if (0 != mysql_stmt_bind_param(stmt, bind))
+	{
+#ifdef _DEBUG
+		TRACE1(_T("InserSoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+	
+	//执行预处理mysql语句
+	if (0 != mysql_stmt_execute(stmt))
+	{
+#ifdef _DEBUG
+		TRACE1(_T("InserSoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+
+	return TRUE;
+#endif
+}
+
+BOOL CDatabase::DeleteSoc(std::string name)
+{
+	CHECKDB;
+	TCHAR szSql[MAX_PATH] = { 0 };
+	_stprintf_s(szSql, DEL_SOC, name.c_str());
+	if (0 != mysql_query(m_pConn, szSql)) {
+#ifdef _DEBUG
+		TRACE1(_T("DeleteSoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+BOOL CDatabase::UpdateSoc(std::string name, const STSOC& soc)
+{
+	CHECKDB;
+	TCHAR szSql[MAX_PATH] = { 0 };
+	_stprintf_s(szSql, MOD_SOC, soc.name.c_str(), soc.provider.c_str(), soc.note.c_str(), name.c_str());
+	if (0 != mysql_query(m_pConn, szSql)) {
+#ifdef _DEBUG
+		TRACE1(_T("UpdateSoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+BOOL CDatabase::QuerySoc(std::vector<STSOC>& vtSoc)
+{
+	CHECKDB;
+	if (0 != mysql_query(m_pConn, QUERY_SOC)) {
+#ifdef _DEBUG
+		TRACE1(_T("QuerySoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+
+	// 获取表数据;
+	MYSQL_RES* pData = mysql_store_result(m_pConn);
+	if (pData == NULL) {
+#ifdef _DEBUG
+		TRACE1(_T("QuerySoc error=%s\n"), m_pError ? m_pError : "");
+#endif
+		return FALSE;
+	}
+
+#ifdef _DEBUG
+	// 统计表字段;
+	unsigned int nLen = mysql_num_fields(pData);
+	// 字段长度是否一致;
+	if (nLen != 3) {
+		mysql_free_result(pData);
+		return FALSE;
+	}
+
+	// 打印出字段名称;
+	TCHAR szLog[MAX_PATH] = { 0 };
+	for (int i = 0; i < nLen; i++) {
+		_stprintf_s(szLog, _T("字段名称:%s\n"), mysql_fetch_field(pData)->name);
+		OutputDebugString(szLog);
+	}
+#endif
+
+	// 遍历数据;
+	MYSQL_ROW row;
+	while ((row = mysql_fetch_row(pData)) != NULL) {
+		STSOC soc;
+		soc.name = row[0];
+		soc.provider = row[1];
+		soc.note = row[2];
+		vtSoc.push_back(soc);
+	}
+
+	// 释放内存;
+	mysql_free_result(pData);
+
+	return TRUE;
+}
+
 
 BOOL CDatabase::InsertBrand(const STBranch& brand)
 {
@@ -206,7 +445,7 @@ BOOL CDatabase::UpdateBrand(std::string name, const STBranch& brand)
 {
 	CHECKDB;
 	TCHAR szSql[MAX_PATH] = { 0 };
-	_stprintf_s(szSql, MOD_BRAND, name.c_str(), brand.name.c_str(), brand.note.c_str());
+	_stprintf_s(szSql, MOD_BRAND, brand.name.c_str(), brand.note.c_str(), name.c_str());
 	if (0 != mysql_query(m_pConn, szSql)) {
 #ifdef _DEBUG
 		TRACE1(_T("UpdateBrand error=%s\n"), m_pError ? m_pError : "");
@@ -268,6 +507,20 @@ BOOL CDatabase::QueryBrand(std::vector<STBranch>& vtBrand)
 	return TRUE;
 }
 
+BOOL CDatabase::ImportLogo(std::string name, std::string file)
+{
+	if (!PathFileExists(file.c_str()))
+		return FALSE;
+
+	
+	return 0;
+}
+
+BOOL CDatabase::ExportLogo(std::string name, std::string file)
+{
+	return 0;
+}
+
 BOOL CDatabase::InsertQuarter(const STQuarter& quarter)
 {
 	CHECKDB;
@@ -317,7 +570,7 @@ BOOL CDatabase::UpdateQuarter(std::string name, const STQuarter& quarter)
 {
 	CHECKDB;
 	TCHAR szSql[MAX_PATH] = { 0 };
-	_stprintf_s(szSql, MOD_QUARTER, name.c_str(), quarter.name.c_str(), quarter.scp.c_str(), quarter.note.c_str());
+	_stprintf_s(szSql, MOD_QUARTER,quarter.name.c_str(), quarter.scp.c_str(), quarter.note.c_str(), name.c_str());
 	if (0 != mysql_query(m_pConn, szSql)) {
 #ifdef _DEBUG
 		TRACE1(_T("UpdateQuarter error=%s\n"), m_pError ? m_pError : "");
@@ -429,7 +682,7 @@ BOOL CDatabase::UpdateServer(std::string name, const STServer& Server)
 {
 	CHECKDB;
 	TCHAR szSql[MAX_PATH] = { 0 };
-	_stprintf_s(szSql, MOD_SERVER, name.c_str(), Server.name.c_str(), Server.ip.c_str(), Server.type.c_str(), Server.user.c_str(), Server.password.c_str(), Server.note.c_str());
+	_stprintf_s(szSql, MOD_SERVER, Server.name.c_str(), Server.ip.c_str(), Server.type.c_str(), Server.user.c_str(), Server.password.c_str(), Server.note.c_str(), name.c_str());
 	if (0 != mysql_query(m_pConn, szSql)) {
 #ifdef _DEBUG
 		TRACE1(_T("UpdateServer error=%s\n"), m_pError ? m_pError : "");

+ 45 - 0
CTSManager/CTSManager/Database.h

@@ -20,6 +20,41 @@ private:
 	std::string m_strPassword;
 	std::string m_strHost;
 
+	static char* pImage;
+	// 该函数只能单线程使用;
+	static char* ConvertBinaryToString(MYSQL *pConn, std::string file)
+	{
+		if (pImage != NULL)
+			delete[]pImage;
+		pImage = NULL;
+
+		if (!PathFileExists(file.c_str()))
+			return NULL;
+
+		FILE* pf = NULL;
+		if (0 != fopen_s(&pf, file.c_str(), _T("rb")))
+			return NULL;
+
+		if (pf == NULL)
+			return NULL;
+
+		fseek(pf, 0, SEEK_END);
+		long nlen = ftell(pf);
+		fseek(pf, 0, SEEK_SET);
+
+		byte *pData = new byte[nlen];
+		fread(pData, nlen, 1, pf);
+		fclose(pf);
+
+		pImage = new char[nlen + 10];
+		mysql_real_escape_string(pConn, pImage, (char*)pData, nlen);
+		if (pData)
+			delete[]pData;
+
+		return pImage;
+	}
+
+	BOOL SetBinaryField(std::string strCondition, void* pDataIn, int nDataLen);
 public:
 	// 初始化连接;
 	BOOL Init(std::string host, std::string user, std::string password, std::string db);
@@ -33,12 +68,22 @@ public:
 	BOOL UpdateProvider(std::string name, const STProvider &provider);
 	BOOL QueryProvider(std::vector<STProvider>& vtProvider);
 
+	// 机芯表;
+	BOOL InserSoc(const STSOC& soc);
+	BOOL InserSoc(std::string name, std::string provider, std::string note);
+	BOOL DeleteSoc(std::string name);
+	BOOL UpdateSoc(std::string name, const STSOC& soc);
+	BOOL QuerySoc(std::vector<STSOC>& vtSoc);
+
 	// 品牌表;
 	BOOL InsertBrand(const STBranch& brand);
 	BOOL InsertBrand(std::string name, std::string note);
 	BOOL DeleteBrand(std::string name);
 	BOOL UpdateBrand(std::string name, const STBranch& brand);
 	BOOL QueryBrand(std::vector<STBranch>& vtBrand);
+	// 导入/导出品牌logo;
+	BOOL ImportLogo(std::string name, std::string file);
+	BOOL ExportLogo(std::string name, std::string file);
 
 	// 季度表;
 	BOOL InsertQuarter(const STQuarter& quarter);

+ 10 - 0
CTSManager/CTSManager/table.h

@@ -6,6 +6,7 @@
 #include <string>
 // 插入数据;
 #define INSER_PROVIDER _T("INSERT INTO `provider` (`name`,`note`) VALUES ('%s', '%s');")
+#define INSER_SOC _T("INSERT INTO `soc` (`name`,`provider`,`note`) VALUES ('%s', '%s', '%s');")
 #define INSER_QUARTER _T("INSERT INTO `quarter` (`name`,`scp`,`note`) VALUES ('%s', '%s', '%s');")
 #define INSER_BRAND _T("INSERT INTO `brand` (`name`,`note`,``) VALUES ('%s', '%s');")
 #define INSER_SERVER _T("INSERT INTO `server` (`name`,`ip`,`type`,`user`,`password`,`note`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s');")
@@ -18,18 +19,21 @@
 
 // 删除数据;
 #define DEL_PROVIDER _T("DELETE FROM `provider` WHERE `name` = '%s';")
+#define DEL_SOC _T("DELETE FROM `soc` WHERE `name` = '%s';")
 #define DEL_BRAND _T("DELETE FROM `brand` WHERE `name` = '%s';")
 #define DEL_QUARTER _T("DELETE FROM `quarter` where `name` = '%s';")
 #define DEL_SERVER _T("DELETE FROM `server` where `name` = '%s';")
 
 // 更新数据;
 #define MOD_PROVIDER _T("UPDATE `provider` SET `name`='%s',`note`='%s' WHERE `name`='%s';")
+#define MOD_SOC _T("UPDATE `soc` SET `name`='%s', `provider`='%s', `note`='%s' WHERE `name`='%s';")
 #define MOD_BRAND _T("UPDATE `brand` SET `name`='%s',`note`='%s' WHERE `name`='%s';")
 #define MOD_QUARTER _T("UPDATE `quarter` SET `name`='%s', `scp` = '%s' ,`note`='%s' WHERE `name`='%s';")
 #define MOD_SERVER _T("UPDATE `server` SET `name`='%s', `ip` = '%s', `type`='%s', `user`='%s', `password`='%s', `note`='%s' WHERE `name`='%s';")
 
 // 查询数据;
 #define QUERY_PROVIDER _T("SELECT `name`, `note` FROM `provider`;")
+#define QUERY_SOC _T("SELECT `name`, `provider`, `note` FROM `soc`;")
 #define QUERY_BRAND _T("SELECT `name`, `note` FROM `brand`;")
 #define QUERY_QUARTER _T("SELECT `name`,`scp`, `note` FROM `quarter`;")
 #define QUERY_SERVER _T("SELECT `name`, `ip`, `type`, `user`, `password`, `note`;")
@@ -40,6 +44,12 @@ typedef struct {
 	std::string note;						// 供应商备注;
 }STProvider, *pSTProvider;
 
+typedef struct {
+	std::string name;						// 机芯名称;
+	std::string provider;					// 供应商名称
+	std::string note;						// 供应商备注;
+}STSOC, * pSTSOC;
+
 // 季度表;
 typedef struct {
 	std::string name;						// 季度名称;