Migrating from DataSnap to Data Abstract
Customers frequently ask us how to migrate from their legacy system to take full advantage of the advanced features in Data Abstract. Eugeny just finished a wiki article covering the ever popular move from DataSnap to Data Abstract. There is even a test case with source code to download. So pull out your legacy DataSnap applications and give them the upgrade you need so you can take advantage of all the great features of Data Abstract. I think you’ll be surprised how easy the migration can be, and happy you made the move!
Server-side
This legacy DataSnap server uses authentication, provides access to the Customer table from Employee.gdb and allows to call custom server methods. So the migrated Data Abstract server will contain two services: the LoginService that will check authentication and the DataService that will be the main service.
Creating Server.RODL in Service Builder
This can be done via RemObjects SDK->Turn the server into a RemObjects SDK Server
function EchoString(Value:WideString):WideString;function ReverseString(Value:WideString):WideString; |
Generation of files from RODL
Call RemObjects SDK->Regenerate Units from RODL. These files will be generated:
- NewLibrary_Intf.pas
- NewLibrary_Invk.pas
- LoginService_Impl.pas
- DataService_Impl.pas
ServerDataModule.pas
Create a new datamodule and drop to it:
- TROIndyHTTPServer
- TROBinMessage
- TROInMemorySessionManager
- TDADriverManager
- TDAConnectionManager
- TDAIBXDriver
Set this value in the Object Inspector:
DAConnectionManager1.DriverManager= DADriverManager1 |
procedure TDataModule1.DataModuleCreate(Sender:TObject);begin ROIndyHTTPServer1.Active:=True;end; |
Select LoginService_Impl.pas.
Add ServerDataModule into the uses section and set
LoginService.SessionManager= ServerDM.ROInMemorySessionManager1. |
procedure TLoginService.SimpleLoginServiceLogin(Sender:TObject; aUserID, aPassword: UTF8String; out aUserInfo: UserInfo;var aLoginSuccessful:Boolean);begin aLoginSuccessful :=(aUserID <;>;'')and(aUserID = aPassword);if aLoginSuccessful then CreateSession;end; procedure TLoginService.SimpleLoginServiceLogout(Sender:TObject);begin DestroySession;end; |
Select DataService_Impl.pas, drop
and set these properties in the ObjectInspector:
DataService.ServiceDataStreamer= DABin2DataStreamer1 DataService.ServiceSchema= DASchema1 DataService.SessionManager= ServerDM.ROInMemorySessionManager1 DataService.RequiresSession=True DASchema1.ConnectionManager= ServerDM.DAConnectionManager1 |
function TDataService.EchoString(const Value: UnicodeString): UnicodeString;begin Result := Value;end; function TDataService.ReverseString(const Value: UnicodeString): UnicodeString;begin Result := StrUtils.ReverseString(Value);end; |
Create a new connection to Employee.gdb and the CUSTOMER table:
Compile and launch the server.
The server side is ready now.
Client-side
The client side contains the login/logout buttons, a grid that shows a table and two buttons that call custom server methods.
Select client.dpr and add NewLibrary_Intf.pas from the server project to the client.dpr
ClientDataModule.pas
Add a new datamodule.
Drop
- TROWinInetHTTPChannel
- TROBinMessage
- TRORemoteService
- TDARemoteDataAdapter
- TDABin2DataStreamer
- TDAVCLReconcileProvider
and set these properties in the Object Inspector:
ROWinInetHTTPChannel1.TargetURL= http://localhost:8099/bin RORemoteService1.Channel= ROWinInetHTTPChannel1 RORemoteService1.Message= ROBinMessage1 RORemoteService1.ServiceName= DataService DARemoteDataAdapter1.DataStreamer= DABin2DataStreamer1 DARemoteDataAdapter1.RemoteService= RORemoteService1 DARemoteDataAdapter1.ReconcileProvider= DAVCLReconcileProvider1 |
MainForm.pas
Add NewLibrary_intf and ClientDataModule into the uses section. Replace the old methods in the MainForm:
procedure TForm2.Button1Click(Sender:TObject);begin DataModule1.tbl_CUSTOMER.Close; DataModule1.tbl_CUSTOMER.Open;end; procedure TForm2.Button2Click(Sender:TObject);begin DataModule1.tbl_CUSTOMER.ApplyUpdates;end; procedure TForm2.Button3Click(Sender:TObject);begin ShowMessage((DataModule1.RORemoteService1as IDataService).EchoString(Edit3.Text));end; procedure TForm2.Button4Click(Sender:TObject);begin ShowMessage((DataModule1.RORemoteService1as IDataService).ReverseString(Edit3.Text));end; procedure TForm2.Button5Click(Sender:TObject);beginifnot CoLoginService.Create(DataModule1.ROBinMessage1,DataModule1.ROWinInetHTTPChannel1).LoginEx(UTF8Encode(Format('UserID=%s;Password=%s',[Edit1.Text,Edit2.Text])))then showMessage('Problems with login');end; procedure TForm2.Button6Click(Sender:TObject);begin DataModule1.tbl_CUSTOMER.Close; CoLoginService.Create(DataModule1.ROBinMessage1,DataModule1.ROWinInetHTTPChannel1).Logout;end; |
P.S.: Don’t forget to remove the old datasnap units from projects.