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

📄 ordervariant.cpp

📁 Data Replication Prototype Using ADO
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"

//#include "OrderVariant.h"
#include "CopyHelper.h"

#pragma warning(disable:4100)
#include <algorithm>
#pragma warning(default:4100)

#include "BellsMacrosX.h"
#include "DBTable.h"
#include "TableHolder.h"

#include <sstream>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

using std::wstring;

///////////////////////////////////////////////////////////////////////////////////

Identity GetIdentityValue(const CDBTable* pTable, size_t offset)
{
	return pTable->GetIdentityValue(offset);
}

void SetIdentityValue(CDBTable* pTable, size_t offset, Identity value) 
{
	CHECK_ADDRESS(pTable);
	pTable->SetIdentityValue(offset, value);
}

///////////////////////////////////////////////////////////////////////////////////

inline CDBTable* HandleCreateTable(const CTableId& idTable, CDBTable*& rpTable, CTableHolder* pHolder)
{
	if(!rpTable)
		rpTable = idTable.GetDBTable(pHolder);
	return rpTable;
}

///////////////////////////////////////////////////////////////////////////////////

CCopyIterator::CCopyIterator(const CCopyIterator& other)
{
	m_ciKind  = ciNotDef; 
	*this = other;
}

const CCopyIterator& CCopyIterator::operator = (const CCopyIterator& other)
{
	Clear();
	*((CCopyIteratorData*)this) = (CCopyIteratorData&)other;
	if(ciMultiple == m_ciKind)
	{
		CHECK_ADDRESS(m_parrSubstRec);
		ASSERT(m_parrSubstRec->GetNumRefs() > 0);
		m_parrSubstRec->upcount();
	}
	return *this;
}

void CCopyIterator::Clear()
{
	if(ciMultiple == m_ciKind)
	{
		CHECK_ADDRESS(m_parrSubstRec);
		ASSERT(m_parrSubstRec->GetNumRefs() > 0);
		m_parrSubstRec->downcount();
		m_parrSubstRec = NULL;
	}
	m_ciKind  = ciNotDef; 
}


void CCopyIterator::SetData(Identity lValueTo, Identity lValueFrom)
{
	Clear();
	m_ciKind = ciSingle;
	m_pair.m_lValueTo = lValueTo; 
	m_pair.m_lValueFrom = lValueFrom;
}

void CCopyIterator::SetData(CSubstRecArrayPtr& parrSubstRec)
{
	Clear();
	m_ciKind = ciMultiple;
	m_parrSubstRec = parrSubstRec;
	m_parrSubstRec->upcount();
}

void CCopyIterator::SetData(CArray<Identity, Identity>* parrId)
{
	Clear();
	m_ciKind = ciByPK;
	m_parrId = parrId;
}

void CCopyIterator::SetData(Identity lPK)
{
	Clear();
	m_ciKind = ciSingle;
	m_pair.m_lValueTo = ID_NOT_DEF; 
	m_pair.m_lValueFrom = lPK;
}

void CCopyIterator::AddData(CSubstRecArrayPtr& parrSubstRec)
{
	if(m_ciKind != ciMultiple)
	{
		ASSERT(0); return;
	}
//	Copy on write
	if(1 == m_parrSubstRec->GetNumRefs())
		m_parrSubstRec->Append(*parrSubstRec);
	else
	{
		ASSERT(m_parrSubstRec->GetNumRefs() > 0);
		CSubstRecArrayPtr arrSubstRec = new CSubstRecArray;
		arrSubstRec->Append(*m_parrSubstRec);
		arrSubstRec->Append(*parrSubstRec);
		m_parrSubstRec->downcount();
		m_parrSubstRec = arrSubstRec;
		m_parrSubstRec->upcount();
	}
}

BOOL CCopyIterator::ByPK()
{
	return ciByPK == m_ciKind 
	|| ciSingle == m_ciKind 
		&& ID_NOT_DEF == m_pair.m_lValueTo 
		&& IsValid(m_pair.m_lValueFrom);
}

Identity CCopyIterator::GetValueTo()
{
	if(ciSingle == m_ciKind)
		return m_pair.m_lValueTo;
	else
	{
		ASSERT(0);
		return ID_NOT_DEF;
	}
}

Identity CCopyIterator::GetValueFrom()
{
	if(ciSingle == m_ciKind)
		return m_pair.m_lValueFrom;
	else
	{
		ASSERT(0);
		return ID_NOT_DEF;
	}
}

Identity CCopyIterator::GetValueTo(int nIndex)
{
	switch(m_ciKind)
	{
		case ciSingle:
			ASSERT(0 == nIndex);
			return m_pair.m_lValueTo;
		case ciMultiple:
			CHECK_ADDRESS(m_parrSubstRec);
			return m_parrSubstRec->GetAt(nIndex).m_lKeyTo;
		default:
			ASSERT(0);
			return ID_NOT_DEF;
	}
}

Identity CCopyIterator::GetValueFrom(int nIndex)
{
	switch(m_ciKind)
	{
		case ciSingle:
			ASSERT(0 == nIndex);
			return m_pair.m_lValueFrom;
		case ciMultiple:
			CHECK_ADDRESS(m_parrSubstRec);
			return m_parrSubstRec->GetAt(nIndex).m_lKeyFrom;
		case ciByPK:
			CHECK_ADDRESS(m_parrId);
			return m_parrId->GetAt(nIndex);
		default:
			ASSERT(0);
			return ID_NOT_DEF;
	}
}

int CCopyIterator::GetSize()
{
	switch(m_ciKind)
	{
		case ciSingle:
			return 1;
		case ciMultiple:
			CHECK_ADDRESS(m_parrSubstRec);
			return m_parrSubstRec->GetSize();
		case ciByPK:
			if(NULL == m_parrId)
				return 0;
			CHECK_ADDRESS(m_parrId);
			return m_parrId->GetSize();
		default:
			ASSERT(0);
			return 0;
	}
}

///////////////////////////////////////////////////////////////////////////////////

inline int safe_cscmp(LPCWSTR string1, LPCWSTR string2)
{
	if(NULL == string1)
		return (NULL == string2)? 0 : -1;
	if(NULL == string2)
		return 1;
	return wcscmp(string1, string2);
}


bool CTableId::operator == (const CTableId& other) const
{
	return !safe_cscmp(m_pszTableName, other.m_pszTableName);
}

bool CTableId::operator < (const CTableId& other) const
{
	return safe_cscmp(m_pszTableName, other.m_pszTableName) < 0;
}

bool CTableId::operator == (const CDBTable* other) const
{
	return !safe_cscmp(m_pszTableName, other->GetTableName());
}

CDBTable* CTableId::GetDBTable(CTableHolder* pHolder) const
{
	if(!m_pfnCreator || !pHolder)
	{
		ASSERT(0); return NULL;
	}
	CDBTable* pTable = NULL;
	if (!pHolder->Lookup(m_pszTableName, pTable))
	{
		pTable = m_pfnCreator(pHolder);
		pHolder->SetDBTable(m_pszTableName, pTable);
	}
	return pTable;
}


///////////////////////////////////////////////////////////////////////////////////


void MakeCopyName(wstring& strName, int nInstance)
{
	wstring strBuf = strName;
	int nIndex = strBuf.find_last_of(L" Copy");
	if(nIndex > 1)
	{
		int i = nIndex + 5;
		for( ; i < strBuf.length(); i++)
			if(strBuf[i] > L'9')
				break;
		if(strBuf.length() == i)
		{
			strName = strName.substr(0, nIndex);
		}
	}
	if(nInstance > 0)
	{
		std::wostringstream s;
		s << strName << L" Copy #" << nInstance;
		strName = s.str();
	}
	else
	{
		strName += L" Copy";
	}
}

///////////////////////////////////////////////////////////////////////////////////

void CXLink::AddCouple()
{
	m_pMapId->SetAt(GetPrimaryKeyFrom(), GetTblCopyTo()->GetPrimaryKey());
	SetPassed();
}

CTblCopyHelper* COrderVariant::GetTblCopyHelper()	
{ 
	CHECK_ADDRESS(m_pTblCopyHelper);
	return m_pTblCopyHelper; 
}

BOOL COrderVariant::IsPassed()
{
	if((m_dwFlags & OV_KIND) != OV_XLINK)
		return (m_dwFlags & OV_PASSED)? TRUE : FALSE;
	if((m_dwFlags & OV_PASSED))
		return TRUE;
	if(!m_pMapId)
	{
		ASSERT(FALSE);
		return FALSE;
	}
	if(m_pMapId->GetCount() && GetTblCopyHelper()->IsPassed(GetTblMasterTo()))
	{
		SetPassed();
		return TRUE;
	}
	return FALSE;
}

BOOL COrderVariant::Convert()
{
	if(NULL != m_pMapId)
	{
		if(IsValid(GetFieldSlaveFrom()))
		{
			Identity lIdTo;
			if(m_pMapId->Lookup(GetFieldSlaveFrom(), lIdTo))
				SetFieldSlaveTo(lIdTo);
			else
			{
				if(IsConvertOnly())
				{
					SetFieldSlaveTo(ID_NULL);
					return TRUE;
				}
				else if(GetTblCopyHelper()->Convert(this))
				{
					if(IsValid(GetFieldSlaveTo()))
					{
						m_pMapId->SetAt(GetFieldSlaveFrom(), GetFieldSlaveTo());
						GetOrderVariantBase()->OnRefAdded(GetFieldSlaveTo());
					}
				}
				else
					return FALSE;
			}
		}
		else
			SetFieldSlaveTo(GetFieldSlaveFrom());
		return TRUE;
	}
	else
		return FALSE;
}


void COrderVariant::SetIDs()
{
	GetTblCopyHelper()->OnSetIDs(this);
	GetOrderVariantBase()->SetIDs();
}

LeaveKind COrderVariant::GetLeaveData()		{ return GetOrderVariantBase()->GetLeaveData(); }

COrderVariant* COrderVariant::ForkEntry(CSubstRecArrayPtr& parrSubstRec)
{
	if(m_pForkEntry)
		if(m_pForkEntry->IsPassed())
		{
			m_pForkEntry->m_pForkEntry = NULL;
			m_pForkEntry = NULL;
		}
		else
		{
			m_pForkEntry->AddSubstRecs(parrSubstRec);
			return NULL;
		}

	COrderVariant* pEntry = new COrderVariant(*this);
	pEntry->ConvertToEntry(parrSubstRec);
	pEntry->m_pMapId = m_pMapId;
	pEntry->SetTblCopyHelper(GetTblCopyHelper());
	m_pForkEntry = pEntry;

⌨️ 快捷键说明

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