projects
/
freeside.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
cursorize cust_bill_pkg_tax_location upgrade, #940
[freeside.git]
/
FS
/
FS
/
Cursor.pm
diff --git
a/FS/FS/Cursor.pm
b/FS/FS/Cursor.pm
index
f3bc1e2
..
d94151f
100644
(file)
--- a/
FS/FS/Cursor.pm
+++ b/
FS/FS/Cursor.pm
@@
-2,12
+2,12
@@
package FS::Cursor;
use strict;
use vars qw($DEBUG $buffer);
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);
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;
# this might become a parameter at some point, but right now, you can
# "local $FS::Cursor::buffer = X;"
$buffer = 200;
@@
-39,24
+39,28
@@
and returns an FS::Cursor object to fetch the rows one at a time.
sub new {
my $class = shift;
my $q = FS::Record::_query(@_); # builds the statement and parameter list
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 => [],
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');
};
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};
$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 $sth = $dbh->prepare($statement)
or die $dbh->errstr;
- my $bind =
0
;
+ my $bind =
1
;
foreach my $value ( @{ $q->{value} } ) {
my $bind_type = shift @{ $q->{bind_type} };
$sth->bind_param($bind++, $value, $bind_type );
foreach my $value ( @{ $q->{value} } ) {
my $bind_type = shift @{ $q->{bind_type} };
$sth->bind_param($bind++, $value, $bind_type );
@@
-101,6
+105,15
@@
sub refill {
scalar @$result;
}
scalar @$result;
}
+sub DESTROY {
+ my $self = shift;
+ 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
=head1 TO DO
=back
=head1 TO DO
@@
-111,6
+124,12
@@
Replace all uses of qsearch with this.
Doesn't support MySQL.
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>
=head1 SEE ALSO
L<FS::Record>