1 package DBIx::Class::Storage::DBI::Pg;
6 use base qw/DBIx::Class::Storage::DBI::MultiColumnIn/;
9 use DBD::Pg qw(:pg_types);
11 # Ask for a DBD::Pg with array support
12 warn "DBD::Pg 2.9.2 or greater is strongly recommended\n"
13 if ($DBD::Pg::VERSION < 2.009002); # pg uses (used?) version::qv()
15 sub with_deferred_fk_checks {
16 my ($self, $sub) = @_;
18 $self->_get_dbh->do('SET CONSTRAINTS ALL DEFERRED');
23 my ($self,$source,$col) = @_;
24 my $seq = ($source->column_info($col)->{sequence} ||= $self->get_autoinc_seq($source,$col))
25 or $self->throw_exception( "could not determine sequence for "
27 . ".$col, please consider adding a "
28 . "schema-qualified sequence to its column info"
31 $self->_dbh_last_insert_id ($self->_dbh, $seq);
34 # there seems to be absolutely no reason to have this as a separate method,
35 # but leaving intact in case someone is already overriding it
36 sub _dbh_last_insert_id {
37 my ($self, $dbh, $seq) = @_;
38 $dbh->last_insert_id(undef, undef, undef, undef, {sequence => $seq});
42 # get the postgres search path, and cache it
43 sub _get_pg_search_path {
45 # cache the search path as ['schema','schema',...] in the storage
47 $self->{_pg_search_path} ||= do {
49 my ($sp_string) = $dbh->selectrow_array('SHOW search_path');
50 while( $sp_string =~ s/("[^"]+"|[^,]+),?// ) {
51 unless( defined $1 and length $1 ) {
52 $self->throw_exception("search path sanity check failed: '$1'")
54 push @search_path, $1;
60 sub _dbh_get_autoinc_seq {
61 my ($self, $dbh, $schema, $table, $col) = @_;
63 my $sqlmaker = $self->sql_maker;
64 local $sqlmaker->{bindtype} = 'normal';
66 my ($where, @bind) = $self->sql_maker->where ({
67 'a.attnum' => {'>', 0},
68 'c.relname' => $table,
70 -not_bool => 'a.attisdropped',
71 (defined $schema && length $schema)
72 ? ( 'n.nspname' => $schema )
73 : ( -bool => \'pg_catalog.pg_table_is_visible(c.oid)' )
76 my ($seq_expr) = $dbh->selectrow_array(<<EOS,undef,@bind);
79 (SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid)
80 FROM pg_catalog.pg_attrdef d
81 WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)
82 FROM pg_catalog.pg_class c
83 JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
84 JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
89 unless (defined $seq_expr && $seq_expr =~ /^nextval\(+'([^']+)'::(?:text|regclass)\)/i ){
90 $seq_expr = '' unless defined $seq_expr;
91 $self->throw_exception("could not parse sequence expression: '$seq_expr'");
98 my ($self,$source,$col) = @_;
101 my $table = $source->name;
103 if (ref $table eq 'SCALAR') {
106 elsif ($table =~ /^(.+)\.(.+)$/) {
107 ($schema, $table) = ($1, $2);
110 $self->dbh_do('_dbh_get_autoinc_seq', $schema, $table, $col);
117 sub datetime_parser_type { return "DateTime::Format::Pg"; }
119 sub bind_attribute_by_data_type {
120 my ($self,$data_type) = @_;
122 my $bind_attributes = {
123 bytea => { pg_type => DBD::Pg::PG_BYTEA },
124 blob => { pg_type => DBD::Pg::PG_BYTEA },
127 if( defined $bind_attributes->{$data_type} ) {
128 return $bind_attributes->{$data_type};
135 sub _sequence_fetch {
136 my ( $self, $type, $seq ) = @_;
137 my ($id) = $self->_get_dbh->selectrow_array("SELECT nextval('${seq}')");
142 my ($self, $name) = @_;
144 $self->_get_dbh->pg_savepoint($name);
148 my ($self, $name) = @_;
150 $self->_get_dbh->pg_release($name);
154 my ($self, $name) = @_;
156 $self->_get_dbh->pg_rollback_to($name);
165 DBIx::Class::Storage::DBI::Pg - Automatic primary key class for PostgreSQL
169 # In your table classes
170 __PACKAGE__->load_components(qw/PK::Auto Core/);
171 __PACKAGE__->set_primary_key('id');
172 __PACKAGE__->sequence('mysequence');
176 This class implements autoincrements for PostgreSQL.
178 =head1 POSTGRESQL SCHEMA SUPPORT
180 This driver supports multiple PostgreSQL schemas, with one caveat: for
181 performance reasons, data about the search path, sequence names, and
182 so forth is queried as needed and CACHED for subsequent uses.
184 For this reason, once your schema is instantiated, you should not
185 change the PostgreSQL schema search path for that schema's database
186 connection. If you do, Bad Things may happen.
188 You should do any necessary manipulation of the search path BEFORE
189 instantiating your schema object, or as part of the on_connect_do
190 option to connect(), for example:
192 my $schema = My::Schema->connect
195 [ 'SET search_path TO myschema, foo, public' ],
201 See L<DBIx::Class/CONTRIBUTORS>
205 You may distribute this code under the same terms as Perl itself.