/usr/local/CPAN/WAIT/WAIT/IndexScan.pm
# -*- Mode: Perl -*-
# IndexScan.pm --
# ITIID : $ITI$ $Header $__Header$
# Author : Ulrich Pfeifer
# Created On : Mon Aug 12 14:05:14 1996
# Last Modified By: Ulrich Pfeifer
# Last Modified On: Sun Nov 22 18:44:43 1998
# Language : CPerl
# Update Count : 65
# Status : Unknown, Use with caution!
#
# Copyright (c) 1996-1997, Ulrich Pfeifer
#
package WAIT::IndexScan;
use strict;
use DB_File;
use Fcntl;
sub new {
my $type = shift;
my $index = shift;
my $code = shift;
my ($first, $tid) = ('', '');
# find the first key
if ($index->{dbh}->seq($first, $tid, R_FIRST)) {
require Carp;
Carp::croak("Could not open scan");
}
# Not sure about this. R_FIRST sets $tid to no-of-records?
# $index->{dbh}->seq($first, $tid, R_NEXT);
# register to avoid unnecessary position calls
$index->{scans}++;
bless {Index => $index, code => $code,
nextk => $first, tid => $tid}, $type or ref($type);
}
sub next {
my $self = shift;
my $dbh = $self->{Index}->{dbh};
my ($key, $tid, $ntid);
if (defined $self->{nextk}) {
unless ($dbh){
require Carp;
Carp::croak("Cannot scan closed index");
}
$key = $self->{nextk};
if ($self->{Index}->{scans} > 1) {
# Another scan is open. Reset the cursor
$dbh->seq($key, $tid, R_CURSOR);
} else {
$tid = $self->{tid};
}
if ($dbh->seq($self->{nextk}, $self->{tid}, R_NEXT)) {
# current tuple is last one
delete $self->{nextk};
}
my @tuple = split /$;/, $key;
my %tuple = (_id => $tid);
for (@{$self->{Index}->{attr}}) {
$tuple{$_} = shift @tuple;
}
if ($self->{code}) { # test condition
&{$self->{code}}(\%tuple)? %tuple : $self->next;
} else {
%tuple;
}
} else {
return;
}
}
sub close { undef $_[0]} # force DESTROY
sub DESTROY {
shift->{Index}->{scans}--;
}
1;