No momento que escrevo estas linhas a versão atual do Postgres é a 9.2 e ao todo são 41 módulos no contrib, então vou iniciar uma série onde vou apresentar o funcionamento da maioria deles e farei isto seguindo a ordem alfabética dos módulos.
Vamos iniciar pelo adminpack que é uma extensão que contém algumas
funções que permitem a manipulação remota de determinados arquivos por
um super-usuário (como o postgres
por exemplo) ou ferramentas
administrativas. É possível, através destas funções, renomear um
arquivo, ler seu conteúdo ou até mesmo escrever no arquivo.
Mas vamos deixar de conversa e vamos ao que interessa: mão-na-massa.
Para utilizar uma contrib
você precisa criar a extensão, e para que
isto ocorra com sucesso você precisa ter ela instalada no cluster.
Seguindo a documentação do Postgres você percebe que a instalação do
módulo depende de como o Postgres foi instalado.
No meu caso o Postgres foi instalado através do código-fonte compilado,
então o que eu preciso fazer é acessar o diretório da instalação e
procurar a contrib
e instalá-la:
$ cd $HOME/programas/PostgreSQL/postgres/contrib/adminpack
$ make install
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -fpic -I../../src/interfaces/libpq -I. -I. -I../../src/include -D_GNU_SOURCE -c -o adminpack.o adminpack.c
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -fpic -shared -o adminpack.so adminpack.o -L../../src/port -Wl,--as-needed -Wl,-rpath,'/home/guedes/.local/postgres/lib',--enable-new-dtags
/bin/mkdir -p '/home/guedes/.local/postgres/lib'
/bin/mkdir -p '/home/guedes/.local/postgres/share/extension'
/bin/mkdir -p '/home/guedes/.local/postgres/share/extension'
/bin/sh ../../config/install-sh -c -m 755 adminpack.so '/home/guedes/.local/postgres/lib/adminpack.so'
/bin/sh ../../config/install-sh -c -m 644 ./adminpack.control '/home/guedes/.local/postgres/share/extension/'
/bin/sh ../../config/install-sh -c -m 644 ./adminpack--1.0.sql '/home/guedes/.local/postgres/share/extension/'
Uma vez que a contrib esteja instalada, seja via pacote ou via compilação, acesse o banco onde você deseja utilizá-la e “carregue-a” através do comando:
testdb=# CREATE EXTENSION adminpack;
testdb# \dx+ adminpack
Objects in extension "adminpack"
Object Description
-------------------------------------------
function pg_file_length(text)
function pg_file_read(text,bigint,bigint)
function pg_file_rename(text,text)
function pg_file_rename(text,text,text)
function pg_file_unlink(text)
function pg_file_write(text,text,boolean)
function pg_logdir_ls()
function pg_logfile_rotate()
E agora vamos testá-la, vamos começar criando um arquivo:
testdb=# select pg_file_write('teste.txt', 'Ola Mundo', false);
pg_file_write
---------------
9
(1 row)
Se tentarmos criar o arquivo novamente não vamos conseguir, e por isso
temos que passar true
no último parâmetro.
testdb=# select pg_file_write('teste.txt', 'Ola Mundo', false);
ERROR: file "teste.txt" exists
testdb=# select pg_file_write('teste.txt', 'Ola Mundo', true);
pg_file_write
---------------
9
(1 row)
Só é possivel manipular arquivos dentro do $PGDATA
do cluster, por
questões de segurança. Sendo assim, é esperado que o arquivo esteja lá:
~$ ls -la $HOME/.local/postgres/data/teste.txt
-rw------- 1 guedes guedes 18 Fev 14 23:15 /home/guedes/.local/postgres/data/teste.txt
~$ cat $HOME/.local/postgres/data/teste.txt
Ola MundoOla Mundo
~$
Ele concatenou sem quebrar linha, como o esperado já que não passamos caracteres de controle de quebra de linha, e agora, para teste, vamos renomear o arquivo (via Postgres, claro):
testdb=# select pg_file_rename('teste.txt', 'ola_mundo');
pg_file_rename
----------------
t
(1 row)
Como foi obtido sucesso, a função retorna true
, entretanto, se
tentarmos sobrescrever um arquivo, mesmo sendo super-usuários, não vamos
conseguir:
testdb=# select pg_file_rename('ola_mundo', 'postgresql.conf');
ERROR: cannot rename to target file "postgresql.conf"
testdb=# select pg_file_rename('ola_mundo', 'postmaster.opts');
ERROR: cannot rename to target file "postmaster.opts"
Podemos ser ousados e tentar algo como:
testdb=# select pg_file_write('postgresql.conf','logging_collector = true', true);
pg_file_write
---------------
24
(1 row)
… reiniciar o cluster:
~$ pg_ctl -D $HOME/.local/postgres/data restart
… e dar uma olhadinha nos logs:
testdb=# select t.* from pg_logdir_ls() t(data_hora timestamp, logfile text);
data_hora | logfile
---------------------+-----------------------------------------
2013-02-27 23:34:59 | pg_log/postgresql-2013-02-27_233459.log
Hum, tá, nem tão ousados assim porque precisamos ter acesso ao S.O. e em muitas situações você não tem este acesso.
AVISO: Cuidado ao escrever em arquivos como
postmaster.opts
oupostgresql.conf
você pode acabar gerando um problema caso o banco precise ser re-iniciado e você tenha concatenado algo errado neles.
Bom por hoje é isto e até a próxima contrib!
Um abraço!