📄 copyhelper.cpp
字号:
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 + -