Instalação do PostgreSQL no Mac OS X

O PostgreSQL é um sistema gerenciador de banco de dados open-source que roda em quase todos os sabores de Unix, incluindo o Mac OS X. Apesar de não ser tão popular quanto seu principal competidor, o MySQL, é totalmente compatível ao ACID, e é capaz de manipular tanto aplicações pequenas quanto grandes. Nesse artigo, será mostrado como instalar e configurar o PostgreSQL no Mac OS X, e depois usa-lo com Perl, Java e PHP. Finalmente, será demonstrado como usar a aplicação web phpPhAdmin para administrar suas bases de dados.

Instalando o PostgreSQL

Antes de instalar o PostgreSQL, você precisará instalar um pacote chamado readline. A maneira mais fácil de obtê-lo é através do projeto Fink. Esse projeto tem por objetivo porta aplicações open-source para Unix para o Darwin e Mac O X, e torna-los disponíveis através de um pacote fácil de suar. Para instalar o Fink, siga essas instruções. Certifique-se de ter o instalador do Fink adequado a sua versão do OS X. Uma vez que o Fink estiver instalado, abra o terminal e digite o seguinte comando para instalar o readline:

liz@mail:~> sudo  /sw/bin/fink install readline

Você pode instalar o porte do Fink para o PostgreSQL, mas uma versão mais recente e estável do PostgreSQL está disponível se instala-lo a partir do código-fonte. Como o processo de compilação é simples, vamos mostrar aqui como instalar a partir do código-fonte, usando o comando curl. A versão mais nova do PostgreSQL pode ser encontrada em PostgreSQL.org. Como sempre, você precisará usar o comando sudo para obter acesso de administrador e poder instalar o sistema:

liz@mail:~> cd /usr/local/src
liz@mail:src> sudo sh
 Password:
root@mail:src> mkdir postgres
root@mail:src> cd postgres
root@mail:postgres>
	curl -O ftp://ftp5.us.postgresql.org/pub/PostgreSQL/source/v7.4.1/postgresql-7.4.1.tar.gz
root@mail:postgres> tar -xzvf postgresql-7.4.1.tar.gz
root@mail:postgres> cd postgresql-7.4.1

(Note que preferimos colocar o código-fonte em /usr/local/src).

Agora que temos os arquivos do código-fonte, podemos executar o script de configuração, compilar e instalar o PostgreSQL. Como instalamos o readline pelo Fink, precisamos adicionar os diretórios do Fink aos argumentos do script configure:

root@mail:postgresql-7.4.1>
	./configure --with-includes=/sw/include/ --with-libraries=/sw/lib
root@mail:postgresql-7.4.1> make
root@mail:postgresql-7.4.1> make install

Em seguida, precisamos adicionar um usuário administrativo chamado “postgres” que efetivamente irá gerenciar as bases de dados. Para adicionar um usuário no MAc OS X, abra as Preferências dos Sistema e selecione Contas, clicando em seguida em Novo Usuário, e entre com o valores mostrados abaixo e clique em Salvar:

Em seguida, retornamos ao terminal para criar um diretório para armazenar os arquivos de dados do PostgreSQL. Esse diretório terá suas permissões de acesso vinculadas ao usuário “postgres” criado acima:

root@mail:~> mkdir /usr/local/pgsql/data
root@mail:~> chown postgres /usr/local/pgsql/data

Precisamos agora logar como “postgres” para podermos completar os passos a seguir. Para fazer isso, digite os comandos abaixo na janela do terminal, seguida pela senha do usuário:

liz@mail:~> su -l postgres

Agora podemos inicializar as bases de dados:

postgres@mail:~> /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data

Como você pode ver, o comando initdb, junto com os outros executáveis do PostgreSQL, pode ser encontrado em /usr/local/pgsql/bin. Para simplificar as coisas, deveriamos adicionar esse diretório ao path de nosso sistema (a lista de diretórios que são pesquisados quando digitamos o nome de um programa na linha de comando). Se estiver usando os shels csh ou tcsh, o comando abaixo irá alterar seu path:

setenv PATH ${PATH}:/usr/local/pgsql/bin

Se estiver usando sh ou bash, use o coamndo abaixo:

export PATH=$PATH:/usr/local/pgsql/bin

Se quiser que a mudança seja permanente, armazene esse comando em algum lugar onde seja re-executado sempre que o terminal for iniciado. Se estiver usando o tcsh, pode criar um arquivo .tcsh no diretório home do usuário. Os comando localizados dentro desse arquivo são executados pelo sistema quando uma sessão do terminal é iniciada. Abaixo segue o arquivo .tcsh que criaremos quando logarmos como “postgres”. Contém o comando para adicionar o /usr/local/pgsql/bin ao path do usuário e uma linha para armazenar a localização dos arquivos de dados do PostgreSQL  em uma variavel chamada PGDATA (que será necessária mais tarde):

setenv PGDATA /usr/local/pgsql/data
setenv PATH ${PATH}:/usr/local/pgsql/bin

Podemos executar os comandos do arquivo .tcsh pelo comando source ~/.tcsh.

Agora estamos prontos para iniciar o servidor PostgreSQL:

postgres@mail> /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start

Depois disso, ele estará ativo e sendo executado. Podemos criar nossa primeiro banco de dados usando o comando createdb:

postgres@mail> createdb test

E é isso. Para entrar no utilitário de linha de comando do PostgreSQL e executar comando SQL no banco de dados, digite o comando:

postgres@mail> psql test

O código do restante desse artigo assume a existência da tabela “foo” no banco de dados “test”. Se quiser executar algum dos exemplos a seguir, vá até a linha de comando do PostgreSQL e execute os comando abaixo. Isso irá criar a tabela “foo” e irá inserir dois campos de dados nela:

test=> create table foo (name varchar primary key, foo_id serial);
NOTICE:  CREATE TABLE will create implicit sequence 'foo_foo_id_seq' for
SERIAL column 'foo.foo_id' CREATE TABLE
test=> insert into foo (name) values ('Liz');
INSERT 16985 1
test=> insert into foo (name) values ('Jason');
INSERT 16986 1

Acesso de usuários e Administração

O PostgreSQL é entregue com regras de acesso bastante frouxas. Se quiser usar o seu banco de dados em um ambiente de produção, ou em um tipo de servidor compartilhado, deve adicionar ao menos um nível básico de segurança. Regras de autenticação de usuário são definidas no arquivo /usr/local/pgsql/data/pg_hba.conf. Como explicado na documentação do PostgreSQL, você pode editar esse arquivo para proteger com senha as contas de usuário, alterar métodos de autenticação para conexões remotas e locais e ativar/desativar acesso de usuário a várias partes do sistema.

Escolhemos aqui pedir senha para todos pelo ajuste do parâmetro METHOD para md5 para todos os usuários. Assim, enquanto garantiremos acesso total a todos os banco de dados pelo usuário “postgres”,  ajustamos os acessos baseados em grupos para outros usuário pela configuração de DATABASE para samegroup para os demais. Por exemplo, para que um usuário tenha permissão de escrita em um banco de dados chamado something, esse usuário terá que ser membro do grupo something. Também  ativamos conexões via sockets a partir do localhost (com as mesmas regras de autenticação), de forma que seremos capazes de usar o JDBC para conectarmos com o PostgreSQL mais tarde. Abaixo segue as linhas relevantes do arquivo pg_hba.conf:

# TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
host    all          postgres    127.0.0.1         255.255.255.255   md5
host    samegroup    all         127.0.0.1         255.255.255.255   md5
local   all          postgres                                        md5
local   samegroup    all                                             md5

Depois de editar o arquivo, precisamos criar uma senha para o super-usuário “postgres”, e reiniciar o servidor de banco de dados para que as mudanças surtam efeito:

postgres@mail:~> psql test
test=# alter user postgres with password 'foo';
test=# \q
postgres@mail:~> pg_ctl reload

Em seguida, para demonstrar o acesso baseado em grupos, criaremos dois novos bancos de dados, chamados shared e private, além de um grupo chamado shared. Depois criaremos um usuário chamado “liz” e adicionaremos esse usuário ao grupo shared, mas não ao grupo private:

postgres@mail:~> psql test
test=# create database shared;
test=# create database private;
test=# create group shared;
test=# create user liz with password 'liz';
test=# alter group shared add user liz;

Agora podemos acessar o banco de dados shared com o usuário “liz”:

liz@mail:~> psql shared liz
Password:
Welcome to psql 7.4.1, the PostgreSQL interactive terminal.
Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit
shared=> \q
liz@mail:~>

Quando tentamos acessar o banco de dados private como “liz”, porém, temos o acesso negado:

liz@mail:~> psql private liz
psql: FATAL:  No pg_hba.conf entry for host localhost, user liz, database private

Naturalmente, o administrador do banco de dados pode acessar o banco de dados private sem ser membro de nenhuma grupo em particular:

liz@mail:~> psql private postgres
Password:
Welcome to psql 7.4.1, the PostgreSQL interactive terminal.
Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit
private=#

Antes de seguir adiante, criaremos um grupo chamado test e adicionaremos o usuário “liz” a ele:

test=# create group test;
test=# alter group shared add user liz;

Isso irá permitir que os exemplos a seguir sejam executados como devem (A menos, é claro, que você deseje criar a sua própria conta e editar os exemplos para que funcionem com a sua conta. Nesse caso, adicione a sua conta ao grupo test e você poderá continuar).

PostgreSQL e Perl

Seus scripts Perl podem interagir com o PostgreSQL via DBI.pm, a popular interface de programação independente de banco de dados. Se já tiver escrito qualquer script Perl para MySQL ou Oracle, você já deve estar familiarizado com ele. Você pode obter o DBI para o MAc OS X via CPAN ou Fink:

liz@mail:~> sudo /sw/bin/fink install dbi-pm

ou

liz@mail:~> sudo perl -MCPAN -e 'install DBI'

Depois de instalar o DBI, precisaremos de um driver específico para o PostgreSQL chamado DBD::Pg. O driver está disponível a partir do CPAN:

liz@mail:~> export POSTGRES_INCLUDE="/usr/local/pgsql/include"
liz@mail:~> export POSTGRES_LIB="/usr/local/pgsql/lib -lssl -lcrypto"
liz@mail:~> sudo perl -MCPAN -e 'install DBD::Pg'

O porte do Fink não está estável ainda, mas deve estra em breve. Se decidir que prefere o Fink, pode sempre digitar o comando abaixo. Você verá um erro de “pacote não encontrado” se não funcionar:

liz@mail:~> sudo /sw/bin/fink install dbd-pg-pg

Note: Dependendo da configuração de seu sistema e da maneira em que o PostgreSQL foi instalado, pode ter que executar o comando ranlib em seu arquivo libpq.a antes de poder instalar o DBD::Pg. Se ver alguma mensagem de erro relacionada ao ranlib ou libpq.a, não se preocupe. Apenas execute o comando abaixo e tudo deve se resolver:

liz@mail:~> sudo ranlib /usr/local/pgsql/lib/libpq.a

Nesse ponto, tanto o DBI quanto o DBD::Pg devem estar instalados. Para testa-los, instalaremos o código Perl abaixo em um arquivo chamado pg.cgi no diretório cgi-bin (/Library/WebServer/CGI-Executables), e garantiremos que o arquivo possa tanto ser lido quanto executado pelo comando: chmod ugo+rx /Library/WebServer/CGI-Executables/pg.cgi.

#!/usr/bin/perl
use DBI;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use strict;
my $c = new CGI();
my $dbname = 'test';
my $user = 'liz';
my $pass = 'liz';
print $c->header();
print $c->start_html("Reading names from table 'foo' in db 'test'");
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname", $user, $pass) or die DBI::errstr;
my $res = $dbh->selectall_arrayref("select name from foo order by foo_id");
for my $row (@$res)
{
    print 'Name: ' , @$row[0] , '<br>';
}
$dbh->disconnect();
print $c->end_html();

Abaixo está a saida desse programa:

PostgreSQL e Java

O colaboradores do PostgreAQL.org tornaram um driver JDBC para o PostgreSQL disponível, o que significa que você pode facilmente usar o PostgreSQL como banco de dados por trás de uma aplicação Java. Baixe o driver JDBC e copie ele para um local compartilhado, como o /Library/Java/Extensions/. Em seguida, certifique que sua variável de ambiente CLASSPATH faça referência a esse diretório. Para esse exemplo, criaremos um novo CLASSPATH no tcsh dessa forma:

liz@mail:~> setenv CLASSPATH /Library/Java/Extensions/pg73jdbc2ee.jar:.

Usuários do bash ou sh devem usar esse comando:

liz@mail:~> export CLASSPATH="/Library/Java/Extensions/pg73jdbc2ee.jar:."

Antes de criar uma conexão via JDBC, edite o seu arquivo pg_hba.conf como mostrado abaixo. Você também precisará editar o arquivo /usr/local/pgsql/data/postgresql.conf para permitir conexões via socket. Como “postgres”, abara o arquivo postgresql.conf e altera a linha:

#tcpip_socket = false

para isso:

tcpip_socket = true

E depois reinicie o servidor:

postgres@mail:~> pg_ctl relaod

Agora estamos prontos para testar a conexão JDBC. Essa pequena classe java contém o código que conecta-se ao PostgreSQL e recupera algumas linhas de uma tabela pequena, como nos exemplos em Perl e PHP. Se você gostaria de configurar um ambiente Java baseado na web, recomendo a leitura dos artigos disponíveis em Java and OS X. Nesse meio tempo, porém, crie um arquivo PgTest.java com o conteúdo abaixo:

import java.sql.*;
import java.text.*;
import java.io.*;
public class PgTest
{
    Connection       db;        // connection object
    Statement        sql;       // statement to run queries with
    // the constructor does all the work in this simple example
    public PgTest(String argv[])
        throws ClassNotFoundException, SQLException
    {
        String database = argv[0];
        String username = argv[1];
        String password = argv[2];
        // load the JDBC driver for PostgreSQL
        Class.forName("org.postgresql.Driver");
        // connect to the datbase server over TCP/IP
        // (requires that you edit pg_hba.conf
        // as shown in the "Authentication" section of this article)
        db = DriverManager.getConnection("jdbc:postgresql:"+database,
                                         username,
                                         password);
        // create a statement for later use
        sql = db.createStatement();
        String theQuery = "select name from foo order by foo_id";
        System.out.println("Now executing query: \""+ theQuery + "\"\n");
        ResultSet results = sql.executeQuery(theQuery);
        if (results != null)
            {
                while (results.next())
                    {
                        System.out.println("Name: "+results.getString("name")+"\n");
                    }
            }
        else
            {
                System.out.println("No rows found");
            }
        results.close();
        db.close();
    }
    public static void showUsage()
    {
        System.out.println("\nUsage:\n "+
                           "java PgTest <database> <username> <password>   \n");
        System.exit(1);
    }
    public static void main (String args[])
    {
        if (args.length != 3) showUsage();
    try
        {
            PgTest showMe = new PgTest(args);
        }
    catch (Exception ex)
        {
            System.out.println("Caught Exception:\n"+ex);
            ex.printStackTrace();
        }
    }
}

Em seguida compilamos e executamos a aplicação Java.

PostgreSQL e PHP

Para que possamos usar o PostgreSQL com o PHP, teremos que recompilar  o PHP. Se você for como a maioria dos usuários OS X, isso irá lhe dar a oportunidade para atualizar o PHP para a versão 4.3.4. Devemos compilar o PHP com o módulo apxs. Essa não é a única solução, mas é a que permite usar o servidor Apache que vem pré-instalado com o Mac OS X. A parte importante é configurar o PHP como a opção –with-pgsql antes da compilação.

Em primeiro lugar, obtenha a última versão do PHP, disponível em PHP.net. Extraia o arquivo, e execute configure e make. Você pode desejar adicionar outros argumentos ao comando ./configure se quiser adicionar algum módulo em particular:

root@mail:src> tar -xzvf php-4.3.4.tar.gz
root@mail:src> cd php-4.3.4/
root@mail:php-4.3.4> ./configure --with-pgsql --with-apxs
root@mail:php-4.3.4> make
root@mail:php-4.3.4> make install
root@mail:php-4.3.4> cp php.ini-dist /usr/local/lib/php.ini

Agora edite o arquivo /etc/httpd/httpd.conf para dizer ao Apache para reconhecer a extensão .php:

  AddType application/x-httpd-php .php

Finalmente, inicie o servidor web com o comando apachectl start ou através da opção Compartilhamento nas Preferências do Sistema.

Documentação para as funções de acesso ao PostgreSQL no PHP podem ser encontradas nessa seção do manual do PHP. Você pode começar, porém, executando um script de teste. Crie um arquivo no diretório raiz do servidor web (normalmente /Library/Webserver/Documents/)  chamado “ph.php”:

<html>
<head>
        <title>Reading names from table 'foo' in db 'test'</title>
<head>
<body>
<?php
$conn = pg_connect("dbname=test user=liz password=liz");
if (!$conn)
{
        print "Unable to Connect to DB";
        exit;
}
$result = pg_query("select name from foo");
if (!$result)
{
        print "Unable to retrieve data";
        exit;
}
while ($arr = pg_fetch_array($result))
{
        print 'Name: ' . $arr['name'] . '<br>';
}
?>
</body>
</html>

Abaixo segue a saída desse script:

Administrando suas base de dados com o phpPgAdmin

Uma vez que tiver instalado o PHP e o suporte a PostgreSQL, pode tirar vantagem do phpPgAdmin, uma aplicação baseado na web que torna simples o gerenciamento de suas bases de dados PostgreSQL. A instalação do phpPgAdmin é simples: simplesmente baixe a aplicação no diretório raiz de seu servidor web, alterar alguns parâmetros de configuração e tudo estará pronto:

root@mail:~> cd /Library/WebServer/Documents/
root@mail:Documents> curl -O http://prdownloads.sourceforge.net/phppgadmin/phpPgAdmin-3.2.1.tar.gz
root@mail:/usr/local/src/phppgadmin> tar -xzvf phpPgAdmin-3.2.1.tar.gz

Se seu servidor estiver visível para qualquer um além dos usuário confiáveis, deve adicionar proteção de acesso ao diretório phpPgAdmin. Se não souber como adicionar autenticação a esse diretório, essas instruções do site Apache.org devem servir para você.

Antes que você possa executar o phpPgAdmin, precisará criar e editar o arquivo de configuração da aplicação, chamado config.inc.php:

root@mail:src> cd /Library/WebServer/Documents/phpPgAdmin
Open config.inc.php and edit it to match the code below:

Abra-o e edite-o para que fique de acordo com o exemplo abaixo:

// The $cfgServers array starts with $cfgServers[1].  Do not use $cfgServers[0].
// You can disable a server config entry by setting host to ''.
$cfgServers[1]['local']         = false;
$cfgServers[1]['host']          = 'localhost';
$cfgServers[1]['port']          = '5432';
$cfgServers[1]['adv_auth']      = true;
$cfgServers[1]['user']          = '';
// if you are not using adv_auth, enter the username to connect all the time
$cfgServers[1]['password']      = '';
// if you are not using adv_auth and a password is required enter a password
$cfgServers[1]['only_db']       = '';
// if set to a db-name, only this db is accessible

isso irá informar a aplicação que existe um servidor na máquina local (localhost), e instrui ela a pedir aos usuário web por um nome de usuário e senha válidos para o PostgreSQL.

Você pode agora abrir o phpPgAdmin em seu navegador preferido. Entre com “postgres” como nome de usuário, e “foo” (ou a senha que você criou anteriormente) como senha. Note que essa não é a senha do usuário “postgres” do OS X mas a senha que criamos com o comando alter user postgresql with password ‘foo’ na linha de comando do pgsql. Uma vez que estiver logado, será capaz de ver e editar as bases de dados, tabelas, usuários e grupos – tudo isso em uma interface web amigável.

Conclusão

O PostgreSQL é um banco de dados robusto que é ideal para desenvolvimento web no Mac OS X. Se estiver interessado em aprender mais sobre o que o PostgreSQL pod fazer, dê uma olhada na documentação para desenvolvedores, ou em algum dos muitos livros disponíveis.