> ## Content Index
> Fetch the complete content index at: https://blogs.remobjects.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Migrating from DataSnap to Data Abstract
- URL: https://blogs.remobjects.com/2012/05/23/migrating-from-datasnap-to-data-abstract/
- Published: 2012-05-23T17:43:57.000Z
- Updated: 2018-08-22T06:17:42.000Z
- Author: jim
- Tags: #Import 2026-08-17 20:17

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](http://wiki.remobjects.com/wiki/Migrating%5Ffrom%5Fa%5FDataSnap%5Fapplication%5Fto%5FData%5FAbstract?ref=blogs.remobjects.com). There is even a [test case with source code to download](http://rorox.remobjects.com/wiki/Migrating%20from%20a%20DataSnap%20application%20to%20Data%20Abstract%5Ftestcase.zip?ref=blogs.remobjects.com). 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](http://wiki.remobjects.com/wiki/Service%5FBuilder?ref=blogs.remobjects.com)

This can be done via *RemObjects SDK->Turn the server into a RemObjects SDK Server*

\[!\[TurnServerIntoRemObjectsSDKServer.png\](http://wiki.remobjects.com/w/images/f/fd/TurnServerIntoRemObjectsSDKServer.png)\](http://wiki.remobjects.com/wiki/File:TurnServerIntoRemObjectsSDKServer.png)After confirmation, \[Service Builder\](http://wiki.remobjects.com/wiki/Service\_Builder "Service Builder") will be launched. For correct work, these two services should be created as descendants of base DataAbstract services. For this, DataAbstract4.RODL should be imported into server.RODL:\[!\[SB UseExistingRODL DataAbstract.png\](http://wiki.remobjects.com/w/images/8/87/SB\_UseExistingRODL\_DataAbstract.png)\](http://wiki.remobjects.com/wiki/File:SB\_UseExistingRODL\_DataAbstract.png)After this, two new services should be created: the Loginservice with SimpleLoginService as the ancestor and the DataService with DataAbstractService as the ancestor. Also create two operations in DataService:

| function EchoString(Value:WideString):WideString;function ReverseString(Value:WideString):WideString; |
| ----------------------------------------------------------------------------------------------------- |

\[!\[SB server rodl.png\](http://wiki.remobjects.com/w/images/5/57/SB\_server\_rodl.png)\](http://wiki.remobjects.com/wiki/File:SB\_server\_rodl.png)Close \[Service Builder\](http://wiki.remobjects.com/wiki/Service\_Builder "Service Builder").

## 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](http://wiki.remobjects.com/wiki/TROIndyHTTPServer%5FClass?ref=blogs.remobjects.com)
- [TROBinMessage](http://wiki.remobjects.com/wiki/TROBinMessage%5FClass?ref=blogs.remobjects.com)
- [TROInMemorySessionManager](http://wiki.remobjects.com/wiki/TROInMemorySessionManager%5FClass?ref=blogs.remobjects.com)
- [TDADriverManager](http://wiki.remobjects.com/wiki/TDADriverManager%5FClass?ref=blogs.remobjects.com)
- [TDAConnectionManager](http://wiki.remobjects.com/wiki/TDAConnectionManager%5FClass?ref=blogs.remobjects.com)
- **TDAIBXDriver**

Set this value in the Object Inspector:

| DAConnectionManager1.DriverManager\= DADriverManager1 |
| ----------------------------------------------------- |

Click on ROIndyHTTPServer1.Dispatchers in the ObjectInspector and add a new dispatcher.\[!\[ROIndyHTTPServer BinDispatcher.png\](http://wiki.remobjects.com/w/images/5/52/ROIndyHTTPServer\_BinDispatcher.png)\](http://wiki.remobjects.com/wiki/File:ROIndyHTTPServer\_BinDispatcher.png)Also create an onCreate event:

| procedure TDataModule1.DataModuleCreate(Sender:TObject);begin ROIndyHTTPServer1.Active:\=True;end; |
| -------------------------------------------------------------------------------------------------- |

\## LoginService\_Impl.pas

Select LoginService\_Impl.pas.

Add ServerDataModule into the uses section and set

| LoginService.SessionManager\= ServerDM.ROInMemorySessionManager1. |
| ----------------------------------------------------------------- |

in the Object Inspector. Two events are required in this unit:

| 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; |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

\## DataService\_Impl.pas

Select DataService\_Impl.pas, drop

- [TDASchema](http://wiki.remobjects.com/wiki/TDASchema%5FClass?ref=blogs.remobjects.com)
- [TDABin2DataStreamer](http://wiki.remobjects.com/wiki/TDABin2DataStreamer%5FClass?ref=blogs.remobjects.com)

and set these properties in the ObjectInspector:

| DataService.ServiceDataStreamer\= DABin2DataStreamer1 DataService.ServiceSchema\= DASchema1 DataService.SessionManager\= ServerDM.ROInMemorySessionManager1 DataService.RequiresSession\=True DASchema1.ConnectionManager\= ServerDM.DAConnectionManager1 |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

Copy the content of these methods from ServerMethodsUnit1.pas:

| function TDataService.EchoString(const Value: UnicodeString): UnicodeString;begin Result :\= Value;end; function TDataService.ReverseString(const Value: UnicodeString): UnicodeString;begin Result :\= StrUtils.ReverseString(Value);end; |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

Double-click on DASchema1 and \[Schema Modeler\](http://wiki.remobjects.com/wiki/Schema\_Modeler "Schema Modeler") will be launched.

Create a new connection to Employee.gdb and the CUSTOMER table:

\[!\[DASM IBX Customer.png\](http://wiki.remobjects.com/w/images/6/6d/DASM\_IBX\_Customer.png)\](http://wiki.remobjects.com/wiki/File:DASM\_IBX\_Customer.png)Close \[Schema Modeler\](http://wiki.remobjects.com/wiki/Schema\_Modeler "Schema Modeler").

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](http://wiki.remobjects.com/wiki/TROWinInetHTTPChannel%5FClass?ref=blogs.remobjects.com)
- [TROBinMessage](http://wiki.remobjects.com/wiki/TROBinMessage%5FClass?ref=blogs.remobjects.com)
- [TRORemoteService](http://wiki.remobjects.com/wiki/TRORemoteService%5FClass?ref=blogs.remobjects.com)
- [TDARemoteDataAdapter](http://wiki.remobjects.com/wiki/TDARemoteDataAdapter%5FClass?ref=blogs.remobjects.com)
- [TDABin2DataStreamer](http://wiki.remobjects.com/wiki/TDABin2DataStreamer%5FClass?ref=blogs.remobjects.com)
- [TDAVCLReconcileProvider](http://wiki.remobjects.com/wiki/TDAVCLReconcileProvider%5FClass?ref=blogs.remobjects.com)

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 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

Click on “Create Data Tables…” in the popup menu of DARemoteDataAdapter1\. The Login Screen will be shown. Type \*UserID=test;Password=test\* in aLoginString and create the CUSTOMERS table in the next dialog.

## 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; |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

And the client side is ready.

P.S.: Don’t forget to remove the old datasnap units from projects.