we don't actually need the results ordered, and i'm sure it doesn't help the planner...
[freeside.git] / FS / FS / Cron / bill.pm
index 312f337..225b372 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use vars qw( @ISA @EXPORT_OK );
 use Exporter;
 use Date::Parse;
+use DBI 1.33; #The "clone" method was added in DBI 1.33. 
 use FS::UID qw(dbh);
 use FS::Record qw(qsearchs);
 use FS::cust_main;
@@ -102,50 +103,62 @@ END
   warn "searching for customers:\n". join("\n", @search). "\n"
     if $opt{'v'} || $opt{'l'};
 
-  my $sth = dbh->prepare(
-    "SELECT custnum FROM cust_main".
-    " WHERE ". join(' AND ', @search)
-  ) or die dbh->errstr;
+  my $cursor_dbh = dbh->clone;
 
-  $sth->execute or die $sth->errstr;
+  $cursor_dbh->do(
+    "DECLARE cron_bill_cursor CURSOR FOR ".
+    "  SELECT custnum FROM cust_main WHERE ". join(' AND ', @search)
+  ) or die $cursor_dbh->errstr;
 
-  my @custnums = map { $_->[0] } @{ $sth->fetchall_arrayref };
+  while ( 1 ) {
 
-  ###
-  # for each custnum, queue or make one customer object and bill
-  # (one at a time, to reduce memory footprint with large #s of customers)
-  ###
-  
-  foreach my $custnum ( @custnums ) {
-  
-    my %args = (
-        'time'         => $time,
-        'invoice_time' => $invoice_time,
-        'actual_time'  => $^T, #when freeside-bill was started
-                               #(not, when using -m, freeside-queued)
-        'check_freq'   => $check_freq,
-        'resetup'      => ( $opt{'s'} ? $opt{'s'} : 0 ),
-    );
-
-    if ( $opt{'m'} ) {
-
-      #add job to queue that calls bill_and_collect with options
-      my $queue = new FS::queue {
-        'job'      => 'FS::cust_main::queued_bill',
-        'secure'   => 'Y',
-        'priority' => 99, #don't get in the way of provisioning jobs
-      };
-      my $error = $queue->insert( 'custnum'=>$custnum, %args );
+    my $sth = $cursor_dbh->prepare('FETCH 100 FROM cron_bill_cursor'); #mysql?
 
-    } else {
+    $sth->execute or die $sth->errstr;
+
+    my @custnums = map { $_->[0] } @{ $sth->fetchall_arrayref };
+
+    last unless scalar(@custnums);
+
+    ###
+    # for each custnum, queue or make one customer object and bill
+    # (one at a time, to reduce memory footprint with large #s of customers)
+    ###
+    
+    foreach my $custnum ( @custnums ) {
+    
+      my %args = (
+          'time'         => $time,
+          'invoice_time' => $invoice_time,
+          'actual_time'  => $^T, #when freeside-bill was started
+                                 #(not, when using -m, freeside-queued)
+          'check_freq'   => $check_freq,
+          'resetup'      => ( $opt{'s'} ? $opt{'s'} : 0 ),
+      );
 
-      my $cust_main = qsearchs( 'cust_main', { 'custnum' => $custnum } );
-      $cust_main->bill_and_collect( %args, 'debug' => $debug );
+      if ( $opt{'m'} ) {
+
+        #add job to queue that calls bill_and_collect with options
+        my $queue = new FS::queue {
+          'job'      => 'FS::cust_main::queued_bill',
+          'secure'   => 'Y',
+          'priority' => 99, #don't get in the way of provisioning jobs
+        };
+        my $error = $queue->insert( 'custnum'=>$custnum, %args );
+
+      } else {
+
+        my $cust_main = qsearchs( 'cust_main', { 'custnum' => $custnum } );
+        $cust_main->bill_and_collect( %args, 'debug' => $debug );
+
+      }
 
     }
 
   }
 
+  $cursor_dbh->commit or die $cursor_dbh->errstr;
+
 }
 
 1;