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

📄 copyhelper.cpp

📁 Data Replication Prototype Using ADO
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					try
					{
						TransferData(static_cast<CTblCopyHelperUpstairs*>(this), CUpstairsContext(),
							pXLink, nCount, false, pXLink->m_pMapId, arrOutpSubstRec);
					}
					catch(transfer_exception&)
					{
						return false;
					}

					pXLink->SetFieldSlaveTo(pXLink->GetTblCopyTo()->GetPrimaryKey());

					if(!pXLink->IsAbandonDependants() && arrOutpSubstRec->GetSize() > 0)
						DoCopyLinkedTables(arrOutpSubstRec, pXLink, false);
				}
				else 
					pXLink->SetFieldSlaveTo(ID_NULL);
//				pXLink->FreeStatements();
			}
		}
	}
	return TRUE;
}

void CTblCopyHelper::AddEntry(COrderEntry* pEntry)
{
	CHECK_ADDRESS(pEntry);
	ASSERT(pEntry->IsEntry());
	pEntry->SetTblCopyHelper(this);
	m_Entries.Add(pEntry);
	if(!IsLazyObjectBinding())
		VERIFY(pEntry->OrderVariantBase());
}

void CTblCopyHelper::AddLink(COrderLink* pL)
{
	CHECK_ADDRESS(pL);
	ASSERT(pL->IsLink());
	for(int i = m_Links.GetSize(); --i >= 0; ) 
	{
		DECLARE_GET_pLink(i);
		if(IsEqual(pL, pLink)) 
		{
			ASSERT(pL->GetFilterType() == pLink->GetFilterType());
			delete pL;
			if(!IsLazyObjectBinding())
				VERIFY(pLink->OrderVariantBase());
			return;
		}
	}
	pL->m_pMapId = m_mapTbl2MapId.GetAtNew(pL->GetTblMasterTo());
	pL->SetTblCopyHelper(this);
	if(!IsLazyObjectBinding())
		VERIFY(pL->OrderVariantBase());
	m_Links.Add(pL);
}

void CTblCopyHelper::AddXLink(CXLink* pL)
{
	int i;
	CHECK_ADDRESS(pL);
	ASSERT(pL->IsXLink());
//	ASSERT(pL->GetTblMasterTo() != pL->GetTblSlaveTo());

	for(i = m_XLinks.GetSize(); --i >= 0; ) 
	{
		DECLARE_GET_pXLink(i);
		if(IsEqual(pL, pXLink)) 
		{
			delete pL;
			if(!IsLazyObjectBinding())
				VERIFY(pXLink->OrderVariantBase());
			return;
		}
	}
	pL->m_pMapId = m_mapTbl2MapId.GetAtNew(pL->GetTblMasterTo());
	pL->SetTblCopyHelper(this);
	if(!IsLazyObjectBinding())
		VERIFY(pL->OrderVariantBase());
	m_XLinks.Add(pL);
}


BOOL CTblCopyHelper::IsSerialLink(COrderLink* pL)
{
	ASSERT(pL);
	switch(pL->GetSerialKind())
	{
		case skNotDefined:
			if(pL->GetTblMasterTo() == pL->GetTblSlaveTo())
			{
				pL->SetSerialKind(skSerial);
				return TRUE;
			}
			else
			{
				for(int i = m_Links.GetSize(); --i >= 0; ) 
				{
					DECLARE_GET_pLink(i);
					if(pL->GetTblMasterTo() == pLink->GetTblSlaveTo() &&
					pLink->GetTblMasterTo() == pL->GetTblSlaveTo())
					{
						pL->SetSerialKind(skSerial);
						return TRUE;
					}
				}
				pL->SetSerialKind(skNotSerial);
				return FALSE;
			}
		case skNotSerial:  return FALSE;
		case skSerial:		 return TRUE;
	}
	ASSERT(0); return FALSE;
}

int CTblCopyHelper::EnumReferenceTables(CXLinkPtrArray* pArray /*= NULL*/)
{
	int nCount = 0;
	for(int i = m_XLinks.GetSize(); --i >= 0; )
	{
		DECLARE_GET_pXLink(i);
		if(pXLink->IsByReference())	
		{
			if(pArray)
				pArray->Add(pXLink);
			nCount++;
		}
	}
	return nCount;
}

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

struct CRefContext {};
		
class CTblCopyHelperRef : public CTblCopyHelper
{
	template<typename T, typename C, typename H>
	friend void TransferData(T* pHolder, const C& rContext, COrderVariant* pVar, 
		int nCount, bool bForceAdd, CMapIdentities* pSubstId, H& rIdHandler);

	bool DoConvertAndFilter(COrderVariant* pVar, CMapIdentities* pMapId, 
		const CRefContext&)
	{
		Identity lPKTo;
		return !pMapId->Lookup(pVar->GetPrimaryKeyFrom(), lPKTo);
	}

	void DoAddDropRecord(COrderVariant* pVar, bool& bUpdate)
	{
		VERIFY(pVar->GetTblCopyTo()->AddRecord(FALSE));
		bUpdate = true;
	}
};

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

BOOL CTblCopyHelper::CopyReferenceTables(CProgressCtrl* pProgress, bool bClear /*= false*/)
{
	int i, j;
	CXLinkPtrArray XLinks;
//	Get reference links
	EnumReferenceTables(&XLinks);
//	Sort them
	for(i = 0; i < XLinks.GetSize() - 1; i++)
		do
			for(j = i + 1; j < XLinks.GetSize(); j++)
			{
				CXLink* pXLink1 = XLinks[i];
				CXLink* pXLink2 = XLinks[j];
				if(pXLink1->GetTblMasterTo() == pXLink2->GetTblSlaveTo())
				{
					ASSERT(pXLink2->GetTblMasterTo() != pXLink1->GetTblSlaveTo());
					std::swap(XLinks[i], XLinks[j]);
					break;
				}
			}
		while(j < XLinks.GetSize());

//	Remove superfluous links
	for(i = 0; i < XLinks.GetSize() - 1; i++)
	{
		CXLink* pXLink1 = XLinks[i];
		for(j = i + 1; j < XLinks.GetSize(); j++)
		{
			CXLink* pXLink2 = XLinks[j];
			if(pXLink1->GetTblMasterTo() == pXLink2->GetTblMasterTo())
			{
				XLinks.RemoveAt(j);
				j--;
				continue;
			}
		}
	}

	if(pProgress)
	{
		pProgress->SetRange(0,
			(short)(GetCount() + XLinks.GetSize() / REFERENCE_PROGRESS_REDUCING_COEFF));
	}

	if(bClear)
	{
		DoClear(XLinks);
	}

//	Replicate data
	for(i = 0; i < XLinks.GetSize(); i++)
	{
		PumpPaintMsg();

		CXLink* pXLink = XLinks[i];
		if(pXLink->IsDontCopyRef())
		{
			pXLink->OnCopyRefSpecial();
		}
		else
		{
			CMapIdentities* pMapId = NULL;
			VERIFY(m_mapTbl2MapId.Lookup(pXLink->GetTblMasterTo(), pMapId));

			CSubstRecArrayPtr arrOutpSubstRec = new CSubstRecArray;
			DWORD dwFilterType = fltNoFilter;
			pXLink->FirstSubType();
			do
			{
				if(pXLink->FindFirstFrom(dwFilterType)) do
				{
					try
					{
						TransferData(static_cast<CTblCopyHelperRef*>(this), CRefContext(),
							pXLink, XLinks.GetSize(), false, pMapId, arrOutpSubstRec);
					}
					catch(transfer_exception&)
					{
						return false;
					}
				}
				while(pXLink->FindNextFrom());
			}
			while(pXLink->NextSubType(NULL, dwFilterType));

			if(!pXLink->PostCopyAll(arrOutpSubstRec))
				return FALSE;
			if(arrOutpSubstRec->GetSize())
				DoCopyLinkedTables(arrOutpSubstRec, pXLink, false);
		}
		pXLink->FreeStatements();

		if(!(i % REFERENCE_PROGRESS_REDUCING_COEFF))
			ShowProgress();
	}
	return TRUE;
}



BOOL CTblCopyHelper::PreCopyTables(CProgressCtrl* pProgressBar)
{
	int i;

	TRACE0(_T("Replication initial tables list:\n"));
	for(int j = m_Entries.GetSize() ; --j >= 0; ) 
	{
		DECLARE_GET_pEntry(j);
		if(pEntry->IsAccessory())
			continue;
		for(i = m_Links.GetSize(); --i >= 0; ) 
		{
			DECLARE_GET_pLink(i);
			if(!IsSerialLink(pLink) && 
			pEntry->GetTblSlaveTo() == pLink->GetTblSlaveTo())
				break;
		}
		if(-1 == i)
		{
			TRACE1(_T("\"%s\"\n"), m_Entries[j]->GetTblSlaveTo().GetTableName());
			m_WorkFlowEntries.insert(m_Entries[j]);
			m_Entries.RemoveAt(j);
		}
	}
	TRACE0(_T("End of Replication initial tables list.\n"));

	for(i = m_XLinks.GetSize(); --i > 0; )
	{
		CXLink* pXLink1 = m_XLinks[i];
		CHECK_ADDRESS(pXLink1);
		if(pXLink1->IsSelfLink())
			TRACE1("Replication: X-link from table \"%s\" to itself. Take special care about copying order.\n", 
					pXLink1->GetTblSlaveTo().GetTableName());
		if(!pXLink1->IsByReference() && !pXLink1->IsPassed())
		{
			int j;
			CMultiSetEntries::const_iterator iter = m_WorkFlowEntries.find(pXLink1);

			if(iter == m_WorkFlowEntries.end())
			{
				for(j = m_Links.GetSize(); --j >= 0; )
				{
					DECLARE_GET_pLink(j);
					CHECK_ADDRESS(pLink);
					if(pLink->GetTblSlaveTo() == pXLink1->GetTblMasterTo())
							break;
				}
				if(-1 == j)
				{
					pXLink1->SetByReference();
					TRACE2(_T("Orfan x-link from the table \"%s\" to the table \"%s\" converted to a r-link.\n"), 
						pXLink1->GetTblMasterTo().GetTableName(), pXLink1->GetTblSlaveTo().GetTableName());
				}
			}
		}

#ifdef _DEBUG
		if(!pXLink1->IsByReference() || !pXLink1->GetTblSlaveTo())
			continue;
		for(int j = i; --j >=0; )
		{
			CXLink* pXLink2 = m_XLinks[j];
			if(!pXLink2->IsByReference())
				continue;
			CHECK_ADDRESS(pXLink2);
			if(pXLink1->GetTblSlaveTo() == pXLink2->GetTblSlaveTo())
			{
				for(int k = m_XLinks.GetSize(); --k >= 0; )
				{
					CXLink* pXLink3 = m_XLinks[k];
					if(!pXLink3->IsByReference())
						continue;
					if(pXLink3->GetTblMasterTo() == pXLink1->GetTblSlaveTo())
					{
						TRACE3("Replication: Duplicate ref.links to table \"%s\" from tables \"%s\" and \"%s\".\n", 
								pXLink1->GetTblSlaveTo().GetTableName(),
								pXLink1->GetTblMasterTo().GetTableName(), 
								pXLink2->GetTblMasterTo().GetTableName());
						break;
					}
				}
			}
		}
#endif//_DEBUG
	}
	
	if (pProgressBar)
	{
		pProgressBar->SetRange(0, (short)GetCount());
		pProgressBar->SetStep(1);
		pProgressBar->SetPos(0);
	}

	return TRUE;
}

////////////////////////////////
// Maps stuff

CMapIdentities* CTblCopyHelper::GetMap(LPCWSTR pszTableName)
{
	if(NULL == pszTableName || 0 == *pszTableName)
	{
		ASSERT(0); return NULL;
	}
	CTableId id(NULL, pszTableName);
	CMapIdentities* pMap = NULL;
	m_mapTbl2MapId.Lookup(id, pMap);
	return pMap;
}

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

bool FixId(Identity& rlId, CMapIdentities* pMapId, bool bLeaveNotFound = false)
{
	if(!IsValid(rlId))
		return false;
	Identity lNewId;
	if(!pMapId->Lookup(rlId, lNewId))
	{
		if(bLeaveNotFound)
			return false;
		rlId = ID_NULL;
		return true;
	}
	if(rlId != lNewId)
	{
		rlId = lNewId;
		return true;
	}
	return false;
}


bool CTblCopyHelper::HasSameDatabases()
{
	if(eNotDef == m_eSameDBases && GetHolderTo() && GetHolderFrom())
		m_eSameDBases = (GetHolderTo()->HasSameDatabase(*GetHolderFrom()))? eSame : eNot;
	return eSame == m_eSameDBases;
}


void CTblCopyHelper::DoHandleRecord(COrderVariant* pLink, bool& bUpdate
												, bool& bHandleDependants)
{
	bool bEditExisting = false;
	bool bAddNew = false;

	CDBTable* pTblTo = pLink->GetTblCopyTo();

	if(pLink->IsUpdateDestination())
		bEditExisting = true;
	else
	{
		UIChoiceKind choice = pLink->GetUIChoiceKind();
		if(uiAskChoice == choice)
		{
			CDlgUIChoicePrompt dlg;

			dlg.m_strStaticText 
				= _T("Matching record is already present in the destination table \"") 
				+ CString(pTblTo->GetTableName()) 
				+ _T("\".\nChoose an appropriate action:");

			switch(dlg.DoModal())
			{
			case IDC_USE_EXISTING:	
				choice = uiUseExisting; 
				break;
			case IDC_CREATE_NEW:		
				choice = uiCreateNew; 
				break;
			case IDC_OVERWRITE:		
				choice = uiOverwrite; 
				break;
			default: ASSERT(0); return;
			}
			AfxGetApp()->RestoreWaitCursor();
			if(dlg.m_bApplyToAll)
				pLink->SetUIChoiceKind(choice);
		}

		switch(choice)
		{
		case uiCreateNew:
			bAddNew = true;
			bUpdate = true;
			break;
		case uiOverwrite:
			bEditExisting = true;
			break;
		}
	}
	if(bEditExisting)
	{
		bHandleDependants = true;
		VERIFY(pTblTo->EditRecord());
	}
	else if (bAddNew)
	{
		bHandleDependants = true;
		VERIFY(pLink->GetTblCopyTo()->AddRecord(FALSE));
	}
	else
		return;

	pLink->CopyData(false);
	VERIFY(GoUpstairs(pTblTo, m_XLinks.GetSize()));
	SetDefValues(pLink);
	pLink->CorrectTableData();
	if (bAddNew)
		pLink->SetUniqueName();
	bUpdate = bAddNew || pTblTo->WasModified();
}

void CTblCopyHelper::ShowProgress()
{
	if(m_nProgressDelay)
		--m_nProgressDelay;
	else if(m_pProgress)
		m_pProgress->OffsetPos(1);
}

void CTblCopyHelper::SetDataProvider(const CTableId& id, CDataProvider* pDataProvider)
{
	pDataProvider->SetParameters(this, id);

	CDataHandlerKey key(id);
	CSetDataProviders::iterator iter 
		= m_DataProviders.find(static_cast<CDataProvider*>(&key));
	if(iter != m_DataProviders.end())
	{
		ASSERT(0);
		delete *iter;
		*iter = pDataProvider;
	}
	else
		m_DataProviders.insert(pDataProvider);
}

⌨️ 快捷键说明

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