X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI%2FPg.pm;h=a8fd85bc27d4e606b07553f108efe3eb5b08c59c;hb=616ca57f8cd27f475da275bbef986fdd42d4069f;hp=0673fe8afa7ef04e01f384e451af4af93b778fa7;hpb=2b8cc2f27d0dc881059e55dd6462bb28b7b8e414;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBI/Pg.pm b/lib/DBIx/Class/Storage/DBI/Pg.pm index 0673fe8..a8fd85b 100644 --- a/lib/DBIx/Class/Storage/DBI/Pg.pm +++ b/lib/DBIx/Class/Storage/DBI/Pg.pm @@ -3,22 +3,18 @@ package DBIx::Class::Storage::DBI::Pg; use strict; use warnings; -use base qw/ - DBIx::Class::Storage::DBI::MultiColumnIn -/; -use mro 'c3'; +use base qw/DBIx::Class::Storage::DBI/; -use DBD::Pg qw(:pg_types); use Scope::Guard (); use Context::Preserve 'preserve_context'; +use DBIx::Class::Carp; +use DBIx::Class::_Util 'modver_gt_or_eq'; use namespace::clean; __PACKAGE__->sql_limit_dialect ('LimitOffset'); __PACKAGE__->sql_quote_char ('"'); - -# Ask for a DBD::Pg with array support -warn __PACKAGE__.": DBD::Pg 2.9.2 or greater is strongly recommended\n" - if ($DBD::Pg::VERSION < 2.009002); # pg uses (used?) version::qv() +__PACKAGE__->datetime_parser_type ('DateTime::Format::Pg'); +__PACKAGE__->_use_multicolumn_in (1); sub _determine_supports_insert_returning { return shift->_server_info->{normalized_dbms_version} >= 8.002 @@ -52,7 +48,7 @@ sub last_insert_id { for my $col (@cols) { my $seq = ( $col_info->{$col}{sequence} ||= $self->dbh_do('_dbh_get_autoinc_seq', $source, $col) ) or $self->throw_exception( sprintf( - 'could not determine sequence for column %s.%s, please consider adding a schema-qualified sequence to its column info', + "Could not determine sequence for column '%s.%s', please consider adding a schema-qualified sequence to its column info", $source->name, $col, )); @@ -99,7 +95,7 @@ sub _dbh_get_autoinc_seq { $seq_expr = '' unless defined $seq_expr; $schema = "$schema." if defined $schema && length $schema; $self->throw_exception( sprintf ( - 'no sequence found for %s%s.%s, check the RDBMS table definition or explicitly set the '. + "No sequence found for '%s%s.%s', check the RDBMS table definition or explicitly set the ". "'sequence' for this column in %s", $schema ? "$schema." : '', $table, @@ -108,7 +104,7 @@ sub _dbh_get_autoinc_seq { )); } - return $1; + return $1; # exception thrown unless match is made above } # custom method for fetching column default, since column_info has a @@ -161,45 +157,96 @@ EOS return $seq_expr; } +sub _dbh_execute_for_fetch { + #my ($self, $source, $sth, $tuple_status, @extra) = @_; + + # This is used for bulk insert, so make sure we use a server-side + # prepared statement from the start, unless it's disabled + local $_[2]->{pg_switch_prepared} = 1 if + modver_gt_or_eq( 'DBD::Pg', '3.0.0' ) + and + $_[2]->FETCH('pg_switch_prepared') > 0 + ; + + shift->next::method(@_); +} sub sqlt_type { return 'PostgreSQL'; } -sub datetime_parser_type { return "DateTime::Format::Pg"; } +# Pg is not able to MAX(boolean_column), sigh... +# +# Generally it would make more sense to have this in the SQLMaker hierarchy, +# so that eventually { -max => ... } DTRT, but plans going forward are +# murky at best +# --ribasushi +# +sub _minmax_operator_for_datatype { + #my ($self, $datatype, $want_max) = @_; + + return ($_[2] ? 'BOOL_OR' : 'BOOL_AND') + if ($_[1] || '') =~ /\Abool(?:ean)?\z/i; + + shift->next::method(@_); +} sub bind_attribute_by_data_type { my ($self,$data_type) = @_; - my $bind_attributes = { - bytea => { pg_type => DBD::Pg::PG_BYTEA }, - blob => { pg_type => DBD::Pg::PG_BYTEA }, - }; - - if( defined $bind_attributes->{$data_type} ) { - return $bind_attributes->{$data_type}; + if ($self->_is_binary_lob_type($data_type)) { + # this is a hot-ish codepath, use an escape flag to minimize + # amount of function/method calls + # the flag is stored in the DBD namespace, so that Class::Unload + # will work (unlikely, but still) + unless ( + modver_gt_or_eq( 'DBD::Pg', '2.17.2' ) + or + $DBD::Pg::__DBIC_DBD_VERSION_CHECK_DONE__ + ) { + if ( $self->_server_info->{normalized_dbms_version} >= 9.0 ) { + $self->throw_exception( + 'BYTEA columns are known to not work on Pg >= 9.0 with DBD::Pg < 2.17.2' + ); + } + elsif ( + require DBIx::Class::Optional::Dependencies + and + my $missing = DBIx::Class::Optional::Dependencies->req_missing_for([qw( rdbms_pg binary_data )]) + ) { + # FIXME - perhaps this needs to be an exception too...? + # too old to test sensibly... + carp ( + __PACKAGE__ . ": BYTEA column support strongly recommends $missing" + ) + } + + $DBD::Pg::__DBIC_DBD_VERSION_CHECK_DONE__ = 1; + } + + return { pg_type => DBD::Pg::PG_BYTEA() }; } else { - return; + return undef; } } -sub _svp_begin { +sub _exec_svp_begin { my ($self, $name) = @_; - $self->_get_dbh->pg_savepoint($name); + $self->_dbh->pg_savepoint($name); } -sub _svp_release { +sub _exec_svp_release { my ($self, $name) = @_; - $self->_get_dbh->pg_release($name); + $self->_dbh->pg_release($name); } -sub _svp_rollback { +sub _exec_svp_rollback { my ($self, $name) = @_; - $self->_get_dbh->pg_rollback_to($name); + $self->_dbh->pg_rollback_to($name); } sub deployment_statements { @@ -258,12 +305,13 @@ option to connect(), for example: }, ); -=head1 AUTHORS - -See L +=head1 FURTHER QUESTIONS? -=head1 LICENSE +Check the list of L. -You may distribute this code under the same terms as Perl itself. +=head1 COPYRIGHT AND LICENSE -=cut +This module is free software L +by the L. You can +redistribute it and/or modify it under the same terms as the +L.