Migrating from BDE to FireDAC

In my last blog I explained about FireDAC, its features and how it will help our Delphi Application’s performance improvements. But still lots of Delphi Applications are using BDE, IBExpress and ADO for DB connectivity and for data access. So when we migrate a Delphi application from old version to new version, I think we should also migrate data accesss components to FireDAC. So in this blog I will explain how to migrate a simple client-server application using BDE data access components, such as TDatabaseTQueryTTable, to the FireDAC. It shows the basic principles of replacing the common components, properties and code, preserving the developers working time and avoiding the common migration pitfalls. Delphi makes migration over the decades relatively painless, however, this doesn’t mean effortless!.

So lets start in steps.

1. Units Changed

We need to replace used BDE units to FireDAC units.
Find 
DBTables   or  Bde.DBTables
Replace
         FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Phys, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.Client, FireDAC.Comp.DataSet

2. BDE components classes compatible with FireDAC

Search BDE classes and replace with FireDAC classes

 BDE
 FireDAC
TSession
TFDManager
TDatabase
TFDConnection
TTable
TFDTable
TQuery
TFDQuery
TStoredProc
TFDStoredproc
TUpdateSQL
TFDUpdateSQL
TBatchMove
TFDDatamove

3. Other Types classes changed

Search BDE classes and replace with FireDAC classes

 BDE
 FireDAC
TParams
TFDParams
TBlobStream
TFDBlobStream
TBDEDataSet
TFDRDBMSDataSet

4. BDE Exception class change

Search BDE classes and replace with FireDAC classes

 BDE
 FireDAC
EDBEngineError
EFDDBEngineException

5. TSession -> TFDManager Properties

Search BDE classes and replace with FireDAC classes

 BDE
 FireDAC
AutosessionName
Not Supported so remove.
KeepConnection
ResourceOptions.KeepConnection
NetFileDir
Not Supported so remove.
PrivateDir
Not Supported so remove.
SessionName
Not Supported so remove.
  
6. TDatabase -> TFDConnection Properties

Search BDE classes and replace with FireDAC classes

 BDE
 FireDAC
AliasName
ConnectionDefName
DatabaseName
ConnectionName
Exclusive
Not Supported so remove.
HandleShared
Not Supported so remove.

Note. Please check LibHandle at runtime.

SessionName
Not Supported so remove.
KeepConnection
ResourceOptions.KeepConnection
Readonly
UpdateOptions.Readonly

Note* - OnLogin Event

Tdatabase.OnLogin event is different than TFDConnection.OnLogin. So we should remove Tdatabase event and re-write TFDConnection Event.

7. TTable -> TFDTable Properties

Search BDE classes and replace with FireDAC classes

 BDE
 FireDAC
Autorefresh
UpdateOptions.RefreshMode = onDemand
DatabaseName
ConnectionName

Connection

Note. Please replace with Connection for better understanding.
Exclusive
Not Supported so remove.
Readonly
UpdateOptions.Readonly
TableType
Not Supported so remove.
UpdateMode
UpdateOptions.UpdateMode
SessionName
Not Supported so remove.

8. TQuery -> TFDQuery Properties

Search BDE classes and replace with FireDAC classes

 BDE
 FireDAC
Autorefresh
UpdateOptions.RefreshMode = onDemand
DatabaseName
ConnectionName

Connection

Note. Please replace with Connection for better understanding.

Datasource
MasterSource

Note. Please check MasterFields

ParamCheck
ResourceOptions.Paramcreate
Requestlive
UpdateOptions.Requestlive
Unidirectional
UpdateOptions.Unidirectional
UpdateMode
UpdateOptions.UpdateMode
SessionName
Not Supported so remove.

9. TStoredProc -> TFDStoredProc Properties

Search BDE classes and replace with FireDAC classes

 BDE
 FireDAC
Autorefresh
UpdateOptions.RefreshMode = onDemand
DatabaseName
ConnectionName

Connection

Note. Please replace with Connection for better understanding.

SessionName
Not supported so remove

10. Sorting

FireDAC components like TFDQuery, TFDTable does not have Sort property. So we have to use IndexFieldNames property for sorting. So where ever we have used Sort for sorting in our project we need to replace with IndexFieldNames like follow.

ADQuery1.IndexFieldNames := 'ORDERID';
or
ADQuery1.IndexFieldNames := 'OrderDate:D;Price'; //D for descending//

11. TBookMark Changes for Dataset components

When we save a bookmark for future use we must use pointer for

var
BookMark : Pointer;
CDS : TClientDataset
……
// Required so your assignment doesn't attempt to free a non-existent bookmark //
 Bookmark := nil;
 TBookmark(Bookmark) := CDS.GetBookmark;

12. Data Property

If we use TFDQuery and ClientDataset together then Data property is mostly used to assign saved data to any other dataset component directly instead of using any loop. Here TFDQuery have also Data property but type is different. Earlier in TADOQuery or other Query component, Data property was OleVariant type which was same type like ClientDataset but now it is IFDDataSetReference.

So we cannot just assign directly like.
//will result an error //
Clientdataset1.Data := FDQuery.Data; 

Above code will compile successfully but will result “Invalid data packet” error at runtime.

In this scenario we have to use TDatasetProvider as mediator to transfer data from once dataset to another. We can use DatasetProvider.Data property like follow.

DataSetProvider1.Dataset := FDQuery1;
FdQuery1.Open;
Clientdataset1.data := DatasetProvider1.data;

13. Extra points to check

Need to change some numeric fields to TBCDFields when it will show error and set Size=2 when in Database field type is like number(15,2)

Comments

Popular posts from this blog

ShellExecute in Delphi

MS Excel Automation in Delphi

Drawing Shapes in Delphi