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

Here is what I would like to do:
use Moose; with 'orm'; has table => ( name => 'my_database_table' );
Given a schema like so:
+--------------------+------------------+
| Field              | Type             |
+--------------------+------------------+
| id                 | int(10) unsigned |
| field1             | varchar(32)      |
| field2             | varchar(32)      |
+--------------------+------------------+
My ORM.pm role would parse this line:
has table => ( name => 'my_database_table' );
And effectively produce a Moose object that would be essentially the same as explicitly coding:
use Moose; has id => ( is => 'ro', isa => 'Int' ); has field1 => ( is => 'rw', isa => 'Str' ); has field2 => ( is => 'rw', isa => 'Str' );
The idea, however, is not to produce a text file ... but rather an in-memory object. I could always use Perl to create the text file for me, i.e. this one liner:
mysql -e 'desc my_database_table' | cut -f1 | perl -ple '$_=qq{has $_ +=> ( is => "rw" );}'
I have searched for others who might have this same desire, but so far no real luck. I imagine will need to use Moose::Exporter or possibly Moose::Util::MetaRole. I really don't know.

So, my question isn't "can someone do this for me?" but rather ... are there any Moose heads out there who might be able to sketch out a rough game plan for solving this problem. Personally, I am starting to believe this is more trouble than it is worth. But please remember -- I am not looking for a fully functional ORM that handles complex relationships -- just some sugar for preventing having to spell out the names of the columns in the table for now. I myself am not sure this is a great idea. :)

Thanks in advance.

Replies are listed 'Best First'.
Re: Moose + ORM
by Corion (Patriarch) on Jul 23, 2009 at 18:35 UTC
      Because from my cursory reading of KiokuDB::Tutorial, KiokuDB bwon't/b do that. I am not looking to store my Moose objects into an Object Graph storage engine ... I am looking to create Moose objects by merely specifying a table name.
        bbcode fail
      Care to elaborate?

        Upon rereading KiokuDB and the original post, I think I got it backwards. You can tell KiokuDB about which columns of your object you want to have as "search columns", that is, real SQL database columns, but it doesn't work the other way around, intuiting the structure of your (ORM) objects from the table structure. Something like MooseX::DBI::Loader, grafting DBIx::Class::Loader onto Moose would be needed, but I'm unaware of that.

Re: Moose + ORM
by Anonymous Monk on Jul 23, 2009 at 19:19 UTC
    For those it may concern -- I have this now:
    package Table; use Moose::Role; use Moose::Exporter; use DBI; Moose::Exporter->setup_import_methods( with_caller => ['parse_table'], also => 'Moose', ); sub parse_table { my $table = shift; my $dbh = DBI->connect( ... ); my $sth = $dbh->selectall_arrayref( "describe $table" ); # loop thru $sth and add Moose attributes }
    And I can create a class that consumes it:
    package MyTable; use Moose; with 'Table'; parse_table( 'my_table' );
    This compiles. Now it seems all I need to do is what that comment says "loop thru $sth and add Moose attributes" ... but how does one add Moose attributes inside such a role?

    Thanks again, you folks help make things like this turn into reusable CPAN modules. :)

      This is not the right way to do this, a role should not export new sugar into the class. I think perhaps you want MooseX::Roles::Parameterized instead.

      -stvn

        And here is what it might look like ...

        package Table; use MooseX::Role::Parameterized; parameter table_name => ( isa => 'Str', required => 1, ); role { my $p = shift; my $table = $p->table_name; my $dbh = DBI->connect( ... ); my $sth = $dbh->selectall_arrayref( "describe $table" ); my @columns = ... do DBI magic here ... foreach my $col (@column) { has $col->{name} => ( is => 'rw', isa => $col->{type}, default => $col->{default}, ); } }; package MyTable; use Moose; with 'Table' => { table_name => 'my_table' };

        -stvn
Re: Moose + ORM
by metaperl (Curate) on Jul 24, 2009 at 15:45 UTC
    does describe table work on all databases?

      No. See DBI and the catalog functions on how to get information in a more portable manner.

        Indeed. The idea would be to allow the client to specify how to "Describe" the database table as well use another RDMS.

        But these things are not important right now and well past the scope of this discussion. This is not an RFC ... but rather a (hopefully) simple question whose answer will allow me to get to the point of submitting an RFC. =)

        See Orion? ;)