[CDBI] New iterator interface

Michael G Schwern schwern at gmail.com
Fri Feb 16 20:55:29 GMT 2007


So I'm toying around with how to make a new iterator interface that's fast and flexible.  My major concerns are:

A) Making the iterator creation flexible so we don't have to change how CDBI calls it again.
B) Not making the interface so broad that it complicates performance (for example, count)

Here's one I'm liking:

	# sth_to_objects() calls it like this with a prepared $sth
	# and @binds and $class is the CDBI class.
	my $it = $iterator_class->new({
		start		=> sub {
			$sth->execute(@binds);
		},
		next		=> sub {
			$class->construct($sth->fetchrow_hashref);
		},
		finish		=> sub {
			$sth->finish;
		},
	});

No first, no count, no slice, no reset.  Those all assume you can rewind or that you're working on a list in order to be efficient.  No delete_all as that's just syntax sugar for "$_->delete for $it->next;"  You get next(), maybe is_finished().

The nice part about it is the iterator does not have to know anything about what its iterating over.  The downside is the iterator has to do everything in terms of those three functions.  If you want to do fancier stuff like first(), count(), slice(), delete_all() and reset() they can be done but they're inefficient.  If you want to write a "fetch at start" style iterator as exists now you can't.  If you want to change how the objects get created you can't.

An alternative is this:

	my $it = $iterator_class->new({
		sth		=> $sth,
		bind_values	=> \@binds,
		cdbi_class	=> $class
	});

This gives the iterator maximum flexibility to do whatever it wants but it has to know a lot about what its iterating over.  I suppose this is fine since it is Class::DBI's iterator.  Can anyone imagine what other data an iterator might need?





More information about the ClassDBI mailing list