use strict;
use vars qw($DEBUG $buffer);
-use base qw( Exporter );
-use FS::Record qw(qsearch dbdef dbh);
-use Data::Dumper;
+use FS::Record;
+use FS::UID qw(myconnect);
use Scalar::Util qw(refaddr);
-$DEBUG = 0;
+$DEBUG = 2;
+
# this might become a parameter at some point, but right now, you can
# "local $FS::Cursor::buffer = X;"
$buffer = 200;
sub new {
my $class = shift;
my $q = FS::Record::_query(@_); # builds the statement and parameter list
+ my $dbh = myconnect();
my $self = {
query => $q,
class => 'FS::' . ($q->{table} || 'Record'),
buffer => [],
+ dbh => $dbh,
};
bless $self, $class;
# the class of record object to return
$self->{class} = "FS::".($q->{table} || 'Record');
+ # save for later, so forked children will not destroy me when they exit
+ $self->{pid} = $$;
+
$self->{id} = sprintf('cursor%08x', refaddr($self));
my $statement = "DECLARE ".$self->{id}." CURSOR FOR ".$q->{statement};
- my $dbh = dbh;
my $sth = $dbh->prepare($statement)
or die $dbh->errstr;
my $bind = 1;
sub DESTROY {
my $self = shift;
- my $statement = "CLOSE ".$self->{id};
- dbh->do($statement);
-}
+ return unless $self->{pid} eq $$;
+ $self->{dbh}->do('CLOSE '. $self->{id})
+ or die $self->{dbh}->errstr; # clean-up the cursor in Pg
+ $self->{dbh}->rollback;
+ $self->{dbh}->disconnect;
+}
=back
Doesn't support MySQL.
+The cursor will close prematurely if any code issues a rollback/commit. If
+you need protection against this use qsearch or fork and get a new dbh
+handle.
+Normally this issue will represent itself this message.
+ERROR: cursor "cursorXXXXXXX" does not exist.
+
=head1 SEE ALSO
L<FS::Record>