Foi criado o processo “Administração do sistema > Base de dados > Tabelas e Índices” com
o objetivo de exibir informações e estatísticas da tabelas e índices da base de dados. Mais
informações no manual
Tabelas e índices.
O processo “Administração do sistema > Scripts agendados > Agendador de scripts” passa a exibir o
progresso dos scripts em execução caso eles tenham informado algum progresso via API
Progress.
O processo “Administração do sistema > Servidores > Servidores” passa a alertar o usuário quando
os endereços “localhost” ou “127.0.0.1” são utilizados. Esses endereços não devem ser utilizados,
pois podem referenciar destinos diferentes dependendo da origem da requisição, podendo causar
falhas de conexão ou alterações indevidas em outro Engine.
Engine
O construtor da classe CriticalSection passa a aceitar como parâmetro o nome único de
identificação da seção crítica. Quando informado no construtor, deixa de ser necessário informar
o nome repetidamente nas chamadas aos métodos enter e leave, simplificando o uso da API e
reduzindo a possibilidade de erros relacionados à inconsistência do nome da seção crítica.
A criação de instâncias de CriticalSection nomeadas passa a ser a forma recomendada de uso
da API e a instância global compartilhada criticalSection passa a ser considerada obsoleta,
embora ainda seja mantida para fins de compatibilidade. Para os cenários de uso onde é complexo
manter instâncias de CriticalSection, foram criados os métodos estáticos enter, tryEnter e
leave que possuem funcionamento similar ao uso da instância global compartilhada, recebendo
o nome da seção crítica como primeiro parâmetro. Mais detalhes na
documentação JSDoc.
Foi criado o método
CriticalSection.prototype.tryEnter
com o objetivo de tentar entrar em uma seção crítica dentro de um tempo limite especificado,
retornando um valor booleano indicando se a entrada foi bem-sucedida ou não. O método enter
também passa a aceitar um tempo limite opcional, mas, no caso desse último método, é gerado um
erro caso o tempo limite seja atingido.
O sistema passa a interromper a espera por uma seção crítica caso a execução de um runtime
JavaScript seja abortada ou se for solicitada a finalização do Engine.
Durante a finalização do Engine, passam a ser registrados no log o status das requisições e
sessões JavaScript ativas que estão impedindo o encerramento do sistema.
A classe
XMLHttpRequest
passa a utilizar uma biblioteca embarcada TLS para conexões HTTPS em vez de depender da
implementação nativa do sistema operacional, tornando o comportamento da API mais consistente e
seguro nos sistemas operacionais suportados pelo Engine. Foi criada a opção useNativeTls
no construtor da classe XMLHttpRequest com o objetivo de permitir reativar a implementação
nativa do sistema operacional, caso ela seja necessária por questões de compatibilidade.
Foi criado o módulo
randomUUID
com o objetivo de gerar UUIDs (Universally Unique Identifiers) na versão 4. O seu uso passa a
ser recomendado em vez do módulo createGUID, que tem uma implementação dependente do sistema
operacional.
O Engine passa a suportar paths longos (superiores a 260 caracteres) no Windows por meio do
manifesto longPathAware. Para que esse suporte seja efetivo, é necessário que o Windows esteja
configurado para habilitar o suporte a paths longos conforme descrito na
documentação oficial da Microsoft.
Caso o suporte a paths longos não esteja ativo no Windows, é possível utilizar o prefixo UNC
estendido \\?\ nos paths informados à classe File para contornar a limitação de 260 caracteres.
Defeitos corrigidos
Desenvolvimento
O processo “Desenvolvimento > Atualização > Atualização de tabelas” realizava um filtro indevido
no lookup do campo “Classes” quando o campo “Produtos” estava preenchido.
Engine
O método JSON.stringify do runtime Ije serializava os valores NaN, Infinity e -Infinity
da exata maneira que são escritos, em vez de substituir por null, contrariando a especificação
ECMAScript. Isso poderia causar falhas ao processar a saída do método JSON.parse na
integração com sistemas externos que seguem a especificação.
A alteração de DataSets poderia falhar caso eles fossem indexados por campos do tipo 'date'.
Campos do tipo 'datetime', que é o tipo atualmente utilizado para representar colunas
do tipo DATE do banco de dados, não eram afetados por esse problema.
Ao abrir a página inicial do sistema, o Engine poderia ignorar a configuração do
navegador padrão do Windows.
A página Requests do Manage não exibia corretamente o usuário autenticado na
execução das rotas HTTP.
O DataSet poderia ficar em um estado inconsistente caso fosse informado um range com
valores incompatíveis com os tipos dos campos indexados. Operações de navegação após a
tentativa de alterar o range poderiam gerar o erro “Access Violation”.
Tarefas gravadas por meio do método Connection.prototype.newTask poderiam apresentar
o valor “31/12/1899” como data da próxima execução caso não fosse informada uma data de forma
explícita na criação da tarefa. Essa falha não impedia a execução da tarefa, no entanto,
ela dificultava o monitoramento e a gestão das tarefas agendadas.
A barra de status da IDE do Engine poderia apresentar valores fracionários como
se fossem chaves caso a parte inteira do valor fosse igual a uma chave existente.
O módulo
getDistinctValues
poderia desconsiderar o range aplicado ao DataSet informado.
Web Framework
O botão de selecionar todos os registros da grade Lookup poderia ficar desabilitado
indevidamente quando a propriedade readOnly do campo era informada com os valores
ReadOnlyMode.FILLED, ReadOnlyMode.AFTER_INSERT ou ReadOnlyMode.ONEDIT.
Não era possível selecionar os registros da grade Lookup para inserção múltipla, opção
habilitada pela propriedade
allowMultipleInsert,
caso o campo fosse somente leitura.
Ao executar o método
Audio.prototype.play
durante a execução de uma activity ocorria o erro “Cannot read properties of undefined”. O
sistema agora passa a reproduzir o áudio, desde que a instância de Audio seja escrita na
próxima interação. Caso ela não seja, o comando será ignorado.
Ao recolher e reexpandir um nó de uma grade em árvore, o alinhamento horizontal dos campos
subsequentes poderia não ser preservado.
A inicialização do Web Framework poderia falhar caso o script “ufs:/uwi/all.js” fosse carregado
em um script de inicialização de sessão ou do roteador HTTP. É importante reforçar que os
scripts “ufs:/uwi/all.js” e “ufs:/uwl/all.js” são mantidos apenas para fins de compatibilidade e
seu uso não é recomendado. Esses scripts carregam códigos desnecessários, em especial em cenários
onde o Web Framework não é utilizado, como no caso das rotas HTTP.
Ao escrever um Label dentro de um elemento oculto (display: none) ocorria o erro
“Label ‘undefined’ não foi encontrado no processo”.
A opção de “Exibir mais resultados” no diálogo de pesquisa não funcionava corretamente
para os resultados das consultas realizadas no banco de dados.
O desbloqueio de sessão por meio de provedores de identidade externos poderia falhar
caso fosse utilizado um balanceador de carga que não informasse o protocolo de origem das
requisições.
A gravação de um registro em uma grade via tecla Enter poderia falhar caso o último campo deste
registro não fosse editável.
A barra de ferramentas da grade detalhe poderia mudar de foco para a grade mestre ao inserir um
novo registro na grade detalhe utilizando a tecla Enter.
O sistema poderia sinalizar indevidamente a necessidade da troca de senhas das contas de suporte.
Ao tentar localizar um valor em um campo da grade poderia ocorrer o deslocamento do foco
da interface para um campo diferente do pesquisado.
Outras alterações
Engine
O timeout padrão dos métodos open, ping e receiveMessage da classe
WebSocket
passa a ser de 30 segundos caso não seja especificado um valor para o parâmetro timeout, adotando
assim o mesmo comportamento padrão da classe XMLHttpRequest.
O uso da classe CriticalSection deixa de ser permitido em filtros JavaScript de DataSets.
Foi removida a propriedade Database.prototype.userLanguage que era obsoleta e não estava
mais em uso. É recomendado que scripts que utilizem o campo iLanguage das tabelas
iGroupUser e iVfs sejam revistos para eliminar a leitura e manipulação desse campo,
pois ele será removido em uma versão futura.
Foram eliminados os construtores das classes EmailMessageHeader e EmailMessagePart. Elas
passam a ser instanciadas apenas pelo Engine por meio dos métodos e propriedades da
classe EmailMessage.