From: Gianni Ceccarelli Date: Fri, 28 May 2010 21:03:53 +0000 (+0000) Subject: docs & cleanup X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=09b689c915d0af19f91f004244925d5acabc98b0;p=dbsrgits%2FDBIx-Class.git docs & cleanup --- diff --git a/lib/DBIx/Class/Storage/DBI/Pg.pm b/lib/DBIx/Class/Storage/DBI/Pg.pm index dae4094..45a2093 100644 --- a/lib/DBIx/Class/Storage/DBI/Pg.pm +++ b/lib/DBIx/Class/Storage/DBI/Pg.pm @@ -20,6 +20,7 @@ __PACKAGE__->_use_multicolumn_in (1); __PACKAGE__->mk_group_accessors('simple' => '_pg_cursor_number'); +# these are package-vars to allow for evil global overrides our $DEFAULT_USE_PG_CURSORS=0; our $DEFAULT_PG_CURSORS_PAGE_SIZE=1000; @@ -237,6 +238,7 @@ sub deployment_statements { sub _populate_dbh { my ($self) = @_; + # cursors are per-connection, so reset the numbering $self->_pg_cursor_number(1); return $self->SUPER::_populate_dbh(); } @@ -290,6 +292,7 @@ sub _select { my $self = shift; my ($ident, $select, $where, $attrs) = @_; + # ugly ugly ugly, but this is the last sub in the call chain that receives $attrs local $self->{_use_pg_cursors}=$self->_should_use_pg_cursors($attrs); local $self->{_pg_cursor_page_size}=$self->_get_pg_cursor_page_size($attrs); @@ -314,18 +317,47 @@ __END__ =head1 NAME -DBIx::Class::Storage::DBI::Pg - Automatic primary key class for PostgreSQL +DBIx::Class::Storage::DBI::Pg - PostgreSQL-specific storage =head1 SYNOPSIS +Automatic primary key support: + # In your result (table) classes use base 'DBIx::Class::Core'; __PACKAGE__->set_primary_key('id'); +Using PostgreSQL cursors on fetches: + + my $schema = MySchemaClass->connection( + $dsn, $user, $pass, + { + use_pg_cursors => 1, + pg_cursors_page_size => 1000, + }); + + # override at ResultSet level + my $rs = $schema->resultset('Something') + ->search({}, { use_pg_cursors => 0}); + =head1 DESCRIPTION This class implements autoincrements for PostgreSQL. +It also implements fetching data via PostgreSQL cursors, as explained +in the documentation for L. + +=head1 CURSORS FETCHING SUPPORT + +By default, PostgreSQL cursors are not used. You can turn them on (or +off again) either via the connection attributes, or via the ResultSet +attributes (the latter take precedence). + +Fetching data using PostgreSQL cursors uses less memory, but is +slightly slower. You can tune the memory / speed trade-off using the +C attribute, which defines how many rows to +fetch at a time (defaults to 1000). + =head1 POSTGRESQL SCHEMA SUPPORT This driver supports multiple PostgreSQL schemas, with one caveat: for diff --git a/lib/DBIx/Class/Storage/DBI/Pg/Sth.pm b/lib/DBIx/Class/Storage/DBI/Pg/Sth.pm index d34f7e0..d8cb268 100644 --- a/lib/DBIx/Class/Storage/DBI/Pg/Sth.pm +++ b/lib/DBIx/Class/Storage/DBI/Pg/Sth.pm @@ -5,7 +5,8 @@ use base 'Class::Accessor::Grouped'; __PACKAGE__->mk_group_accessors('simple' => 'storage', - 'cursor_id', 'cursor_created', + 'cursor_id', 'cursor_sql', + 'cursor_created', 'cursor_sth', 'fetch_sth', 'page_size', ); @@ -21,15 +22,15 @@ sub new { $storage->_get_next_pg_cursor_number() ); my $hold= ($sql =~ /\bFOR\s+UPDATE\s*\z/i) ? '' : 'WITH HOLD'; - $sql="DECLARE $csr_id CURSOR $hold FOR $sql"; + $self->cursor_sql("DECLARE $csr_id CURSOR $hold FOR $sql"); $self->cursor_id($csr_id); - $self->cursor_sth($storage->_dbh_sth($dbh,$sql)); + $self->cursor_sth(undef); $self->cursor_created(0); $self->page_size($page_size); return $self; } else { - die "Can only be used for SELECTS"; + die "Can only be used for SELECTs"; } } @@ -37,6 +38,14 @@ sub _cursor_name_from_number { return 'dbic_pg_cursor_'.$_[1]; } +sub _prepare_cursor_sth { + my ($self)=@_; + + return if $self->cursor_sth; + + $self->cursor_sth($self->storage->sth($self->cursor_sql)); +} + sub _cleanup_sth { my ($self)=@_; @@ -62,14 +71,19 @@ sub DESTROY { sub bind_param { my ($self,@bind_args)=@_; + $self->_prepare_cursor_sth; + return $self->cursor_sth->bind_param(@bind_args); } sub execute { my ($self,@bind_values)=@_; - $self->cursor_created(1); - return $self->cursor_sth->execute(@bind_values); + $self->_prepare_cursor_sth; + + my $ret=$self->cursor_sth->execute(@bind_values); + $self->cursor_created(1) if $ret; + return $ret; } # bind_param_array & execute_array not used for SELECT statements, so @@ -86,7 +100,7 @@ sub finish { $self->fetch_sth->finish if $self->fetch_sth; return $self->cursor_sth->finish if $self->cursor_sth; - return 0; + return 1; } sub _check_cursor_end { @@ -103,7 +117,7 @@ sub _run_fetch_sth { my ($self)=@_; if (!$self->cursor_created) { - $self->cursor_sth->execute(); + $self->execute(); } $self->fetch_sth->finish if $self->fetch_sth;