have the big query find customers in batches. this should be way more efficient...
authorivan <ivan>
Wed, 22 Apr 2009 00:54:03 +0000 (00:54 +0000)
committerivan <ivan>
Wed, 22 Apr 2009 00:54:03 +0000 (00:54 +0000)
FS/FS/Cron/bill.pm

index 312f337..6537018 100644 (file)
@@ -95,52 +95,65 @@ END
 
   push @search, "( $where_pkg OR $where_event )";
 
-  ###
-  # get a list of custnums
-  ###
-
-  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;
-
-  $sth->execute or die $sth->errstr;
-
-  my @custnums = map { $_->[0] } @{ $sth->fetchall_arrayref };
-
-  ###
-  # 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 );
-
-    } else {
-
-      my $cust_main = qsearchs( 'cust_main', { 'custnum' => $custnum } );
-      $cust_main->bill_and_collect( %args, 'debug' => $debug );
+  my $prev_custnum = 0;
+  while ( 1 ) {
+
+    ###
+    # get a list of custnums
+    ###
+
+    warn "searching for customers:\n".
+           join("\n", @search).
+           "custnum > $prev_custnum\n"
+      if $opt{'v'} || $opt{'l'};
+
+    my $sth = dbh->prepare(
+      "SELECT custnum FROM cust_main".
+      " WHERE ". join(' AND ', @search).
+      " AND custnum > $prev_custnum ".
+      " ORDER BY custnum LIMIT 100 "
+    ) or die dbh->errstr;
+
+    $sth->execute or die $sth->errstr;
+
+    my @custnums = map { $_->[0] } @{ $sth->fetchall_arrayref };
+
+    last unless scalar(@custnums);
+
+    $prev_custnum = $custnums[-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 );
+
+      } else {
+
+        my $cust_main = qsearchs( 'cust_main', { 'custnum' => $custnum } );
+        $cust_main->bill_and_collect( %args, 'debug' => $debug );
+
+      }
 
     }