o elefante poliglota

Post on 13-Apr-2017

560 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

O ElefantePoliglota

Dickson S. Guedes@guediz

PGDay PR 2015 - Curitiba, PR

poliglotaadjetivo e substantivo de dois gêneros

1. que ou aquele que sabe ou fala muitas línguas.2. que está escrito em muitas línguas; poliglótico.3. diz-se da ave que é capaz de imitar muitos sons e

arremedar outras aves.

ATENÇÃO: esta palestra é umaviagem!

vamos começar com umahipótese

seria possível transformar umservidor Postgres em um

servidor WEB?

ahn?! que esse careca tafalando?

vamos começar a viagem…

no mundo "dos computadô"

o dado nu e crú

[ entrada ] -> [ processamento ] -> [ saida ]

continuo processo de transformação dedados

no mundo "das Internet"

Browser

Apache, Rails, Django, JBoss,Cowboy, Phoenix, Node.js

Javascript

JSON

Javascript Object Notation{ "nome": "Joao", "endereco" : { "cep": "88000-00", "rua": "Das Saudades", "nro": 453, "bairro": "Centro" }, "dependentes": [ { "nome": "Maria", "parentesco": "esposa" }, { "nome": "Mario", "parentesco": "filho" }, { "nome": "Marina", "parentesco": "filha" } ]}

ecoandovar pessoa = { "nome": "Joao", "endereco" : { "cep": "88000-00", "rua": "Das Saudades", "nro": 453, "bairro": "Centro" }, "dependentes": [ { "nome": "Maria", "parentesco": "esposa" }, { "nome": "Mario", "parentesco": "filho" }, { "nome": "Marina", "parentesco": "filha" } ]}

console.log(pessoa.nome); => "Joao" console.log(pessoa["dependentes"][0]["nome"]); => "Maria"

Voltando ao Javascript

callbackvar audita = function(objeto) { console.log(objeto.nome + " foi inserido!");}

var pessoa = new Pessoa();

pessoa.on('after-save', audita);

pessoa = { "nome": "Joao", ... }pessoa.save();

=> Joao foi inserido!

alguem lembra?

Websockets

pub/sub

o movimento deJavascriptização

Node.js

respirem …

no mundo do Postgres

a extensibilidade que liberta

Postgres não é apenas umSGDB

é uma plataforma dedesenvolvimento de aplicações

o catalogo# \dt pg_catalog. List of relations Schema | Name | Type | Owner ------------+-------------------------+-------+---------- pg_catalog | pg_aggregate | table | postgres ... pg_catalog | pg_class | table | postgres ... pg_catalog | pg_database | table | postgres pg_catalog | pg_foreign_data_wrapper | table | postgres pg_catalog | pg_foreign_server | table | postgres pg_catalog | pg_foreign_table | table | postgres pg_catalog | pg_index | table | postgres ... pg_catalog | pg_language | table | postgres ... pg_catalog | pg_operator | table | postgres ... pg_catalog | pg_type | table | postgres pg_catalog | pg_user_mapping | table | postgres

operadores (pg_operator)+-/*o seu mais novo operador pode estar aqui…

tipos (pg_type)integernumerictext…jsonjsonbo seu tipo pode estar aqui também

linguagens (pg_language)plpgsqlplperlplpythonplv8 - javascripta sua linguagem pode estar aqui também

respirem …

plv8

plv8 - Javascript no Postgres

vamos usar o mesmo exemplo doJavascript

DO LANGUAGE plv8 $$var pessoa = { "nome": "Joao", "endereco" : { "cep": "88000-00", "rua": "Das Saudades", "nro": 453, "bairro": "Centro" }, "dependentes": [ { "nome": "Maria", "parentesco": "esposa" }, { "nome": "Mario", "parentesco": "filho" }, { "nome": "Marina", "parentesco": "filha" } ]}

plv8.elog(NOTICE, pessoa.nome);plv8.elog(NOTICE, pessoa["dependentes"][0]["nome"]);$$;

FDW - foreign data wrappers(pg_foreign_data_wrapper)

file_fdwpostgres_fdwmysql_fdwmongo_fdwmulticornque tal o seu aqui também?

FDW - um exemplo nativoCREATE EXTENSION postgres_fdw;

CREATE SERVER servidor_de_consultas FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host '192.168.1.1', dbname 'banco', port '5432');

CREATE USER MAPPING FOR CURRENT_USERSERVER servidor_de_consultas OPTIONS (user 'usuario_consulta', password 'consulta');

CREATE FOREIGN TABLE pessoas (cpf numeric, nome varchar) SERVER servidor_de_consultas OPTIONS ( schema_name 'recursos_humanos', table_name 'tb_funcionarios');

EXPLAIN (ANALYZE,VERBOSE, BUFFERS) SELECT * FROM pessoas WHERE cpf = 1234567891; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------ Foreign Scan on public.pessoas (cost=100.00..118.06 rows=3 width=104) (actual time=46.039..46.040 rows=1 loops=1) Output: cpf, nome Remote SQL: SELECT cpf, nome FROM recursos_humanos.tb_funcionarios WHERE ((cpf = 1234567891::numeric)) Planning time: 0.061 ms Execution time: 105.232 ms(5 registros)

FDW - um exemplo multicornhttp://multicorn.org/implementing-an-fdw/

BGW - background workers

BGW - uma visão geralexecuta junto com o postgresmorre junto com o postgresmas também pode ser dinamicoé um daemono poder esta nas mãos de seu criadorvocê tem que escreve-lo em C

BGW - um exemplopostmaster|-̀- autovacuum|-̀- checkpointer|-̀- bgwriter|-̀- matador_de_conexoes_ociosas|-̀- analisador_da_saude_do_banco...

background worker como umaporta de entrada

BGW é em C, ou seja …

Mas você pode inicia-lo utilizando umafunção do banco

--

SELECT net_http_server(8000);

e um novo BGW iniciapostmaster|-̀- autovacuum|-̀- checkpointer|-̀- bgwriter|-̀- matador_de_conexoes_ociosas|-̀- analisador_da_saude_do_banco|-̀- net_http_server...

LISTEN/NOTIFY

LISTEN SESSAO A SESSAO B

psql -d banco | psql -d banco |> LISTEN usuario_logou; | > ...

LISTEN SESSAO A SESSAO B

psql -d banco | psql -d banco |> LISTEN usuario_logou; | > ...> LISTEN usuario_logou; | > ... | > INSERT INTO login (current_timestamp, 'JOSE');... o cara coxilou por uns minutos ... |

LISTEN SESSAO A SESSAO B

psql -d banco | psql -d banco |> LISTEN usuario_logou; | > ...> LISTEN usuario_logou; | > ... | > INSERT INTO login (current_timestamp, 'JOSE');... o cara coxilou por uns minutos ... | | > NOTIFY usuario_logou, 'JOSE'; |

LISTEN SESSAO A SESSAO B

psql -d banco | psql -d banco |> LISTEN usuario_logou; | > ...> LISTEN usuario_logou; | > ... | > INSERT INTO login (current_timestamp, 'JOSE');... o cara coxilou por uns minutos ... | | > NOTIFY usuario_logou, 'JOSE';> LISTEN usuario_logou; | |

LISTEN SESSAO A SESSAO B

psql -d banco | psql -d banco |> LISTEN usuario_logou; | > ...> LISTEN usuario_logou; | > ... | > INSERT INTO login (current_timestamp, 'JOSE');... o cara coxilou por uns minutos ... | | > NOTIFY usuario_logou, 'JOSE';> LISTEN usuario_logou; | |Notificação assíncrona "usuario_logou" com |mensagem "JOSE" recebida do processo do |servidor com PID 25439. |

a contrib tcntest=# create table tcndatatest-# (test(# a int not null,test(# b date not null,test(# c text,test(# primary key (a, b)test(# );CREATE TABLEtest=# create trigger tcndata_tcn_triggertest-# after insert or update or delete on tcndatatest-# for each row execute procedure triggered_change_notification();CREATE TRIGGER

vendo o resultado da tcntest=# listen tcn;LISTENtest=# insert into tcndata values (1, date '2012-12-22', 'one'),test-# (1, date '2012-12-23', 'another'),test-# (2, date '2012-12-23', 'two');INSERT 0 3Asynchronous notification "tcn" with payload ""tcndata",I,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.Asynchronous notification "tcn" with payload ""tcndata",I,"a"='1',"b"='2012-12-23'" received from server process with PID 22770.Asynchronous notification "tcn" with payload ""tcndata",I,"a"='2',"b"='2012-12-23'" received from server process with PID 22770.test=# update tcndata set c = 'uno' where a = 1;UPDATE 2Asynchronous notification "tcn" with payload ""tcndata",U,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.Asynchronous notification "tcn" with payload ""tcndata",U,"a"='1',"b"='2012-12-23'" received from server process with PID 22770.test=# delete from tcndata where a = 1 and b = date '2012-12-22';DELETE 1Asynchronous notification "tcn" with payload ""tcndata",D,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.

respirem …

finalizando …

(quase)

hipoteticamente pensando …

como poderia ser um servidor web noPostgres?

iniciando a aplicaçãoCREATE SCHEMA todo_list;

CREATE TABLE todo_list.itens( conteudo jsonb );

CREATE INDEX ix_itens_id ON todo_list.itens USING GIN ((conteudo->'id'));

SELECT pg_web_app_start('todo_list', 8000);

guedes@betelgeuse ~$curl -X PUT http://ip.servidor:8000/item/ -d '{ "id": 1, "descricao": "compartilhar conhecimento"}'{ "response": "created" }

curl -X GET http://ip.servidor:8000/item/1{ "id": 1, "descricao": "compartilhar conhecimento"}

curl -X DELETE http://ip.servidor:8000/item/1{ "response": "deleted" }

curl -X GET http://ip.servidor:8000/item/1

qual é a magica dopg_web_app_start('todo_list', 8000) ?

todo_list.app()CREATE FUNCTION todo_list.app() RETURNS jsonb LANGUAGE plv8 AS $$var TodoListApp = PgWebApp();

TodoListApp.get('/', function(req, res) { res.send('<html> .... </html>');});

TodoListApp.get('/item/:id', function(req, res) { plv8.execute('SELECT * FROM todo_list.itens WHERE id = $1', [ req.params.id ]);});

TodoListApp.put('/item', function(req, res) { plv8.execute('INSERT INTO todo_list.itens VALUES ($1)', [ req.body ]);});

TodoListApp.post('/item', function(req, res) { plv8.execute('UPDATE todo_list.itens SET conteudo = $1 WHERE id = $2', [ req.body, req.params.id ]);});

TodoListApp.delete('/item', function(req, res) { plv8.execute('DELETE FROM todo_list.itens WHERE id = $1', [ req.params.id ]);});

TodoListApp.on('usuario_logado', function(payload) { plv8.elog(NOTICE, 'O usuario ' + payload + ' logou!');});

RETURN TodoListApp;$$;

é como se eu publicasse meuesquema todo_list na porta

8000

mas …

você pode esquecer tudo isto …

e dar uma olhada no pg_rest

no fim das contas você vaiperceber que ..

não há limites para o que vocêpode fazer com o Postgres …

e que não há limite para a suaimaginação …

mas tenha a certeza de que ocaminho seja divertido

compartilhem conhecimento

inspirem

e é isso, obrigado! :)Conferencia Brasileira de PostgreSQL

18 a 20 de Novembro

email: guedes@guedesoft.netgithub: twitter:

http://pgbr.postgresql.org.br/

http://github.com/guedeshttp://twitter.com/guediz

top related