rje has asked for the wisdom of the Perl Monks concerning the following question:

Gentlemonks,

I am thinking about an Entity Bean package. I'm sure someone has written a CPAN module for this already. Something not unlike Tie::DBI, or actually more like Class::DBI.

What am I thinking of? A package that streamlines the creation of objects from rows in a database.

For example, I'm managing a configuration table... call it CONFIG. It has columns like this:
   location_id (primary key)
   local_dir
   file_pattern
   count_method
   log_level
   production
   destinations
   archive
So, I'm writing a Perl package that accepts a database handle and a primary key, queries the db, and populates its fields appropriately, when I got to idly thinking that all this should already be done for me. But where? And how?

Perl isn't magic. Any package that automated this kind of process would still have to know what columns to query and where to put them. Or perhaps I'm thinking about it backwards. The target class has a table name and a list of column names, and feeds them to the automation package -- which could have the database handle. Fine. Then perhaps it also has a place to store the data once retrieved. Well, of course it does: the class has access methods. So how about I name those methods the same as the column names... ok. Then the automation package does a SELECT, then calls the target class' methods to load the column values in.

Surely this kind of thing has already been done. So does anyone know the name of the package? I must be overlooking something obvious (like tie, or something).

Thanks,
Rob

Replies are listed 'Best First'.
Re: Perl Entity Bean
by Corion (Patriarch) on Dec 28, 2004 at 22:28 UTC

    I don't really understand what exactly you want, but maybe Class::DBI::Loader does what you want? It magically constructs your (Class::DBI-based) classes out of the database according to what the database tells it the columns are:

    # assume a table "person" package MyDB; use strict; use FindBin; use File::Spec; use Class::DBI::Loader; use base 'Class::DBI'; my $dbfile = File::Spec->catfile( $FindBin::Bin, 'mydb.sqlite' ); Class::DBI::Loader->new( dsn => "dbi:SQLite:dbname=$dbfile", relationships => 1, namespace => '', ); my $person = Person->retrieve(1); # get first person
Re: Perl Entity Bean
by simonm (Vicar) on Dec 29, 2004 at 00:44 UTC
    There are multiple solutions to this problem on CPAN. See the POOP Group summary for a partial catalog.

    Among the choices are Class::DBI and my own DBIx::SQLEngine. Using SQLEngine, creating a Perl class for records from a particular table is done as follows:

    my $sqldb = DBIx::SQLEngine->new( @dbi_connect_params ); $sqldb->record_class( $tablename, $classname, 'Accessors' ); my $record = $classname->select_record( $primary_key ); print $record->column1(); $record->column2( $new_value ); $record->update_record();
Re: Perl Entity Bean
by revdiablo (Prior) on Dec 28, 2004 at 22:30 UTC

    You mention Class::DBI, but don't explain what about your idea is different. On a quick reading, it sounds quite similar. Can you explain the distinction?

      Yes, it might do the trick just fine. Part of my unknowingness is because I'm trying to define exactly what I want -- in the Java world, there are magic libraries that people never really have to know about, and therefore relatively young or stupid Java programmers can do dangerous things (for example, Entity Beans can render useless a web service).

      But with Perl, we generally see more of the guts of packages, so my eyes always get a little glazed over when I'm browsing CPAN.

      Actually, Class::DBI looks like what I want. It says it creates the accessors/mutators, but it's not clear whether they're just get/set methods or (as it seems to imply) that it creates lvalue methods along the lines of
         sub column_name : lvalue { $column_name{+shift}; }
      
      Or am I just not reading it right?

      Rob
        in the Java world, there are magic libraries that people never really have to know about ... But with Perl, we generally see more of the guts of packages

        If you're talking about Class::DBI, then I have to disagree. The only thing you have to do is define the table structure. It handles all the SQL behind the scenes, as well as the creation of classes. And if you don't even want to define the table structure, there's Class::DBI::Loader, which reads it directly from the database. I'm not sure how much more magical you can get.

        If you're talking about Perl and Java in general, then, again, I can't agree. My experience says the opposite. I find Perl modules do more "magic" than Java libraries, on the whole. Perhaps you could convince me otherwise with some specific examples, but I digress.

        It says it creates the accessors/mutators, but it's not clear whether they're just get/set methods or (as it seems to imply) that it creates lvalue methods

        It's pretty clear to me that they're the argument-taking variety of get/set methods, rather than lvalues. Here's an example from the SYNOPSIS:

        my $cd = $artist->add_to_cds({ cdid => 1, title => 'October', year => 1980, }); # Oops, got it wrong. $cd->year(1981); $cd->update;

        Notice the call to year on the $cd object.

Re: Perl Entity Bean
by johnnywang (Priest) on Dec 29, 2004 at 07:33 UTC
    Class::DBI and its brothers are what you want. I also think that perl does more magic than java, partly becuase perl is more dynamic (despite java's reflection). I did a little meditation on this topic (perl, Class::DBI and OO for dynamic languages). From my rusty memory of EJBs, EJB does bundle more in the same package, e.g., instance pooling, transaction, etc., which is probably why it is so heavy, and easily abused.
Re: Perl Entity Bean
by VSarkiss (Monsignor) on Dec 28, 2004 at 22:55 UTC