I'm using Rose with a fairly large MySQL database and using an
iterator like

    my $itr = Bar->get_bars_iterator();
    while($itr->next()) {

won't work because by default, an iterator will read in all records from
the DB, which won't fit into memory.

Using

    my $itr = Bar->get_bars_iterator( per_page => 20 );
    while($itr->next()) {

works nicely, but I would rather not be in charge of keeping track
of which page I'm currently reading and if there's more pages to
be fetched.

So I thought: Couldn't Rose have 'pager' objects acting like iterators,
but fetching all available data in configurable chunks?

The attached patch allows to say

    my $pager = Bar->get_bars_pager( per_page => 20 );
    while($pager->next()) {

and the pager will act like an iterator, but instead of running
out after one page, it will create a new iterator under the hood
and continue until there's no more records to be fetched.

What do you think?

-- Mike

Mike Schilli
[EMAIL PROTECTED]

--- Manager.pm.org      2007-03-23 06:26:15.000000000 -0800
+++ Manager.pm.new      2007-03-23 08:33:55.492735974 -0800
@@ -86,7 +86,8 @@

 sub object_class { }

-sub default_manager_method_types { qw(objects iterator count delete update) }
+sub default_manager_method_types { qw(objects iterator count delete update
+                                      pager ) }

 sub make_manager_methods
 {
@@ -240,6 +241,26 @@
             @_, return_iterator => 1, object_class => $object_class)
         };
       }
+      elsif($type eq 'pager')
+      {
+        my $base_method_name =
+          $have_full_name ? "${target_class}::$name" :
+                            "${target_class}::get_${name}";
+        my $iterator_method_name = "${base_method_name}_iterator";
+        my $pager_method_name    = "${base_method_name}_pager";
+
+        *{$pager_method_name} = sub
+        {
+          shift;
+          my($next, $finish) =
+              $class_invocant->get_pager_methods($iterator_method_name, @_);
+
+          my $iterator = Rose::DB::Object::Iterator->new(active => 1);
+          $iterator->_next_code($next);
+          $iterator->_finish_code($finish);
+          return $iterator;
+        };
+      }
       elsif($type eq 'delete')
       {
         my $method_name =
@@ -284,6 +305,31 @@
   }
 }

+sub get_pager_methods
+{
+  my($class, $method, %options) = @_;
+
+  my $per_page        = ($options{per_page} || 20);
+  my $page            = 0;
+  my $itr;
+  my $page_items_done = 0;
+
+  my $next = sub {
+        # Page done? Get next iterator.
+      if(!$itr or $page_items_done == $per_page) {
+          $itr = $class->$method( page => ++$page, per_page => $per_page );
+          $page_items_done = 0;
+      }
+
+      $page_items_done++;
+      return $itr->next();
+  };
+
+  my $finish = sub { $itr->_finish_code() if $itr; };
+
+  return($next, $finish);
+}
+
 sub get_objects_count
 {
   my($class) = shift;

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to