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