# PostgreSQL

Esse guia listará as instalações/atualizações necessárias para funcionamento dos produtos utilizando o banco de dados PostgreSQL.

Nota

  • No momento, só existem rotinas para uso do Zeedhi Angular. Posteriormente, nessa mesma documentação, serão disponibilizados os passos para uso do Zeedhi Next.
  • Nem todas as bibliotecas foram tratadas, apenas as indispensáveis para a rotina de login.

# Pré-Requisitos

# PHP 7.4

As rotinas foram desenvolvidas para utilização com o PHP 7.4. Caso ainda não tenha realizado a atualização, siga os passos desse guia.

# Driver

Instale o driver do Postgre para o PHP em seu ambiente com os comandos:

sudo apt update
sudo apt install php7.4-pgsql

Nota

  • Os comandos acima são para ambientes Linux (como o WSL, máquina própria, entre outros...).
  • Execute onde seu PHP estiver sendo executado (dentro do container do docker, por exemplo).
  • Caso utilize o cloud9, solicite ao setor de Redes a instalação.

# Atualizações

# composer.json

  • zeedhi/framework: 2.6.* (ou superior)
  • teknisa/libraries: 3.3.* (ou superior)
  • zeedhi/zhuaclbackend: 2.10.* (ou superior)
# modules.json

Atualizem a versão do módulo de Login para a versão 4.9.* (ou superior)

"login": {
    (...)
    "maxVersion": "4.9.*",
    (...)
}

# Configurações

# db.xml

Alterações na conexão com o banco de dados:

  • driver: Agora será utilizado o pdo_pgsql.
  • user, password e host: Configurem de acordo com a base de dados desejada.
    • Procurem o setor de Redes para mais informações.
  • port: Valor padrão agora é 5432, caso não possuir uma específica.
  • dbname: Agora será utilizado o postgres.
  • platform: Agora será utilizado o service com o id customPostgreSQLPlatform.

Exemplo de db.xml preenchido:

<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <parameters>
        <parameter key="connection_params" type="collection">
            <parameter key="driver">pdo_pgsql</parameter>
            <parameter key="user">usr_org_20</parameter>
            <parameter key="password">teknisa</parameter>
            <parameter key="host">192.168.122.10</parameter>
            <parameter key="port">5432</parameter>
            <parameter key="dbname">postgres</parameter>
            <parameter key="platform" type="service" id="customPostgreSQLPlatform"/>
            <parameter key="charset">utf8</parameter>
        </parameter>
    </parameters>
</container>
# Service

Registrem o service customPostgreSQLPlatform em algum de seus arquivos xml (configurações gerais, como essa, geralmente são feitas no general.xml):

<service id="customPostgreSQLPlatform" class="Zeedhi\Framework\ORM\Platform\PostgreSQLPlatform"/>

# Query


Por padrão, o Oracle sempre retorna as colunas em maiúsculo, formato utilizado atualmente. Porém, o Postgre sempre retorna em minúsculo. Isso impacta diretamente na forma de desenvolver.

Exemplo:

SELECT ID, NAME
  FROM PROJECT

Executando no Oracle, a saída seria:

array(2) { 
    ["ID"]   => "1"
    ["NAME"] => "Projeto 1"
}

Já no Postgre...

array(2) { 
    ["id"]   => "1"
    ["name"] => "Projeto 1"
}

Utilizando a função fetchAssoc do php para a execução da query, o acesso aos dados seria, por exemplo, $data[ID]. Como o Postgre retorna em minúsculo, geraria erro de posição não existente no array.

Solução:

SELECT ID AS "ID", NAME AS "NAME"
  FROM PROJECT

Será necessário forçar que a coluna seja retornada em maiúsculo, utilizando as "COLUMN". Dessa forma, indiferente do banco de dados que estiver utilizando, o código PHP será o mesmo.

Atenção

Infelizmente, será necessário alterar todas as queries!

# Queries diferentes entre os bancos


Vão existir inúmeros casos onde a mesma query não funcionará em Oracle e Postgre ao mesmo tempo. Será necessário tratar caso a caso.

# Crud

Adicionar nova propriedade no datasource chamada query_pdo_pgsql. Internamente, caso exista essa propriedade, o framework irá executar a query de acordo com o driver do banco configurado no db.xml automaticamente.

Exemplo:

{
    "zhu_access_control_rule_login": {
        "tableName": "ZHU_ACCESS_CONTROL_RULE",
        "columns": [
            "NAME",
            "UNIQUE_ID",
            "RULE",
            "RULE_UNDEFINED",
            "GROUP_ID"
        ],
        "primaryKeys": [
            "UNIQUE_ID"
        ],
        "query": "SELECT * FROM TABLE (ZHU_RULE_BY_PROJECT (:PROJECT_ID, :GROUP_ID))",
        "query_pdo_pgsql": "SELECT * FROM zhu_rule_by_project (:PROJECT_ID, :GROUP_ID)"
    }
}

Nota

No Crud, mesmo quando estiver utilizando query, não há a necessidade de utilizar as "COLUMN". Deve-se informar a query normalmente porque todo o tratamento será realizado internamente pelo framework

# Execuções pelo PHP próprio

Foi criada a classe QuerySelector no framework para retornar a query a ser utilizada de acordo, novamente, com o driver.

Exemplo:

    use Zeedhi\Framework\DependencyInjection\InstanceManager;
    use Zeedhi\Framework\Util\QuerySelector;

    public function dualQuery($id) {
        $connection = InstanceManager::getInstance()->getService('entityManager')->getConnection();
        
        $queryOracle = <<<SQL
           SELECT ID, NAME, SYSDATE AS DATA
             FROM PROJECT
            WHERE ID = :ID
SQL;

        $queryPostgre = <<<SQL
           SELECT ID AS "ID", NAME AS "NAME", NOW() AS "DATA"
             FROM PROJECT
            WHERE ID = :ID
SQL;

        $params = array (
            'ID' => $id
        );
        $arrayQueries = array (
            'default'   => $queryOracle,
            'pdo_pgsql' => $queryPostgre
        );
        $query = QuerySelector::getQueryByDriver($connection, $arrayQueries);

        return $connection->fetchAll($query, $params);
    }

Um caso que deverá atrapalhar muita gente... SYSDATE não existe no Postgre! 👍

Há formas de utilizar TO_DATE que funcionará em ambos, mas haverá a necessidade de alteração...