[SQLCE강좌] 6. MR 아키텍쳐와 구현 방법



안녕 하세요.
멍구 입니다.

여섯번째 강좌 시작 하겠습니다.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

MR 아키텍쳐

MR이란 DBMS의 병합 복제 기능을 이용하여 SQLCE와 동기화 하는 방법입니다.
MSSQL의 DB를 복제해서 SQLCE의 DB로 싱크받아 PDA에 저장하고 있는 것이지요.
SQLCE DB의 경우 하나의 DB가 하나의 물리적인 파일로 보관 됩니다.
보완을 위해 암호를 걸 수 도 있습니다.

사용자 삽입 이미지

위의 그림을 보면 가장 아래 SQL서버가 있고, 그 위에 SQL Server Reconciler는
저번 강좌에서 MR을 위한 SQL서버 셋팅 부분 입니다.

그 위에 SQL Server CE Server Agent는 ssceda20.dll로서
IIS에서 구동되는 ISAPI로 구현 되어있습니다.

Client영역의 SQL Server CE Client Agent는 PDA에 SQLCE를 설치하면서 등록한
DLL파일들입니다. 아마 ssceca20.dll라는 파일이 아닌가 생각 됩니다.
그 옆으로는 DB생성을 담당하는 SQL Server CE Database Engine이
있고, 그 아래 SQLCE의 실제 DB인 확장자가 sdf인 파일입니다.

이렇게 MR은 싱크를 받는 실제 Data를 Client( PDA )의 파일로 저장하게 됩니다.
그리고 필요에 따라 ADOCE를 통해 SQL Server CE Database에 접근해
SQL Server CE Database Engine를 사용하여 DB를 생성하거나
아니면 기 생성된 DB를 삽입/삭제 /추가 가 가능 합니다.


------------------------------------------------------------------

EVC로 MR구현

먼저 EVC를 실행하고 프로젝트를 하나 생성합니다.

사용자 삽입 이미지

여기서는 MRNorthwind라는 프로젝트를 생성하겠습니다.
간단하게 다이얼로그 베이스로 나머지 설정은 다 기본값을 넘어갑니다.

그렇게 생성된 프로젝트에서 코드를 보기 전에
먼서 EVT에서 몇가지 설정할 것이 있습니다.
설치한 SQLCE와 ADOCE를 연결하기 위한 과정입니다.

사용자 삽입 이미지

첫번째로 [Alt]-[F7]키를 눌러 Project setting 다이얼로그를 띄워 Link탭을 열어,
Obejct/library modules란에 ca_mergex20.lib를 입력합니다.

사용자 삽입 이미지

두번째로 Tools / Options 의 Options 다이얼로그를 띄워 Directories탭을 열어,
Show directorys의 Include Files로 맞추고, ADOCE와 SQLCE의 해더파일 경로를 맞춰줍니다

사용자 삽입 이미지

마찮가지로 Show directorys의 Library Files로 맞추고, ADOCE와 SQLCE의
해더파일 경로를 맞춰줍니다. 이때는 해당 PDA의 CPU타잎에 알맞는 경로를
지정해야 합니다.

만약 SQLCE를 설치하고 처음 작업하는 프로젝트라면 ADOCE 해더파일이 없습니다.
EVT를 설치한 C:\Program Files\Microsoft eMbedded Tools\EVC\WCE300\BIN
폴더를 열어보면 midl.exe라는 파일을
ADOCE가 설치 되어 있는 C:\Windows CE Tools\dataaccess31\include로
카피한후

>midl adoce31.idl
>midl adocec31.idl

위와 같이 실행하여 idl로 해더 파일을 생성해 주어야 합니다.
아래의 그림은 그 결과입니다.

사용자 삽입 이미지


사용자 삽입 이미지


리소스는 위 그림과 같이 구성합니다.
파란색 글씨는 해당 콘트롤의 ID입니다.

각 버튼의 클릭 이벤트 함수를 정의 합니다.

	afx_msg void OnBtnSync();
afx_msg void OnBtnSetList();

OnInitDialog()함수에 리스트롤 초기화 하는 코드를 삽입합니다.

#include <ca_mergex20.h>
#include <ADOCE31.H>

MRNorthwindDlg.cpp파일 윗부분에 SQLCE와 ADOCE를 사용하기 위해
include문을 추가 합니다..
      CListCtrl* pList = (CListCtrl*) GetDlgItem( IDC_LIST );
pList->InsertColumn( 0, L"ID", LVCFMT_CENTER, 50 );
pList->InsertColumn( 1, L"Name", LVCFMT_CENTER, 100 );
OnBtnSync()함수에 DB싱크를 하는 코드를 삽입합니다.
	ISSCEMerge* pCEMerge;
// SQLCE사용을 위한 COM 초기화
CoCreateInstance( CLSID_Replication, NULL,
CLSCTX_INPROC_SERVER, IID_ISSCEMerge,
(LPVOID*)&pCEMerge );
// 웹서버 접근을 위한 경로 및 권한 설정
pCEMerge->put_InternetURL( _T("http://192.168.0.2/mobile/sscesa20.dll") );
pCEMerge->put_InternetLogin( _T("") );
pCEMerge->put_InternetPassword( _T("") );
// SQL서버에 접속해 데이타를 동기화 시키기 위한 설정
pCEMerge->put_Publication( _T("Northwind") );
pCEMerge->put_PublisherDatabase( _T("Northwind") );
pCEMerge->put_Publisher( _T("TESTSERVER") );
pCEMerge->put_PublisherSecurityMode( (REPL_SECURITY_TYPE)DB_AUTHENTICATION );
pCEMerge->put_PublisherLogin( _T("sa") );
pCEMerge->put_PublisherPassword( _T("sa") );
// SQLCE에 싱크를 받아 저장하기 위한 설정
pCEMerge->put_Subscriber( _T("newtype") );
pCEMerge->put_SubscriberConnectionString( _T("Data Source = \\My Documents\\Northwind.sdf") );
pCEMerge->AddSubscription(CREATE_DATABASE);
// 각 설정을 반영한다.
pCEMerge->Initialize();
// 실제 동기화를 시작한다.
pCEMerge->Run();
// 사용한 자원 해제
pCEMerge->Terminate();
pCEMerge->Release();

위의 코드는 SQL서버와 동기화 부분입니다.
코드에 주석을 달아 그렇게 어렵지 않을 것입니다.
단, put_Subscriber의 인자 값을 조정하면 SQL서버의 필터링 설정에서
HOST_NAME()함수를 사용해 필터링기능을 사용할 수 있습니다.

이제 ADOCE를 사용하는 부분이 남았는데, ADOCE를 사용하는데 많이 불편합니다.
그래서 ADOCE를 조금은 편하게 사용할 수 있도록 만들어 놓은 클래스를 사용하겠습니다.
먼저 아래의 파일을 다른 이름으로 대상 저장을 해 프로젝트에 추가 합니다.


위의 클래스를 사용하깅 위해 include문을 추가 합니다..

#include "VORecordset.h"

OnBtnSetList()함수에 아래의 코드를 삽입합니다.

	CListCtrl*   pList = (CListCtrl*) GetDlgItem( IDC_LIST );
HRESULT hr;
CVORecordset rs;
CString strSQL = L"SELECT OrderID, ShipName FROM Orders";
hr = rs.Open( L"\\My Documents\\Northwind.sdf",
((BSTR)(LPCTSTR)strSQL),
adOpenKeyset, adLockOptimistic);
// 결과를 리스트에 넣는다.
for (int i=0; !rs.IsEOF(); i++)
{
pList->InsertItem( i, rs.GetFieldValueString( 0 ) );
pList->SetItemText( i, 1, rs.GetFieldValueString(1) );
rs.MoveNext();
}
rs.Close();

이제 컴파일 하여 실행해 봅시다.
처음에 실행을 하면 아래 그림과 같은 아무것도 없는 리스트가 나옵니다.
사용자 삽입 이미지

여기서 [Sync]버튼을 클릭하고
C:\Windows CE Tools\wce300\MS Pocket PC\emulation\palm300\My Documents
폴더를 열어 보면 Northwind.sdf파일이 생성된것을 볼 수 있습니다.
이 파일은 SQLCE파일로서 SQL서버에서 동기화을 받은 Orders테이블의 내용인것입니다.

이제 [List]버튼을 클릭합니다.

사용자 삽입 이미지

리스트에 내용이 채워지는 것을 볼 수 있습니다.

강좌의 전체 소스 받고 싶으시면
를 클릭하세요



이상으로 MR의 설명이 끝났습니다.
위와 같은 방법으로 MR을 사용하면 컴 객체 초기화등 여러 불편한 점이 많이 있습니다.
그래서 제가 MR을 조금은 쉽게 사용할 수 있도록 클래스를 만들 었습니다.
아래의 파일을 다른 이름으로 대상 저장 하여 사용 하시면 됩니다.


MRNorthwind2.exe

업데이트된 전체

-----------------------------------------------------------------

덧글

EVC를 에뮬에서 컴파일 하면 wincore에러가 나는 경우가 있습니다.
이것은 .NET계열의 IME와 충돌하는 것으로 별도 코드를 추가해야 합니다.

App객체에 PreTranslateMessage를 재정의 해 아래의 코드를 추가합니다.
BOOL CMRNorthwindApp::PreTranslateMessage(MSG* pMsg) 
{
#ifdef _WIN32_WCE_EMULATION
if( ! ::IsWindow(pMsg->hwnd))
return TRUE;
#endif
return CWinApp::PreTranslateMessage(pMsg);
}


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

이상으로 긴 여섯번째 강좌를 마칩니다.
강좌라는게 쉬운게 아니군요.
원래의 계획은 간단하게 코드만 설명하려 했는데..
아니다 싶어 일을 크게 벌려 놨더니 힘드네여.. ㅡㅡ;;
그래도 이제 끝이 보이네요.

다음 강좌는 RDA 아키텍쳐와 구현 방법에 대해 알아 보겠습니다.