Polyfill no PostgreSQL - Lidando com retrocompatibilidade

Visão Greral

Frequentemente precisamos usar algum recurso recente de alguma determinada tecnologia, e precisamos lidar com a ausência destes recurso em versões anteriores desta tecnologia.

Em casos como esse, é comum o uso da técnica conhecida como Polyfill:

No desenvolvimento de software, um polyfill é um código que implementa um novo recurso padrão de um ambiente de implantação em uma versão antiga desse ambiente que não oferece suporte nativo ao recurso. Wikipedia (inglês)

Essa técnica é muito comum no desenvolvimento Web, onde os Polyfills são desenvolvidos usando JavaScript.

Neste tópico vou abordar uma maneira de aplicar essa técnica no PostgreSQL.

Implementação

Essa implementação consiste em:

  • Criar um schema novo, que vai hospedar as funções de retrocompatibilidade para uma versão em específico do PostgreSQL. Chamei esse schema de polyfill_pg<version>, onde “version” é o número da versão sem pontos e com 1 zero à esquerda.

  • Criar as funções que ainda não existem na versão legado neste novo schema, com o mesmo nome, quantidade e tipos de parâmetros.

  • Adicionar o schema criado no “path” padrão da conexão (Search Path), fazendo com que a função fique disponível sem precisar especificar o schema.

Optei agrupar as funções em um schema de acordo com a versão que desejo alcançar, porque dessa maneira, quando a versão do PostgreSQL for atualizada e o Polyfill não for mais necessário, basta excluir o schema.

Código do Polyfill

Segue o código que adiciona suporte aos recursos do PostgreSQL 9.5 em versões anteriores.

-- Este script cria um schema no banco de dados postgres chamdo "polyfill_pg095" 
-- suportar algumas funções das versã 9.5 do banco em versões anteriores (a partir da 9.3)
-- Após a criação do schema, basta usá-lo o "path" padrão com o comando "set search_path"
CREATE SCHEMA IF NOT EXISTS polyfill_pg095;

SET SEARCH_PATH = polyfill_pg095;

CREATE OR REPLACE FUNCTION array_position (v_array ANYARRAY, v_element ANYELEMENT, v_dim INT DEFAULT 1)
    RETURNS INT AS
$BODY$
DECLARE

BEGIN
    FOR n IN 1..COALESCE(ARRAY_UPPER(v_array, v_dim),0)
    LOOP
        IF v_array[n] = v_element THEN
            RETURN n;
        END IF;
    END LOOP;
END;
$BODY$
LANGUAGE plpgsql STABLE;

-- Adicione outras funções abaixo

Neste exemplo, apenas a função array_position está sendo criada, mas outras funções podem ser adicionadas.

Preste muito atenção no tipo e quantidade de parâmetro (assinatura das funções) no nomento de criar as funções de compatibilidade.
1 curtida