Windows 10 Store, Android, iOS, OS X, Linux: recursos para migrar sua aplicação Delphi/C++ Builder e suportar TODAS as plataformas (parte 5)

Estamos na quinta parte desta coletânea de artigos e tutoriais para migração de aplicações Delphi e C++ Builder, e hoje vamos falar sobre componentes de terceiros. Caso não os tenha encontrado, os artigos anteriores podem ser encontrados nos seguintes links:

Componentes e bibliotecas de terceiros são sempre um assunto polêmico.

Em muitas ocasiões, são a salvação quando precisamos de uma solução rápida para algo não contemplado nativamente pelo produto, ou ainda que vai lhe exigir um bom tempo de codificação, do qual você não dispõe.

Por outro lado, podem render uma boa dor de cabeça se não os tratamos de maneira adequada, com todo o gerenciamento e controle que você aplica ao seu próprio código fonte.

Eis uma lista – incompleta – dos problemas mais comuns relacionados a sua utilização, sejam componentes comerciais ou Open Source:

  • o componente acaba sendo descontinuado por qualquer razão, e você não tem o código fonte dos mesmos
  • o fornecedor tarda em disponibilizar uma versão atualizada, e isso está retardando seu processo de migração para uma versão mais recente do compilador
  • o componente é ótimo em uma determinada plataforma, mas não possui uma solução similar para suportar múltiplas plataformas

Ainda assim, os benefícios em se utilizar algumas soluções especializadas em seu projeto, o tempo salvo em codificação, a certeza de estar utilizando algo já amplamente provado, e a satisfação de seu cliente com a solução de alto nível e extremamente profissional que você está apresentando, em grande parte das vezes, não tem preço.

Então, se sua decisão é por utilizar componentes externos, tenho aqui algumas sugestões para você – novamente uma lista incompleta:

  • Revise uma vez mais os componentes e bibliotecas nativas, e tenha certeza que o framework nativo não cobre suas necessidades
  • Revise uma vez mais se você (ou seu cliente) realmente necessita do recurso em questão. Será que ele (cliente) realmente espera este recurso, ou você achou aquele Label piscante que gira 360 graus a coisa mais incrível do mundo?
  • Sempre que possível, obtenha o código-fonte do componente, e o versione em seu repositório, juntamente com o projeto – mesmo que o pacote seja de código aberto e encontre-se público no Github ou similar. Você nunca sabe quando o “dono” do projeto vai mudar de ideia.
  • Optando por utilizar um componente sem o código-fonte, tenha certeza tratar-se de um fornecedor consolidado e  conhecido no mercado. Observe para quantas versões do produto ele já disponibilizou o componente, e qual seu compromisso com novas releases. Pergunte pelo seu roadmap.
  • Fornecedores de componentes para múltiplas plataformas costumam ser  bastante estáveis.
  • Parcimônia é a palavra chave ao pensar em componentes de terceiros. Lembre-se que todo exagero é ruim, praticamente em todas as áreas da vida e da programação 😉

Encontrando seus Componentes

Num processo de migração, a etapa zero é tomar a nova versão da IDE, e instalar todos os componente utilizados na versão atual de seu projeto.

A grande novidade nesta área é o GetIT. Trata-se de um gerenciador de pacotes integrado na IDE (lançado a partir do XE8), o qual disponibiliza e instala automaticamente uma vasta quantidade de componentes, comerciais e de código aberto.

800px-getitwindow

Mas e seu componente não pode ser encontrado no GetIt? A lista de componentes disponíveis é boa, mas obviamente não compreende todo o universo de possibilidades.

Para este cenário, além do bom e velho Google… existem alguns bons repositórios disponíveis:

Se você deseja contribuir com esta lista, envie sua sugestão, seja sobre um único componente ou um repositório, provavelmente será útil para outros desenvolvedores!

 

 

Advertisements

Windows 10 Store, Android, iOS, OS X, Linux: recursos para migrar sua aplicação Delphi/C++ Builder e suportar TODAS as plataformas (parte 4)

Estamos na quarta parte desta coletânea de artigos e tutoriais para migração de aplicações Delphi (e também C++ Builder).

Iniciamos por uma visão geral de projetos de migração (parte 1), passamos por impactos do Unicode (ou não) em projetos Delphi e C++ (parte 2), e também por compilação nativa 64 bit, disponível desde o XE2 (parte 3).

Hoje vamos abordar migração de frameworks de acesso a dados, ou seja, BDE, ADO, DBX, IBX, e tantos outros disponíveis.

Iniciando pelo saudoso BDE, este framework de acesso a dados possui algumas características que o diferenciam de todos os demais. O BDE pode ser considerado – guardadas as devidas proporções – um middleware. Isto porque, para funcionar, o BDE necessita de uma instalação completa no sistema operacional onde seu projeto será executado, o que não ocorre com nenhum outro framework Delphi ou C++. Ele possui dlls as quais são responsáveis pelo acesso aos mais diversos banco de dados, em um processo que ocorre de maneira externa ao espaço de memória e ao processo alocado pela aplicação. Complicou? Então vamos detalhar isso um pouco mais…

Por tratar-se de um processo externo a sua aplicação, algo como uma camada adicional carregada no momento em que uma conexão com o banco de dados é estabelecida pela primeira vez por esta aplicação, o BDE permitia algumas “peripécias” não suportadas por outro frameworks, como por exemplo:

  • O BDE permitia facilmente suportar múltiplos banco de dados, de maneira quase transparente, isso graças a esta camada intermediária, que fazia a “conversação” com cada um dos banco de dados suportados, e entregava uma resposta homogênea para sua aplicação. Na prática, sua aplicação não sabia efetivamente a qual banco de dados estava  conectado, digamos assim.
  • O BDE, por tratar-se de um processo externo a sua aplicação, permitia as aplicações compartilharem uma mesma conexão com o banco de dados entre distintos executáveis. Basicamente, tudo o que você tinha que fazer era utilizar um “handle” compartilhado e voilà, podemos ter uma aplicação modularizada em distintos executáveis em uma mesma máquina compartilhando da mesma conexão ao banco de dados.

Outros frameworks, como DBX, também apresentação dlls externas, porém as mesmas não representam um processo externo a sua aplicação, ao contrário, são carregadas no espaço de memória do executável principal, não permitindo o compartilhamento da conexão.

Os demais, como o FireDAC, são código 100% Pascal ou C++, e são compilados efetivamente com sua aplicação, não possuindo drivers externos de qualquer espécie, sendo uma enorme vantagem no deployment e também em aplicações multiplataforma.

De todos eles, o FireDAC aparece com o melhor framework disponível atualmente para acesso a dados, sendo disparado a melhor opção para migração de BDE, já que ele “imita” o comportamento do mesmo, exceção feita ao compartilhamento de uma conexão entre executáveis distintos, o que pode ser solucionado de outras maneiras (utilização de BPLs, multicamadas, pool de conexões, etc.).

FireDAC possui características que nenhum outro framework oferece, seja no mundo Delphi e C++ Builder, seja em qualquer ambiente de desenvolvimento, como .NET ou Java. Um deles é o suporte a consultas SQL em bases de dados heterogêneas, em resumo, fazer uma Join entre Oracle e SQL Server e um arquivo XML, para citar um exemplo apenas.

Migrando seu Projeto

Existem muitas formas de se migrar um projeto, algumas mais eficientes que ouras, mas você não vai encontrar uma receita mágica. Existem sim alguns recursos realmente úteis e de alta produtividade, os quais vou resumir abaixo.

Iniciando por conhecer melhor o FireDAC, recomendo estes webinars, gravado para a série Delphi Academy:

  1. Acesso a Dados com FireDAC
  2. FireDAC Cached Updates
  3. FireDAC DataSets em Memória
  4. FireDAC Local SQL Cache
... algumas horas depois...

Agora que você já conhece o beabá do FireDAC, a migração efetiva pode ser facilitada em muito com a utilização de um utilitário chamado reFind.exe. Trata-se de um executável de linha de comando, o qual – com a ajuda de expressões regulares – vai fazer um parser em seu projeto, de acordo com configurações que você vai determinar em um arquivo de script, e substituir o antigo framework pelo FireDAC.

Felizmente, já faz parte do pacote de exemplos que a ferramenta traz, scripts para migração de BDE e DBX, ambos para FireDAC. Mas observe que, baseado nos scripts existentes, e na documentação, você será capaz de criar seu próprio script, e migrar qualquer outro framework ou componente, não há nada no reFind criado especialmente para o FireDAC, neste caso o FireDAC é um caso de uso do reFind.

Detalhes sobre o reFind você pode encontrar nestes links da documentação:

http://docwiki.embarcadero.com/RADStudio/Berlin/en/Migrating_dbExpress_Applications_to_FireDAC
http://docwiki.embarcadero.com/RADStudio/Berlin/en/ReFind.exe,_the_Search_and_Replace_Utility_Using_Perl_RegEx_Expressions

Mas também tenho um tutorial completo de migração em um dos episódios do Academy, onde algumas técnicas e recursos adicionais são discutidos:

Bem, por hoje é o que temos ;-). Espero que estes recursos sejam úteis de alguma forma, e no próximo – e último artigo da série – vamos explorar a migração de componentes de terceiros.

Até lá!

 

Windows 10 Store, Android, iOS, OS X, Linux: recursos para migrar sua aplicação Delphi/C++ Builder e suportar TODAS as plataformas (parte 2)

Na primeira parte deste artigo (aqui) exploramos os principais desafios na migração de projetos Delphi/C++ Builder, listamos alguns tópicos que vamos tratar ao longo de uma série de artigos, e iniciamos o entendimento da parte teórica sobre Unicode.

Neste post vamos retomar o assunto Unicode, porém de um ponto de vista mais técnico, buscando compreender as alterações que são necessárias (ou não) em um projeto.

Vale ressaltar que o suporte a Unicode foi introduzido no Delphi/C++ Builder 2009, portanto, projetos compilados em versões 2009+ não devem sofrer qualquer impacto no tocante a Unicode durante um processo de migração.

O que mudou?

A partir da versão 2009 (inclusive), o tipo String passou a ser definido pelo tipo UnicodeString, que é uma string UTF-16. Da mesma forma, o tipo Char é agora WideChar, um tipo de caractere de dois bytes e PChar é um PWideChar, um ponteiro para um Char de dois bytes.

O ponto significativo sobre as alterações a esses tipos de dados básicos é que, no mínimo, cada caractere é representado por pelo menos um “code unit” (dois bytes), e às vezes mais.

Coincidente com essas mudanças é que o tamanho de uma sequência de caracteres, em bytes, não é mais igual ao número de caracteres na sequência de caracteres. Da mesma forma, um valor do tipo Char não é mais um único byte; são dois bytes.

Opção #1: Mantenha tudo em seu lugar

Uma das opções com relação a Unicode é simplesmente não fazer nada. Isso mesmo… ou na verdade… quase isso. Nas versões anteriores a 2009, o tipo String era então mapeado para AnsiString. Logo, reverter as declaração de String para AnsiString pode ser uma alternativa para uma migração rápida – caso você não necessite suportar caracteres estendidos. O que precisa ser feito, na verdade, é converter declarações String para AnsiString, Chars para AnsiChars e PChars para PAnsiChars.

Para auxiliar nesta tarefa, um membro do Australian Delphi Users Group (ADUG) – Roger Connell – criou um convertor para pesquisar seus arquivos  Delphi (.pas e .dpr) e fazer as conversões, se essa abordagem funciona para você:http: /www.innovasolutions.com.au/delphistuf/ADUGStringToAnsiStringConv.htm

Obviamente, mesmo reduzindo as mudanças ao mínimo, testar e validar sua aplicação previamente a enviá-la para um ambiente de produção, continua sendo uma recomendação mandatória.

Opção #2: Abraçando o Unicode de vez

O Unicode incentiva o uso de alguns novos termos. Por exemplo, a idéia de “caractere” é um pouco menos preciso no mundo do Unicode do que você pode estar acostumado. No Unicode, o termo mais preciso é “code point”. A partir da versão 2009, o SizeOf (Char) é 2. Dependendo da codificação, é possível que um determinado caractere ocupe mais de dois bytes. Estas sequências são chamadas de “Surrogate Pairs“. Assim, um “code point” é um código exclusivo atribuído a um elemento definido pelo Unicode.org. Mais comumente isso é um “caractere”, mas nem sempre.

String agora é igual a UnicodeString, logo suas suposições anteriores sobre o tamanho em bytes de uma matriz de caracteres ou sequência de caracteres podem agora estar incorretas.

Procure qualquer código que:

  • Pressupõe que SizeOf (Char) é 1.
  • Pressupõe que o comprimento de uma sequência de caracteres é igual ao número de bytes na sequência de caracteres.
  • Diretamente manipula sequências de caracteres ou PChars.
  • Grava e lê strings em algum tipo de armazenamento persistente.

As duas suposições listadas aqui primeiro não são verdadeiras para Unicode, porque para Unicode SizeOf (Char) é maior que 1 byte, e o comprimento de uma sequência de caracteres é metade do número de bytes.

Além disso, o código que grava ou lê a partir de armazenamentos persistentes precisa garantir que o número correto de bytes estão sendo gravados ou lidos, uma vez que um caractere pode não ser mais capaz de ser representado como um único byte.

Compreendidas estas alterações, temos um sem números de ótimos documentos e tutoriais para se aprofundar no tema Unicode, os quais estou listando abaixo, porém gostaria de chamar a atenção para uma ferramenta em especial, o Unicode Statistics Tool. Este pequeno utilitário tem a capacidade de revisar seu código e dizer onde e o que você provavelmente vai ter que mudar. Obviamente, trata-se de um auxiliar e não uma ferramenta mágica, mas ajudará muito!

Recursos Adicionais