P.S. While answering a question, this email could be adapted for a Catalyst cookbook / etc entry if one wants to.

Octavian Rasnita wrote:
I agree and yes, that sample code could give bad ideas.
In my case I am the app designer, coder, maintainer, site admin, everything but 
the web designer and I've done it so for not specifying these settings in more 
places.

I have the same role in my situation, but I also designed the project so it is easier for someone else to come along and maintain it.

Is there another place where I could put these settings for a certain DBIC 
schema?
For example, can I put them in the MyApp/Schema.pm, orsomewhere else? Can you 
give an example?

I can show you a simplified version of what I have done, but with any identifying details changed to protect the innocent. My version uses straight DBI+DBIx::Connector rather than DBIC but you should be able to adapt the design to DBIC or any other database API; my version is also Pg-specific but only minor tweaks would be needed to work with something else. Since this is from a proprietary application rather than a CPAN module, I can get away with requiring and exploiting the latest Perl version, 5.12.x, rather than giving those up to support older Perls.

1. Here is the relevant portion of MyApp.conf, which uses Config::General as per Catalyst's default these days.

    <Model DB>
        <args>
            db_host localhost
            db_port 5444
            db_name myproj_v1_db
            db_user myproj_v1_usr_myapp
            db_pass myapppass
        </args>
    </Model>

2. Here is the slightly simplified version of MyApp/Model/DB.pm, which uses Catalyst::Model::Adaptor, and in such a way to support different class and file names (requires 0.09+):

    use 5.012002;
    use utf8;
    use warnings FATAL => 'all';

    use MyDBMSLib 0.001;

    package MyApp::Model::DB 0.001;

    use parent 'Catalyst::Model::Adaptor';  # requires >= 0.09

    __PACKAGE__->config( class => 'MyDBMSLib' );

    1;

3. Here is a complete/template content of MyDBMSLib.pm; the original had multiple classes in it but I removed the other ones and simplified the main one; the original file was named after a different package than what I kept:

    use 5.012002;
    use utf8;
    use warnings FATAL => 'all';

    use DBIx::Connector;
    use DBI;
    use DBD::Pg;

    ###########################################################################
    ###########################################################################

    { package MyDBMSLib 0.001; # class

        use namespace::autoclean;

        use Try::Tiny;

        use Moose;

        has 'db_host' => (is => 'ro', isa => 'Str', required => 1 );
        has 'db_port' => (is => 'ro', isa => 'Int', required => 1 );
        has 'db_name' => (is => 'ro', isa => 'Str', required => 1 );
        has 'db_user' => (is => 'ro', isa => 'Str', required => 1 );
        has 'db_pass' => (is => 'ro', isa => 'Str', required => 1 );

        # This is the actual (as far as we're concerned) Pg database connection
        # object; the connection is opened the first time the _dbc attr is read
        # and it is closed when the _dbc attr is garbage collected.
        has '_dbc' => (
            is       => 'ro',
            isa      => 'DBIx::Connector',
            required => 1,
            lazy     => 1,
            default  => \&_lazy_default_for_dbc,
        );

    ###########################################################################

    sub _lazy_default_for_dbc {
        my ($process) = @_;
        my $dbc = try {
            my $dsn = sprintf( q{dbi:Pg:dbname=%s;host=%s;port=%s},
                $process->db_name(), $process->db_host(), $process->db_port() );
            my $dbc = DBIx::Connector->new( $dsn,
                $process->db_user(), $process->db_pass(),
                { 'RaiseError' => 1, 'AutoCommit' => 1 },
            );
            my $dbh = $dbc->dbh();
            # SET UP ANY OTHER CLIENT SETTINGS HERE ON $dbh
            return $dbc;
        }
        catch {
confess sprintf( q{Could not open connection to Pg server or db: %s}, $_ );
        };
        return $dbc;
    }

    ###########################################################################

    # PUT OTHER USEFUL MyDBMSLib METHODS HERE

    ###########################################################################

        __PACKAGE__->meta()->make_immutable();

    } # class MyDBMSLib

    ###########################################################################
    ###########################################################################

    1;

For your version, mainly just replace _dbc with an object of whatever initial class you have with DBIC that takes the db connection config args.

Your analogy to _lazy_default_for_dbc is where you feed DBIC its actual config args, where some can be defined in MyDBMSLib itself and others taken from the config file.

-- Darren Duncan

_______________________________________________
List: [email protected]
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/[email protected]/
Dev site: http://dev.catalyst.perl.org/

Reply via email to