-+  Associazione
-+  Documenti
-+  Eventi
-+  Community
-+  Blog
-+  Link

Ottobre 2013

Dom Lun Mar Mer Gio Ven Sab
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Cerca






 

« VII Pisa.pm meeting - 1 dicembre 2005 | Home | Perl Advent Calendar! »

Pillola di Novembre: Class::DBI
30.11.05

La "pillola di Perl" su Computer Programming questo mese parla di Class::DBI, con un articolo di Stefano Rodighiero.

Il compito non è facile: ho solo 2000 caratteri, e devo spiegare qualcosa di pratico da fare in Perl. Niente oneliner o tecniche simili: Perl è uno strumento che permette magie ben più potenti. E come se non bastasse ho già usato 200 caratteri solo per divagare! Dove non sarò io abbastanza stringato, dunque, lo sarà Perl.

Class::DBI

Se si parla di grandi risultati con piccolo sforzo, Class::DBI (CDBI) è un bell’esempio.

Supponiamo di avere la seguente tabella in un database:

CREATE TABLE persone (
    id int unsigned not null auto_increment,
    nome varchar( 50 ),
    cognome varchar( 50 ),
    primary key( id )
);

Se si adoperasse solo DBI (lo standard Perl per manipolare database) bisognerebbe scrivere codice Perl per la connessione al DB, codice SQL per le query, e così via. Con Class::DBI, invece, prepariamo per prima cosa una classe di configurazione con i parametri di connessione al DB (uso MySQL, ma non siamo vincolati a questo RDBMS):

package App::DBI;
use base 'Class::DBI'; # la superclasse e` Class::DBI
App::DBI->set_db(Main => 'dbi:mysql:mydb', 'login', ‘password');
1;

E ora una sottoclasse che rappresenta gli oggetti Persona, corrispondenti alle righe della tabella:

package App::Persona;
use base 'App::DBI';
App::Persona->table('persone');
App::Persona->columns( All => qw/ id nome cognome / ); 
1;

Tutto qui.
CDBI provvede automaticamente a generare i metodi per il fetch e lo store di record, gli accessor/mutator per ogni campo (avranno il nome delle colonne della tabella), un metodo search() per impostare criteri di selezione, e così via. Per un esempio, inserite qualche riga nella tabella e poi usate il codice del Listato 1.

CDBI fà molte altre cose. Visto però che la gestione di relazioni tra tabelle è fondamentale, vediamone un esempio. Supponiamo che le persone siano in realtà impiegati, e che ciascuno lavori in un certo ufficio. Avremo quindi una tabella ufficio (vedere il Listato 2), la cui chiave primaria sarà referenziata nella tabella persone (dove dunque dovremo aggiungere un colonna). La classe App::Ufficio sarà molto simile a quella già vista:

package App::Ufficio;
use base 'App::DBI';
App::Ufficio->table('uffici');
App::Ufficio->columns( All => qw/ id label / );
App::Ufficio->has_many( impiegati => ‘App::Persona’ );
1;

Attenzione a has_many()! Stabilisce che altri oggetti saranno legati alle istanze della classe che abbiamo definito.

Simmetricamente, aggiungeremo ufficio alle colonne della classe App::Persona.
Modifichiamo la chiamata a columns() come segue:

App::Persona->columns( All => qw/ id nome cognome ufficio / );

Indichiamo poi che ufficio è un riferimento ad una instanza della classe App::Ufficio:

App::Persona->has_a( ufficio => ‘App::Ufficio’ );

Nel Listato 2 c’è un esempio che mostra il funzionamento di quello che abbiamo preparato.

Spero di essere riuscito a mostrare un po’ della potenza di CDBI. Attenzione però! Non sempre le tabelle SQL si possono mappare direttamente in classi. L’adozione di strumenti potenti come CDBI non può non passare attraverso una attenta fase di progettazione.

Listato 1

#!/usr/bin/perl

use strict;
use warnings;

use App::Persona;

my $persone = App::Persona->retrieve_all();
# $persone e` un iteratore

while( defined( my $c = $persone->next() )) {
    print $c->nome() . " " . $c->cognome() . "\n";
}

Listato 2

#!/usr/bin/perl

# CREATE TABLE uffici (
#    id int unsigned not null auto_increment,
#    label varchar( 50 ),
#    primary key( id )
# );
# 
# CREATE TABLE persone (
#    id int unsigned not null auto_increment,
#    nome varchar( 50 ),
#    cognome varchar( 50 ),
#    ufficio int unsigned,
#    primary key( id )
# );

use strict;
use warnings;

use App::Persona;
use App::Ufficio;

my $uffici = App::Ufficio->retrieve_all();

while( defined( my $u = $uffici->next() )) {
	print $u->label() . "\n";

	my $impiegati = $u->impiegati();

    while (defined( my $i = $impiegati->next() )) {
		print "\t" . $i->nome() . " " $i->cognome . "\n";
	}
}

Inviato da larsen il 30.11.05 18:10
Ti è piaciuto questo articolo? Iscriviti al feed!










Devo ricordare i dati personali?






D:
Sull'autore...
D:
La ML di Perl.it
Iscriviti! mongers@lists.perl.it è la lista ufficiale di Perl Mongers Italia per porre quesiti di tipo tecnico, per rimanere aggiornato su meeting, incontri, manifestazioni e novità su Perl.it.
D:
Annunci Google