X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI.pm;h=78d7321de19d780c3a2270cb3a53b565ced7cf24;hb=f83d99c80b593ccf0c445784cda98cb4de0c8564;hp=8bcb42441807d1194e2e017629bdab74a35242dc;hpb=986e4fcaa25c60c5bc527e7f89a271138cf4752a;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 8bcb424..78d7321 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -240,7 +240,7 @@ use base qw/DBIx::Class/; __PACKAGE__->load_components(qw/AccessorGroup/); __PACKAGE__->mk_group_accessors('simple' => - qw/connect_info _dbh _sql_maker _conn_pid _conn_tid debug debugfh + qw/_connect_info _dbh _sql_maker _conn_pid _conn_tid debug debugfh cursor on_connect_do transaction_depth/); sub new { @@ -277,6 +277,25 @@ This class represents the connection to the database =cut +=head2 connect_info + +Connection information arrayref. Can either be the same arguments +one would pass to DBI->connect, or a code-reference which returns +a connected database handle. In either case, there is an optional +final element in the arrayref, which can hold a hashref of +connection-specific Storage::DBI options. These include +C, and the sql_maker options C, +C, and C. Examples: + + ->connect_info([ 'dbi:SQLite:./foo.db' ]); + ->connect_info(sub { DBI->connect(...) }); + ->connect_info([ 'dbi:Pg:dbname=foo', + 'postgres', + '', + { AutoCommit => 0 }, + { quote_char => q{`}, name_sep => q{@} }, + ]); + =head2 on_connect_do Executes the sql statements given as a listref on every db connect. @@ -345,6 +364,12 @@ sub ensure_connected { } } +=head2 dbh + +Returns the dbh - a data base handle of class L. + +=cut + sub dbh { my ($self) = @_; @@ -360,9 +385,40 @@ sub sql_maker { return $self->_sql_maker; } +sub connect_info { + my ($self, $info_arg) = @_; + + if($info_arg) { + my $info = [ @$info_arg ]; # copy because we can alter it + my $last_info = $info->[-1]; + if(ref $last_info eq 'HASH') { + my $used; + if(my $on_connect_do = $last_info->{on_connect_do}) { + $used = 1; + $self->on_connect_do($on_connect_do); + } + for my $sql_maker_opt (qw/limit_dialect quote_char name_sep/) { + if(my $opt_val = $last_info->{$sql_maker_opt}) { + $used = 1; + $self->sql_maker->$sql_maker_opt($opt_val); + } + } + + # remove our options hashref if it was there, to avoid confusing + # DBI in the case the user didn't use all 4 DBI options, as in: + # [ 'dbi:SQLite:foo.db', { quote_char => q{`} } ] + pop(@$info) if $used; + } + + $self->_connect_info($info); + } + + $self->_connect_info; +} + sub _populate_dbh { my ($self) = @_; - my @info = @{$self->connect_info || []}; + my @info = @{$self->_connect_info || []}; $self->_dbh($self->_connect(@info)); my $driver = $self->_dbh->{Driver}->{Name}; eval "require DBIx::Class::Storage::DBI::${driver}"; @@ -420,10 +476,13 @@ an entire code block to be executed transactionally. sub txn_begin { my $self = shift; - if (($self->{transaction_depth}++ == 0) and ($self->dbh->{AutoCommit})) { - $self->debugfh->print("BEGIN WORK\n") - if ($self->debug); - $self->dbh->begin_work; + if ($self->{transaction_depth}++ == 0) { + my $dbh = $self->dbh; + if ($dbh->{AutoCommit}) { + $self->debugfh->print("BEGIN WORK\n") + if ($self->debug); + $dbh->begin_work; + } } } @@ -436,10 +495,11 @@ Issues a commit against the current dbh. sub txn_commit { my $self = shift; if ($self->{transaction_depth} == 0) { - unless ($self->dbh->{AutoCommit}) { + my $dbh = $self->dbh; + unless ($dbh->{AutoCommit}) { $self->debugfh->print("COMMIT\n") if ($self->debug); - $self->dbh->commit; + $dbh->commit; } } else { @@ -464,10 +524,11 @@ sub txn_rollback { eval { if ($self->{transaction_depth} == 0) { - unless ($self->dbh->{AutoCommit}) { + my $dbh = $self->dbh; + unless ($dbh->{AutoCommit}) { $self->debugfh->print("ROLLBACK\n") if ($self->debug); - $self->dbh->rollback; + $dbh->rollback; } } else { @@ -591,14 +652,16 @@ Returns database type info for a given table columns. sub columns_info_for { my ($self, $table) = @_; - if ($self->dbh->can('column_info')) { + my $dbh = $self->dbh; + + if ($dbh->can('column_info')) { my %result; - my $old_raise_err = $self->dbh->{RaiseError}; - my $old_print_err = $self->dbh->{PrintError}; - $self->dbh->{RaiseError} = 1; - $self->dbh->{PrintError} = 0; + my $old_raise_err = $dbh->{RaiseError}; + my $old_print_err = $dbh->{PrintError}; + $dbh->{RaiseError} = 1; + $dbh->{PrintError} = 0; eval { - my $sth = $self->dbh->column_info( undef, undef, $table, '%' ); + my $sth = $dbh->column_info( undef, undef, $table, '%' ); $sth->execute(); while ( my $info = $sth->fetchrow_hashref() ){ my %column_info; @@ -610,21 +673,21 @@ sub columns_info_for { $result{$info->{COLUMN_NAME}} = \%column_info; } }; - $self->dbh->{RaiseError} = $old_raise_err; - $self->dbh->{PrintError} = $old_print_err; + $dbh->{RaiseError} = $old_raise_err; + $dbh->{PrintError} = $old_print_err; return \%result if !$@; } my %result; - my $sth = $self->dbh->prepare("SELECT * FROM $table WHERE 1=0"); + my $sth = $dbh->prepare("SELECT * FROM $table WHERE 1=0"); $sth->execute; my @columns = @{$sth->{NAME_lc}}; for my $i ( 0 .. $#columns ){ my %column_info; my $type_num = $sth->{TYPE}->[$i]; my $type_name; - if(defined $type_num && $self->dbh->can('type_info')) { - my $type_info = $self->dbh->type_info($type_num); + if(defined $type_num && $dbh->can('type_info')) { + my $type_info = $dbh->type_info($type_num); $type_name = $type_info->{TYPE_NAME} if $type_info; } $column_info{data_type} = $type_name ? $type_name : $type_num;