X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI.pm;h=436f54034b5b7d8766c4544f1bd7b2426038ac9c;hb=0bd8e0585b592d2583f28b6922b47afa78559cf4;hp=3be098195beab3ad3aa741fdc841f1ecd1559a35;hpb=eabde904f520c3d68eb83235f02610b021b221c0;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 3be0981..436f540 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -112,6 +112,12 @@ mixed together: %extra_attributes, }]; + $connect_info_args = [{ + dbh_maker => sub { DBI->connect (...) }, + %dbi_attributes, + %extra_attributes, + }]; + This is particularly useful for L based applications, allowing the following config (L style): @@ -125,6 +131,10 @@ following config (L style): +The C/C/C combination can be substituted by the +C key whose value is a coderef that returns a connected +L + =back Please note that the L docs recommend that you always explicitly @@ -337,6 +347,12 @@ L # Connect via subref ->connect_info([ sub { DBI->connect(...) } ]); + # Connect via subref in hashref + ->connect_info([{ + dbh_maker => sub { DBI->connect(...) }, + on_connect_do => 'alter session ...', + }]); + # A bit more complicated ->connect_info( [ @@ -407,8 +423,21 @@ sub connect_info { elsif (ref $args[0] eq 'HASH') { # single hashref (i.e. Catalyst config) %attrs = %{$args[0]}; @args = (); - for (qw/password user dsn/) { - unshift @args, delete $attrs{$_}; + if (my $code = delete $attrs{dbh_maker}) { + @args = $code; + + my @ignored = grep { delete $attrs{$_} } (qw/dsn user password/); + if (@ignored) { + carp sprintf ( + 'Attribute(s) %s in connect_info were ignored, as they can not be applied ' + . "to the result of 'dbh_maker'", + + join (', ', map { "'$_'" } (@ignored) ), + ); + } + } + else { + @args = delete @attrs{qw/dsn user password/}; } } else { # otherwise assume dsn/user/password + \%attrs + \%extra_attrs @@ -847,10 +876,18 @@ sub _determine_driver { if ($self->_dbh) { # we are connected $driver = $self->_dbh->{Driver}{Name}; } else { - # try to use dsn to not require being connected, the driver may still - # force a connection in _rebless to determine version - ($driver) = $self->_dbi_connect_info->[0] =~ /dbi:([^:]+):/i; - $started_unconnected = 1; + # if connect_info is a CODEREF, we have no choice but to connect + if (ref $self->_dbi_connect_info->[0] && + Scalar::Util::reftype($self->_dbi_connect_info->[0]) eq 'CODE') { + $self->_populate_dbh; + $driver = $self->_dbh->{Driver}{Name}; + } + else { + # try to use dsn to not require being connected, the driver may still + # force a connection in _rebless to determine version + ($driver) = $self->_dbi_connect_info->[0] =~ /dbi:([^:]+):/i; + $started_unconnected = 1; + } } my $storage_class = "DBIx::Class::Storage::DBI::${driver}"; @@ -1224,7 +1261,7 @@ sub _dbh_execute { sub _execute { my $self = shift; - $self->dbh_do('_dbh_execute', @_) + $self->dbh_do('_dbh_execute', @_); # retry over disconnects } sub insert { @@ -1987,7 +2024,7 @@ sub _dbh_sth { sub sth { my ($self, $sql) = @_; - $self->dbh_do('_dbh_sth', $sql); + $self->dbh_do('_dbh_sth', $sql); # retry over disconnects } sub _dbh_columns_info_for { @@ -2049,7 +2086,7 @@ sub _dbh_columns_info_for { sub columns_info_for { my ($self, $table) = @_; - $self->dbh_do('_dbh_columns_info_for', $table); + $self->_dbh_columns_info_for ($self->_get_dbh, $table); } =head2 last_insert_id @@ -2075,7 +2112,38 @@ EOE sub last_insert_id { my $self = shift; - $self->dbh_do('_dbh_last_insert_id', @_); + $self->_dbh_last_insert_id ($self->_dbh, @_); +} + +=head2 _native_data_type + +=over 4 + +=item Arguments: $type_name + +=back + +This API is B, will almost definitely change in the future, and +currently only used by L<::AutoCast|DBIx::Class::Storage::DBI::AutoCast> and +L<::Sybase|DBIx::Class::Storage::DBI::Sybase>. + +The default implementation returns C, implement in your Storage driver if +you need this functionality. + +Should map types from other databases to the native RDBMS type, for example +C to C. + +Types with modifiers should map to the underlying data type. For example, +C should become C. + +Composite types should map to the container type, for example +C becomes C. + +=cut + +sub _native_data_type { + #my ($self, $data_type) = @_; + return undef } =head2 sqlt_type