• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Dkid

[Perl] DBIC & MySQL

Interessante?   3 membros votaram

  1. 1. Interessante?

    • sim
      3
    • não
      0

Please inicie sessão ou registe-se para votar.

2 mensagens neste tópico

DBIx::Class

Ando a elaborar um projecto em que é necessário utilizar o DBIC, e tenho-me deparado com grandes dificuldades em construir pesquisas(Selects em SQL ou Searches em DBIC).

Portanto decidi abordar o tema aqui no P@P, pode ser que haja mais pessoas com dificuldades, eu incluído (que ainda não as superei).

Antes demais, o que é o DBIC ?

É um modulo que nos permite “mapear” uma (ou várias) bases de dados

EN : http://en.wikipedia.org/wiki/Object-relational_mapping

PT-BR : http://pt.wikipedia.org/wiki/Mapeamento_objeto-relacional

Precisamos então de:

Servidor SQL (MySQL)

DBIx::Class (instalar pelo cpan)

E... muita paciência

Criar a base de dados

create database dbswiak;

use dbswiak;

-- has_one

create table Utilizadores(

utilizador int not null primary key AUTO_INCREMENT,

nome varchar(20),

mail varchar(30)

);

-- belongs_to

create table Passwords(

pswd int not null primary key AUTO_INCREMENT,

password varchar(20),

utilizadorID int,

Foreign key(utilizadorID) References Utilizadores(utilizador)

);

-- Relacionado com Utilizador

insert into Utilizadores(nome,mail) values('usr','email@mail.com');

insert into Passwords(password,utilizadorID) values('pswd','1');

Após a base de dados estar construida temos duas alternativas:

1- Mapeamos as tabelas manualmente;

2- Usamos o DBIx::Class::Schema::Loader, que nos mapea automaticamente, mas isso não significa que nos faça o trabalho todo.

O que o DBIx::Class::Schema::Loader não faz?

Ele não vos gera a relação das tabelas, logo vamos ter de escrever essa parte do código.

Para fazermos uso do DBIx::Class::Schema::Loader vamos à consola(terminal) e escrevemos algo semelhante :

perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:/home/user/Desktop/Esquema/ -e 'make_schema_at("DB::Esquema", { debug => 1 }, [ "dbi:mysql:dbname=dbswiak","root" ])'

dump_to_dir deve ser alterado para o destino que pretendem.

Para mim esta é a forma mais rápida de termos o trabalho feito, existem outras formas de fazer este “serviço”.

Após isso, devem ter 2 pastas (DB, e Esquema neste caso)

Modulo Passwords

package DB::Esquema::Passwords;



use strict;

use warnings;



use base 'DBIx::Class';



__PACKAGE__->load_components("Core");

__PACKAGE__->table("Passwords");

__PACKAGE__->add_columns(

  "pswd",

  { data_type => "INT", default_value => undef, is_nullable => 0, size => 11 },

  "password",

  {

    data_type => "VARCHAR",

    default_value => undef,

    is_nullable => 1,

    size => 20,

  },

  "utilizadorid",

  { data_type => "INT", default_value => undef, is_nullable => 1, size => 11 },

);

__PACKAGE__->set_primary_key("pswd");

# Created by DBIx::Class::Schema::Loader v0.04006 @ 2009-11-17 15:02:43

# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:5r8RYDfmdvfJ4AsmEOCvoA





# You can replace this text with custom content, and it will be preserved on regeneration

1;

O que falta neste modulo ? Falta a relação com a tabela Utilizadores.

Antes dos comentários, e por baixo da linha

__PACKAGE__->set_primary_key("pswd");

Devem escrever:

__PACKAGE__->belongs_to('utilizadorid' => 'DB::Esquema::Utilizadores');

Módulo Utilizadores

package DB::Esquema::Utilizadores;



use strict;

use warnings;



use base 'DBIx::Class';



__PACKAGE__->load_components("Core");

__PACKAGE__->table("Utilizadores");

__PACKAGE__->add_columns(

  "utilizador",

  { data_type => "INT", default_value => undef, is_nullable => 0, size => 11 },

  "nome",

  {

    data_type => "VARCHAR",

    default_value => undef,

    is_nullable => 1,

    size => 20,

  },

  "mail",

  {

    data_type => "VARCHAR",

    default_value => undef,

    is_nullable => 1,

    size => 30,

  },

);

__PACKAGE__->set_primary_key("utilizador");

__PACKAGE__->has_one('utilizador' => 'DB::Esquema::Passwords', 'utilizadorid');



# Created by DBIx::Class::Schema::Loader v0.04006 @ 2009-11-17 15:02:43

# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:oOS+GMFNAgHBA65eOhnmMw





# You can replace this text with custom content, and it will be preserved on regeneration

1;

Agora... o que faço eu com isto? Como é que trabalho a informação?

#!/usr/bin/perl -w



#vamos ligar os pragmas

use strict;

use diagnostics;	# diagnostico, grande ajuda

use lib '/var/www/projectox/lib'; 	#path onde estao os meus modulos

use DB::Esquema;	#path para os modulos

use Data::Dumper; #useless aqui



system('clear'); # limpa o ecrã



my $esquema = DB::Esquema->connect("dbi:mysql:dbname=dbswiak","root","");

$esquema->storage->debug(1);	#debug!



my $resultado = $esquema->resultset('Utilizadores')->search( #não é o nome da tabela, é sim o nome do modulo Utilizadores(case sensitive)

undef,{ #undef porque não vamos usar o WHERE; A explicação que recebi : because it's just prefetch, it doesn't add a WHERE condition

     prefetch => { 'utilizador' => 'utilizadorid' }

  }

)->next();

Isto tem o seguinte resultado:

SELECT me.utilizador, me.nome, me.mail, utilizador.pswd, utilizador.password, utilizador.utilizadorid, utilizadorid.utilizador, utilizadorid.nome, utilizadorid.mail 
FROM Utilizadores me JOIN Passwords utilizador 
ON utilizador.utilizadorid = me.utilizador 
JOIN Utilizadores utilizadorid 
ON utilizadorid.utilizador = utilizador.utilizadorid: 

Podem ver o resultado com uma query ao servidor.

Não era bem esse o resultado que eu pretendia, apenas queria algumas colunas, mas ainda não consegui. Não estou muito preocupado, pois no ambiente web depois posso seleccionar apenas os campos que me interessam e fica resolvido... lol. Mas ainda hei-de matutar nessa solução.

Fontes :

http://search.cpan.org/~frew/DBIx-Class-0.08114/

IRC : #dbix-class no irc.perl.org/6667

Conselho, quando se meterem nisto deixem de pensar em SQL, pensem em objectos, porque na verdade é o que eles são. (Foi um bom conselho que me deram)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas,

Bem diz o ditado que devagar se vai ao longe (espero que sim ;)).

Quando queremos determinadas colunas usamos a função columns e determinamos quais nos interessam:

my $resultado = $tomada->resultset('Contactos')->search( undef, #Contactos = tabela
 {columns => [ qw/ contacto nome mail mensagem /] } # as colunas que me interessam
);

#output da informação por cada contacto que houver na base de dados
while (my $contacto = $resultado->next) {
	print "Contacto ID:". $contacto->contacto ."\nNome:". $contacto->nome ."\nEmail:". $contacto->mail .
"\nMensagem:". $contacto->mensagem . "\n";
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora