⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ii_mysql.cpp

📁 linux下mysql调用
💻 CPP
字号:
//====================================================================
// 文件名: ii_mysql.cpp
//
// 文件描述:
// ------------------------------------------------------------------
// 跨平台通用数据库接口Mysql数据库插件实现
// ------------------------------------------------------------------
// 
// 时间: 2002.9
// 编程: 喻宜
// ------------------------------------------------------------------
// 修改说明(请按格式说明)...
//====================================================================

#include <stdlib.h>
#include "../../../../include/ies_templ.h"
#include "../../../../include/dbi_odbc.h"

#ifdef WIN32
#define __WIN__
#include <winsock.h>
#endif

#include "./include/mysql.h"

///////////////////////////////////////////////////////////////////
// MYSQL DATABASE
///////////////////////////////////////////////////////////////////
class CIIMysqlDBI
{
public:
	CIIMysqlDBI();
	~CIIMysqlDBI();

public:
	//连接和断开数据库
	bool Open(const char *i_pIpAddr, const char *i_pDbName,
					const char *i_pszUser, const char *i_pszPwd);
	void Close();

	bool ExecuteSQL(const char *i_pszSqlStr);				//执行SQL语句

	bool IsTableExist(const char *i_szTableName);			//判断表是否存在

	//获取错误号和错误字符串
	int GetErrorNo();
	const char* GetErrorStr();

	bool PrepareSQL(const char *i_pStringSQL);			//准备SQL语句
	void CloseSQL();									//关闭本次SQL处理

	//ODBC操作
	bool BindCol(int i_nColType,
			int i_nColSize, void *i_pColAddr);		//绑定列
	bool BindPara(int i_nParaType,
			int i_nParaSize, void *i_pParaAddr);	//绑定参数

	int Exec();										//执行SQL语句
	bool Fetch();									//获取查询结果

	bool IsEnd()									//是否到了记录尾
		{return m_bIsEnd;}

	// 事务操作
	bool BeginTrans();
	bool Commit();
	bool Rollback();

protected:
	bool PassPara();								//传递参数信息
	bool PassCol();									//传递列信息

	bool MakeColInfo();								//整理列信息(为计算偏移量)

private:
	bool		m_bIsOpenDB;						//是否打开数据库
	bool		m_bIsPrepareSQL;					//是否准备SQL语句
	bool		m_bIsEnd;							//是否查询到尾
	CIIString	m_pszSql;							//SQL语句
	CIIString	m_pszSqlBak;						//SQL语句备份
	CIIString	m_pszNextSql;
	CIILog		m_iiLog;							//日志
	CIIString	m_pszError;							//错误字符串

	MYSQL*		m_pConnMysql;						//连接参数
	MYSQL_RES*	m_pResMysql;						//查询结果
	MYSQL_ROW	m_sRowMysql;						//记录集

	CIIArray<SBind>	m_arPara;						//参数信息集
	CIIArray<SBind> m_arCol;						//字段信息集

	int			m_nRowSize;							//一个记录的大小
	int			m_nRowCount;						//记录个数
	int			m_nColCount;						//字段个数
	int			m_nRowId;							//ODBC中记录获取第几次	
	int			m_nSqlType;
};

CIIMysqlDBI::CIIMysqlDBI():
	m_pResMysql(NULL),
	m_sRowMysql(NULL),
	m_pConnMysql(NULL),
	m_bIsPrepareSQL(false),
	m_nRowCount(0),
	m_nRowId(0),
	m_nSqlType(0),
	m_bIsOpenDB(false),
	m_bIsEnd(true)
{
	m_iiLog.SetProcName("mysql_db");
	m_arPara.SetSize(10);
	m_arCol.SetSize(20);
}

CIIMysqlDBI::~CIIMysqlDBI()
{
	if (m_bIsOpenDB)
		Close();
}

bool CIIMysqlDBI::Open(const char *i_pIpAddr, const char *i_pDbName, const char *i_pszUser, const char *i_pszPwd)
{
	m_pConnMysql = mysql_init((MYSQL*)0);

	if (m_pConnMysql == NULL)
		return false;

	if (mysql_real_connect(m_pConnMysql, i_pIpAddr, i_pszUser, 
							i_pszPwd, i_pDbName, 0, NULL, CLIENT_FOUND_ROWS) == NULL)
	{
		return false;
	}

	m_bIsOpenDB = true;
	return true;
}

void CIIMysqlDBI::Close()
{
	if (m_bIsPrepareSQL)
	{
		CloseSQL();
		m_bIsPrepareSQL = false;
	}

	if (m_pConnMysql != NULL)
	{
		mysql_close(m_pConnMysql);
		m_pConnMysql = NULL;
	}
	m_bIsOpenDB = false;
}

bool CIIMysqlDBI::ExecuteSQL(const char *i_pszSqlStr)
{
	if (m_pConnMysql == NULL)
		return false;

	if (mysql_query(m_pConnMysql, i_pszSqlStr) == 0)
		return true;

	return false;
}

bool CIIMysqlDBI::IsTableExist(const char *i_szTableName)
{
	CIIString tSQLString = "SELECT * FROM ";

	if (i_szTableName == NULL)
		return false;

	tSQLString += i_szTableName;
	tSQLString += " WHERE 1=0";

	return ExecuteSQL(tSQLString.GetBuf());
}

int CIIMysqlDBI::GetErrorNo()
{
	return mysql_errno(m_pConnMysql);
}

const char* CIIMysqlDBI::GetErrorStr()
{
	m_pszError = mysql_error(m_pConnMysql);
	return m_pszError.GetBuf();
}

bool CIIMysqlDBI::PrepareSQL(const char *i_pStringSQL)
{
	if (!m_bIsOpenDB)
		return false;

	//如果未关闭SQL,则先关闭SQL
	if (m_bIsPrepareSQL)
		CloseSQL();

	m_pszSql = i_pStringSQL;
	m_pszSql.TrimAll();
	m_pszSqlBak = m_pszSql;
	m_bIsPrepareSQL = true;

	CIIString tStr = m_pszSql.Left(6);
	tStr.ToUpper();

	if (tStr == "SELECT")
		m_nSqlType = 1;
	else if (tStr == "UPDATE" || tStr == "DELETE")
		m_nSqlType = 2;
	else
		m_nSqlType = 0;

	return true;
}

void CIIMysqlDBI::CloseSQL()
{
	if (m_pResMysql)
	{
		mysql_free_result(m_pResMysql);
		m_pResMysql = NULL;
	}

	m_arCol.Empty();
	m_arPara.Empty();
	m_pszNextSql.Empty();

	m_nRowCount = 0;
	m_nRowId = 0;
	m_bIsEnd = false;
	m_bIsPrepareSQL = false;
}

bool CIIMysqlDBI::BindCol(int i_nColType,
						int i_nColSize, void *i_pColAddr)
{
	SBind tmp;
	bool bRet;

	if (i_pColAddr == NULL)
		return false;

	tmp.nType = i_nColType;
	tmp.pAddr = i_pColAddr;
	tmp.nSize = i_nColSize;

	bRet = m_arCol.AddLast(tmp);
	return bRet;
}

bool CIIMysqlDBI::BindPara(int i_nParaType,
						   int i_nParaSize, void *i_pParaAddr)
{
	SBind tmp;
	bool bRet;

	if (i_pParaAddr == NULL)
		return false;

	tmp.nType = i_nParaType;
	tmp.pAddr = i_pParaAddr;
	tmp.nSize = i_nParaSize;

	bRet = m_arPara.AddLast(tmp);
	return bRet;
}

bool CIIMysqlDBI::PassCol()
{
	CIITime tmpTime;
	STimeInfo *tTime;

	if (!m_bIsOpenDB)
		return false;

	for (int i = 0; i < m_arCol.GetNum(); i++)
	{
		if (m_sRowMysql[i] == NULL)		//结果为空则下一个
			continue;

		switch (m_arCol[i].nType)
		{
		case IES_SQL_BOOL:
		case IES_SQL_UTINYINT:
			*(Juint8*)m_arCol[i].pAddr = (Juint8)atoi(m_sRowMysql[i]);
			break;
		case IES_SQL_SMALLINT:
			*(Jint16*)m_arCol[i].pAddr = (Jint16)atoi(m_sRowMysql[i]);
			break;
		case IES_SQL_USMALLINT:
			*(Juint16*)m_arCol[i].pAddr = (Juint16)atoi(m_sRowMysql[i]);
			break;
		case IES_SQL_INT:
			*(Jint32*)m_arCol[i].pAddr = (Jint32)atoi(m_sRowMysql[i]);
			break;
		case IES_SQL_UINT:
			*(Juint32*)m_arCol[i].pAddr = (Juint32)atoi(m_sRowMysql[i]);
			break;
		case IES_SQL_FLOAT:
			*(float*)m_arCol[i].pAddr = (float)atof(m_sRowMysql[i]);
			break;
		case IES_SQL_DOUBLE:
			*(double*)m_arCol[i].pAddr = (double)atof(m_sRowMysql[i]);
			break;
		case IES_SQL_TIMESTAMP:
			tmpTime.SetTime(m_sRowMysql[i]);
			tTime = (STimeInfo*)m_arCol[i].pAddr;
			tTime->nYear = tmpTime.GetYear();
			tTime->nMonth = tmpTime.GetMonth();
			tTime->nDay = tmpTime.GetDay();
			tTime->nHour = tmpTime.GetHour();
			tTime->nMinute = tmpTime.GetMinute();
			tTime->nSecond = tmpTime.GetSecond();
			break;
		case IES_SQL_STRING:
			strcpy((char*)m_arCol[i].pAddr, m_sRowMysql[i]);
			break;
		case IES_SQL_BINARY:
			memcpy(m_arCol[i].pAddr, m_sRowMysql[i], m_arCol[i].nSize);
			break;
		}
	}
	return true;
}

bool CIIMysqlDBI::PassPara()
{
	char tmpBuf[513];
	int id = 0;
	int len;
	CIITime tTime;
	CIIString tmp;

	for (int i = 0; i < m_arPara.GetNum(); i++)
	{
		len = 0;
		STimeInfo *pTime;

		tmp = "\'";

		id = m_pszSql.Find("?");

		switch (m_arPara[i].nType)
		{
		case IES_SQL_BOOL:			//
		case IES_SQL_UTINYINT:		//tinyint -> char
			sprintf(tmpBuf, "%d", *(Juint8*)(m_arPara[i].pAddr));
			m_pszSql.ReplaceAt(id, 1, tmpBuf);
			break;
		case IES_SQL_SMALLINT:		//smallint -> short
			sprintf(tmpBuf, "%d", *(Jint16*)(m_arPara[i].pAddr));
			m_pszSql.ReplaceAt(id, 1, tmpBuf);
			break;
		case IES_SQL_USMALLINT:		//smallint -> short
			sprintf(tmpBuf, "%d", *(Juint16*)(m_arPara[i].pAddr));
			m_pszSql.ReplaceAt(id, 1, tmpBuf);
			break;
		case IES_SQL_INT:			//int -> int
			sprintf(tmpBuf, "%d", *(Jint32*)(m_arPara[i].pAddr));
			m_pszSql.ReplaceAt(id, 1, tmpBuf);
			break;
		case IES_SQL_UINT:			//int -> int
			sprintf(tmpBuf, "%d", *(Juint32*)(m_arPara[i].pAddr));
			m_pszSql.ReplaceAt(id, 1, tmpBuf);
			break;
		case IES_SQL_FLOAT:		//float -> float
			sprintf(tmpBuf, "%f", *(float*)(m_arPara[i].pAddr));
			m_pszSql.ReplaceAt(id, 1, tmpBuf);
			break;
		case IES_SQL_DOUBLE:		//double -> double
			sprintf(tmpBuf, "%f", *(double*)(m_arPara[i].pAddr));
			m_pszSql.ReplaceAt(id, 1, tmpBuf);
			break;
		case IES_SQL_TIMESTAMP:	//timestamp -> STimeInfo
			pTime = (STimeInfo*)m_arPara[i].pAddr;
			sprintf(tmpBuf, "\'%04d-%02d-%02d %02d:%02d:%02d\'", pTime->nYear, pTime->nMonth,
					pTime->nDay, pTime->nHour, pTime->nMinute, pTime->nSecond);
			m_pszSql.ReplaceAt(id, 1, tmpBuf);
			break;
		case IES_SQL_STRING:		//字符串
			strncpy(tmpBuf, (char*)m_arPara[i].pAddr, m_arPara[i].nSize);
			tmp += tmpBuf;
			tmp += "\'";
			m_pszSql.ReplaceAt(id, 1, tmp.GetBuf());
			break;
		case IES_SQL_BINARY:		//二进制
			mysql_escape_string(tmpBuf, (char*)m_arPara[i].pAddr, m_arPara[i].nSize);
			tmp += tmpBuf;
			tmp += "\'";
			m_pszSql.ReplaceAt(id, 1, tmp.GetBuf());
			break;
		}
	}
	return true;
}

int CIIMysqlDBI::Exec()
{
	int nRet = 1;
	if (!m_bIsOpenDB)
	{
		nRet = 0;
		goto CLEAR;
	}

	if (!PassPara())
	{
		nRet = 0;
		goto CLEAR;
	}

	if (mysql_query(m_pConnMysql, m_pszSql.GetBuf()) != 0)
	{
		nRet = 0;
		goto CLEAR;
	}
	
	if (m_nSqlType == 1)		//SELECT语句
	{
		m_pResMysql = mysql_store_result(m_pConnMysql);

		if (m_pResMysql == 0)
		{
			nRet = 0;
			goto CLEAR;
		}

		m_nRowCount = (int)mysql_num_rows(m_pResMysql);
		return 1;
	}
	else if (m_nSqlType == 2)	//UPDATE语句
	{
		if (mysql_affected_rows(m_pConnMysql) == 0)
			nRet = -1;
	}

CLEAR:
	m_pszSql = m_pszSqlBak;
	m_arPara.Empty();
	return nRet;
}

bool CIIMysqlDBI::Fetch()
{
	bool bRet;

	if (!m_bIsOpenDB)
		return false;

	m_nRowId++;
	if (m_nRowId > m_nRowCount)
	{
		m_bIsEnd = true;
		return true;
	}

	m_sRowMysql = mysql_fetch_row(m_pResMysql);

	if (m_sRowMysql == NULL)
	{
		m_bIsEnd = true;
		return false;
	}
	m_bIsEnd = false;
	
	bRet = PassCol();
	return bRet;
}

bool CIIMysqlDBI::BeginTrans()
{
    if (mysql_query(m_pConnMysql, "BEGIN WORK"))
		return false;
    return true;
}

bool CIIMysqlDBI::Commit()
{
    if (mysql_query(m_pConnMysql, "COMMIT"))
		return false;
    return true;
}

bool CIIMysqlDBI::Rollback()
{
    if (mysql_query(m_pConnMysql, "ROLLBACK"))
		return false;
    return true;
}

//=======================================================================
// 接口实现
//=======================================================================
extern "C" void* ii_open(const char *i_pszSrv, const char *i_pszIpAddr,
						const char *i_pszDBName, const char *i_pszUser, const char *i_pszPwd)
{
	CIIMysqlDBI *t_pDatabase = new CIIMysqlDBI;

	if (!t_pDatabase->Open(i_pszIpAddr, i_pszDBName, i_pszUser, i_pszPwd))
	{
		delete t_pDatabase;
		return NULL;
	}
	return t_pDatabase;
}

extern "C" void ii_close(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	t_pDatabase->Close();

	if (t_pDatabase != NULL)
		delete t_pDatabase;
}

extern "C" bool ii_execute_sql(const void *i_pDatabase, const char *i_pszSqlStr)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->ExecuteSQL(i_pszSqlStr);
}

extern "C" bool ii_is_table_exist(const void *i_pDatabase, const char *i_szTableName)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->IsTableExist(i_szTableName);
}

extern "C" bool ii_prepare_sql(const void *i_pDatabase, const char *i_pStringSQL)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->PrepareSQL(i_pStringSQL);
}

extern "C" bool ii_bind_col(const void *i_pDatabase, int i_nColType,
								int i_nColSize, void *i_pColAddr)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->BindCol(i_nColType, i_nColSize, i_pColAddr);
}

extern "C" bool ii_bind_para(const void *i_pDatabase, int i_nParaType,
								int i_nParaSize, void *i_pParaAddr)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->BindPara(i_nParaType, i_nParaSize, i_pParaAddr);
}

extern "C" int ii_exec(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->Exec();
}

extern "C" bool ii_fetch(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->Fetch();
}

extern "C" bool ii_is_end(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->IsEnd();
}

extern "C" void ii_close_sql(const void *i_pDatabase, bool i_bCommit)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	t_pDatabase->CloseSQL();
}

extern "C" int ii_get_error_no(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->GetErrorNo();
}

extern "C" const char* ii_get_error_str(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->GetErrorStr();
}

extern "C" bool ii_begin_trans(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->BeginTrans();
}

extern "C" bool ii_commit(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->Commit();
}

extern "C" bool ii_rollback(const void *i_pDatabase)
{
	CIIMysqlDBI *t_pDatabase = (CIIMysqlDBI*)i_pDatabase;
	return t_pDatabase->Rollback();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -