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

📄 datalink.cpp

📁 数据访问的定义类
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include "stdafx.h"
#include "DataLink.h"
#include <atlbase.h>

// ado supproted
#pragma warning(disable:4146)
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace \
	rename("EOF","IsEOF")
#pragma warning(default:4146)


#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#ifndef _WIN64
#define DWORD_PTR DWORD
#endif

/////////////////////////////////////////////////////////////////////////////
// datalink state

void _SetErrorInfo(ErrorsPtr pErrors)
{
	if (pErrors->Count <= 0)
		return;

	CComPtr<ICreateErrorInfo> spErrorInfo;
	if (FAILED(CreateErrorInfo(&spErrorInfo)))
		return;

	ErrorPtr pError = pErrors->Item[COleVariant(0L)];
	spErrorInfo->SetDescription(pError->Description);
	spErrorInfo->SetSource(pError->Source);
	spErrorInfo->SetHelpContext(pError->HelpContext);
	spErrorInfo->SetHelpFile(pError->HelpFile);

	_AFX_DATALINK_STATE* pState = _afxDataLinkState.GetData();
	if (pState->m_pErrorInfo != NULL)
		pState->m_pErrorInfo->Release();
	spErrorInfo->QueryInterface(__uuidof(IErrorInfo), (void**)&pState->m_pErrorInfo);
	::SetErrorInfo(0, pState->m_pErrorInfo);
}

BOOL AFXAPI AfxGetErrorMessage(CString& rString)
{
	DWORD dwError = ::GetLastError();
	if (dwError != 0)
	{
		return TRUE;
	}

	CComPtr<IErrorInfo> pErrorInfo;
	::GetErrorInfo(0, &pErrorInfo);
	if (pErrorInfo == NULL)
	{
		// 使用 Common 错误信息
		_AFX_DATALINK_STATE* pState = _afxDataLinkState.GetData();
		pErrorInfo = pState->m_pErrorInfo;
	}

	if (pErrorInfo != NULL)
	{
		CComBSTR description;
		pErrorInfo->GetDescription(&description);

		//rString.SetString(CString(description));
		memcpy(rString.GetBufferSetLength(description.Length()), CString(description), description.Length() * sizeof(TCHAR));
		rString.ReleaseBuffer();
		return TRUE;
	}

	return FALSE;
}

void AFXAPI AfxSetErrorMessage(LPCTSTR lpString)
{
	CComPtr<ICreateErrorInfo> spErrorInfo;
	if (FAILED(CreateErrorInfo(&spErrorInfo)))
		return;

	CComBSTR description(lpString);
	spErrorInfo->SetDescription(description);
	spErrorInfo->SetSource(description);
	spErrorInfo->SetHelpContext(0L);
	spErrorInfo->SetHelpFile(NULL);

	_AFX_DATALINK_STATE* pState = _afxDataLinkState.GetData();
	if (pState->m_pErrorInfo != NULL)
		pState->m_pErrorInfo->Release();
	spErrorInfo->QueryInterface(__uuidof(IErrorInfo), (void**)&pState->m_pErrorInfo);
	::SetErrorInfo(0, pState->m_pErrorInfo);
}


/////////////////////////////////////////////////////////////////////////////
// datalink state

_AFX_DATALINK_STATE::_AFX_DATALINK_STATE()
{
	m_pszConnectionString = NULL;
	m_pErrorInfo = NULL;
}

_AFX_DATALINK_STATE::~_AFX_DATALINK_STATE()
{
	free((void*)m_pszConnectionString);
	if (m_pErrorInfo != NULL)
		m_pErrorInfo->Release();
}

PROCESS_LOCAL(_AFX_DATALINK_STATE, _afxDataLinkState)

/////////////////////////////////////////////////////////////////////////////
// datalink globals and implementation helpers

void AFXAPI AfxDataLinkTerm()
{
}

void AFXAPI AfxSetDataLink(LPCTSTR lpszConnectionString)
{
	ASSERT(lpszConnectionString != NULL);

	_AFX_DATALINK_STATE* pState = _afxDataLinkState.GetData();
	BOOL bEnable = AfxEnableMemoryTracking(FALSE);
	free((void*)pState->m_pszConnectionString);
	pState->m_pszConnectionString = _tcsdup(lpszConnectionString);
	AfxEnableMemoryTracking(bEnable);
}

void AFXAPI AfxGetDataLink(CString& strConnectionString)
{
	_AFX_DATALINK_STATE* pState = _afxDataLinkState.GetData();
	//strConnectionString.SetString(pState->m_pszConnectionString);
	int nLen = lstrlen(pState->m_pszConnectionString);
	memcpy(strConnectionString.GetBufferSetLength(nLen), pState->m_pszConnectionString, nLen * sizeof(TCHAR));
	strConnectionString.ReleaseBuffer();
}

//////////////////////////////////////////////////////////////////////////////
// Helpers

void AFXAPI _AfxSetCurrentRecord(long* plCurrentRecord, long nRows, RETCODE nRetCode)
{
	if (*plCurrentRecord != AFX_CURRENT_RECORD_UNDEFINED &&
		nRetCode != SQL_NO_DATA_FOUND)
		*plCurrentRecord += nRows;
}

void AFXAPI _AfxSetRecordCount(long* plRecordCount, long lCurrentRecord,
	BOOL bEOFSeen, RETCODE nRetCode)
{
	// If not at the end and haven't yet been to the end, incr count
	if (nRetCode != SQL_NO_DATA_FOUND && !bEOFSeen &&
		lCurrentRecord != AFX_CURRENT_RECORD_UNDEFINED)
	{
		// lCurrentRecord 0-based and it's already been set
		*plRecordCount =
			__max(*plRecordCount, lCurrentRecord + 1);
	}
}


/////////////////////////////////////////////////////////////////////////////
// tchar globals helpers

// 去除前置空格
LPCTSTR _tltrim(LPCTSTR string)
{
	while (_istspace(*string))
		string++;
	return string;
}

// 去除右置空格
void _trtrim(LPTSTR string)
{
	string += lstrlen(string);
	while (_istspace(*(--string)))
		*string = '\0';
}

// 返回指向第一个出现分割符的字符串,忽略成对出现的分隔符
LPCTSTR _tcschr2(LPCTSTR string, LPTSTR item, TCHAR chSep)
{
	LPCTSTR lpchEnd = _tcschr(string, chSep);
	if (item != NULL) *item = '\0';
	while (lpchEnd != NULL && *(lpchEnd+1) == chSep)
	{
		// 如果分割符成对出现,忽略第二个分割符
		if (item != NULL)
			_tcsncat(item, string, (int)(lpchEnd - string) + 1);
		string = lpchEnd + 2;
		lpchEnd = _tcschr(string, chSep);
	}

	if (item != NULL)
		_tcsncat(item, string, (lpchEnd == NULL) ? lstrlen(string) : (int)(lpchEnd - string));
	return lpchEnd;
}

LPCTSTR _tsplitattr(LPCTSTR string, LPTSTR keyName, LPTSTR value, TCHAR chSep = _T(';'))
{
	TCHAR chOldSep = chSep;
	chSep = _T('=');
	string = _tcschr2(_tltrim(string), keyName, chSep);
	if (keyName != NULL) _trtrim(keyName);
	if (string == NULL)
		return NULL;

	string = _tltrim(++string);
	chSep = _tcschr(_T("\'\""), *string) ? *(string++) : chOldSep;
	string = _tcschr2(string, value, chSep);
	if (string != NULL && chSep != chOldSep)
		string = _tcschr2(++string, NULL, chOldSep);

	if (value != NULL) _trtrim(value);
	return (string == NULL) ? NULL : ++string;
}

// 拷贝字符串,如果字符串包含分隔符,分隔符成对出现
LPTSTR _tcscpy2(LPTSTR string, LPCTSTR source, TCHAR chSep)
{
	*string = '\0';
	if (source == NULL)
		return string;

	LPCTSTR lpchEnd = _tcschr(source, chSep);
	while (lpchEnd != NULL && *lpchEnd == chSep)
	{
		// 如果字符串包含分隔符,分隔符成对出现
		_tcsncat(string, source, (int)(lpchEnd - source) + 1);
		_tcsncat(string, lpchEnd, 1);
		source = lpchEnd + 1;
		lpchEnd = _tcschr(source, chSep);
	}
	int nLen = (lpchEnd == NULL) ? lstrlen(source) : (int)(lpchEnd - source);
	return _tcsncat(string, source, nLen);
}

// 返回指向下一个字符串的指针,跳过由分隔符 ''()[]限定的字符串
const TCHAR* _strinc2(const TCHAR* string)
{
	ASSERT(string != NULL);
	DWORD dwReserve = 0;	// 保留右分隔符的列表,最多4个嵌套
	for (BOOL bSeek = FALSE; *string != 0; string++, bSeek = TRUE)
	{
		if (*string == LOBYTE(dwReserve))
			dwReserve = dwReserve >> 8;
		else if (*string == _T('\''))
			dwReserve = (DWORD_PTR)(_T('\'')) & 0xff | dwReserve << 8;
		else if (*string == _T('('))
			dwReserve = (DWORD_PTR)(_T(')')) & 0xff | dwReserve << 8;
		else if (*string == _T('['))
			dwReserve = (DWORD_PTR)(_T(']')) & 0xff | dwReserve << 8;
		else if (dwReserve == 0 && bSeek)
			break;
	}
	return string;
}

// 返回指向第一个出现分割符的字符串的索引,跳过由分隔符 ''()[]限定的字符串
const TCHAR* _tcschr2(const TCHAR* string, const TCHAR chSep)
{
	while (*string != 0)
	{
		if (chSep == *string)
			return string;
		string = _strinc2(string);
	}

	return NULL;
}

// 返回指向第一个出现分割符的字符串的索引,跳过由分隔符 ''()[]限定的字符串
size_t _tcscspn2(const TCHAR* string, const TCHAR* strCharSet)
{
	LPCTSTR lpchEnd = string;
	while (*lpchEnd != 0)
	{
		if (_tcschr(strCharSet, *lpchEnd) != NULL)
			break;
		lpchEnd = _strinc2(lpchEnd);
	}

	return size_t(lpchEnd - string);
}

int _istspace2(TCHAR c)
{
	return (_istspace(c) || c == _T('\n') || c == _T('\t')) ? 1 : 0;
}

int _tcsnicmp2(const TCHAR *string1, const TCHAR *string2, size_t count)
{
	size_t count2 = lstrlen(string2);
	if (count2 != count)
		return (int)(count - count2);
	return _tcsnicmp(string1, string2, count);
}

// 返回指向第一个出现关键字的字符串之后的索引,跳过由分隔符 ''()[]限定的字符串
// 如果没有找到关键字,返回字符串的长度
size_t _tcskey1(const TCHAR* string, const TCHAR* strSearch)
{
	ASSERT(strSearch != NULL);
	int nLen;
	BOOL bResult;
	LPCTSTR lpchEnd = string;
	while (*lpchEnd != 0)
	{
		nLen = (int)_tcscspn2(lpchEnd, _T(" \t\n"));
		bResult = (_tcsnicmp2(lpchEnd, strSearch, nLen) == 0);

		lpchEnd += nLen;
		if (*lpchEnd != 0)
			lpchEnd++;	// point past the space
		if (bResult)
			break;
	}

	return (lpchEnd - string);
}

// 返回指向第一个出现关键字的字符串之前的索引,跳过由分隔符 ''()[]限定的字符串
// 如果没有找到关键字,返回字符串的长度
size_t _tcskey2(const TCHAR* string, const TCHAR* strSearch)
{
	ASSERT(strSearch != NULL);
	int nLen;
	LPCTSTR lpchEnd = string;
	while (*lpchEnd != 0)
	{
		nLen = (int)_tcscspn2(lpchEnd, _T(" \t\n"));
		if (_tcsnicmp2(lpchEnd, strSearch, nLen) == 0)
			break;

		lpchEnd += nLen;
		if (*lpchEnd != 0)
			lpchEnd++;	// point past the space
	}

	if (*lpchEnd != 0 && (lpchEnd - string) > 0)
		lpchEnd--;	// point to the space

	return (lpchEnd - string);
}

// 返回指向第一个出现"join"的字符串之前的索引,跳过由分隔符 ''()[]限定的字符串
// 如果没有找到关键字,返回字符串的长度
size_t _tcskey3(const TCHAR* string, const TCHAR* strSearch)
{
	int nLen;
	LPCTSTR lpchEnd = string;
	while (*lpchEnd != 0)
	{
		nLen = (int)_tcscspn2(lpchEnd, _T(" \t\n"));
		if (_tcsnicmp2(lpchEnd, _T("inner"), nLen) == 0 ||
			_tcsnicmp2(lpchEnd, _T("left"), nLen) == 0 ||
			_tcsnicmp2(lpchEnd, _T("right"), nLen) == 0 ||
			_tcsnicmp2(lpchEnd, _T("full"), nLen) == 0 ||
			_tcsnicmp2(lpchEnd, strSearch, nLen) == 0)
			break;

		lpchEnd += nLen;
		if (*lpchEnd != 0)
			lpchEnd++;	// point past the space
	}

	if (*lpchEnd != 0 && (lpchEnd - string) > 0)
		lpchEnd--;	// point to the space

	return (lpchEnd - string);
}


/////////////////////////////////////////////////////////////////////////////
// sql string globals helpers

// 将SQL语句格式化为标准格式
// 列别名使用AS;表别名使用空格
void SqlString_Normalize(CString& rString)
{
	int nNewLength = rString.GetLength();
	LPCTSTR pszBuffer = rString.GetBuffer(nNewLength);
	while (*pszBuffer != 0)
	{
		// 如果当前是空格,下一个字符是分隔符,删除当前字符
		if (_istspace2(*pszBuffer) && *(pszBuffer+1) != _T('[') &&
			(_istpunct(*(pszBuffer+1)) || _istspace2(*(pszBuffer+1))))
		{
			memmove((void*)pszBuffer, pszBuffer+1, 
				(lstrlen(pszBuffer))*sizeof(TCHAR));
			nNewLength--;
			continue;
		}

		// 如果当前是分隔符,下一个是空格,删除下一个字符
		if (_istpunct(*pszBuffer) && _istspace2(*(pszBuffer+1)))
		{
			memmove((void*)(pszBuffer+1), pszBuffer+2, 
				(lstrlen(pszBuffer)-1)*sizeof(TCHAR));
			nNewLength--;
			continue;
		}

		pszBuffer = _strinc2(pszBuffer);
	}

	rString.ReleaseBuffer();
}

void SqlString_Insert(CString& rString, int &nIndex, LPCTSTR lpszKey)
{
	if (nIndex > 0 && !_istspace2(rString[nIndex-1]))
		rString.Insert(nIndex++, _T(' '));
	rString.Insert(nIndex, lpszKey);
	nIndex += lstrlen(lpszKey);
	if (rString[nIndex] != 0 && !_istspace2(rString[nIndex]))
		rString.Insert(nIndex++, _T(' '));
}

// 删除指定长度的字符并在指定的起始点插入另一组字符。
int SqlString_Stuff(CString& rString, int nIndex, int nCount, LPCTSTR psz)
{
	if(nIndex < 0)
		nIndex = 0;

	int nLength = rString.GetLength();
	if (nIndex > nLength)
		nIndex = nLength;
	if ((nIndex + nCount) > nLength)
		nCount = nLength - nIndex;

	if(nCount < 0)
		nCount = 0;

	int nNewLength = nLength;
	int nInsertLength = (psz != NULL) ? int(strlen(psz)) : 0;
	if (nCount > 0 || nInsertLength > 0)
	{
		nNewLength += nInsertLength - nCount;

		LPTSTR pszBuffer = rString.GetBuffer(nNewLength);
		// move existing bytes down
		memmove(pszBuffer+nIndex+nInsertLength, pszBuffer+nIndex+nCount, 
			(nNewLength-nIndex-nInsertLength+1)*sizeof(TCHAR));
		memcpy(pszBuffer+nIndex, psz, nInsertLength*sizeof(TCHAR));
		rString.ReleaseBuffer();
	}

	return(nNewLength);
}

BOOL SqlString_Alias(CString& rAlias)
{
	int nIndex = (int)_tcscspn2(rAlias, _T(" ,()"));
	if (nIndex < rAlias.GetLength())
	{
		rAlias.Insert(0, _T('['));
		rAlias.Insert(rAlias.GetLength(), _T(']'));
		return TRUE;
	}

	return FALSE;
}

BOOL SqlString_SelectList(LPCTSTR lpszFullString, int& nIndex, int& nCount)
{
	nIndex = (int)_tcskey1(lpszFullString, _T("select"));
	lpszFullString += nIndex;
	if (*lpszFullString == 0)
	{
		nCount = 0;
		return FALSE;
	}

	nCount = (int)_tcskey2(lpszFullString, _T("from"));
	return TRUE;
}

int SqlString_ColumnCount(LPCTSTR lpszSelectList)
{
	for (int nCount=0; lpszSelectList != NULL; nCount++)
	{
		lpszSelectList = _tcschr2(lpszSelectList, _T(','));
		if (lpszSelectList != NULL)
			lpszSelectList++;
	}

	return nCount;
}

BOOL SqlString_ColumnItem(LPCTSTR lpszSelectList, int nIndex, int& nStart, 
						  int& nCount)
{
	LPCTSTR lpchStart = lpszSelectList;
	while (nIndex--)
	{
		lpchStart = _tcschr2(lpchStart, _T(','));
		if (lpchStart == NULL)

⌨️ 快捷键说明

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