Visão Geral
Atualmente, o contexto de conexão com o banco de dados do Formulário é definido a nível de Objeto.
Trabalhar com um contexto único de conexão é uma excelente prática para criar fronteiras de dados, deixando clara a origem e o destino das informações. No entanto, em cenários de integração de sistemas, essa restrição se converte em um gargalo de complexidade; o desenvolvedor acaba sendo forçado a criar múltiplos Objetos apenas para acessar bancos de dados distintos, ou precisa recorrer a scripts complexos em C# para contornar a limitação dentro de um mesmo objeto.
Para simplificar a modelagem e potencializar a integração de dados relacionais, implementaremos uma melhoria estrutural no objeto Formulário, permitindo o uso de múltiplas conexões dentro do seu contexto. Essa alteração trará impacto direto e adicionará o suporte à seleção de conexão nas seguintes ações de procedimento:
- Carregar Registro.
- Carregar Conjunto de Registros.
- Executar Código SQL.
Interface de usuário
Ao planejar alterações de interface, nossa prioridade é realizar a menor mudança de layout possível para acomodar os novos recursos. O objetivo dessa abordagem é preservar a memória motora dos usuários e evitar uma nova curva de aprendizado.
Seguindo essa premissa, a principal alteração visual deste recurso ocorrerá na janela de configuração do comando. Incluiremos, logo antes do campo Limite, um campo de seleção (Dropdown/ComboBox) para que o usuário defina qual conexão deseja utilizar para o comando que será executado.
Para garantir a fluidez na modelagem e a retrocompatibilidade de Formulários já existentes, este novo campo virá preenchido, por padrão, com a conexão principal do Formulário – aquela já definida nas configurações originais do Objeto.
Comportamento
O objetivo final deste recurso é permitir abrir um ou mais conexões usando um único objeto. Sendo assim, alguns comportamentos são esperados:
-
Gerenciamento das transações entre as conexões:
Podendo ser aberto mais de uma conexão é necessário se atentar em como as transações paralelas irão se comportar durante a execução dos eventos. Alguns cenários que podem ser adicionados no escopo de teste, que ajudem a tirar alguns dados:'Conexão A' preenchendo campos e gravando na 'conexão B'e'Conexão A e B' atualizando registro, mas erro de execução na 'conexão B'. [nota: Durante o desenvolvimento podem ser observado cenários mais precisos que deem dados para gerar informação sobre o comportamento do recurso] -
Inclusão da conexão como dependência:
A conexão deixando de estar vinculada diretamente ao Formulário, torna necessário o Objeto conhecer as conexões possíveis. Sendo assim, precisaremos adicionar as conexões como uma dependência de Objeto. [nota: Esse processo não pode ser gerenciado diretamente pelo usuário, sendo adicionado/removido automaticamente] -
Gerenciamento de pacote:
A geração/importação de pacote (.lcp) também é afetada pelo recurso. Nela será necessário alterar a versão do XML gerado para o Formulário incluindo a informação de quais conexões são usadas pelo Objeto.
Agora que compreendemos o escopo de atuação deste recurso, é fundamental detalhar o seu fluxo de execução e como os componentes interagem nos bastidores.
O ponto de partida deste fluxo é a Escolha e Interpretação da conexão diretamente na Janela de Comando. A partir dessa seleção, ocorre uma interação direta com a Dependências de Objetos: ao vincular ou remover o uso de uma conexão em uma ação, o sistema deve registrar ou excluir automaticamente essa dependência na estrutura do Formulário.
Por fim, o Gerenciamento de Pacotes sofre uma interação indireta, mas essencial. Durante a geração de um pacote, deverá ser garantido que o XML contenha todas as referências das múltiplas conexões utilizadas pelo Objeto. Da mesma forma, no momento da importação, o processo interpretará esses dados para reconstruir os vínculos corretamente no ambiente de destino.
Inclusão de dependência
O recurso de dependência de objeto permite ao desenvolvedor informar manualmente uma dependência que não está explicitamente criada no objeto. saiba mais
Aproveitando essa interface, vamos centralizar o gerenciamento das dependências do Objeto nesta mesma tela. Para viabilizar isso, implementaremos uma melhoria no recurso atual, que adiciona o suporte a dependências fixas. Essas dependências serão rastreadas e injetadas automaticamente pelo sistema, e não poderão ser removidas pelo usuário. O objetivo é reaproveitar a interface existente para fornecer uma visão transparente, unificada e completa de todos os componentes dos quais o Objeto alvo depende.
Estrutural
No arquivo de pacote (LCP), a seção que armazena essas informações está localizada na tag <DependencesXml>. Atualmente, o conteúdo dessa tag carrega um valor textual de um XML serializado, criando uma camada dupla de serialização desnecessária.
<DependencesXml>
{OUTRO_XML_SERIALIZADO}
</DependencesXml>
Deverá ser feito uma refatoração estrutural neste arquivo para remover a camada extra de serialização/desserialização. A nova abordagem gerará uma estrutura XML concreta e tipada, utilizando nativamente a classe LATROMI.Types.ObjectReferences.
resultado esperado:
<references>
<!-- dependence items -->
</references>
Como impacto direto dessa mudança, será necessário ajustar o localizador de dependências da plataforma para identificar e processar corretamente a nova estrutura de referências. Além disso, é indispensável a criação de uma camada de Adapter simples no processo de importação. Essa camada garantirá a retrocompatibilidade, permitindo que a plataforma continue lendo e importando LCPs legados que ainda utilizam a estrutura antiga de XML embutido.
Nota: Verificar a possibilidade de usar
LATROMI.BLL.Fixers.FormFixerpara ajustar a retrocompatibilidade.
Gerenciamento programático de dependências
Diferente das referencias incluídas manualmente pelo desenvolvedor, as dependências fixas são manipuladas diretamente pelo sistema, quando um Objeto ou recurso é adicionado no escopo de dependências do Objeto em questão.
A alteração desta etapa deverá ocorrer principalmente no componente DependenceControl, que deverá incluir uma abertura para manipular os itens presentes na Grid, por fonte externas e também devem ser incluídos eventos no componente para poder ser replicado em locais que estejam diretamente ligados a esta logica.
Alterações no interpretador
Esta é uma etapa crucial da implementação. Até o momento, os ajustes descritos ocorreram a nível de modelagem e configuração dos metadados. Agora, precisamos definir como o motor do LATROMI interpretará e processará essas informações durante a execução em tempo real, especificamente nas ações Carregar Registro, Carregar Conjunto de Registros e Executar Código SQL.
Essas três ações terão uma camada semelhante de processamento para gerenciar o novo contexto de múltiplas conexões. O interpretador deverá ser adaptado para garantir os seguintes pilares operacionais:
-
Ciclo de Vida da Conexão:
Assegurar a identificação e abertura correta da conexão selecionada na ação, garantindo o fechamento e a devolução adequada ao pool de conexões após o término do escopo. -
Gerenciamento de Transações:
Controle rigoroso dos comandos de Commit e Rollback. As transações devem respeitar o limite de suas respectivas conexões, lidando corretamente com sucessos ou falhas paralelas sem vazar escopo de uma conexão para outra. -
Rastreabilidade e Logs:
O sistema de geração de logs de execução deverá ser enriquecido. Passa a ser obrigatório registrar explicitamente qual conexão foi utilizada para disparar o comando, facilitando auditorias e o debug por parte dos desenvolvedores.
Gerenciamento de pacote
A estrutura do arquivo de pacote (LCP) sofrerá um impacto indireto com a implementação deste recurso. Será necessário ajustar as lógicas de exportação e importação para garantir a integridade dessas novas dependências:
-
Geração de Pacote:
Incluirá a Tag dereferencesna estrutura do XML nos objetos deFormulárioeConsulta. -
Importação de Pacote:
Deverá validar a existência das conexões exigidas pelo pacote no ambiente de destino. Caso identifique conexões ausentes, o sistema alertará quais vínculos não foram encontrados ao fim da importação e a mesma será concluída utilizando uma estratégia de fallback. As ações que dependiam da conexão inexistente serão automaticamente redirecionadas para utilizar a conexão da janela de importação.

