Brunosimioni's Blog

Tecnologia, informação e opinião.

Esse blog mudou!

leave a comment »

Esse blog foi alterado para o endereço próprio:

http://blog.brunosimioni.com

Written by Bruno Simioni

31 de março de 2015 at 10:06 AM

Publicado em Uncategorized

SQL/MED com jdbc_fdw / Integrando o PostgreSQL 9.2 com dados externos

leave a comment »

Pessoal, seguindo o post anterior de integração do PostgreSQL com dados externos utilizando o odbc_fdw, esse tutorial trata da integração do SGBD PostgreSQL (9.2) com diversas fontes de dados externas através de padrões bem definidos.

A conexão de dados é estabelecida através do padrão ISO/IEC 9075-9:2003 ou popularmente conhecida como SQL/MED, especificado no PostgreSQL via api do SQL/MED. A implementação que gostaria de trazer até vocês é a JDBC_FDW do meu amigo indiano Atri, que foi fruto do projeto GsoC 2012 que ele participou.

Eu (e também a Ampliato) preferi utilizar o JDBC_FDW ao invés do anteriormente mencionado aqui ODBC_FDW. O conector JDBC_FDW dá mais possibilidades (justamente por trabalhar com conectores jdbc e quase todo SGBD possuir uma implementação da especificação) e faz uma tratativa melhor para coerção de dados, além de também melhorar o tratamento de excessões e erros, podendo também ser utilizada em parceria com outros softwares / componentes do mundo Java. Tive experiências muito ruins com o ODBC_FDW por SIG_SEGFAULT, o que geralmente levava o banco inteiro a baixo. Também não tive problemas de desempenho para consultas básicas / moderadas.

Além disso, há um impasse técnico que aflige todo aventureiro que tenta algum FDW. Vivemos tempos de indefinições nesse mundo de implementação dos conectores, pois o PostgreSQL vem mudando a especificação da API FDW. Tais modificões tornou tanto o ODBC_FDW quanto o JDBC_FDW obsoletos na visão da versão mais recente (no momento 9.3).

Ainda não testei o JDBC_FDW na recém-lançada versão 9.3 do PostgreSQL, mas receio que não vá funcionar. Indico a versão 9.2, onde já usei tanto em ambiente Windows (PostgreSQL + JDBC_FDW compilados em Visual Studio. Não funciona em MingW, nem tente), quanto em Linux (compilados com GCC), e tive boas experiências em ambos os ambientes, conectados. O ODBC_FDW ficou pra trás já na versão 9.1.

Uma lista de todos os conectores FDW disponíveis para o PostgreSQL pode ser encontrada em sua wiki.  Com muito esforço na lista de emails pgsql-hackers o módulo postgresql_fdw foi incluso como contrib oficial (isso é, módulo adicional suportado, oficialmente incluso no source code. O restante dos FDWs são independentes, mantidos – ou não – por uma comunidade de aventureiros ou empresas). O postgresql_fdw veio para por um ponto final no dblink, anteriormente utilizado para realizar conexões e cross-database joins entre bancos distintos no mesmo cluster do SGBD.

Enfim, o JDBC_FDW nada mais é que um wrapper para a API FDW do PostgreSQL, basicamente respondendo da seguinte forma:

a) Usuário executa statement “Select * From TabelaEstrangeira”

b) PostgreSQL identifica TabelaEstrangeira como uma FDW, aciona o wrapper específico dessa (CREATE SERVER), que vai até a .so (ou .dll), e chama uma função pré-definida, dependendo da fase do statement. A .so (ou .dll) é o JDBC_FDW compilado, escrito em C.

c) Na chamada da função, em algum momento é instanciada um JVM (daí a importância da libjvm.so que vou mencionar abaixo). A JVM injeta no classpath da aplicação a implementação JDBC do banco destino.

d) A JVM manipula as chamadas do banco distinto através do JDBC.

e) JDBC_FDW faz coerção de dados e manipulação de volta dos dados para a API FDW do PostgreSQL.

f) PostgreSQL devolve os dados manipulados ao usuário.

De forma bem geral e abstrata é isso. Pra quem quiser se aventurar e escrever seu próprio FDW, aqui vai um link de como fazê-lo.

Vamos aos passos de instalação:

1. Baixe o jdbc_fdw através do github. Descompacte na pasta dos fontes (subpasta contrib) e prepare-se, pois você vai compilar código. Para realizar a compilação é necessário que você possua o código-fonte original que utilizou para compilar sua instalação do PostgreSQL. Caso não possua seu fonte original (instalou via yum / apt-get / zypper), recomendo remover a instalação antiga e instale na unha. Aqui tem a explicação de como realizar. Não esqueça que após a compilação é necessário iniciar o cluster através do initdb. É um procedimento simples de toda santa compilação: configure / make / make install.

2. Uma vez em  <SOURCE_POSTGRESQL/contrib/JDBC_FDW>, siga os passos do Atri aqui. Não se esqueça de realizar o link simbólico da libjvm.so. Ela será importante para que o JDBC_FDW funcione corretamente.

3. configure / make / make install.

4. Inicie o PostgreSQL (pg_ctl start -D PG_DATA).

5. Pronto, seu código está compilado e dentro da árvore do PostgreSQL. Registre a extensão instalada através do comando:

psql -c “CREATE EXTENSION jdbc_fdw” <BANCO>

Estamos quase lá. A partir de agora, todos os códigos serão executados dentro de uma conexão com algum banco no PostgreSQL (de preferência, o banco que você criou a extensão).

6. Crie um servidor para dados externos dentro do banco desejado no PostgreSQL (via psql ou outra ferramenta que preferir)

CREATE SERVER jdbc_serv FOREIGN DATA WRAPPER jdbc_fdw OPTIONS(
drivername 'org.sqlite.JDBC',
url 'jdbc:sqlite:/home/bruno/sqlitedatabase.db',
querytimeout '15',
jarfile '/home/bruno/sqlite-jdbc-3.7.2.jar',
maxheapsize '600'
);

Caso você tenha feito merda, remova o servidor através de:

DROP SERVER jdbc_serv;

7. Como todo SGBD de respeito exige um usuário e senha, mapeie seu usuário atual do banco PostgreSQL com o usuário do banco destino através de:

CREATE USER MAPPING FOR <PG_USER> SERVER jdbc_serv OPTIONS (username ‘<REMOTE_USER>’, password ‘s3cr3t’);

Caso você tenha feito merda, remova o mapeamento através de:

DROP USER MAPPING FOR <PG_USER> SERVER jdbc_serv;

8. Finalmente, mapeie a tabela remota com uma tabela local, através de um FOREIGN TABLE:

CREATE FOREIGN TABLE jdbc_table (
db_idfuncionario varchar,
db_re varchar,
db_nome varchar)
SERVER jdbc_serv
OPTIONS (query ‘select db_idfuncionario, db_re, db_nome from funcionarios;’);

Consulte a tabela:

select * from odbc_table limit 10; e seja feliz

Enfim, temos a conexão funcionando. Tive bons resultados com MS SQLServer 2000, MS SQLServer 2005, MS SQLServer 2008, SQLite, MySQL, e PostgreSQL 9.2.

Em tempo 1: Infelizmente a API FDW disponível na versão 9.2 é somente leitura. Além disso, a API da 9.2 não permite push-down join. Isso significa que se você realizar um join entre uma tabela local e uma estrangeira, a API irá primeiro recuperar todos os registros da tabela estrangeira e realizar um join local no PostgreSQL, e não remotamente como deveria acontecer. Escrita e push-down join em FDW somente na 9.3+.

Em tempo 2: O projeto JDBC_FDW está a procura de interessados em realizar a migração pra versão 9.3 do PostgreSQL (e implementar push-down / write). Quem tiver interesse não pense duas vezes em forkar o projeto do github!

Boa sorte!

Instalando o Teleduc 4

leave a comment »

Teleduc v4

Aqui vai um breve relato da experiência de instalação e desenvolvimento do tipo third-part do Teleduc v4. As minhas recomendações já foram passadas diretamente a equipe do NIED (Núcleo da Unicamp responsável pelo desenvolvimento do sistema). Enquanto as recomendações não são aplicadas, segue um pequeno passo-a-passo para ajudar a quem venha se interessar.

Encontrando o documento
1. Após uma busca simples no Google por ‘instalação teleduc’, encontrei o link do pdf no NIED referente ao procedimento de instalação.

2. Ao clicar no primeiro link, ganhei um 404 para o endereço: http://fenix.nied.unicamp.br/repositories/entry/teleduc/instalacao/Guia_de_Instalacao.pdf

3. No segundo resultado, tive sucesso, para o link http://www.teleduc.org.br/downloads/Guia_de_instalacao.pdf

Processo de instalação
3.1 Ao abrir o documento, senti falta de um formato formal ao documento, uma vez que é feito pelo pessoal do NIED. Acho que ficaria legal se o manual técnico tive ao menos, o logotipo do produto, bem como do NIED, criando uma identidade que faça menção aos criadores.

3.2 Ao passar pela instalação do LAMP, coloquei uma sugestão de inserir o link para o Bitnami Stack. Esse produto, gratuíto e opensource, traz um appliance pronto para ser colocado em produção, ao invés de ter que ter acesso a super usuário da máquina e instalar diretamente na árvore do sistema operacional, gerando possíveis conflitos. Ex: Possuo 3 ou 4 softwares que utilizam a pilha LAMP, e alguns deles só rodam com versões específicas de PHP e MySQL. Instalei 4 pilhas da Bitnami e configurei os bancos e apaches em portas diferentes, viabilizando tudo em uma máquina só. O site do Bitnami é: http://bitnami.org/ . Apenas complementando, pelo que vi no código fonte, o Teleduc usa variáveis globais do PHP. Unir esse aspecto ao fato do software rodar como superusuário, é gerar um grande backdoor no servidor que rodará o aplicativo.

3.3 Na seção seguinte, o manual me instrui a criar um usuário ‘teleduc’, específico para rodar a aplicação. Esse passo poderia ser comentado, explicando sua importância.

3.4 Antes desse passo, as versões do softwares envolvidos também poderiam ser especificadas para melhorar o entendimento de qual ambiente escolher para instalar. Problema exemplo que tive: nenhum dos arquivos .php do software possui diretivas explícitas do PHP. Para tal, é necessário adicionar diretivas de short_open_tag = On no arquivo de configuração do PHP.ini.

3.5 O manual técnico não menciona que será necessário instalar e configurar o sendmail para que o software envie emails automaticamente. Particularmente, o sendmail é muito complicado, de difícil configuração, e muito provavelmente leva seu email diretamente para a caixa de spam do destinatário (alunos e cordenadores de custo). Nesse ponto, seria muito legal poder informar um endereço de servidor SMTP, para que o Teleduc o use para enviar os emails. Dá pra fazer isso via sendmail (teleduc > sendmail > servidor smtp > destinatário), mas também é de difícil configuração.

Um outro ponto é que, durante a configuração do Teleduc (as páginas que configuram o banco/conexões/etc), não explicitam como os links enviados por email ficarão de acordo com o endereço de hospedagem do teleduc. Por exemplo, após uma série de tentativas e erros, consegui configurar isso no nosso servidor, que tem o teleduc disponível via: http://———-:8085/teleduc, para enviar os links corretos por email. Outro problema é o remetente, que inicialmente veio como: NAO_RESPONDA@——-“:8085@heaven.ampliato.com.br (???)

ps: —— é a url do host, ex: asd.asd.com.br

3.6 As configurações do httpd.conf não são explicadas, e para um responsável de TI, que visa segurança de dados, fica difícil pois ele vai ter que procurar cada diretiva e entender o que faz, para garantir que vai funcionar.

3.7 No item 4, a url da aplicação pode não ser aquela especificada, dependendo da instalação. Vale uma explicação de como ela é montada.

3.8 Para finalizar o manual, acredito que valeria a pena colocar um glossário no documento, além de uma seção de erros comuns, como os que eu reportei aqui.

Suporte e canal de ajuda
4. Houve diversos pontos de dúvida durante o processo de instalação, e senti falta de uma referência ao grupo de desenvolvimento do projeto, ou o responsável com que eu pudesse tirar dúvidas. No mundo opensource é muito comum haver canais de comunicação com os responsáveis do software. Para isso, sugiro:

4.1 Lista de emails pública para desenvolvedores e para usuários, ex: teleduc-dev@googlegroups.com e teleduc-users@googlegroups.com

4.2 Canal de IRC em algum servidor público, como a Mozilla (irc.mozilla.org), ou o Freenode (irc.freenode.net). É só mandar um email aos administradores solicitando a criação de uma sala. Muita gente utiliza o IRC para desenvolver remoto. Muita mesmo.

4.3 Sistema de tracker para abertura de bugs. Aqui, vale a pena citar o Redmine ou o Trac, que são ferramentas muito boas para esse trabalho.

4.4 Sistema de forum para discussões com a comunidade, além de notificações, publicações e dúvidas abertas.

Desenvolvimento third-part.
5. Quando iniciei o desenvolvimento da integração, busquei por documentos que mostrassem como a base foi modelada, como o software foi construído, e quais são os conceitos que ele emprega. Não tivemos sucesso nesse processo, e vale comentar:

5.1 No site, há menção a um documento chamado teleduc-v3.0-documentacao.tar.gz mas o link é inválido. Após diversas consultas no Google, o encontramos no ftp de uma outra universidade. A documentação está incompleta, contendo somente os MERs, e da versão antiga. Não encontramos um equivalente para a versão 4, que estamos utilizando. O link é: ftp://ftp.fja.edu.br/ead/teleduc/teleduc-v3.0-documentacao.tar.gz

5.2 Não encontramos diagramas de sequência/atividade que pudesse mostrar como o software funciona, nem como os arquivos-fonte são utilizados5.3 Não encontramos nenhum documento oficial que possa nos ajudar em relação aos conceitos do Teleduc. O que chegamos mais perto foi um manual de usuário de uma outra universidade: http://www.unilasalle.edu.br/canoas/ftp/ead/Teleduc.Manual%20Usuario.pdf , que mostra alguns dos conceitos básicos da ferramenta, mas também não cobre detalhes técnicos sobre qual a versão, e demais dados.Consegui algum sucesso no desenvolvimento da integração via tentativa/erro, e entendendo como as coisas se comportam dentro da base de dados. Como são bancos diferentes em cada curso, ficou mais simples de entender a organização.
Caso o leitor ainda esteja tendo problemas, não deixe de comentar.

Written by Bruno Simioni

21 de dezembro de 2012 at 11:32 PM

Publicado em Experimentos

Tagged with , , , ,

Sobre clientes Web.

leave a comment »

Olá leitores,

Dando continuidade ao assunto de construção de aplicações Web, como iniciado no post anterior, iniciarei falando um pouco do que eu entendo sobre clientes Web.

Denomindo cliente Web, qualquer software que seja capaz de utilizar a Web como plataforma de construção de aplicação. Utilizar a Web como plataforma, é utilizar os protocolos abertos que a formam, utilizar os padrões que a denominam, e oferecer, no mínimo, os recursos disponíveis através do uso desta. Portanto, denomino cliente Web, desde uma página hospedada em um servidor, a um cliente desktop construído através de tecnologias Web.

Inicialmente vejo como objetivo, criar e definir um modelo de arquitetura de cliente que seja capaz de cobrir tantos os clientes que são produzidos através de navegadores, quanto clientes construido em desktop. É necessário observar que clientes desktop que utilizam a plataforma web (portanto, aproveitando a segurança e flexibilidade de aplicações desktop, e a viabilidade de aplicações de navegadores), são categorizados como aplicações ricas para Internet (RIA). Pra quem ainda não conhece essa categorização, vale a pena dar uma olhada nas referências, e talvez comece a fazer sentido a aparição de nomes como Adobe AIR, Microsoft Silverlight, Sun JavaFx, Mozilla Xulrunner, e derivados. Portanto, caminharei para o lado de clientes RIA, que utilizam a Web como plataforma, para a construção de aplicações.

Sobre a estrutura de dados que fomenta a construção de aplicações, imagino dividi a solução em algumas partes, cada qual, com sua finalidade. Eu imagino, inicialmente, 3 camadas responsáveis, consecutivamente, por, apresentação, arcabouço comum de infraestrutura de aplicação, e plataforma de execução.

Sobre a construção de interfaces

A primeira camada seria a construção da lógica exclusiva da aplicação (interface, estilos, e lógica de funcionamento do programa). Seria ideal que essa primeira camada fosse construída cada qual, com seu padrão Web já estabelecido (preferencialmente pela W3C), e principalmente, com tecnologias abertas e livres de plataforma.

Sobre interface de usuário, existem duas maneiras comuns de construí-la: programáticamente e declarativamente. Eu, particularmente, vejo a construção declarativa de interfaces, uma forma mais intuitiva e interoperável de definir a característica “visível e usável” da aplicação. A utilização de um formato taxonômico interoperável (alguma derivação do XML, ou o próprio, através de um XML Schema) seria ideal para esse caso.

Para ilustrar as duas abordagens sobre construções de interfaces, ilustro a construção hipotética de uma caixa horizontal com uma caixa de texto e um botão dentro.

Da maneira programática, funcionaria da seguinte forma (em JavaScript):

var CaixaHorizontal = new CaixaHorizontal();

var TextBox = new TextBox();

var Button = new Button();

CaixaHorizontal.adicioneFilho(TextBox);

CaixaHorizontal.adicioneFilho(Button);

Da maneira declarativa, já seria construído da seguinte forma (alguma derivação de XML, utilizando algum NameSpace):

<caixahorizontal>

<textbox/>

<button/>

</caixahorizontal>

Há quem prefira a construção programática, e há quem prefira a declarativa. Eu acredito ser mais efetivo a declarativa, já que pode-se separar a lógica da aplicação, da construção de sua inteface de usuário.

Continuando o raciocínio, uma vez construída declarativamente a interface de usuário, então, através de folhas de estilos (que funcione da mesma forma em qualquer plataforma.), define-se os estilos dos componentes que foram criados através da linguagem declarativa. Vale lembrar que tais folhas de estilos, devem condizer com o gosto de consumidor. Já que estamos falando de construção de interfaces que sejam semelhantes, em diferentes plataformas, podemos manter as características de cada plataforma, ou então, definir uma característica única, que seja a mesma para as três plataformas. Estou dizendo, por exemplo, que se um botão deve ser igual em diferentes sistemas operacionais, então ele terá que ser, caso não, ele deverá ter a aparência nativa de cada plataforma.

Para o caso das folhas de estilos, a minha preferência fica com o CSS, aliado às entidades declaradas na construção da interface. Portanto, posso criar uma classe CSS “botao”, e associá-la ao meu elemento XML, definido em algum NameSpace, da seguinte forma:

.botao {border: 1px solid red;}

<button class=”botao”/>

E então, em qualquer diabo de lugar que eu rodar minha interface gráfica, ela terá uma borda vermelha no botão (o que não é nada indicado, sobre a borda vermelha).

Sobre a lógica de funcionamento do programa, através de uma linguagem prototipada ou orientada a objetos, permitindo escalabilidade na lógica.

Sobre o framework de aplicação

A segunda camada, seria a base da aplicação, sendo um framework que conseguisse abstrair critérios de aplicação, bem como chamadas a recursos que estão na web, e fomalização de interfaces de comunicação com plugins, o que permitiria a flexibilização do framework, e a personalização deste, conforme a necessidade. Este framework seria escrito em uma linguagem de altíssimo nível (linguagem de programação de quarta ou quinta geração, e portanto, interpretada (ou compilada), mas livre de plataforma).

Sobre a plataforma de execução

Referências:

http://pt.wikipedia.org/wiki/Internet_rica

http://en.wikipedia.org/wiki/Rich_Internet_application

Written by Bruno Simioni

21 de dezembro de 2012 at 11:25 PM

Criando um bot de XMPP utilizando a Smack.

leave a comment »

Senhores, boa noite. Segue código para implementar rapidamente um cliente de XMPP utilizando a biblioteca Smack (implementação opensouce de XMPP para java). Eu pesquisei algumas outras bibliotecas, mas escolhi essa devido a sua documentação e maturidade da ferramenta.

Vamos a brincadeira.

// connect to gtalk server
ConnectionConfiguration connConfig = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
this.conn = new XMPPConnection(connConfig);
this.conn.connect();
// login 
this.conn.login(aUserName, aPassword);

// set presence status info
Presence presence = new Presence(Presence.Type.available);
this.conn.sendPacket(presence);

// receive any packet
PacketListener pl = new PacketListener() {
    @Override
    public void processPacket(Packet p) 
    {
        if (p instanceof Message) 
        {
            Message msg = (Message) p;
            responseMessage(msg);
        }
    }
};

this.conn.addPacketListener(pl, null);

// retrieve user list
Roster roster = this.conn.getRoster();
roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);

roster.addRosterListener(new RosterListener() {

    @Override
    public void presenceChanged(Presence arg0) {

    }

    @Override
    public void entriesUpdated(Collection<String> arg0) {

    }

    @Override
    public void entriesDeleted(Collection<String> arg0) {

    }

    @Override
    public void entriesAdded(Collection<String> arg0) {
    }
});

Boa sorte a todos.

Written by Bruno Simioni

21 de dezembro de 2012 at 11:21 PM

Publicado em Experimentos

Tagged with , , , , , ,

Criando um bot de XMPP utilizando a Smack.

leave a comment »

Senhores, boa noite. Segue código para implementar rapidamente um cliente de XMPP utilizando a biblioteca Smack (implementação opensouce de XMPP para java). Eu pesquisei algumas outras bibliotecas, mas escolhi essa devido a sua documentação e maturidade da ferramenta.

Vamos a brincadeira.

// connect to gtalk server
ConnectionConfiguration connConfig = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
this.conn = new XMPPConnection(connConfig);this.conn.connect();

// login 
this.conn.login(aUserName, aPassword); 

// set presence status info
Presence presence = new Presence(Presence.Type.available);
this.conn.sendPacket(presence);

// receive any packet
PacketListener pl = new PacketListener() {    
    @Override
    public void processPacket(Packet p)     
    {        
        if (p instanceof Message)         
        {            
            Message msg = (Message) p;
            responseMessage(msg);
        }
    }
};

this.conn.addPacketListener(pl, null);

// retrieve user list
Roster roster = this.conn.getRoster();
roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);

roster.addRosterListener(new RosterListener() {
    @Override
    public void presenceChanged(Presence arg0) {
    }

    @Override public void entriesUpdated(Collection<String> arg0) {
    }        

    @Override    
    public void entriesDeleted(Collection<String> arg0) {
    }        

    @Override public void entriesAdded(Collection<String> arg0) {    
    }
});

Boa sorte a todos.

Written by Bruno Simioni

18 de novembro de 2011 at 10:22 PM

Publicado em Experimentos

Acessando o Gmail com Push-IMAP e JavaMail

leave a comment »

Boa tarde leitores!

Segue um exemplo de como acessar o Gmail via JavaMail, utilizando a estratégia de server push, evitando assim, realizar polling no servidor para verificar se novas mensagens chegaram! Não se deve esquecer de implementar um tratador de queda de conexão, afinal, o controle deverá ser maior!

Properties props = System.getProperties();
 props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
 props.setProperty("mail.imap.socketFactory.fallback", "false");
 props.setProperty("mail.store.protocol", "imaps");
 Session session = Session.getDefaultInstance(props, null);
IMAPStore server;
try {
 server = (IMAPStore) session.getStore("imaps");
 }
 catch(Exception e) {}
try {
// aImapAddr deverá apontar para imap.googlemail.com fora dos EUA
server.connect(aImapAddr, aUserName, aPassword);
 IMAPFolder folder = (IMAPFolder) server.getFolder("INBOX");
 folder.open(Folder.READ_WRITE);
// defina um listener
 folder.addMessageCountListener(new MessageCountListener() {
 @Override
 public void messagesRemoved(MessageCountEvent arg0) {
 System.out.println("ops, mensagens removidas!");
 }
@Override
 public void messagesAdded(MessageCountEvent arg0) {
 System.out.println("ops, novas mensagens!");
 }
 });
// entre em espera
 folder.idle();

Boa sorte a todos!

Written by Bruno Simioni

18 de novembro de 2011 at 1:00 PM

Publicado em Experimentos

Tagged with , , , , ,

SQL/MED com odbc_fdw no PostgreSQL 9.1.1

with 2 comments

Pessoal, seguindo o post anterior, continuei minha pesquisa e resolvi postar um outro tutorial estendendo a conexão do PostgreSQL com qualquer banco, através do ODBC.

Para realizar essa ponte é necessária a utilização de um servidor ODBC local, e a extensão odbc_fdw do PostgreSQL, além do driver ODBC do SGBD específico a conexão é desejável.

A idéia geral é que o PostgreSQL converse com um servidor ODBC, que através de drivers, consegue conversar com diversos SGBDs. O mapeamento de tipos e de tabelas é feito diretamente dentro do odbc_fdw no PostgreSQL.

Vamos a receita, iniciando pela configuração do servidor ODBC, e logo após, a configuração do conector SQL/MED:

1. Instale o servidor ODBC no sistema operacional. No meu caso, estou utilizando o linux OpenSuse 11.4, e para realizar o procedimento, instalei o software unixODBC diretamente do YaST.

2. Instale o driver ODBC para o banco destino da conexão. No meu caso, conectei o PostgreSQL em um servidor SQLServer 2005 via FreeTDS (implementação livre do protocolo Tabular Data Stream). Para ganhar tempo e não precisar ficar procurando dependências do FreeTDS para realizar a compilação do zero, instalei um repositório do build service (devel:languages:misc) que já possuia uma compilação para minha distro.

3. Verifique a instalação do driver. No meu caso, a biblioteca responsável pelo driver TDS para o unixODBC estava em /usr/lib64/libtdsodbc.so.0

4. Configure o unixODBC. Através da ferramenta gráfica ODBCConfig é possível instrumentar os arquivos de configuração (tanto de sistema em /etc/unixODBC/{odbc.ini,odbcinst.ini}, quanto de usuário em ~/.odbc.ini) de maneira mais simples. Após a instalação do FreeTDS, já deverá ser possível visualizá-lo na lista de drivers da ferramenta. O próximo passo é configurar uma conexão (DataSource Name – DSN) do ODBC com o banco destino, através do driver instalado.

Visualização dos drivers instalados no unixODBC

CRUD para adição de um DSN

5. Após a finalização do registro do DSN de conexão com seu banco, verifique as configurações nos arquivos referentes. Se você está executando como superusuário, verifique os arquivos de configuração (odbc.ini,odbcinst.ini) em /etc/unixODBC. Caso esteja executando como usuário normal, verifique em ~/.odbc.ini.

6. Faça um teste de conexão do unixODBC através de um utilitário do projeto chamado isql. Este software é um pequeno cliente SQL que permite conectar-se nos bancos suportados pelos drivers registrados (via DSN) no unixODBC. Para o teste, execute:

isql -v <DSN> <UID> <PASSWD>, e brinque com sql. O parâmetro -v indica modo verbose, informando possíveis erros.

.

.

.

Pausa para o café.

.

.

.

Essa primeira parte da receita tratou de efetivar a conexão do unixODBC com o SGBD destino. Uma vez que essa conexão está garantida e estável, podemos seguir em frente, para os passos do odbc_fdw.Assim como anotado no post anterior, é possível realizar a instalação do odbc_fdw via PGNX, ou via Makefile e compilação na unha. Vamos pelo caminho das pedras.

8. Baixe o odbc_fdw através desse link. Descompacte e prepare-se, pois você vai compilar código. Para realizar a compilação é necessário o header do sql.h, que são encontrados no pacote unixODBC-devel. Baixe o pacote através do seu gerenciador de pacotes. Após o download, entre na pasta descompactada do odbc_fdw, execute:

PATH=<CAMINHO DO PG_CONFIG (binários do PGSQL)>:$PATH USE_PGXS=1 make
PATH=<CAMINHO DO PG_CONFIG (binários do PGSQL)>:$PATH USE_PGXS=1 make install

9. Pronto, seu código está compilado e dentro da árvore do PostgreSQL. Registre a extensão instalada através do comando:

psql -c “CREATE EXTENSION odbc_fdw” <BANCO>

Estamos quase lá. A partir de agora, todos os códigos serão executados dentro de uma conexão com algum banco no PostgreSQL (de preferência, o banco que você criou a extensão).

10. Crie um servidor para dados externos utilizando o DSN que você especificou na configuração do driver no unixODBC:

CREATE SERVER odbc_server FOREIGN DATA WRAPPER odbc_fdw OPTIONS (dsn ‘<DSN DO ODBC>’);

Caso você tenha feito merda, remova o servidor através de:

DROP SERVER  odbc_server;

11. Como todo SGBD de respeito exige um usuário e senha, mapeie seu usuário atual do banco PostgreSQL com o usuário do banco destino através de:

CREATE USER MAPPING FOR <PG_USER> SERVER odbc_server OPTIONS (username ‘<REMOTE_USER>’, password ‘s3cr3t’);

Caso você tenha feito merda, remova o mapeamento através de:

DROP USER MAPPING FOR <PG_USER> SERVER odbc_server;

12. Finalmente, mapeie a tabela remota com uma tabela local, através de um FOREIGN TABLE:

CREATE FOREIGN TABLE odbc_table (
db_idfuncionario varchar,
db_re varchar,
db_nome varchar
)
SERVER odbc_server
OPTIONS (
database ‘<REMOTE_DB>’,
schema ‘<REMOTE_SCHEMA>’,
sql_query ‘select idfuncionario, re, nome from funcionarios’,
sql_count ‘select count(*) from funcionarios’,
db_idfuncionario ‘idfuncionario’,
db_re ‘re’,
db_nome ‘nome’
);

Consulte a tabela:

select * from odbc_table limit 10; e seja feliz.

A foreign table permite diversos atributos para mapeamento entre a tabela remota e a local. A tabela completa pode ser encontrada no site do projeto.

Boa sorte!

Written by Bruno Simioni

29 de setembro de 2011 at 1:30 AM

SQL/MED com twitter_fdw no PostgreSQL 9.1.1

leave a comment »

Fala galera.

Segue uma pequena receita que bolei baseado em alguns tutoriais e textos, para utilização do SQL/MED dentro do PostgreSQL 9.1.1, para realizar a comunicação com o Twitter via SQL, através de sua API JSON.

A mágica acontece graças a libcurl e a libjson, que traduzem os resultados JSON da api do Twitter e realizam a transformação para dimensões relacionais do banco, através de uma tabela chamanda twitter.

Eu testei na versão 9.1.1, entretanto é possível o seu funcionamento desde a versão 8.4.

1. Faça o download da extensão do PostgreSQL (ou baixe via PGXNClient) em: http://pgxn.org/dist/twitter_fdw/ e descompacte.

2. Você vai compilar a extensão (via PGXNClient ou Makefile manual), então certifique-se que a libcurl-devel esteja  instalada no seu ambiente. A libjson já vem com o pacote, ligada estaticamente.

3. Passos para compilar:

3.1: export USE_PGXS=1

3.2: PATH=<CAMINHO DO PG_CONFIG (bin da instalação)>:$PATH make

3.3: make install

4. Crie a extensão dentro do PostgreSQL, uma vez que esta já foi compilada e instalada na pasta de binários do SGBD.

psql -c “CREATE EXTENSION twitter_fdw” <BANCO>

5. Faça uma consulta no Twitter utilizando SQL.

SELECT from_user, created_at, text FROM twitter WHERE q = ‘#postgresql’;

6. Como referência, segue a estrutura da tabela criada pela extensão:

Onde q é utilizada como coluna virtual para realizar buscas na API, e pode ser utiliza, por exemplo como: WHERE q = ‘#sometext’

Boa sorte a todos!

Written by Bruno Simioni

28 de setembro de 2011 at 11:37 PM

Publicado em Experimentos

Tagged with , , , , , ,

Script de proximidade para bluetooth.

leave a comment »

E aí minha gente. Segue um pequeno script pra lidar com qualidade de sinal bluetooth. É necessário sua adaptação pra funcionar corretamente.

Um abraço e boa sorte!

#!/bin/bash
# Baseado em http://gentoo-wiki.com/Talk:TIP_Bluetooth_Proximity_Monitor

# PARA EDITAR!

# MAC do dispositivo Bluetooth
DEVICE="00:00:00:00:00:00" 

# Distancia em segundos de intervalo de checagem.
CHECK_INTERVAL=2

# Limitante do RSSI
THRESHOLD=-15

# Comando a rodar quando você estiver distante
FAR_CMD='/usr/bin/gnome-screensaver-command --activate'

# Comando a rodar quando estiver próximo
NEAR_CMD='/usr/bin/gnome-screensaver-command --poke'

HCITOOL="/usr/bin/hcitool"
STARTX_PID=0
DEBUG="/tmp/btproximity.log"

connected=0

function msg {
    echo "$1" #>> "$DEBUG"
}

function check_connection {
    connected=0;
    found=0
    for s in `$HCITOOL con`; do
        if [[ "$s" == "$DEVICE" ]]; then
            found=1;
        fi
    done
    if [[ $found == 1 ]]; then
        connected=1;
    else
       msg 'Attempting connection...'
        if [ -z "`$HCITOOL cc $DEVICE 2>&1`" ]; then
            msg 'Connected.'
            connected=1;
        else
                if [ -z "`l2ping -c 2 $DEVICE 2>&1`" ]; then
                        if [ -z "`$HCITOOL cc $DEVICE 2>&1`" ]; then
                            msg 'Connected.'
                            connected=1;
                        else
                        msg "ERROR: Could not connect to device $DEVICE."
                        connected=0;
                        fi
                fi
        fi
    fi
}

check_connection

while [[ $connected -eq 0 ]]; do
    check_connection
    sleep 3
done

name=`$HCITOOL name $DEVICE`
msg "Monitoring proximity of \"$name\" [$DEVICE]";

state="near"
while /bin/true; do

    check_connection

    if [[ $connected -eq 1 ]]; then
        rssi=$($HCITOOL rssi $DEVICE | sed -e 's/RSSI return value: //g')

        if [[ $rssi -le $THRESHOLD ]]; then
            if [[ "$state" == "near" ]]; then
                msg "*** Device \"$name\" [$DEVICE] has left proximity"
                state="far"
                $FAR_CMD > /dev/null 2>&1
            fi
        else
            if [[ "$state" == "far" && $rssi -ge $[$THRESHOLD+2] ]]; then
                msg "*** Device \"$name\" [$DEVICE] is within proximity"
                state="near"
                $NEAR_CMD > /dev/null 2>&1
                STARTX_PID=$(pgrep startx)
            fi
        fi
        msg "state = $state, RSSI = $rssi"
    fi

    sleep $CHECK_INTERVAL
done

Written by Bruno Simioni

11 de julho de 2011 at 8:42 PM

Publicado em Experimentos

Tagged with , , ,