www.pudn.com > pop3.rar > CMailAdapter.cpp


/****************************************************************** 
// CMailAdapter.cpp 
// Function	: 为Push Server和Push POP3 Server提供统一的邮件处理接口。 
//		它从本地查找数据库,将邮件以统一的数据结构形式提供给调用者, 
//		并提供邮件查找功能、编码功能和附件转换功能(通过Attachment 
//		 Converter进行)。 
// Author	: wan ning 
// Date		: 2006/11/24 
// history	: 2006/12/18 将OCCI改为ADO		 
*******************************************************************/ 
 
#include  
#include          // MFC core and standard components 
#include          // MFC extensions 
#include 		// MFC support for Internet Explorer 4 Common Controls 
 
#ifndef _AFX_NO_AFXCMN_SUPPORT 
#include 			// MFC support for Windows Common Controls 
#endif // _AFX_NO_AFXCMN_SUPPORT 
 
#include "CMailAdapter.h" 
#include "FileConvert.h" 
 
#include "ShortMsgBean.h" 
 
 
 
#include "mimeb64.h" 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
CMailAdapter::CMailAdapter() 
{ 
	memset( &m_oldMailDetail, 0, sizeof(m_oldMailDetail) ); 
	b_firstConn = TRUE; 
} 
 
CMailAdapter::~CMailAdapter() 
{ 
	// 释放DB链接 
	m_Conn.ReleaseConn(); 
	 
	if( m_oldMailDetail.lpAttach != NULL ) 
	{ 
		free( m_oldMailDetail.lpAttach ); 
	} 
} 
 
BOOL CMailAdapter::InitDBConnet() 
{ 
	BOOL bRet = TRUE;	 
	// 第一次建立连接时的情况 
	if ( b_firstConn ) 
	{ 
		bRet = m_Conn.CreateConn(); 
		b_firstConn = FALSE; 
	} 
	// 连接已经建立的情况 
	else if ( !m_Conn.CheckConn() ) 
	{ 
		bRet = m_Conn.CreateConn(); 
	} 
	 
	return bRet; 
} 
 
CString CMailAdapter::GetLastError() 
{ 
	return m_strLastError; 
} 
 
//-------------------------------------------------------------- 
//	功能:获取用户ID 
//	参数: 
//	IN CString strUserName 用户名 
//	IN CString strPassword 密码 
//	OUT int &iUserID 用户ID 
//	返回值:用户合法为TRUE 非法为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::GetUserID( 
	CString strUserName,  
	CString strPassword,  
	int &iUserID ) 
{ 
	BOOL bRet = TRUE;	 
	CString str, strSql; 
	 
	// 检测DB连接,如果未连接则建立连接 
	if ( !InitDBConnet() ) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return FALSE; 
	} 
	 
	// 组装SQL语句 
	str = "SELECT USER_ID " 
			"FROM MAIL_USER " 
			"WHERE USER_NAME = '%s' " 
					"AND USER_PASSWORD = '%s' "; 
		 
	strSql.Format( str, strUserName, strPassword ); 
	 
	// 执行SQL 
	CAdoRecordset rs; 
	if( rs.Execute(strSql, m_Conn) ) 
	{ 
		// 当检索到数据时,取出用户ID 
		if ( !rs.Eof() ) 
		{ 
			iUserID = rs.GetInt("USER_ID"); 
		} 
		// 当检索到0条数据时,认为用户不合法 
		else 
		{ 
			m_strLastError = _T( ZERO_RECORD ); 
			bRet=FALSE; 
		} 
	} 
	// DB操作失败的情况 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
		bRet = FALSE; 
	} 
	 
	// 关闭数据集 
	rs.Close(); 
	 
	return bRet; 
 
} 
 
//-------------------------------------------------------------- 
//	功能:获取用户密码 
//	参数: 
//	IN CString strUserName 用户名 
//	OUT CString strPassword 用户密码 
//	返回值:用户合法为TRUE 非法为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::GetPassword( 
	CString strUserName,  
	CString &strPassword ) 
{ 
	BOOL bRet = TRUE; 
	 
	CString str, strSql; 
 
	if ( !InitDBConnet() ) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return FALSE; 
	} 
	 
	// 组装SQL语句 
	str = "SELECT USER_PASSWORD " 
			"FROM MAIL_USER " 
			"WHERE USER_NAME = '%s' " ; 
		 
	strSql.Format( str, strUserName ); 
	 
	CAdoRecordset rs; 
	if( rs.Execute(strSql, m_Conn) ) 
	{ 
		if ( !rs.Eof() ) 
		{ 
			strPassword = rs.GetString("USER_PASSWORD"); 
		} 
		else 
		{ 
			m_strLastError = _T( ZERO_RECORD ); 
			bRet=FALSE; 
		} 
	} 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
		bRet = FALSE; 
	} 
	 
	rs.Close(); 
	 
	return bRet; 
 
} 
 
//-------------------------------------------------------------- 
//	功能:获取邮件ID列表 
//	参数: 
//	IN int iUserID 用户ID 
//	OUT CStringList &slMailID 用户邮件ID列表 
//	返回值:用户合法为TRUE 非法为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::GetMailIDList(int iUserID, CStringList &slMailID) 
{ 
	BOOL bRet = TRUE; 
	 
	CString str, strSql; 
 
	if ( !InitDBConnet() ) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return FALSE; 
	} 
	 
	// 组装SQL语句,获取邮件ID列表(未读,未删除) 修改usermailbox 为 user_mailbox 
	str = "select mail_id " 
			"from mail " 
			"where mailbox_id in " 
				"(select mailbox_id " 
				"from user_mailbox " 
				"where user_id = %d " 
				  ") " 
		//		"and mail_read_tag = %d "//20070327//只对未删除的邮件ID 
				"and mail_delete_tag = %d "	 
				"order by mail_id"; 
		 
	strSql.Format(str, iUserID,/* MAIL_NOT_READED,*/ MAIL_UNDELETE); 
	 
	CAdoRecordset rs; 
	if( rs.Execute(strSql, m_Conn) ) 
	{ 
		CString strTemp; 
		while ( !rs.Eof() ) 
		{ 
			strTemp = rs.GetString("MAIL_ID"); 
			slMailID.AddTail( strTemp ); 
			rs.MoveNext();			 
		} 
/*		 
		// 检索到0条记录时 
		if ( slMailID.IsEmpty() ) 
		{ 
			m_strLastError = _T(ZERO_RECORD); 
			bRtn=FALSE; 
		} 
*/ 
	} 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
		bRet = FALSE; 
	} 
	 
	rs.Close(); 
	 
	return bRet; 
 
} 
 
//-------------------------------------------------------------- 
//	功能:获取邮件列表 
//	参数: 
//	IN CStringList &strlMailIds 邮件ID列表 
//	IN BOOL bContentNeeded 是否需要包含正文 
//	IN BOOL bAttachmentNeeded 是否需要包含附件 
//	OUT CPtrList &plMails 邮件指针列表, 必须在调用此函数前构造链表, 
//		它的长度必须和 strlMailIds 的长度相等 
//	返回值:检索的邮件个数 -1为连接DB失败, 
//-------------------------------------------------------------- 
int CMailAdapter::GetMailList(  
	CStringList &strlMailIds,  
	BOOL bContentNeeded,  
	BOOL bAttachmentNeeded,  
	CPtrList &plMails ) 
{ 
	BOOL bRet; 
	int iMailcount = 0; 
	LPVOID pMail;	 
	 
	// 邮件ID列表不能为空 
	ASSERT( !strlMailIds.IsEmpty() ); 
	ASSERT( strlMailIds.GetCount() == plMails.GetCount() ); 
 
	POSITION posMailID	= strlMailIds.GetHeadPosition(); 
	POSITION posMail	= plMails.GetHeadPosition(); 
	 
	pMail = plMails.GetNext(posMail); 
	 
	// 取出邮件ID列表中的ID号并查询MAIL表 
	// 如果查询成功将查询出的数据挨个写入邮件列表并将邮件个数加1 
	for ( posMailID, posMail; posMailID!=NULL;)  
	{ 
			 
		bRet = GetSingleMail(strlMailIds.GetNext(posMailID),  
									bContentNeeded,  
									bAttachmentNeeded,  
									pMail); 
		if ( bRet )  
		{ 
			iMailcount++; 
			if ( posMail != NULL ) 
			{ 
				pMail = plMails.GetNext(posMail); 
			} 
		} 
	 
	} 
	 
	return iMailcount; 
 
} 
 
/*-------------------------------------------------------------------- 
功  能: 从数据库中检索单个邮件 
参  数: IN CString &strMailID 邮件ID字符串 
		IN BOOL bContentNeeded 是否需要包含正文 
		IN BOOL bAttachmentNeeded 是否需要包含附件 
		OUT LPVOID pMail 邮件指针 
返回值: 检索到数据为TRUE,失败或检索出0条数据为FALSE 
--------------------------------------------------------------------*/ 
BOOL CMailAdapter::GetSingleMail( 
	CString &strMailID, 
	BOOL bContentNeeded, 
	BOOL bAttachmentNeeded, 
	LPVOID pMail ) 
{ 
	BOOL bRtn = TRUE; 
	int	i = 1; 
//	unsigned int ui_clobLength; 
	MailDetail *aMailDetail =(MailDetail *)pMail; 
 
	// 建立DB连接 
	if ( !InitDBConnet() ) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return -1; 
	} 
	 
	CString strSql,str; 
	CString strMailContent = ""; 
	 
	// 需要包含正文 
	if ( bContentNeeded ) 
	{	 
		strMailContent = _T(",MAIL_CONTENT ");	 
	} 
 
	str = _T( "SELECT " 
				"MAIL_ID, " 
				"MAILBOX_ID, " 
				"MAIL_NOTE_ID, " 
				"MAIL_SRC_NOTE_ID, " 
				"MAIL_SUBJECT, " 
				"MAIL_SENDER, " 
				"MAIL_TO, " 
				"MAIL_CC, " 
				"MAIL_BCC, " 
				"MAIL_IMPORTANCE, " 
				"MAIL_SIZE, " 
				"MAIL_ATTACH_TAG, " 
				"MAIL_ATTACH_COUNTER, " 
				"MAIL_SEND_TIME, " 
				"MAIL_READ_TAG, " 
				"MAIL_DELETE_TAG, " 
				"MAIL_TIMESTAMP  " 
				"%s " 
			"FROM MAIL " 
			"WHERE MAIL_ID = %s" ); 
 
	strSql.Format( str, strMailContent, strMailID ); 
/*		 
		Statement *stmt = m_Conn->createStatement(string(strSql)); 
		ResultSet *rs = stmt->executeQuery(); 
*/	 
	CAdoRecordset rs; 
	if( rs.Execute(strSql, m_Conn) ) 
	{ 
		if ( !rs.Eof() ) 
		{	 
			aMailDetail->iMailID = rs.GetInt("MAIL_ID"); 
			aMailDetail->iMailboxID = rs.GetInt("MAILBOX_ID"); 
			aMailDetail->strMailNoteID = rs.GetString("MAIL_NOTE_ID"); 
			aMailDetail->strMailSrcNoteID = rs.GetString("MAIL_SRC_NOTE_ID"); 
			aMailDetail->strMailSubject = rs.GetString("MAIL_SUBJECT"); 
			aMailDetail->strMailSender = rs.GetString("MAIL_SENDER"); 
			aMailDetail->strMailTo = rs.GetString("MAIL_TO"); 
			aMailDetail->strMailCc = rs.GetString("MAIL_CC"); 
			aMailDetail->strMailBcc = rs.GetString("MAIL_BCC"); 
			aMailDetail->iImportance = rs.GetInt("MAIL_IMPORTANCE"); 
			aMailDetail->iMailSize = rs.GetInt("MAIL_SIZE"); 
			 
			// 需要包含正文 
			if ( bContentNeeded ) 
			{ 
				//2007-03-08------------------ 
				aMailDetail->strMailContent=rs.GetClob("MAIL_CONTENT"); 
				//----------------2007-03-08 
 
/*	未完成,缺少获得Clob的函数			 
				// 获得数据库中相应的邮件正文 
				Clob *mailContent = &rs->getClob(i++); 
				LPTSTR contentBuf;  
				 
				if ( !mailContent->isNull() ) 
				{ 
					// CLOB.length() 返回的是字符数,而并非byte数 
					ui_clobLength = mailContent->length() * 2; 
					 
					contentBuf = aMailDetail->strMailContent.GetBuffer(ui_clobLength); 
					ZeroMemory(contentBuf, ui_clobLength); 
					 
					mailContent->read(ui_clobLength,  
									(unsigned char *)contentBuf,  
									ui_clobLength); 
					 
					aMailDetail->strMailContent.ReleaseBuffer(); 
				 
				} 
				// 数据库中的邮件正文为空 
				else 
				{ 
					aMailDetail->strMailContent = ""; 
				} 
*/			 
			}// end if ( bContentNeeded ) 
			// 如果用户不需要邮件正文,则直接赋给结构体相应的项一个空串 
			else 
			{ 
				aMailDetail->strMailContent = strMailContent; 
			} 
			 
			// 当需要包含附件时,从数据库中读出数据 
			if ( bAttachmentNeeded ) 
			{ 
				aMailDetail->bMailAttachTag = rs.GetInt("MAIL_ATTACH_TAG"); //0 FALSE 
			} 
			// 不需要附件时,至附件标记为FALSE 
			else 
			{ 
				aMailDetail->bMailAttachTag = FALSE; 
			} 
			 
			aMailDetail->iMailAttachCounter = rs.GetInt("MAIL_ATTACH_COUNTER"); 
//完成2007-03-08 X未完成,缺少获得日期的函数X 		 
			aMailDetail->ftMailSendTime = rs.GetDate("MAIL_SEND_TIME"); 
			aMailDetail->bMailReadTag = rs.GetInt("MAIL_READ_TAG"); //0 FALSE 
			aMailDetail->bMailDeleteTag = rs.GetInt("MAIL_DELETE_TAG"); //0 FALSE 
			aMailDetail->ftMailRecvTime = rs.GetDate("MAIL_TIMESTAMP"); 
// 
			// 当用户需要附件并且数据库中MAIL_ATTACH_TAG为真时,检索附件表 
			if ( aMailDetail->bMailAttachTag ) 
			{ 
				// 释放原附件链表中的数据 
				freeAttachList(aMailDetail->plAttachment); 
				MailAttachment *p_attach; 
			 
				// 获取附件 
				str = _T("SELECT * FROM ATTACH WHERE MAIL_ID = %s"); 
				strSql.Format( str, strMailID ); 
			 
				if( rs.Execute(strSql, m_Conn) ) 
				{ 
					// 将附件追加到附件链表中 
					while( !rs.Eof() ) 
					{ 
						p_attach = new MailAttachment(); 
						p_attach->iAttachID = rs.GetInt("ATTACH_ID"); 
						p_attach->iMailID = rs.GetInt("MAIL_ID"); 
						p_attach->strAttachSrcNoteID = rs.GetString("ATTACH_SRC_NOTE_ID"); 
						p_attach->iAttachSize = rs.GetInt("ATTACH_SIZE"); 
						p_attach->strAttachFileName = rs.GetString("ATTACH_FILE_NAME"); 
						//ATTACH_PATH_NAME字段中放附件内容ATTACH_PATH_NAME->ATTACH_CONTENT 
						p_attach->strAttachContent = rs.GetClob("ATTACH_CONTENT"); 
						//附件内容转换文件 
						CString strPathName; 
						if( SaveContentToFile(p_attach, strPathName) ) 
						{ 
							p_attach->strAttachPathName = strPathName;							 
						} 
 
//完成2007-03-08 X未完成,缺少获得日期的函数X 			 
						p_attach->ftMailRecvTime = rs.GetDate("ATTACH_TIMESTAMP"); 
//						 
						p_attach->strAttachFileName.TrimLeft(); 
						p_attach->strAttachPathName.TrimLeft(); 
						// 附件名和附件路径名不能为空 
						ASSERT( !p_attach->strAttachFileName.IsEmpty() ); 
						ASSERT( !p_attach->strAttachPathName.IsEmpty() ); 
						//convertMailStruct(aMailDetail); 
						aMailDetail->plAttachment.AddTail( p_attach ); 
						rs.MoveNext(); 
					}// end while 
				} 
				else 
				{ 
					m_strLastError = rs.GetLastError(); 
					bRtn = FALSE; 
				} 
				 
				// 当附件标记为真,而附件表中又无相应数据时 
				ASSERT( !aMailDetail->plAttachment.IsEmpty() ); 
				 
				// 附件个数与实际存入附件链表中的个数不符 
				ASSERT( aMailDetail->iMailAttachCounter  
						== aMailDetail->plAttachment.GetCount() ); 
 
			}// end if ( aMailDetail.bMailAttachTag ) 
			 
		}// end if ( rs->next() == TRUE ) 
		// 当检索到0条邮件时,返回FALSE 
		else 
		{ 
			m_strLastError = _T(ZERO_RECORD); 
			bRtn = FALSE; 
		} 
 
	} // end if( rs.Execute(strSql, m_Conn) ) 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
		bRtn = FALSE; 
	} 
 
	rs.Close(); 
 
	return bRtn; 
} 
//-------------------------------------------------------------- 
//	功能:标记已删除邮件 
//	参数: 
//	IN CStringList &strlMailIds 邮件ID列表 
//	返回值:成功为TRUE 失败为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::SetDeleteMailTags( CStringList &strlMailIds ) 
{ 
	return SetColumeTags( strlMailIds, "MAIL_DELETE_TAG", MAIL_DELETE ); 
} 
 
//-------------------------------------------------------------- 
//	功能:标记已读邮件 
//	参数: 
//	IN CStringList &strlMailIds 邮件ID列表 
//	返回值:成功为TRUE 失败为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::SetReadMailTags( CStringList &strlMailIds ) 
{ 
	return SetColumeTags( strlMailIds, "MAIL_READ_TAG", MAIL_READED ); 
} 
 
//-------------------------------------------------------------- 
//	功能:标记短信发送状态 
//	参数: 
//	IN int iMailID 邮件ID 
//  IN int iNotifyState 发送状态 
//	返回值:成功为TRUE 失败为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::SetNotifyState( int iMailID, int iNotifyState ) 
{ 
	CStringList strlMailIds; 
	BOOL bRet; 
	CString strMailId; 
 
	strMailId.Format("%d",iMailID); 
	strlMailIds.AddTail(strMailId); 
	 
	bRet =  SetColumeTags( strlMailIds, "MAIL_SMS_NOTIFY", iNotifyState ); 
	 
	strlMailIds.RemoveAll(); 
	 
	return bRet; 
} 
 
//-------------------------------------------------------------- 
//	功能:将Mail表中指定记录的某一属性设置为指定值 
//	参数: 
//	IN CStringList &strlMailIds 邮件ID列表 
//  IN CString strColumeName	属性名 
//  IN int iTag					要设置的整型值 
//	返回值:成功为TRUE 失败为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::SetColumeTags( CStringList &strlMailIds, CString strColumeName, int iTag) 
{ 
	CString strMailIDs; 
	int iMailIdCount; 
	BOOL bRet = TRUE; 
	 
	iMailIdCount = strlMailIds.GetCount(); 
	 
	// 有要设置的邮件 
	if ( iMailIdCount != 0) 
	{ 
		CString strSql,str; 
		CAdoRecordset rs; 
		 
		// 初始化DB连接 
		if ( !InitDBConnet() ) 
		{ 
			m_strLastError = m_Conn.GetLastError(); 
			return FALSE; 
		} 
	 
		// 组装SQL语句 
		str = "UPDATE MAIL " 
				"SET %s = %d " 
				"WHERE MAIL_ID = %s  "; 
		 
		// 将邮件已删除标记为1 
		POSITION posMailID	= strlMailIds.GetHeadPosition(); 
		 
		while ( iMailIdCount-- > 0 )  
		{ 
			strMailIDs = strlMailIds.GetNext(posMailID); 
 
			strSql.Format( str, strColumeName, iTag, strMailIDs ); 
				 
			if( !rs.Execute(strSql, m_Conn) ) 
			{ 
				m_strLastError = rs.GetLastError(); 
				bRet = FALSE; 
			} 
		} 
 
		rs.Close(); 
		 
	} 
 
	return bRet; 
} 
 
//-------------------------------------------------------------- 
//	功能:获得所有用户的新邮件列表,得到SMS所需的信息 
//	参数: 
//	IN BOOL bIsFist			标记是否是从程序启动的第一次检索 
//  OUT CPtrList &plMails	邮件列表引用 
//  IN int iTag				要设置的整型值 
//	返回值:成功为TRUE 失败为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::GetSMSMailList(int tryCount, CPtrList &plMails) 
{ 
	BOOL bRet = TRUE; 
	SMBean *pSMBean; 
	CString strSql; 
 
	// 初始化DB连接 
	if ( !InitDBConnet() ) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return FALSE; 
	} 
	 
	strSql = MakeNotiySQL(tryCount); 
 
	CAdoRecordset rs; 
	if( rs.Execute(strSql, m_Conn) ) 
	{ 
		while ( !rs.Eof() ) 
		{ 
			pSMBean =   new SMBean();  
			pSMBean->m_iMailID		= rs.GetInt("mail_id"); 
			pSMBean->m_itryCount    = rs.GetInt("mail_sms_notify"); 
			pSMBean->m_cNotifyType = rs.GetInt("user_notify_type");		 
			pSMBean->m_strMailID	= rs.GetString("mail_note_id");		 
			pSMBean->m_strMailSender = rs.GetString("mail_sender"); 
			pSMBean->m_strMailTo	= rs.GetString("mail_to"); 
			//得到电话号码及区号 
			pSMBean->m_strTelephone = rs.GetString("user_telephone"); 
			pSMBean->m_strAreaNum = rs.GetString("user_areanum"); 
			// 2007-03-12 使用GetDate获得时间 
			pSMBean->m_sendTime		= rs.GetDate("mail_send_time"); 
 
			pSMBean->m_strSubject	= rs.GetString("mail_subject");			 
 
			plMails.AddTail( pSMBean );	 
			rs.MoveNext(); 
		} 
 
	} 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
		bRet = FALSE; 
	} 
	 
	rs.Close(); 
 
	return bRet; 
} 
 
//-------------------------------------------------------------- 
//	功能:为SMS提供检索新邮件的SQL文 
//	参数: 
//	IN BOOL bIsFist		标记是否是从程序启动的第一次检索 
//	返回值:组装完的SQL语句 
//-------------------------------------------------------------- 
CString CMailAdapter::MakeNotiySQL(int tryCount) 
{ 
	/* 
	CString str = _T( 
		"SELECT mail_id, " 
		        "mail_sms_notify, " 
				"user_notify_type, " 
				"mail_note_id, " 
				"mail_sender, " 
				"mail_to, " 
				"mail_send_time, " 
				"user_telephone, " 
				"user_areanum, " 
				"mail_subject "	 
				"FROM MAIL_USER, MAIL, USER_MAILBOX " 
		"WHERE " 
				"MAIL.MAILBOX_ID=USER_MAILBOX.MAILBOX_ID " 
				"AND USER_MAILBOX.USER_ID = MAIL_USER.USER_ID " 
				"AND MAIL.MAIL_READ_TAG = 0 "//AND MAIL_DELETE_TAG = 0  
				//20070327//对未收到短信前已读的邮件不发短信 
				"AND MAIL.MAIL_SMS_NOTIFY >= 0 " 
				"AND MAIL.MAIL_SMS_NOTIFY < %d"); 
*/ 
	CString str = _T( 
		"SELECT rownum, " 
                "b.mail_id, " 
                "b.mail_sms_notify, " 
				"b.mail_note_id, " 
				"b.mail_sender, " 
				"b.mail_to, " 
				"b.mail_send_time, " 
				"b.mail_subject, " 
				"a.user_telephone, " 
				"a.user_areanum, " 
                "a.user_notify_type " 
				"FROM MAIL_USER a, MAIL b, USER_MAILBOX d " 
		"WHERE " 
				"b.MAILBOX_ID=d.MAILBOX_ID " 
				"AND d.USER_ID = a.USER_ID " 
				"AND b.MAIL_READ_TAG = 0 " 
				"AND b.MAIL_SMS_NOTIFY >= 0 "  
				"AND b.MAIL_SMS_NOTIFY < %d " 
                "AND rownum < 100 "); 
 
    CString strSQL; 
	strSQL.Format(str, tryCount); 
	return strSQL; 
} 
 
//-------------------------------------------------------------- 
//	功能:转换邮件附件格式 
//	参数: 
//	IN CMap mapConvertRule 附件转换规则 
//	IN&OUT LPVOID pMail 邮件结构指针 
//	返回值:成功为TRUE,失败为FALSE 
//  备注:如果有附件转换失败,则继续处理其它附件 
//-------------------------------------------------------------- 
BOOL CMailAdapter::ConvertMailAttachment(  
	CMap &mapConvertRule,  
	LPVOID pMail ) 
{ 
	 
//	BOOL	bRet; 
	int		nFirst; 
	CString	strAttachType; 
	int		iSrcType; 
	int		iDestType; 
	int		nElementCount; 
	CStringArray	strArr; 
	CString			strPathName; 
	 
	MailDetail *mailDetail = (MailDetail *)pMail; 
	MailAttachment *attach; 
		 
	POSITION pos = mailDetail->plAttachment.GetHeadPosition(); 
	 
	// 遍历附件列表,转换附件类型,并将转换后的附件添加到附件列表中 
	for ( pos; NULL != pos; )  
	{ 
		attach = (MailAttachment *)mailDetail->plAttachment.GetNext(pos); 
		 
		// 获得的附件类型 
		nFirst = attach->strAttachFileName.ReverseFind('.') + 1; 
		strAttachType = &(((LPCTSTR)attach->strAttachFileName )[nFirst]); 
		 
		// 得到后缀的类型,不考虑后缀的大小写 
		iSrcType = typeToInt( strAttachType ); 
		 
		// 察看是否需要类型转换 
		if ( mapConvertRule.Lookup( iSrcType, iDestType ) ) 
		{ 
			// 初始化 CStringArray 为空 
			strArr.RemoveAll(); 
 
			if ( ConvertAttachment( iSrcType, iDestType,  
				attach->strAttachPathName, strArr, m_strLastError ) ) 
			// 转换成功时将转换后的文件名和文件路径名存入附件链表 
			{ 
				nElementCount = strArr.GetSize(); 
				// 转换后生成一个文件的情况 
				strPathName = strArr.ElementAt(--nElementCount); 
				nFirst = strPathName.ReverseFind('\\') + 1; 
				attach->strAttachFileName = &(((LPCTSTR)strPathName )[nFirst]); 
				attach->strAttachPathName = strPathName; 
				 
				// 转换后生成多个文件的情况 
				// 从后往前挨个取出转换后的文件路径名放入申请的附件结构体, 
				// 并将结构体追加到附件链表头部 
				MailAttachment *p_attch; 
				while ( --nElementCount >= 0 ) 
				{ 
					strPathName = strArr.ElementAt(nElementCount); 
					 
					// 内存释放在 MailAttachment 的析构函数中完成 
					p_attch = new MailAttachment(); 
					 
					nFirst = strPathName.ReverseFind('\\') + 1; 
					p_attch->strAttachFileName = &(((LPCTSTR)strPathName )[nFirst]); 
					p_attch->strAttachPathName = strPathName; 
					 
					mailDetail->plAttachment.AddHead(p_attch); 
				}// end while 
			 
			}// end if 
			else 
			// 转换失败时继续后继附件转换 
			{ 
				//return FALSE; 
				continue; 
			} 
		}// end if 
	 
	}// end for 
 
	return TRUE; 
} 
 
//-------------------------------------------------------------- 
//	功能:转换邮件为MIME编码字符串 
//	参数: 
//	IN  LPVOID pMail 邮件结构指针 
//	OUT CString &strMail 邮件字符串指针 
//	返回值:成功为TRUE,失败为FALSE 
//-------------------------------------------------------------- 
BOOL CMailAdapter::GetMailString(  
	LPVOID pMail,  
	CString &strMail ) 
{ 
#define RRROR_MSG_LENGTH	255 
	 
	BOOL bRet = FALSE; 
	char errorMsg[RRROR_MSG_LENGTH]; 
 
	// 将 MailDetail 结构体转换为 NoteDetail 结构体 
	// 用于作为 getMailString 函数的实参 
	if ( !convertMailStruct( pMail ) ) 
	{ 
		return bRet; 
	} 
	 
	// 计算用于存放MIME编码后的邮件的长度, 
	// 用于初始化缓存 
	try  
	{	 
	 
		long imimeStrLen = getMimeStrLen( &m_oldMailDetail, errorMsg ); 
 
		 
		if ( -1L == imimeStrLen ) 
		{ 
			m_strLastError = errorMsg; 
			return bRet; 
		} 
		 
		// 获得 CString 的缓存 
		char *pstrMail = strMail.GetBuffer( (int)imimeStrLen ); 
		 
		// 将邮件结构体中的信息 MIME 编码到 CString 的缓存 
		bRet = getMailString( &m_oldMailDetail, pstrMail, errorMsg); 
		 
		// 释放 CString 的缓存 
		strMail.ReleaseBuffer(); 
	} 
	// 当 GetBuffer 失败时抛出 CMemoryException 异常 
	catch ( CMemoryException &e) 
	{ 
		e.GetErrorMessage(errorMsg, RRROR_MSG_LENGTH); 
		bRet = FALSE; 
	} 
	 
	m_strLastError = errorMsg; 
	 
	return bRet; 
 
}// BOOL CMailAdapter::GetMailString() 
 
//-------------------------------------------------------------- 
//	功能:将邮件结构体转换成标准C的新式 
//	参数: 
//	IN LPVOID pMail邮件结构指针 
//	返回值:TRUE 成功,FALSE 失败 
//-------------------------------------------------------------- 
BOOL CMailAdapter::convertMailStruct( LPVOID pMail ) 
{ 
	MailDetail *newMailDetail = (MailDetail *)pMail; 
	 
	// subject 
	m_oldMailDetail.pcSubject = (LPSTR)(LPCTSTR) 
		( newMailDetail->strMailSubject );	 
	// sender 
	m_oldMailDetail.pcDisplaySender = (LPSTR)(LPCTSTR) 
		( newMailDetail->strMailSender ); 
	// To 
	m_oldMailDetail.pcDisplayTo = (LPSTR)(LPCTSTR) 
		( newMailDetail->strMailTo ); 
	// Cc 
	m_oldMailDetail.pcDisplayCc = (LPSTR)(LPCTSTR) 
		( newMailDetail->strMailCc ); 
	// Bcc 
	m_oldMailDetail.pcDisplayBcc = (LPSTR)(LPCTSTR) 
		( newMailDetail->strMailBcc ); 
 
	// Importance 
	m_oldMailDetail.lImportance = (long) 
		( newMailDetail->iImportance ); 
	 
	// Text body size 
	m_oldMailDetail.lSize = (long) 
		( newMailDetail->iMailSize ); 
	// Text body 
	m_oldMailDetail.pcBodyContent = (LPSTR)(LPCTSTR) 
		( newMailDetail->strMailContent ); 
 
	// Attachment tag 
	m_oldMailDetail.bHasAttach = newMailDetail->bMailAttachTag; 
	// Count of attachment 
	m_oldMailDetail.iAttachCount = newMailDetail->plAttachment.GetCount(); 
	 
	 
	// attachment 
	// 将CPtrList转成 MAIL_ATCH 类型的数组 
	if ( m_oldMailDetail.bHasAttach ) 
	{ 
		// 分配足够的空间,如果失败程序返回false 
		// 在析构函数中释放内存空间  
		m_oldMailDetail.lpAttach = (LPMAIL_ATCH) 
			malloc(	sizeof(MAIL_ATCH) * m_oldMailDetail.iAttachCount ); 
		 
		if ( NULL == m_oldMailDetail.lpAttach ) 
		{ 
			m_strLastError.Format( "malloc failed! %s %d", __FILE__, __LINE__); 
			return FALSE; 
		} 
 
		// 遍历 CPtrList 链表,并将附件名和存放路径存入 MAIL_ATCH 相应的成员中 
		MailAttachment *newAttach; 
		LPMAIL_ATCH		oldAttach = m_oldMailDetail.lpAttach; 
		int i = 0; 
 
		POSITION pos = newMailDetail->plAttachment.GetHeadPosition(); 
		for ( pos; NULL != pos; )  
		{ 
			newAttach = (MailAttachment *)newMailDetail->plAttachment.GetNext(pos); 
			 
			oldAttach[i].lpszName = (LPSTR)(LPCTSTR) 
				( newAttach->strAttachFileName ); 
 
			oldAttach[i].lpszPathName = (LPSTR)(LPCTSTR) 
				( newAttach->strAttachPathName ); 
 
			/*CString strPathName; 
			if( SaveContentToFile(newAttach, strPathName) ) 
			{ 
				newAttach->strAttachPathName = strPathName; 
				oldAttach[i].lpszPathName = (LPSTR)(LPCTSTR)(newAttach->strAttachPathName); 
			 
			} 
			else 
			{ 
 
			}*/ 
 
			i++; 
		} 
 
	} 
	 
	return TRUE; 
 
}// BOOL CMailAdapter::convertMailStruct() 
 
int CMailAdapter::typeToInt(CString &Type) 
{ 
	if ( 0 == Type.CompareNoCase("doc") )	return FILE_TYPE_DOC; 
	else if (0 == Type.CompareNoCase("xls") )	return FILE_TYPE_XLS; 
	else if (0 == Type.CompareNoCase("ppt") )	return FILE_TYPE_PPT; 
	else if (0 == Type.CompareNoCase("htm") )	return FILE_TYPE_HTM; 
	else if (0 == Type.CompareNoCase("txt") )	return FILE_TYPE_TXT; 
	else if (0 == Type.CompareNoCase("xml") )	return FILE_TYPE_XML; 
	else if (0 == Type.CompareNoCase("mht") )	return FILE_TYPE_MHT; 
	else if (0 == Type.CompareNoCase("rtf") )	return FILE_TYPE_RTF; 
	else if (0 == Type.CompareNoCase("prn") )	return FILE_TYPE_PRN; 
	else if (0 == Type.CompareNoCase("gif") )	return FILE_TYPE_GIF; 
	else if (0 == Type.CompareNoCase("jpg") )	return FILE_TYPE_JPG; 
	else if (0 == Type.CompareNoCase("png") )	return FILE_TYPE_PNG; 
	else if (0 == Type.CompareNoCase("bmp") )	return FILE_TYPE_BMP; 
	else if (0 == Type.CompareNoCase("tif") )	return FILE_TYPE_TIF; 
	else if (0 == Type.CompareNoCase("emf") )	return FILE_TYPE_EMF; 
	else  
		return -1; 
} 
 
//-------------------------------------------------------------- 
//	功能:为邮件列表申请空间 
//	参数: 
//	IN&OUT CPtrList &plMails 邮件链表引用 
//	IN int imailCount 邮件个数 
//	返回值:TRUE 成功,FALSE 失败 
//-------------------------------------------------------------- 
BOOL CMailAdapter::NewMailList(CPtrList &plMails, int imailCount) 
{ 
	MailDetail * pmail; 
	 
	for( int i=0; i 0 )  
	{ 
		MailAttachment * p_attach; 
		POSITION pos = plAttachment.GetHeadPosition(); 
			for ( pos; NULL != pos; )  
			{ 
				p_attach = (MailAttachment *)plAttachment.GetNext(pos); 
				delete p_attach; 
			} 
		plAttachment.RemoveAll(); 
	} 
} 
/*--------------------------------------------------------------------- 
功  能: 插入数据到MAIL_TRANS_LOG表 
参  数: IN mailtranslog 
返回值: TRUE 成功 FALSE 失败 
Author: fengxin 
Date  : 2007/02/26 
---------------------------------------------------------------------*/ 
BOOL CMailAdapter::InsertMailTransLog(tagMAIL_TRANS_LOG mailtranslog) 
{ 
	BOOL bRet = TRUE; 
	CString str,strSql; 
	CTime tm; 
	CString strtime; 
 
	//得到当前时间 
	tm = CTime::GetCurrentTime(); 
	strtime=tm.Format("%Y-%m-%d %X"); 
 
	if(mailtranslog.log_createtime.GetLength()==0) 
	{ 
		mailtranslog.log_createtime = strtime; 
	} 
	if(mailtranslog.log_timestamp.GetLength()==0) 
	{ 
		mailtranslog.log_timestamp = strtime; 
	} 
	 
	//检查数据库连接,如果未连接则建立连接 
	if(!InitDBConnet()) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return FALSE; 
	} 
	 
	//组装SQL语句 
	str="INSERT INTO MAIL_TRANS_LOG(LOG_ID," 
		"MAIL_ID," 
		"LOG_OPRATE," 
		"LOG_MAIL_SIZE," 
		"LOG_TIME_CON," 
		"LOG_RESULT," 
		"LOG_SHOW," 
		"LOG_DICTATE," 
		"LOG_CREATETIME," 
		"LOG_TIMESTAMP) " 
		"VALUES(SEQ_MAIL_TRANS_LOG_ID.nextval," 
		"'%d'," 
		"'%s'," 
		"'%d'," 
		"'%d'," 
		"'%d'," 
		"'%s'," 
		"'%s'," 
		"to_date('%s','YYYY-MM-DD HH24:MI:SS')," 
		"to_date('%s','YYYY-MM-DD HH24:MI:SS'))" ; 
	 
	strSql.Format(str, 
		mailtranslog.mail_id, 
		mailtranslog.log_oprate, 
		mailtranslog.log_mail_size, 
		mailtranslog.log_time_con, 
		mailtranslog.log_result, 
		mailtranslog.log_show, 
		mailtranslog.log_dictate, 
		mailtranslog.log_createtime, 
		mailtranslog.log_timestamp); 
	 
	//执行SQL 
	CAdoRecordset rs; 
	if(rs.Execute(strSql,m_Conn)) 
	{ 
		//执行成功时,返回TRUE 
		mailtranslog.mail_id=0; 
		mailtranslog.log_oprate.Empty(); 
		mailtranslog.log_mail_size=0; 
		mailtranslog.log_time_con=0; 
		mailtranslog.log_result=0; 
		mailtranslog.log_show.Empty(); 
		mailtranslog.log_dictate.Empty(); 
		mailtranslog.log_createtime.Empty(); 
		mailtranslog.log_timestamp.Empty(); 
		bRet=TRUE; 
	} 
	//DB操作失败 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
		bRet = FALSE; 
	} 
 
	rs.Close(); 
 
	return bRet; 
} 
 
/*--------------------------------------------------------------------- 
功  能: 插入数据到PUSH_LOG表 
参  数: IN pushlog 
返回值: TRUE 成功 FALSE 失败 
Author: fengxin 
Date  : 2007/02/26 
---------------------------------------------------------------------*/ 
BOOL CMailAdapter::InsertPushLog(tagPUSH_LOG pushlog) 
{ 
	BOOL bRet=TRUE; 
	CString str,strSql; 
	CTime tm; 
	CString strtime; 
	 
	//得到当前时间 
	tm=CTime::GetCurrentTime(); 
	strtime=tm.Format("%Y-%m-%d %X"); 
	 
	if(pushlog.log_createtime.GetLength()==0) 
	{ 
		pushlog.log_createtime = strtime; 
	} 
	if(pushlog.log_timestamp.GetLength()==0) 
	{ 
		pushlog.log_timestamp = strtime; 
	} 
	 
	//检查数据库连接,如果未连接则建立连接 
	if(!InitDBConnet()) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return FALSE; 
	} 
	 
	//组装SQL语句 
	str="INSERT INTO PUSH_LOG(LOG_ID," 
		"MAIL_ID," 
		"LOG_OPRATE," 
		"LOG_MAIL_SIZE," 
		"LOG_TIME_CON," 
		"LOG_RESULT," 
		"LOG_SHOW," 
		"LOG_DICTATE," 
		"LOG_CREATETIME," 
		"LOG_TIMESTAMP) " 
		"VALUES(SEQ_PUSH_LOG_ID.nextval," 
		"%d," 
		"'%s'," 
		"%d," 
		"%d," 
		"%d," 
		"'%s'," 
		"'%s'," 
		"to_date('%s','YYYY-MM-DD HH24:MI:SS')," 
		"to_date('%s','YYYY-MM-DD HH24:MI:SS'))" ; 
	 
	strSql.Format(str, 
		pushlog.mail_id, 
		pushlog.log_oprate, 
		pushlog.log_mail_size, 
		pushlog.log_time_con, 
		pushlog.log_result, 
		pushlog.log_show, 
		pushlog.log_dictate, 
		pushlog.log_createtime, 
		pushlog.log_timestamp); 
	 
	//执行SQL 
	CAdoRecordset rs; 
	if(rs.Execute(strSql,m_Conn)) 
	{ 
		//执行成功时,返回TRUE 
		pushlog.mail_id=0; 
		pushlog.log_oprate.Empty(); 
		pushlog.log_mail_size=0; 
		pushlog.log_time_con=0; 
		pushlog.log_result=0; 
		pushlog.log_show.Empty(); 
		pushlog.log_dictate.Empty(); 
		pushlog.log_createtime.Empty(); 
		pushlog.log_timestamp.Empty(); 
		bRet=TRUE; 
	} 
	//DB操作失败 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
		bRet = FALSE; 
	} 
	 
	rs.Close(); 
	 
	return bRet; 
} 
 
/*--------------------------------------------------------------------- 
功  能: 插入数据到SERVER_LOG表 
参  数: IN serverlog 
返回值: TRUE 成功 FALSE 失败 
Author: luming 
Date  : 2007/03/22 
---------------------------------------------------------------------*/ 
BOOL CMailAdapter::InsertServerLog(tagSERVER_LOG serverlog) 
{ 
	BOOL bRet=TRUE; 
	CString str,strSql; 
	CTime tm; 
	CString strtime; 
	 
	//得到当前时间 
	tm=CTime::GetCurrentTime(); 
	strtime=tm.Format("%Y-%m-%d %X"); 
	 
	if(serverlog.log_createtime.GetLength()==0) 
	{ 
		serverlog.log_createtime = strtime; 
	} 
	if(serverlog.log_timestamp.GetLength()==0) 
	{ 
		serverlog.log_timestamp = strtime; 
	} 
	 
	//检查数据库连接,如果未连接则建立连接 
	if(!InitDBConnet()) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return FALSE; 
	} 
	 
	//组装SQL语句 
	str="INSERT INTO SERVER_LOG(LOG_ID," 
		"SERVER_NAME," 
		"SERVER_TYPE," 
		"SERVER_STATE," 
		"LOG_SHOW," 
		"LOG_CREATETIME," 
		"LOG_TIMESTAMP) " 
		"VALUES(SEQ_SERVER_LOG_ID.nextval," 
		"'%s'," 
		"'%s'," 
		"%d," 
		"'%s'," 
		"to_date('%s','YYYY-MM-DD HH24:MI:SS')," 
		"to_date('%s','YYYY-MM-DD HH24:MI:SS'))" ; 
	 
	strSql.Format(str, 
		serverlog.log_servername, 
		serverlog.log_servertype, 
		serverlog.log_serverstate, 
		serverlog.log_show, 
		serverlog.log_createtime, 
		serverlog.log_timestamp); 
	 
	//执行SQL 
	CAdoRecordset rs; 
	if(rs.Execute(strSql,m_Conn)) 
	{ 
		//执行成功时,返回TRUE 
		serverlog.log_servername.Empty(); 
		serverlog.log_servertype.Empty(); 
		serverlog.log_serverstate = 0; 
		serverlog.log_show.Empty(); 
		serverlog.log_createtime.Empty(); 
		serverlog.log_timestamp.Empty(); 
		bRet=TRUE; 
	} 
	//DB操作失败 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
		bRet = FALSE; 
	} 
	 
	rs.Close(); 
	 
	return bRet; 
} 
 
BOOL CMailAdapter::SaveContentToFile(MailAttachment *newAttach, 
									 CString &strPathName) 
{ 
	static int i = 0;//静态变量区别同一封邮件收多次的情况 
	TCHAR szTempPath[_MAX_PATH]; 
	TCHAR szTempPath1[_MAX_PATH]; 
	TCHAR szChr[_MAX_PATH]; 
    GetTempPath(_MAX_PATH, szTempPath);//得到系统临时文件夹的路径 
	GetTempPath(_MAX_PATH, szTempPath1);//得到系统临时文件夹的路径 
	//创建以附件ID命名的文件夹 
	sprintf(szChr,"%d_%d",newAttach->iAttachID,i++); 
//	strcat(szTempPath1,"\"); 
	strcat(szTempPath1,szChr); 
 
    DWORD   dwAttr; 
    dwAttr=GetFileAttributes(szTempPath1); 
    if(dwAttr==0xFFFFFFFF) //文件夹不存在 
	{ 
		if(CreateDirectory(szTempPath1,NULL)) 
		{ 
			strPathName.Format("%s\\%s", 
						szTempPath1, 
						newAttach->strAttachFileName); 
		} 
		else//创建文件夹失败时文件放在当前临时文件夹下 
		{ 
			strPathName.Format("%s\\%s", 
				szTempPath, 
				newAttach->strAttachFileName);	 
		} 
	}	 
	else 
	{ 
		strPathName.Format("%s\\%s", 
					szTempPath1, 
					newAttach->strAttachFileName); 
	} 
	int ispaceSize = newAttach->strAttachContent.GetLength(); 
	char *ch = (char*)malloc(ispaceSize + 1); 
	int iFileLength = Base64Decode((unsigned char *const)ch, newAttach->strAttachContent); 
	 
	CFile file;//  
	if( file.Open(strPathName, CFile::modeCreate | CFile::modeWrite) ) 
	{ 
		file.Write(ch, iFileLength); 
	} 
	else 
	{ 
		return FALSE; 
	} 
 
	file.Close(); 
 
	delete []ch; 
 
	return TRUE; 
} 
 
/*--------------------------------------------------------------------- 
功  能: 取数据从PROG_PARAM表 
参  数: IN int ParamID 
返回值: 成功: 当前值  失败: -1  
Author: fengxin 
Date  : 2007/02/26 
---------------------------------------------------------------------*/ 
 
int CMailAdapter::GetIntervalTime(int ParamID) 
{ 
	CString str,strSql; 
	int iRet = -1; 
	//检查数据库连接,如果未连接则建立连接 
	if(!InitDBConnet()) 
	{ 
		m_strLastError = m_Conn.GetLastError(); 
		return iRet; 
	} 
	//组装SQL语句 
	str = " SELECT PARAM_VALUE FROM PROG_PARAM WHERE PARAM_ID=%d"; 
	 
	strSql.Format(str,ParamID); 
 
	//执行SQL 
	CAdoRecordset rs; 
	if(rs.Execute(strSql,m_Conn)) 
	{ 
		iRet = rs.GetInt("PARAM_VALUE"); 
	} 
	else 
	{ 
		m_strLastError = rs.GetLastError(); 
	} 
 
	rs.Close(); 
	 
	return iRet; 
}