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
[email protected]
https://lists.sourceforge.net/lists/listinfo/rose-db-object