Configurar o PDI 9.4 no macOS (x86)

A versão 9.4 é a última de código aberto e está presente no repositório do brew.

Fazendo a instalação do data-integration pelo brew ou baixando e descompactando o arquivo em pasta local, uma pequena alteração é necessária para fazer o PDI (spoon) abrir.

  • Copie o arquivo “Data Integration.app” para a pasta /Applications
  • Edite o arquivo “/Applications/Data Integration.app/Contents/MacOS/JavaApplicationStub” e corrija o BASE_DIR para apontar para a pasta do data-integration

O aplicativo deverá aparecer no Launchpad mas também pode ser executado via linha de comando:

/Applications/Data\ Integration.app/Contents/MacOS/JavaApplicationStub

Configurar COLLATE e CTYPE no PostgreSQL

Ao instalar um novo serviço de servidor PostgreSQL as opções de COLLATE e CTYPE podem estar fora da configuração ideal.

Não é possível alterar essas opções em bancos já criados. Uma solução é fazer um backup, criar o banco com as opções desejadas e restaurar o banco na sequencia.

Para deixar as opções no estado padrão desejado, execute o script abaixo.

ALTER database template1 is_template=false;

DROP database template1;

CREATE DATABASE template1
WITH OWNER = postgres
   ENCODING = 'UTF8'
   TABLESPACE = pg_default
   LC_COLLATE = 'en_US.UTF-8'
   LC_CTYPE = 'en_US.UTF-8'
   CONNECTION LIMIT = -1
   TEMPLATE template0;

ALTER database template1 is_template=true;

Adicionar script sh como aplicativo no macOS

Podemos transformar qualquer arquivo executável .sh em um app dentro do desktop macOS, incluindo ícone e atalho no dock.

  1. certificar que o arquivo sh possui o atributo de executável
  2. criar um script com o comando [ do shell script “sh ~/pasta/arquivo.sh” ]
  3. salvar o script
  4. exportar o script para formato de arquivo como aplicativo (isso vai gerar um arquivo .app)
  5. abrir a janela de obter informações do arquivo .app gerado
  6. arrastar e soltar o ícone na parte superior esquerda da janela de informações
  7. copiar o arquivo .app para a pasta de aplicativos
  8. abrir o aplicativo e fixar o atalho no dock

Trocando o dono (OWNER) de todas tabelas de um banco de dados PostgreSQL

Eventualmente podemos nos defrontar uma um banco de dados cujas tabelas possuem diferentes donos (alguma falta de padrão no momento da criação).

O script abaixo troca o dono para o desejado. Deve ser executado dentro do banco alvo.

SELECT format(
          'ALTER TABLE public.%I OWNER TO novo_dono',
          table_name
       )
FROM information_schema.tables
WHERE table_schema = 'public'
  AND table_type = 'BASE TABLE' \gexec

Seleção global dos elementos da coluna em tabelas html

Em casos onde temos mais de uma coluna com o recurso de seleção global dentro de uma tabela html, podemos usar o exemplo abaixo para controlar qual elemento foi selecionado.

<th data-sortable="false" width="150px" class="text-danger">
    <input class="form-check-input" type="checkbox" id="chkSelectAllRem" />
    <label for="chkSelectAllRem">Todas/Nenhuma</label>
</th>
<th data-sortable="false" width="150px" class="text-success">
    <input class="form-check-input" type="checkbox" id="chkSelectAllEnc" />
    <label for="chkSelectAllEnc">Todas/Nenhuma</label>
</th>

...

<td>
    <div class="form-check">
        <input class="form-check-input" type="checkbox" name="op_rem[]" value="<?= $row->id_pr_ordens ?>"
               id="op_rem.<?= $row->id_pr_ordens ?>">
        <label class="form-check-label text-danger" for="op_rem.<?= $row->id_pr_ordens ?>">Remover</label>
    </div>
</td>
<td>
    <div class="form-check">
        <input class="form-check-input" type="checkbox" name="op_enc[]" value="<?= $row->id_pr_ordens ?>"
               id="op_enc.<?= $row->id_pr_ordens ?>" />
        <label class="form-check-label text-success" for="op_enc.<?= $row->id_pr_ordens ?>">Encerrar</label>
    </div>
</td>

...

<script>
$("th input[type='checkbox']").on("change", function() {
    // remove seleção de todos checkboxes
    $('input[type="checkbox"]').not(this).prop("checked", false);
    // seleciona todos os elemento da coluna selecionada
    var cb = $(this), // checkbox that was changed
        th = cb.parent(), // get parent th
        col = th.index() + 1; // get column index. note nth-child starts at 1, not zero
    $("tbody td:nth-child(" + col + ") input").prop("checked", this.checked); // select the inputs and [un]check it
});

$(document).ready(function() {
    // uncheck other boxes on the same row
    $(".form-check-input").click(function() {
        $('input[type="checkbox"]').change(function() {
            $(this).closest('tr').find('input[type="checkbox"]').not(this).prop('checked', false);
        });
    });
});
</script>

Atualizando estado da linha da tabela com jQuery

De acordo com o conteúdo de cada linha de uma tabela html podemos modificar as propriedades dos elementos usando jQuery.

No exemplo abaixo temos uma tabela onde atribuímos os valores a serem observados nos campos data dentro da tag <tr>.

<form action="<?= $acao_aplicar ?>" method="post" id="form1">
    <input type="hidden" name="id_requisicao" value="<?= $requisicao->id ?> ">
    <table class="table table-sm small table-striped" id="itensTable">
        <thead>
            <tr>
                <th>Item</th>
                <th>Produto</th>
                <th>Descrição</th>
                <th>Unidade</th>
                <th class="text-end">Qt. Calculada</th>
                <th class="text-end">Saldo</th>
                <th width="140px" class="text-end">Qt. Solicitada</th>
            </tr>
        </thead>

        <tbody>
            <?php foreach ($itens as $row): ?>
                <tr class="align-middle" data-produto-ativo="<?= $row->produto_ativo ?>"
                    data-quantidade="<?= $row->qt_solicitada ?>">
                    <!-- item -->
                    <td>
                        <?= $row->item ?>
                    </td>
                    <!-- produto -->
                    <td>
                        <?= $row->produto_codigo ?>
                    </td>
                    <!-- descricao -->
                    <td>
                        <?= $row->produto_descricao ?>
                    </td>
                    <!-- unidade -->
                    <td>
                        <?= $row->produto_unidade ?>
                    </td>
                    <!-- quantidade calculada -->
                    <td class="text-end">
                        <?= number_format($row->qt_calculada, 3, ',', '.') ?>
                    </td>
                    <!-- saldo -->
                    <td class="text-end">
                        <?= number_format($row->saldo, 3, ',', '.') ?>
                    </td>
                    <!-- quantidade solicitada -->
                    <td>
                        <input type="hidden" name="id[]" value="<?= $row->id ?>">
                        <input type="number" style="text-align:right" class="form-control form-control-sm"
                               name="qt_solicitada[]" value="<?= $row->qt_solicitada ?>" required>
                    </td>
                </tr>
            <?php endforeach ?>
        </tbody>

    </table>
</form>

Em seguida, o código jQuery faz as alterações nos elementos.

<script>
    $(document).ready(function () {
        $('#itensTable tbody tr').each(function () {
            var produto_ativo = $(this).data('produto-ativo');
            var quantidade = $(this).data('quantidade');
            if (produto_ativo === 'f') {
                $(this).find('td').addClass('text-danger');
                $(this).find('input').prop('disabled', true);
                $(this).find('input').prop('required', false);
            }
            if (quantidade == 0) {
                $(this).find('td').addClass('text-secondary');
                $(this).find('input').prop('disabled', true);
                $(this).find('input').prop('required', false);
            }
        });
    });
</script>

Dica: nunca utilize underscore nos nomes dos campos data (ex: data-produto_inativo).

XDebug no VSCode para CodeIgniter 4

A junção do PHP com o XDebug permite a depuração do código em passos com a visualização dos valores das variáveis em tempo real.

Para quem tem projetos CI4, a configuração abaixo deve ser inserida no arquivo launch.json do VSCode.

{
    "name": "CI4 Spark XDebug",
    "type": "php",
    "request": "launch",
    "runtimeArgs": [
        "spark",
        "serve",
        "-dxdebug.mode=debug",
        "-dxdebug.start_with_request=yes",
        "-S",
        "localhost:8080",
    ],
    "env": {
        "XDEBUG_MODE": "debug",
        "XDEBUG_SESSION": "factor",
    },
    "externalConsole": false,
    "program": "",
    "cwd": "${workspaceRoot}",
    "port": 9003,
    "serverReadyAction": {
        "action": "openExternally",
        "killOnServerStop": false
}

Campos DATA de bancos MySQL no PDI

Dependendo da versão das bibliotecas de acesso a um banco MySQL, o Pentaho pode retornar erro ao ler colunas do tipo DATE, especialmente no que se refere à interpretação do fuso horário.

A mensagem que normalmente aparece é

HOUR_OF_DAY: 0 -> 1

Definindo o fuso horário nas opções de carga dos aplicativos do PDI resolve esse problema. Por exemplo, colocando a definição “-Duser.timezone=GMT-3” dentro do spoon.bat na linha set OPT=…

Executando jobs e transformações do Pentaho no prompt de comando

Não necessariamente somos obrigados a configurar um PDI Server para agendar a execução dos trabalhos e transformações em um servidor.

É possível executar um comando no servidor que dispara a rotina desejada.

Para executar transformações (ktr) usamos o seguinte comando:

sh pan.sh -rep: -file=<arquivo>.ktr

Para executar trabalhos (kjb) usamos o seguinte comando:

sh kitchen.sh -rep: -file=<arquivo>.kjb

Instalando o PDI 9.3 no Windows 10/11

Passos:

Opcionalmente, para fixar o atalho no menu iniciar, crie uma pasta (ex: Extras) em %appdata%/Microsoft/Windows/Start Menu/Programs/ e mova o arquivo do atalho para essa pasta. Na sequencia, abra o menu iniciar e procure pelo nome do atalho, a opção de fixar em iniciar estará disponível.