Evan Carroll
Evan Carroll

Reputation: 1

How does DBIx::Class::Storage::DBI's connect_info work?

The docs for connect_info:

connect_info

This method is normally called by "connection" in DBIx::Class::Schema, which encapsulates its argument list in an arrayref before passing them here.

The argument list may contain:

  • The same 4-element argument set one would normally pass to "connect" in DBI, optionally followed by extra attributes recognized by DBIx::Class:

    $connect_info_args = [ $dsn, $user, $password, \%dbi_attributes?, \%extra_attributes? ];
    
  • A single code reference which returns a connected DBI database handle optionally followed by extra attributes recognized by DBIx::Class:

    $connect_info_args = [ sub { DBI->connect (...) }, \%extra_attributes? ];
    
  • A single hashref with all the attributes and the dsn/user/password mixed together:

    $connect_info_args = [{
        dsn => $dsn,
        user => $user,
        password => $pass,
        %dbi_attributes,
        %extra_attributes,
    }];
    
    $connect_info_args = [{
        dbh_maker => sub { DBI->connect (...) },  
        %dbi_attributes,
        %extra_attributes,
    }];
    

    This is particularly useful for Catalyst based applications, allowing the following config (Config::General style):

    <Model::DB>
        schema_class   App::DB
        <connect_info>
            dsn          dbi:mysql:database=test
            user         testuser
            password     TestPass
            AutoCommit   1
        </connect_info>
    </Model::DB>
    

    The dsn/user/password combination can be substituted by the dbh_maker key whose value is a coderef that returns a connected DBI database handle

Please note that the DBI docs recommend that you always explicitly set AutoCommit to either 0 or 1. DBIx::Class further recommends that it be set to 1, and that you perform transactions via our "txn_do" in DBIx::Class::Schema method. DBIx::Class will set it to 1 if you do not do explicitly set it to zero. This is the default for most DBDs. See "DBIx::Class and AutoCommit" for details.

What is this? Is it a method called internally, or a global? And, if it's a method called internally why is it being sent either a dbh maker, or four arguments? What determines what it is sent? It's listed as being a method. What is $connect_info_args?

Upvotes: 0

Views: 714

Answers (1)

Evan Carroll
Evan Carroll

Reputation: 1

Here is how I got it to work

Schema Class

You've got to use the storage that's done like this (and you can find it in the docs)

package MyDBIC::Schema;
__PACKAGE__->storage_type("DBIx::Class::Storage::DBI::mysql::MySubClass")

Storage Class

package DBIx::Class::Storage::DBI::mysql::MySubClass;
use mro 'c3';
use base 'DBIx::Class::Storage::DBI::mysql';
sub connect_info {
     my $self = shift;
     my $retval = $self->next::method([{
         username => _username(),
         password => $password,
         dsn => "my:dsn:"
     })
     $retval;
};

I found a rough example of how to do it burred here. Talk about shitty docs..

connect_info appears to be broke. Things tried.

  • Subclassing a Storage with a custom connect_info. It gets called, but nothing it returns does anything useful. Calling ->connect->storage->ensure_connected; on a schema results in error.
  • Wrapping connect_info with Moose::around(). Fails to wrap. The method 'connect_info' was not found in the inheritance hierarchy.
  • Calling $self->connect_info() from BUILD... DBIx::Class::Storage::DBI::connect_info gets called but no matter what I hand to it, the sub only gets $self, the first argument.
  • Calling __PACKAGE__->connect_info({}) or __PACKAGE__->connect_info([{}]) results in both arguments being sent to the DBIx::Class::Storage::DBI::connect_info but the lack of a $self results in Class::XSAccessor: invalid instance method invocant: no hash ref supplied at when the sub tries to write to the accessor.

Upvotes: 0

Related Questions