Post: Migrando do BDE, DBExpress e AnyDac para FireDac

Alessandro Medeiros

Compartilhar no whatsapp
Compartilhar no facebook
Compartilhar no twitter
Compartilhar no linkedin
Compartilhar no facebook

Fala ai Radizeiro e Radizeiras, tudo bom com vocês?

Quantas vezes você já tentou migrar sua Middle de acesso a dados para o FireDac, e acabou desistindo achando que irá levar horas e fazendo com que seu tempo fique perdido.

Você possui o Rad Studio atualizado e seu projeto encontra-se ainda nos primórdios da programação.

Pensando em você a Embarcadero disponibilizou uma ferramenta de linha de comando para ajudar em suas migrações, estou falando o reFind.

O que é esse tal de reFind?

O reFind é uma ferramenta de linha de comando baseado em expressões regulares e pode processar arquivos de texto arbitrários para substituir ocorrências de certos padrões de texto, como por exemplo referencias a units em cláusulas “uses” e tipos de componentes nas declarações de classe.

Sua utilização é bem simples e irei demonstrar usando o próprio exemplo que acompanha o RAD Studio, e este exemplo que irei usar será do DBX para FireDac, estou usando a versão mais recente do Delphi CE, que encontra-se C:\Users\Public\Documents\Embarcadero\Studio\19.0\Samples\Object Pascal\Database\FireDAC\Tool\reFind\DBX2FDMigration.

Na pasta do exemplo existe um arquivo chamado FireDAC_Migrate_DBX.TXT, este arquivo informa para o aplicativo reFind tudo que é para ser feito, veja um pouco da estrutura deste arquivo.


#unuse Data.SqlExpr
#unuse Data.DBXCommon
#unuse Data.DBConnAdmin
#unuse Data.DBXDynalink
#unuse SqlExpr
#unuse DBXCommon
#unuse DBConnAdmin
#unuse DBXDynalink

...

// Driver units -------------------------------------------------------------------------------
#migrate Data.DbxDb2 -> FireDAC.Phys.DB2
#migrate Data.DbxFirebird -> FireDAC.Phys.FB
#migrate Data.DbxInformix -> FireDAC.Phys.Infx
#migrate Data.DbxInterbase -> FireDAC.Phys.IB
#migrate Data.DbxMSSQL -> FireDAC.Phys.MSSQL
#migrate Data.DbxMySql -> FireDAC.Phys.MySQL
#migrate Data.DbxOdbc -> FireDAC.Phys.ODBC
#migrate Data.DbxOracle -> FireDAC.Phys.Oracle
#migrate Data.DbxSqlite -> FireDAC.Phys.SQLite
#migrate Data.DbxSybaseASA -> FireDAC.Phys.ASA
#migrate Data.DbxSybaseASE -> FireDAC.Phys.ODBC

// Generic types -------------------------------------------------------------------------------
#migrate TDBXIsolation -> TFDTxIsolation, FireDAC.Stan.Option
#migrate TDBXIsolations.ReadCommitted -> xiReadCommitted, FireDAC.Stan.Option
#migrate TDBXIsolations.RepeatableRead -> xiRepeatableRead, FireDAC.Stan.Option
#migrate TDBXIsolations.DirtyRead -> xiDirtyRead, FireDAC.Stan.Option
#migrate TDBXIsolations.Serializable -> xiSerializible, FireDAC.Stan.Option
#migrate TDBXIsolations.SnapShot -> xiSnapshot, FireDAC.Stan.Option

...

Repare que tudo que precisa ser feito para alterar classes, métodos, propriedades, eventos, etc será feito pelo reFind. Ele irá remover uses antigas do DBExpress, alterar as units necessárias para invocar as classes FireDAC, trocar enumerados, remover métodos do DBX que não existem no FD e muito mais, tudo isso num simples comando. Durante a execução o reFind gera um arquivo .bak para cada um dos arquivos que ele alterar caso você precisa verificar algo ou voltar a versão anterior.

No exemplo existe um arquivo chamado migrate.bat

Vamos dar uma olha nesse arquivo


cd Forms
md FireDAC_MeetingOrg
del /Q FireDAC_MeetingOrg\*.*
copy *.* FireDAC_MeetingOrg\*.*
reFind.exe FireDAC_MeetingOrg\*.pas FireDAC_MeetingOrg\*.dfm FireDAC_MeetingOrg\*.fmx /X:..\..\FireDAC_Migrate_DBX.txt

Esse script cria uma pasta e copia todos os arquivos para essa pasta criada, e na ultima linha ele executa o reFind, neste ponto ele “vasculha” todos os arquivos .pas, .dfm e .fmx, seguido do parâmetros /X: e o arquivo com as instruções.

Observe que após executarmos o migrate.bat ele realiza a alteração onde os arquivo que estão marcado como Modified.

Horas atrás

Observe o projeto antes da migração.

Veja como está as units do dataModule que contem o SQLConnection.


uses
SysUtils, Classes, DB, SqlExpr, WideStrings, DBXDynalink, Data.DBXInterBase;

type
TMainDM = class(TDataModule)
SQLConnection: TSQLConnection;
procedure DataModuleCreate(Sender: TObject);
procedure SQLConnectionBeforeConnect(Sender: TObject);

...

procedure TMainDM.DataModuleCreate(Sender: TObject);
begin
if not SQLConnection.Connected then
SQLConnection.Open;
TMainForm(Application.MainForm).DBConnection := SQLConnection;
end;

procedure TMainDM.SQLConnectionBeforeConnect(Sender: TObject);
begin
SQLConnection.LoadParamsFromIniFile
(IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)) +
'dbxconnections.ini');
end;

Veja o código do dataModule com os demais componentes DBX


uses
System.UITypes, SysUtils, Classes, FMTBcd, DBClient, Provider, DB, SqlExpr;

type
TAbstractDataModule = class(TDataModule)
    sqlControl: TSQLDataSet;
    dspControl: TDataSetProvider;
    cdsControl: TClientDataSet;
    procedure DataModuleCreate(Sender: TObject);
    procedure cdsControlBeforeDelete(DataSet: TDataSet);
    procedure cdsControlBeforeRefresh(DataSet: TDataSet);
    { published section explicit here for didactic purpose only }
published
    procedure cdsApplyUpdates(DataSet: TDataSet);
    procedure cdsCancelUpdates(DataSet: TDataSet);
    procedure cdsReconcileError(DataSet: TCustomClientDataSet;
        E: EReconcileError; UpdateKind: TUpdateKind;
        var Action: TReconcileAction);
    strict private
    fDBConnection: TSQLConnection;
    function GetDBConnection: TSQLConnection;
    procedure SetDBConnection(value: TSQLConnection);
    { Private declarations }
public
    { Public declarations }
    property DBConnection: TSQLConnection read GetDBConnection
        write SetDBConnection;
    procedure CheckRequiredFields(DataSet: TDataSet);
    function GenerateID(Gen: string): Integer;
end;

...

function TAbstractDataModule.GenerateID(Gen: string): Integer;
var
    sqlID: TSQLQuery;
begin
    sqlID := TSQLQuery.Create(nil);
    sqlID.SQLConnection := TMainForm(Application.MainForm).DBConnection;
    try
        sqlID.SQL.Add('SELECT GEN_ID(' + Gen + ', 1) AS ID');
        sqlID.SQL.Add(' FROM RDB$DATABASE');
        sqlID.Open;

        if sqlID.RecordCount > 0 then
            Result := sqlID.FieldByName('ID').AsInteger
        else
            Result := -1;
    finally
        sqlID.Free;
    end;
end;

Veja agora depois da migração como os nossos dataModules ficaram e o código.

Você pode observar que o componente foi alterado para TFDConnection mas manteve a nomenclatura.

Veja como ficou o código.


uses
    SysUtils, Classes, DB, WideStrings, FireDAC.Phys.IB,
    FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf,
    FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async,
    FireDAC.Phys, FireDAC.Comp.Client, FireDAC.DBX.Migrate;

type
    TMainDM = class(TDataModule)
        SQLConnection: TFDConnection;
        procedure DataModuleCreate(Sender: TObject);
        procedure SQLConnectionBeforeConnect(Sender: TObject);

...

procedure TMainDM.DataModuleCreate(Sender: TObject);
begin
    if not SQLConnection.Connected then
        SQLConnection.Open;
    TMainForm(Application.MainForm).DBConnection := SQLConnection;
end;

procedure TMainDM.SQLConnectionBeforeConnect(Sender: TObject);
begin
    SQLConnection.LoadParamsFromIniFile
    (IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)) +
    'dbxconnections.ini');
end;

Observe que onde estava o DBX foram alteradas para o FireDac, até foi incluida novas units referente ao FireDac.

Veja o outro dataModule

Assim também foi feito no outro dataModule, que alterou para TFDQuery o componente anterior.

veja o mesmo código só que com as alterações.


uses
    System.UITypes, SysUtils, Classes, FMTBcd, DBClient, Provider, DB,
    FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf,
    FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async,
    FireDAC.Phys, FireDAC.Comp.Client, FireDAC.DBX.Migrate, FireDAC.Stan.Param,
    FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.DataSet;

type
    TAbstractDataModule = class(TDataModule)
        sqlControl: TFDQuery;
        dspControl: TDataSetProvider;
        cdsControl: TClientDataSet;
        procedure DataModuleCreate(Sender: TObject);
        procedure cdsControlBeforeDelete(DataSet: TDataSet);
        procedure cdsControlBeforeRefresh(DataSet: TDataSet);
        { published section explicit here for didactic purpose only }
    published
        procedure cdsApplyUpdates(DataSet: TDataSet);
        procedure cdsCancelUpdates(DataSet: TDataSet);
        procedure cdsReconcileError(DataSet: TCustomClientDataSet;
            E: EReconcileError; UpdateKind: TUpdateKind;
            var Action: TReconcileAction);
    strict private
        fDBConnection: TFDConnection;
        function GetDBConnection: TFDConnection;
        procedure SetDBConnection(value: TFDConnection);
        { Private declarations }
    public
        { Public declarations }
        property DBConnection: TFDConnection read GetDBConnection
            write SetDBConnection;
        procedure CheckRequiredFields(DataSet: TDataSet);
        function GenerateID(Gen: string): Integer;
    end;

...

function TAbstractDataModule.GenerateID(Gen: string): Integer;
var
    sqlID: TFDQuery;
begin
    sqlID := TFDQuery.Create(nil);
    sqlID.Connection := TMainForm(Application.MainForm).DBConnection;
    try
        sqlID.SQL.Add('SELECT GEN_ID(' + Gen + ', 1) AS ID');
        sqlID.SQL.Add(' FROM RDB$DATABASE');
        sqlID.Open;

        if sqlID.RecordCount > 0 then
            Result := sqlID.FieldByName('ID').AsInteger
        else
            Result := -1;
    finally
        sqlID.Free;
    end;
end;

Observe que tudo que era relacionado ao componente DBX sofreram alterações para o FireDac.

Com isso nosso pequeno exemplo passa a funcionar usando o FireDac, com apenas uma linha de comando todo o projeto é migrado para o FireDac.

E agora você achava que iria sofrer para migrar para o FireDac.

Não precisa mais se preocupar, seguindo esse exemplo e adaptando para o seu cenário, irá ter todo seu projeto legado que usava DBX para o FireDac sem dor de cabeça.

 

 

Técnicas Avançadas de Delphi

Se você quer ter todas as técnicas necessárias para que possa alavancar seus conhecimentos em Delphi, é esse o treinamento perfeito para você.

Neste treinamento criei um mix de conteúdo sobre as mais avançadas técnicas de desenvolvimento em Delphi.

Nesse treinamento eu reuni as minhas melhores aulas dos meus mais diversos treinamento para entregar  para você um conteúdo que vai direto ao ponto, para que você não perca tempo e nem dinheiro na hora de aprender Delphi.

Dê um salto de qualidade na sua carreira e no seu produto!

Neste treinamento você terá os seguintes módulos:

  • Qualidade de Código
  • Boas Práticas de Programação
  • Padrões de Projeto
  • Dicas e Truques
  • Firemonkey
  • Mobile
  • VCL

Dê um salto de qualidade na sua carreira e no seu produto.

CLIQUE AQUI PARA SABER MAIS SOBRE O TREINAMENTO DE TÉCNICAS AVANÇADAS DE DELPHI





Faça sua busca

CATEGORIAS

POSTS RECENTES

E caso você tem interesse de conhecer mais sobre Migrando do BDE, DBExpress e AnyDac para FireDac, acesse o nosso portal do CLUBE DE PROGRAMADORES EM DELPHI
Você não terá só conteúdos relacionados ao Migrando do BDE, DBExpress e AnyDac para FireDac, mas uma quantidade enorme de conteúdos que poderá lhe ajudar muito no seu dia a dia, é uma verdadeira NETFLIX para os programadores Delphi.
Gostou?
Compartilhe:
Compartilhar no whatsapp
Compartilhar no facebook
Compartilhar no twitter
Compartilhar no linkedin
Compartilhar no facebook

Embarque no foguete com milhares de devs para aprender desenvolvimento, evoluir de forma contínua e se manter relevante no mercado.

Sobre
Dúvidas
Cadastre-se em nossa lista

Para ter acesso em primeira mão, a tudo que acontece na Academia do Código, basta se cadastrar em nossa lista

Grupo Thulio Bittencourt | Academia do Código

#FaçaPartedaHistória

Copyright © 2021 – Todos os direitos reservados