#if !defined(AFX_DBSERVER_H__AF2FA33C_6798_4903_8952_598C6ACC1C7B__INCLUDED_)
#define AFX_DBSERVER_H__AF2FA33C_6798_4903_8952_598C6ACC1C7B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DbServer.h : _xZkqqHx_iDhHiDgCiDfPiBfL_xHqqkZx_ _xZkqqHx_iDhEiDeAiDeDiDiL_xHqqkZx_
//

#include "AutoLock.h"			// For FCAutoReadLock.
#include "File32.h"				// For FCFile32.
#include "ServerTableManager.h"	// For FCServerTableManager.
#include "DynamicServer.h"		// Baseclass.

class FCServerTableManager;
struct FCTableName;

/////////////////////////////////////////////////////////////////////////////
// FCServerLockRec.

/*************************************************************************
 * <_xZkqqHx_iNfMjBkCjBmM_xHqqkZx_>	FCServerLockRec
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	READ_xZkqqHx_iDiNiDgCiDeOiBeB_xHqqkZx_WRITE_xZkqqHx_iDiNiDgCiDeOiCmMiKmHjHjNiDeJiDhFiDfHiDeGiDeOiDgHiBeC_xHqqkZx_
 *			_xZkqqHx_iDgFiBfLiDhFiDiLjGlM_xHqqkZx_ -> _xZkqqHx_iKmHjHjNiDeJiDhFiDfHiDeGiDeOiDgH_xHqqkZx_ _xZkqqHx_iDgFiBfLiDhFiDiLiCmJjHjIjHhAiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	06.02.10 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
struct FCServerLockRec
{
	FCAutoReadLock	m_autoReadLock;
	FCAutoWriteLock	m_autoWriteLock;
}; // struct FCServerLockRec.

typedef auto_ptr<FCServerLockRec>	FCServerLockRecAuto;

/////////////////////////////////////////////////////////////////////////////
// FCIndexFile.

/*************************************************************************
 * <_xZkqqHx_iDeOiDiJiDfI_xHqqkZx_>	FCIndexFile
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDeDiDjDiDgGiDgCiDeOiDfIiDgFiBfLiDhFiDiLiCmMjDmHiCnNiPgPiClFiCmJjHjIjHhAiBeC_xHqqkZx_
 *			_xZkqqHx_iDeDiDjDiDgGiDgCiDeOiDfIiDgFiBfLiDhFiDiLiDhEiDeAiDeDiDiLiCpAiDeJiBfLiDhGiDjDiClFiBeBiPoOjFpBiCpAiOoGiCoIiPgPiClHiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	06.02.10 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
class FCIndexFile
{
public:
	FCIndexFile (const FCTableName& tableName);
	~FCIndexFile ();
	DWORD	GetRecordCount () const;
	flint	GetDataFilePosition (DWORD dwIndex);
	void	SeekToIndex (DWORD dwIndex);
	DWORD	GetCurrentIndex () const;
	void	Read (	flint& fliPrimaryId,
					DWORD& dwAppendIdentifier,
					flint& fliDataFilePositionTail);
	static flint	GetIndexFilePosition (DWORD dwIndex);
protected:
	FCFile32	m_file;
}; // class FCIndexFile.

/////////////////////////////////////////////////////////////////////////////
// FCDbServer

/*************************************************************************
 * <_xZkqqHx_iDeOiDiJiDfI_xHqqkZx_>	DynamicServer
 *
 * <_xZkqqHx_iLeAjEfM_xHqqkZx_>	_xZkqqHx_iDfEiBfLiDgPiBfLiCgDiCgLiCgLiCmMiDeDiDjDiDfOiDhEiDeGiBfLiDfIiCpAiOmAjBjFiBeC_xHqqkZx_
 *
 * <_xZkqqHx_jHjKjHpA_xHqqkZx_>	06.02.10 Fukushiro M. _xZkqqHx_iNoMjAkM_xHqqkZx_
 *************************************************************************/
class FCDbServer : public DynamicServer
{
public:
	FCDbServer ();

	virtual ~FCDbServer ();

	virtual void	Initialize ();

	virtual void	Terminate ();

friend class FCServerTableManager;

// _xZkqqHx_iMpGiKeKiDeDiDjDiDfOiDhEiDeGiBfLiDfIiCmMiOmAjBjFiKnGjAjEiBeC_xHqqkZx_
protected:
	virtual void	SetLoginUserName (const wchar_t* wcpUserName);

	virtual DsErr	CheckTopGroupPath (const wchar_t* wcpTopDirPath);

	virtual DsErr	TryReadLock (	GUID& guidTable,
									DWORD& dwDeleteIdentifier,
									DWORD& dwAppendIdentifier,
									const DsTableName& dsTableName);

	virtual DsErr	TryWriteLock (const DsTableName& dsTableName);

	virtual DsErr	CreateWriteLock (const DsTableName& dsTableName);

	virtual BOOL	ReadUnlock (const DsTableName& dsTableName);

	virtual BOOL	WriteUnlock (const DsTableName& dsTableName);

	virtual BOOL	IsReadLocked (const DsTableName& dsTableName) const;

	virtual BOOL	IsWriteLocked (const DsTableName& dsTableName) const;

	virtual void	WhoLockingFile (DsString& dsUserName, const DsTableName& dsTableName) const;

	virtual void	SendTransaction (	BOOL bMultiUserAccessable,
										BOOL bReturnImmediate,
										const wchar_t* wcpTopDirPath[],
										const BYTE* pTransaction[],
										size_t szTransaction[],
										long lTopDirCount);

	virtual DsErr	GetFlushErrorCode () const;

	virtual void	GetFlushErrorMessage (DsString& dstrErrorMessage) const;

	virtual DWORD	GetRecordCount (const DsTableName& dsTableName);

	virtual void	LoadTableIndex (DsArray<BYTE>& vTableIndex,
									const DsTableName& dsTableName,
									DWORD dwBeginIndex,
									DWORD dwEndIndex);

	virtual void	LoadTableRecords (	DsArray<BYTE>& vTableRecord,
										const DsTableName& dsTableName,
										DWORD dwBeginIndex,
										DWORD dwEndIndex);

	virtual void	GetUnlockRequestGroup (DsArray<DsTableName>& dsGroupNameArray);

	virtual BOOL	IsFlushing () const;

	virtual BOOL	IsGroupExist (const DsTableName& dsGroupName) const;

	virtual BOOL	IsTableExist (const DsTableName& dsTableName) const;

	virtual DsErr	DeleteTopGroup (const wchar_t* wcpTopDirPath);

	virtual BOOL	IsRecoveryRequired (const wchar_t* wcpTopDirPath) const;

	virtual BOOL	IsTopGroupExist (const wchar_t* wcpTopDirPath) const;

	virtual FDTIME	GetLastModifiedFdtime (const DsTableName& dsTableName) const;

	virtual DWORD	OnDlgOpenDirectory (DsString& dsDirPath,
										HWND hwndParent,
										const wchar_t* wcpInitPath,
										const DWORD* pCtrlIdArray,
										const wchar_t** pCtrlTextArray,
										size_t szCtrlTextCount) const;

	virtual DWORD	OnDlgSaveTopGroup (	DsString& dstrTopGroupPath,
										HWND hwndParent,
										const wchar_t* wcpDlgTitle,
										const wchar_t* wcpInitPath,
										const wchar_t* wcpDocumentType,
										const wchar_t* wcpExt,
										const DWORD* pCtrlIdArray,
										const wchar_t** pCtrlTextArray,
										size_t szCtrlTextCount,
										BOOL bIsJustifyWindow) const;

	virtual DWORD	OnDlgOpenTopGroup (	DsString& dstrTopGroupPath,
										HWND hwndParent,
										const wchar_t* wcpDlgTitle,
										const wchar_t* wcpFilePath,
										const wchar_t* wcpDocumentType,
										const wchar_t* wcpExt,
										const DWORD* pCtrlIdArray,
										const wchar_t** pCtrlTextArray,
										size_t szCtrlTextCount,
										BOOL bIsJustifyWindow) const;

	virtual void	TerminateFlushThread ();

	virtual void	MakeUniqTopGroupPath (	DsString& dsTopGroupPath,
											const wchar_t* wcpPath,
											const wchar_t* wcpExt) const;

// 06.02.22 Fukushiro M. 1_xZkqqHx_iNhDiNoNiPjM_xHqqkZx_ ()
//	virtual void	GetTmpDirectory (DsString& dsDirPath) const;

	virtual void	SetCurrentDirectory (const wchar_t* wcpDirPath);

	virtual void	GetCurrentDirectory (DsString& dsDirPath) const;

friend class FCServerTableManager;
// _xZkqqHx_iDiBiDjDiDgPiBfLiKnGjAjEiBeC_xHqqkZx_
protected:
	virtual DsErr	TryReadLock (	GUID& guidTable,
									DWORD& dwDeleteIdentifier,
									DWORD& dwAppendIdentifier,
									const FCTableName& tableName);

	virtual DsErr	TryWriteLock (const FCTableName& tableName);

	virtual DsErr	TryExclusiveReadLock (const FCTableName& tableName);

	virtual DsErr	CreateWriteLock (const FCTableName& tableName);

	virtual BOOL	ReadUnlock (const FCTableName& tableName);

	virtual BOOL	WriteUnlock (const FCTableName& tableName);

	virtual void	RemoveUnlockRequest (const FCTableName& tableName);

	virtual BOOL	IsReadLocked (const FCTableName& tableName) const;

	virtual BOOL	IsWriteLocked (const FCTableName& tableName) const;

	virtual void	GetReadLockInfo (	GUID& guidTable,
										DWORD& dwDeleteIdentifier,
										DWORD& dwAppendIdentifier,
										const FCTableName& tableName) const;

	virtual void	ResetFlushError ();

	virtual void	SetFlushError (DsErr dsFormatId, ...);

	virtual WString	GetFlushErrorMessage () const;

	virtual DWORD	GetRecordCount (const FCTableName& tableName);

	virtual void	LoadTableIndex (DsArray<BYTE>& vTableIndex,
									const FCTableName& tableName,
									DWORD dwBeginIndex,
									DWORD dwEndIndex);

	virtual void	LoadTableRecords (	DsArray<BYTE>& vTableRecord,
										const FCTableName& tableName,
										DWORD dwBeginIndex,
										DWORD dwEndIndex);

	virtual void	GetUnlockRequestGroup (vector<FCTableName>& vGroupName);

	virtual BOOL	IsGroupExist (const FCTableName& groupName) const;

	virtual BOOL	IsTableExist (const FCTableName& tableName) const;

	virtual FCServerLockRec*	GetLockRec (const FCTableName& tableName);

	virtual const FCServerLockRec*	GetLockRec (const FCTableName& tableName) const;

	virtual void	SetLockRec (const FCTableName& tableName, FCServerLockRec* pLockRec);

	virtual void	ReduceWatchUnlockRequestThread ();

	virtual void	SetUnlockRequestGroup (const FCTableName aGroupName[], size_t szGroupNameCount);

	virtual void	ClearInvalidUnlockRequest ();

	virtual void	GetWriteLockedTable (vector<FCTableName>& vTableName) const;

	virtual void	DeleteLock (const FCTableName& tableName);

	virtual void	FlushThreadProc ();

	static void WatchUnlockRequestCallback (void* data, const FCTableName aGroupName[], size_t szGroupNameCount);

	static void WINAPI myFlushAllThread (LPVOID pvoid);

	static int	CALLBACK myBrowseCallbackProc (HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData);

protected:
	// _LOCK_REC:_xZkqqHx_iDiNiDgCiDeOiKnGjIeBjFmPjAjEiBeCiDhEiDiJiDgCiDfGiDiFiDfIiDiMiDgCiDgIiBeFiDeOiDiJiDeDiDeBiDjDiDgHiDfIiDiMiDgCiDgIiCkJiCoHiMmEiCmOiCoKiCoJiBeC_xHqqkZx_
	//			 _xZkqqHx_iDhEiDiJiDgCiDfGiDiFiDfIiDiMiDgCiDgIiPiIjHjNjCiGiCmNjAoIjHeMiClDiCoKiCoJiBeC_xHqqkZx_
	struct _LOCK_REC
	{
		map<FCTableName, FCServerLockRecAuto>	m_mpTableNameToLockRec;		// _xZkqqHx_iDgFiBfLiDhFiDiLjGlM_xHqqkZx_->_xZkqqHx_iDiNiDgCiDeOiBeC_xHqqkZx_
		map<FCTableName, int>					m_mpGroupNameToUnlockReq;	// _xZkqqHx_iDePiDiLiBfLiDhGjGlM_xHqqkZx_->_xZkqqHx_iJpAjFpKjHhGiLiBiDhEiDeAiDeDiDiLiBeC_xHqqkZx_
	};

	FCCsAreaDef<_LOCK_REC>					m_csaLockRec;
	typedef FCCsAreaRead<_LOCK_REC>			lr_read;
	typedef FCCsAreaWrite<_LOCK_REC>		lr_write;
	typedef FCCsAreaReadWrite<_LOCK_REC>	lr_readwrite;

	// _UNLOCK_REQ :_xZkqqHx_iDiNiDgCiDeOiJpAjFpKjHhGiLiBiKmEiOiLiDfIiDiMiDgCiDgIiBeFiDeOiDiJiDeDiDeBiDjDiDgHiDfIiDiMiDgCiDgIiCkJiCoHiDeBiDeOiDfKiDfIiClDiCoKiCoJjFmPjAjEiBeC_xHqqkZx_
	struct _UNLOCK_REQ
	{
		_UNLOCK_REQ () : m_fdmtLastUnlockRequest(0) {}
		FDMILLISECTIME						m_fdmtLastUnlockRequest;		// _xZkqqHx_iNmFiMoDiCmJiJpAjFpKiDiBiDgCiDfKiBfLiDfHiCpAjBjHjFhEiClFiClNiOjOiKnEiCpAiLeMjIfOiBeC_xHqqkZx_
		map<FCTableName, FDMILLISECTIME>	m_mpUnlockReqDirToValidTime;	// _xZkqqHx_iDiNiDgCiDeOiJpAjFpKjHhGiLiBiCpAiOpDiCkPiCmEiCkCiCoJiDgFiBfLiDhFiDiL_xHqqkZx_->_xZkqqHx_iJpAjFpKiKpKiMmAiBeC_xHqqkZx_
	};
	FCCsAreaDef<_UNLOCK_REQ>				m_csaUnlockReq;
	typedef FCCsAreaRead<_UNLOCK_REQ>		ur_read;
	typedef FCCsAreaWrite<_UNLOCK_REQ>		ur_write;
	typedef FCCsAreaReadWrite<_UNLOCK_REQ>	ur_readwrite;

	// _THREAD_DATA:_xZkqqHx_iDhEiDiJiDgCiDfGiDiFiDfIiDiMiDgCiDgIiCnGiCmMiDgGiBfLiDfOiOpDiCkPjDgOiClFjHhAjFmPjAjEiBeC_xHqqkZx_
	//				_xZkqqHx_iOoFiCmJiDhEiDiJiDgCiDfGiDiFiDfIiDiMiDgCiDgIiBgJiDhEiDiJiDgCiDfGiDiFiOhHiOkGiOjOiCmJiDeOiDiJiDeDiDeBiDjDiDgHiDfIiDiMiDgCiDgIiBgKiCkJiCoHiMmEiCmOiCoKiCoJiBeC_xHqqkZx_
	struct _THREAD_DATA
	{
		_THREAD_DATA () :	m_hFlushThreadHandle(INVALID_HANDLE_VALUE),	// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFiDfIiDiMiDgCiDgIiCmMiDgOiDjDiDgIiDiLiBeC_xHqqkZx_
							m_hThreadEvent(INVALID_HANDLE_VALUE),		// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFiDfIiDiMiDgCiDgIiLoMjDkOiDeDiDhIiDjDiDgHiBeC_xHqqkZx_
// 06.03.15 Fukushiro M. 1_xZkqqHx_iNhDjCmHiJmB_xHqqkZx_ ()
							m_bIsTerminate(FALSE),						// _xZkqqHx_iDfIiDiMiDgCiDgIiPeJjHlJjHhGiLiBiCkKiCkAiCoJiCkJiBeI_xHqqkZx_
							m_bIsFlushing(FALSE),						// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFjCiGiCkJiCmHiCkEiCkJiCmMjElLjCoIjHhAiBeC_xHqqkZx_
							m_dsFlushErrorCode(0),						// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFjCiGiCmMiDeHiDiJiBfLiDfCiBfLiDgIiBeC_xHqqkZx_
							m_bMultiUserAccessable(TRUE)				// _xZkqqHx_jFkBjAjEiDiGiBfLiDfFiBfLiCkJiCoHjDkPiOjOiDeBiDeOiDfKiDfIiJmCjEfMiCmJiClHiCoJiCkJiBeI_xHqqkZx_
					{}

		HANDLE		m_hFlushThreadHandle;		// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFiDfIiDiMiDgCiDgIiCmMiDgOiDjDiDgIiDiLiBeC_xHqqkZx_
		HANDLE		m_hThreadEvent;				// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFiDfIiDiMiDgCiDgIiLoMjDkOiDeDiDhIiDjDiDgHiBeC_xHqqkZx_
// 06.03.15 Fukushiro M. 1_xZkqqHx_iNhDjCmHiJmB_xHqqkZx_ ()
		BOOL		m_bIsTerminate;				// _xZkqqHx_iDfIiDiMiDgCiDgIiPeJjHlJjHhGiLiBiCkKiCkAiCoJiCkJiBeI_xHqqkZx_
		BOOL		m_bIsFlushing;				// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFjCiGiCkJiCmHiCkEiCkJiCmMjElLjCoIjHhAiBeC_xHqqkZx_
		DsErr		m_dsFlushErrorCode;			// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFjCiGiCmMiDeHiDiJiBfLiDfCiBfLiDgIiBeC_xHqqkZx_
		WString		m_wstrFlushErrorMessage;	// _xZkqqHx_iDhEiDiJiDgCiDfGiDiFjCiGiCmMiDeHiDiJiBfLiDiBiDgCiDfKiBfLiDfHiBeC_xHqqkZx_

		vector<HString>	m_vTopDirPath;
		vector<BYTE*>	m_vTransaction;
		vector<size_t>	m_vTransactionSize;
		vector<FCTableName>	m_vWriteLockedTableName;
		BOOL			m_bMultiUserAccessable;		// _xZkqqHx_jFkBjAjEiDiGiBfLiDfFiBfLiCkJiCoHjDkPiOjOiDeBiDeOiDfKiDfIiJmCjEfMiCmJiClHiCoJiCkJiBeI_xHqqkZx_
	};
	FCCsAreaDef<_THREAD_DATA>				m_csaThreadData;
	typedef FCCsAreaRead<_THREAD_DATA>		td_read;
	typedef FCCsAreaWrite<_THREAD_DATA>		td_write;
	typedef FCCsAreaReadWrite<_THREAD_DATA>	td_readwrite;
}; // class FCDbServer.

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

#endif // !defined(AFX_DBSERVER_H__AF2FA33C_6798_4903_8952_598C6ACC1C7B__INCLUDED_)
