Neste tópico vou mostrar como realizar a comparação entre duas revisões (do mesmo objeto ou de objetos diferentes) usando a ferramenta WinMerge de uma forma prática.
Primeiramente, é preciso entender que o WinMerge é uma ferramenta de comparação de texto, e portanto precisaremos ter os objetos formatados em texto plano.
Para facilitar o nosso trabalho, vamos utilizar o estado serializado do objeto que fica salvo nas Revisões do Controle de Versão do LATROMI.
Essa implementação será realizada usando um Extrator de Arquivos, que vai receber como parâmetro os dados dos objetos a serem comparados, gerando um arquivo .ps1
. Quando este arquivo for baixado pelo usuário bastará executá-lo para fazer a comparação.
O banco de dados usado neste exemplo é o PostgreSQL.
Preparando o Ambiente
-
Certifique-se de que a extensão de arquivo
.ps1
esteja liberada no IIS. Mais informações neste link. -
Certifique-se de que o PowerShell esteja instalado no computador que vai baixar o arquivo para fazer a comparação dos objetos. O PowerShell é necessário para executar os scripts
.ps1
.Para verificar se o PowerShell está instalado, basta digitar
powershell
no prompt de comando: -
Execute o arquivo
.bat
a seguir como administrador para permitir que o PowerShell execute os scripts e para defini-lo como programa padrão para abrir os arquivos.ps1
:@ECHO OFF REM Obtem informacoes necessarias para configuar o tipo de arquivo ".ps1" FOR /f "tokens=3" %%a IN ('REG QUERY "HKEY_CLASSES_ROOT\.ps1" ^|findstr /ri "REG_SZ"') DO SET file_type=%%a FOR /f "tokens=3" %%a IN ('REG QUERY "HKEY_CLASSES_ROOT\%file_type%\Shell" ^|findstr /ri "REG_SZ"') DO SET default_command=%%a REM Define o Powershell como programa padrao para abrir/executar arquivos ".ps1" ECHO Confirando chave de registro ECHO HKEY_CLASSES_ROOT\%file_type%\Shell\%default_command%\Command REG Add "HKEY_CLASSES_ROOT\%file_type%\Shell\%default_command%\Command" /ve /d "powershell \"%%1\"" /f ECHO. REM Desbloqueia a execucao de scripts nao-assinados ECHO Confirando politicas do Powershell powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted ECHO. ECHO Fim PAUSE
-
Instale o WinMerge no computador que vai fazer a comparação dos objetos.
Extrator de Arquivos
Crie um novo extrator de arquivos, e adicione os seguintes Parâmetros:
Nome | Descrição |
---|---|
objA_UpgradeCode | Código de Atualização do primeiro objeto (esq.) |
objA_Revision | Número da Revisão do primeiro objeto (esq.) |
objB_UpgradeCode | Código de Atualização do segundo (dir.) |
objB_Revision | Número da Revisão do segundo objeto (dir.) |
Na Fonte de Dados, selecione a conexão “LATROMI” e informe o comando SQL abaixo:
WITH
-- Retorna informações do arquivo A
file1 AS
(
SELECT
g.upgradecode,
r.revisionid AS revision,
format('%s-r%s.%s', g.upgradecode, r.revisionid, CASE WHEN r.objectserialization LIKE '<%' THEN 'xml' ELSE 'json' END) AS name,
r.objectserialization AS content
FROM wecdb.globalidmapping g
LEFT JOIN wecdb.revisiondetails r ON r.objectglobalid = g.id AND r.revisionid = {?PARAM objA_Revision} -- Revisão
WHERE g.upgradecode = '{?PARAM objA_UpgradeCode}' -- Código de Atualização
),
-- Retorna informações do arquivo B
file2 AS
(
SELECT
g.upgradecode,
r.revisionid AS revision,
format('%s-r%s.%s', g.upgradecode, r.revisionid, CASE WHEN r.objectserialization LIKE '<%' THEN 'xml' ELSE 'json' END) AS name,
r.objectserialization AS content
FROM wecdb.globalidmapping g
LEFT JOIN wecdb.revisiondetails r ON r.objectglobalid = g.id AND r.revisionid = {?PARAM objB_Revision} -- Revisão
WHERE g.upgradecode = '{?PARAM objB_UpgradeCode}' -- Código de Atualização
),
powershell AS (
SELECT
$$
# Modifica a codificacao para UTF-8
CHCP 65001
# Criar diretorio onde os arquivos serao extraidos
$working_directory = [System.IO.Path]::GetTempPath() + "\WinMerge Comparison\" + [guid]::NewGuid().Guid
$left_filename = "{{filename1}}"
$right_filename = "{{filename2}}"
$unpacker = "{{plugin}}"
Write-Host "Criando pastas..."
mkdir -Force $working_directory
mkdir -Force "$working_directory\Files"
Write-Host "Extraindo arquivos em $working_directory"
$left_file = @"
{{file1}}
"@
$right_file = @"
{{file2}}
"@
$project_file=@"
<?xml version="1.0" encoding="UTF-8"?>
<project>
<paths>
<left>Files\$left_filename</left>
<right>Files\$right_filename</right>
<unpacker>$unpacker</unpacker>
</paths>
</project>
"@
Add-Content "$working_directory\Files\$left_filename" $left_file
Add-Content "$working_directory\Files\$right_filename" $right_file
Add-Content "$working_directory\project.WinMerge" $project_file
Invoke-Item "$working_directory\project.WinMerge"
$$::TEXT script
)
SELECT
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(script, '{{filename1}}', file1.name),
'{{filename2}}', file2.name),
'{{plugin}}', CASE WHEN file1.name LIKE '%.xml' THEN 'PrettifyXML' ELSE 'PrettifyJSON' END),
'{{file1}}', file1.content),
'{{file2}}', file2.content) AS content,
-- Gera nome para o arquivo .bat
CASE WHEN file1.upgradecode = file2.upgradecode THEN
format('%s/WinMergeCompare-%s.r%s_x_r%s.ps1', TO_CHAR(CURRENT_TIMESTAMP, 'YYMMDDHH24MISS'), file1.upgradecode, file1.revision, file2.revision)
ELSE
format('%s/WinMergeCompare-%s.r%s_x_%s.r%s.ps1', TO_CHAR(CURRENT_TIMESTAMP, 'YYMMDDHH24MISS'), file1.upgradecode, file1.revision, file2.upgradecode, file2.revision)
END AS filename,
'UTF-8' AS encoding
FROM file1, file2, powershell
Nas Configurações, relacione as colunas da seguinte maneira:
Campo | Coluna |
---|---|
Conteúdo do Arquivo | content |
Nome do Arquivo | name |
Codificação do Arquivo | encoding |
Salve e está pronto! Agora basta chamar o Extrator de Arquivos onde você precisar, como por exemplo, em uma Consulta.
Você também pode chamar diretamente pela URL do extrator de arquivos para testar:
http://site.dominio.com.br/web/downloadfile/{Codigo de Atualização do Extrator}/
?_objA_upgradeCode={valor}
&_objA_revision={valor}
&_objB_upgradeCode={valor}
&_objB_revision={valor}
Sobre o arquivo .ps1
Se você não estiver interessado em saber o que faz o arquivo .ps1
, pode pular essa etapa.
Caso tenha interesse, saiba que ele realiza as seguintes operações:
-
Cria um diretório temporário em:
{pasta temporário do windows}\WinMerge Comparison\{valor aleatório}
-
Salva a serialização dos objetos (XML ou JSON) em arquivos físicos, na pasta temporária criada acima.
-
Cria um arquivo de projeto do WinMerge (
.WinMerge
), com a seguinte estrutura:<?xml version="1.0" encoding="UTF-8"?> <project> <paths> <left>{Caminho do arquivo 1}</left> <right>{Caminho do arquivo 2}</right> <unpacker>{Plugin desempacotador de XML ou JSON}</unpacker> </paths> </project>
-
Executa o arquivo de projeto do WinMerge criado acima.
Considerações Finais
Esta solução passou por alguma modificações até chegar ao estágio atual.
Inicialmente, era utilizado apenas um arquivo .bat
, mas quando a extração envolvia arquivos muito grandes, estes arquivos acabavam sendo “cortados”.
Fora isso, a performance do PowerShell para fazer a extração dos arquivos se mostrou muito superior.