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

📄 copyhelper.h

📁 Data Replication Prototype Using ADO
💻 H
字号:

#ifndef __CopyHelper_h__
#define __CopyHelper_h__


#include "OrderVariant.h"


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

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

inline bool HasParams(DWORD dwFilterType)
{
	return fltNoFilter != dwFilterType && dwFilterType < 0x00010000;
}

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


class pchar_stack
{
	struct buffer
	{
		buffer* pNext;
	};

public:
	pchar_stack()  { m_pBuf = NULL; }
	~pchar_stack() { RemoveAll(); }

	char* get(size_t nSize) const;
	void put(void* p) const;
	void RemoveAll();

private:
	mutable buffer* m_pBuf;
};


template<typename T>
class cached_alloc : public std::allocator<T>
{
friend class cached_alloc;

	typedef std::allocator<T> super;
	
	const pchar_stack& m_cache;

	template <class T> T* get(size_type _N, T*) 
	{ 
		return (T*) m_cache.get(_N * sizeof T);
	}

public:

	typedef size_t size_type;

	typedef T value_type;
	typedef value_type *pointer;
	typedef const value_type *const_pointer;
	typedef value_type & reference;
	typedef const value_type & const_reference;

	cached_alloc(const pchar_stack&  c) : m_cache(c) {}

	template<typename _Other>
		cached_alloc(const cached_alloc<_Other>& c)  : m_cache(c.m_cache) {}

	char *_Charalloc(size_type _N)
	{
		return m_cache.get(_N);
	}
	pointer allocate(size_type _N, const void* = NULL)
	{
		return get(_N, (pointer) 0);
	}
	void deallocate(void _FARQ *_P, size_type)
	{
		m_cache.put(_P);
	}
	
public:
	template<class _Other>
		struct rebind
		{	// convert an allocator<_Ty> to an allocator <_Other>
		typedef cached_alloc<_Other> other;
		};

};


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

#define REFERENCE_PROGRESS_REDUCING_COEFF	4

typedef CTypedPtrArray<CPtrArray, CDBTable*> CDBTablePtrArray;
typedef CTypedPtrArray<CPtrArray, CXLink*> CXLinkPtrArray;


struct DBASE_VERSION
{
	long m_lVersion_Number;
	long m_lSubVersion_Number;
	long m_lRelease_Number;
	long m_lRevision_Number;
	DBASE_VERSION()
	{
		m_lVersion_Number = m_lSubVersion_Number 
		= m_lRelease_Number = m_lRevision_Number = 0;
	}
	DBASE_VERSION(long lVersion_Number,
					  long lSubVersion_Number,
					  long lRelease_Number,
					  long lRevision_Number)
	{
		m_lVersion_Number		= lVersion_Number;
		m_lSubVersion_Number = lSubVersion_Number;
		m_lRelease_Number		= lRelease_Number;
		m_lRevision_Number	= lRevision_Number;
	}
	bool IsValid() 
	{ 
		return m_lVersion_Number || m_lSubVersion_Number 
		|| m_lRelease_Number || m_lRevision_Number;
	}
};

long Compare(const DBASE_VERSION& V1, const DBASE_VERSION& V2);

inline bool operator == (const DBASE_VERSION& V1, const DBASE_VERSION& V2)
{
	return Compare(V1, V2) == 0l;
}

inline bool operator != (const DBASE_VERSION& V1, const DBASE_VERSION& V2)
{
	return Compare(V1, V2) != 0l;
}

inline bool operator <= (const DBASE_VERSION& V1, const DBASE_VERSION& V2)
{
	return Compare(V1, V2) <= 0l;
}

inline bool operator >= (const DBASE_VERSION& V1, const DBASE_VERSION& V2)
{
	return Compare(V1, V2) >= 0l;
}

inline bool operator < (const DBASE_VERSION& V1, const DBASE_VERSION& V2)
{
	return Compare(V1, V2) < 0l;
}

inline bool operator > (const DBASE_VERSION& V1, const DBASE_VERSION& V2)
{
	return Compare(V1, V2) > 0l;
}


class ETLLIB_EXPORT CMapTbl2MapId 
: public CMap<CTableId, const CTableId&, CMapIdentities*, CMapIdentities*>
{
	typedef CMap<CTableId, const CTableId&, CMapIdentities*, CMapIdentities*> super;
public:
	CMapIdentities* GetAtNew(CTableId pTableTo);
};

enum EHandleResult { handled, postpone, error };


typedef CTypedPtrArray<CPtrArray, COrderEntry*> CArrayEntries;

typedef COrderVariantKey* POrderVariantKey;

struct IsPOrderEntryLess
{
	bool operator()(POrderVariantKey p1, POrderVariantKey p2) const
	{
		CHECK_ADDRESS(p1); CHECK_ADDRESS(p2);
		return p1->GetCopyTableId() < p2->GetCopyTableId();
	}
};

typedef std::multiset<COrderVariant*, IsPOrderEntryLess>	CMultiSetEntries;

typedef CDataHandlerKey* PDataHandlerKey;

struct IsPDataHandlerKeyLess
{
	bool operator()(PDataHandlerKey p1, PDataHandlerKey p2) const
	{
		CHECK_ADDRESS(p1); CHECK_ADDRESS(p2);
		return p1->GetCopyTableId() < p2->GetCopyTableId();
	}
};

typedef std::set<CDataHandler*, IsPDataHandlerKeyLess> CSetVariantBases;
typedef std::set<CDataProvider*, IsPDataHandlerKeyLess> CSetDataProviders;

typedef std::multimap<long, long>							CMultiMapIds;

class ETLLIB_EXPORT CTblCopyHelper 
{
friend CDataHandler* COrderVariant::GetOrderVariantBase();
friend CDataHandler* COrderVariant::GetSlaveOrderVariantBase();
friend CDataProvider* CDataHandler::GetDataProvider();

protected:
	CArrayEntries									m_Entries;
	CMultiSetEntries								m_WorkFlowEntries;
	CTypedPtrArray<CPtrArray, COrderLink*> m_Links;
	CTypedPtrArray<CPtrArray, CXLink*>		m_XLinks;
	CMapTbl2MapId m_mapTbl2MapId;

	BOOL GoDownstairs(CCopyIterator CopyIterator,
							COrderVariant* pTwinTables);
	BOOL DoCopyLinkedTables(CSubstRecArrayPtr& parrSubstRec,
							COrderVariantKey* pTwinTables, bool bPrimary);
	BOOL HasVirginXLinks(CTableId pTblTo, int nCount);
	COrderLink* GetSelfLink(CTableId pTblTo);
	BOOL GoUpstairs(CDBTable* pTblTo, int nCount);
	virtual void SetDefValues(COrderVariant* ) {}
	void AddEntry(COrderEntry* pEntry);
	void AddLink(COrderLink* pLink);
	void AddXLink(CXLink* pL);


	BOOL CopyReferenceTables(CProgressCtrl* pProgress, bool bClear = false);
	void DoClear(const CXLinkPtrArray& ) {}
	virtual BOOL PreCopyTables(CProgressCtrl* pProgress);
	BOOL DoCopyTables(CProgressCtrl* pProgress);
	virtual BOOL PostCopyTables()			{ return TRUE; }
	virtual void SetFormerVersion();
	void SetCurrentVersion();
	int EnumReferenceTables(CXLinkPtrArray* pArray = NULL);
	int GetNumReferenceTables()
		{
			if(-1 == m_nReferenceTables)
				m_nReferenceTables = EnumReferenceTables();
			return m_nReferenceTables;
		}
	EHandleResult HandleEntry(COrderEntry* pEntry);

	CProgressCtrl* GetProgressCtrl() { return m_pProgress; }

//	Use this method cautiously
	CMapIdentities* GetMap(LPCWSTR pszTableName);

	bool IsLazyObjectBinding() const		{ return m_bLazyObjectBinding; }
	void SetLazyObjectBinding(bool bSet)	{ m_bLazyObjectBinding = bSet; }

	CMapIdentities* GetMap(const CTableId& id)
	{
		return m_mapTbl2MapId.GetAtNew(id);
	}

	void DoHandleRecord(COrderVariant* pLink, bool& bUpdate, bool& bHandleDependants);
	void ShowProgress();

	void SetDataProvider(const CTableId& id, CDataProvider* pDataProvider);

public:
	CTblCopyHelper();
	~CTblCopyHelper();
	void FreeArrays();
	void FreeDBHolders();
	void SetDataSources(CTableHolder* pHolderTo, 
		CTableHolder* pHolderFrom = NULL, 
		BOOL bAutoDelete = FALSE);

	BOOL CopyTables(CProgressCtrl* pProgressBar = NULL);
	CMapTbl2MapId* GetMapTbl2MapId() { return  &m_mapTbl2MapId; };
	virtual int GetCount() { return m_WorkFlowEntries.size() + m_Links.GetSize(); }

	CTableHolder* GetHolderTo()   
	{ 
		CHECK_ADDRESS(m_pHolderTo);
		return m_pHolderTo; 
	}
	CTableHolder* GetHolderFrom() 
	{ 
		CHECK_ADDRESS(m_pHolderFrom);	
		return m_pHolderFrom;
	}
	const DBASE_VERSION& GetFormerVersion() 
		{ 
			ASSERT(m_FormerVersion.IsValid());
			return m_FormerVersion; 
		}

	bool IsPassed(CTableId pTblTo);
	void MarkRelatedXLinksPassed(CTableId pTblTo);

	virtual void OnSetIDs(COrderVariant* )	{}
	virtual bool Convert(COrderVariant* )
		{
			return false;
		}
	void SetFlags(DWORD dwCopyFlags)
		{
			m_dwCopyFlags = dwCopyFlags;
		}
	DWORD GetFlags()	{ return m_dwCopyFlags; }

	BOOL IsSerialLink(COrderLink* pLink);
	bool HasSameDatabases();

private:
	CTableHolder* m_pHolderTo;
	CTableHolder* m_pHolderFrom;
	BOOL m_bAutoDelete;
	CProgressCtrl* m_pProgress;

	DBASE_VERSION m_FormerVersion;

	CSetVariantBases m_mapOrderVariants;
	CSetDataProviders m_DataProviders;

	int  m_nReferenceTables;

	enum { eNotDef = -1, eNot, eSame } m_eSameDBases;

	bool m_bLazyObjectBinding;

	int m_nProgressDelay;

	pchar_stack m_LongMapMemCache;

protected:
	DWORD			 m_dwCopyFlags;
};

#define FIELD_MACRO(Table, Field) Field

#define COPY_ENTRY(ValueTo, ValueFrom, Table, Field, FilterType)			\
	AddEntry(new CTypedEntryLink<C##Table>(CCopyIterator(ValueTo,ValueFrom),\
		CreateTableId<C##Table>(), FIELD_MACRO(C##Table, Field), FilterType))

#define COPY_ENTRY_ACCESSORY(Value, Table, Field)							\
	COPY_ENTRY(Value, Value, Table, Field, fltUndefined)

#define COPY_ENTRY_PK(ArrayId, Table, Field)								\
	AddEntry(new CTypedEntryLink<C##Table>(ArrayId,							\
		CreateTableId<C##Table>(), FIELD_MACRO(C##Table, Field)))

#define COPY_LINK(MsTable, SlTable, SlField, FilterType)					\
	AddLink(new CTypedEntryLink<C##SlTable>(CreateTableId<C##MsTable>(),	\
		CreateTableId<C##SlTable>(), FIELD_MACRO(C##SlTable, SlField), FilterType))

#define COPY_XLINK(MsTable, SlTable, SlField)								\
	AddXLink(new CTypedEntryLink<C##MsTable>(false, CreateTableId<C##MsTable>(),\
		CreateTableId<C##SlTable>(), FIELD_MACRO(C##SlTable, SlField)))

#define COPY_RLINK(MsTable, SlTable, SlField)								\
	AddXLink(new CTypedEntryLink<C##MsTable>(true, CreateTableId<C##MsTable>(),\
		CreateTableId<C##SlTable>(), FIELD_MACRO(C##SlTable, SlField)))

#endif// __CopyHelper_h__

⌨️ 快捷键说明

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