Back-End

29 mar, 2016

Foreign Data Wrappers com PostgreSQL e PHP

Publicidade

PostgreSQL é mais que um banco de dados relacional. Ele tem muitas características legais. Hoje vamos brincar um pouco com Foreign Data Wrappers (FDW). A ideia é criar uma tabela virtual a partir de uma fonte de dados externa e usar da mesma forma que uma tabela tradicional.

Vou mostrar um exemplo. Imagine que temos uma fonte de dados REST na porta 8888. Vamos usar esta aplicação Silex, por exemplo:

use Silex\Application;
 
$app = new Application();
 
$app->get('/', function(Application $app) {
 
    return $app->json([
        ['name' => 'Peter', 'surname' => 'Parker'],
        ['name' => 'Clark', 'surname' => 'Kent'],
        ['name' => 'Bruce', 'surname' => 'Wayne'],
    ]);
});
 
$app->run();

Queremos usar essa fonte de dados no PostgreSQL, então precisamos usar um “www foreign data wrapper”.

Primeiro, criamos a extensão (talvez seja necessário compilar a extensão. Você pode seguir as instruções de instalação aqui).

CREATE EXTENSION www_fdw;

Agora, com a extensão, precisamos criar um “servidor”. Ele será apenas um proxy que se conecta ao serviço REST real.

CREATE SERVER myRestServer FOREIGN DATA WRAPPER www_fdw OPTIONS (uri 'http://localhost:8888');

Agora, vamos mapear nosso usuário até o servidor.

CREATE USER MAPPING FOR gonzalo SERVER myRestServer;

E finalmente precisamos apenas da nossa “Tabela externa” (Foreign table).

CREATE FOREIGN TABLE myRest (
    name text,
    surname text
) SERVER myRestServer;

Agora podemos executar consultas SQL usando a nossa Foreign table.

SELECT * FROM myRest

É preciso ter cuidado com uma coisa. Podemos usar cláusulas WHERE, mas se rodarmos:

SELECT * FROM myRest WHERE name='Peter'

Teremos um output semelhante ao “SELECT * FROM myRest”. Isso porque se quisermos filtrar algo com uma cláusula WHERE dentro do Foreign, precisamos fazer isso no serviço remoto. WHERE name=‘Peter’ significa que nosso banco de dados vai executar a seguinte requisição:

http://localhost:8888?name=Peter

E precisamos manipular esse parâmetro. Por exemplo, fazendo algo assim:

use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
 
$app = new Application();
 
$app->get('/', function(Application $app, Request $request) {
    $name = $request->get('name');
 
    $data = [
        ['name' => 'Peter', 'surname' => 'Parker'],
        ['name' => 'Clark', 'surname' => 'Kent'],
        ['name' => 'Bruce', 'surname' => 'Wayne'],
    ];
    return $app->json(array_filter($data, function($reg) use($name){
        return $name ? $reg['name'] == $name : true;
    }));
});
 
$app->run();

***

Gonzalo Ayuso faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://gonzalo123.com/2016/02/22/foreign-data-wrappers-with-postgresql-and-php/