Hello Carl,
the following code should work, although it
doesn't use a callback for handle the found entry
(not testet, there may be syntax errors):
use Net::LDAP::Control::Paged;
use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED );
# connect and bind with error handling
my $ldap = Net::LDAP->new( "ldaphost", port=>10999 )
or die "Error in connecting to 'ldaphost': $@;
my $rc = $ldap->bind( $bindDn, password => $password );
if( $rc->code ) {
PrintLdapError( $ldap, $rc, "Error in bind
as '$bindDn'" ); # error handling
}
my $pagedControl = Net::LDAP::Control::Paged->new( size => 500 );
my @searchArgs = (
control => [ $pagedControl ],
base => "ou=users,o=Broadband,o=no",
scope => "subtree",
filter => "(objectClass=top)",
);
my $cookie;
while(1) {
print "=" x 60, "\nNext page\n", "=" x 60, "\n";
my $searchResult = $ldap->search( @searchArgs );
$searchResult->code and last; # only continue at LDAP_SUCCESS
# do something with the found entries
while( my $entry = $searchResult->shift_entry ) {
$entry->dump;
}
# get Cookie from Paged Control
my( $response ) = $searchResult->control( LDAP_CONTROL_PAGED )
or last;
my $cookie = $response->cookie or last;
# set cookie for next search
$pagedControl->cookie( $cookie );
} # while 1
# if cookie is set => error, tell server that search is finished
if( $cookie ) {
$pagedControl->cookie( $cookie );
$pagedControl->size( 0 );
$ldap->search( @searchArgs );
} # if
$ldap->unbind();
sub PrintLdapError { # default error handling, needs to be improved
my( $ldap, $rc, $msg ) = @_;
my $name = ldap_error_name( $rc );
my $text = ldap_error_text( $rc );
my $descr = ldap_error_desc( $rc );
die join "\n", $msg, "Name: $name", "Descr: $descr", "Text: $text", '';
} # PrintLdapError
Have fun,
Martin
At 09:51 02.04.2008, Carl Stefan Grøtter wrote:
Hello!
I am actually trying to make a script that should browse through about
150.000 objects and compare the data with another (Oracle based) system.
If I limit the search to e.g 5000 it works fine (takes about 20-30
seconds), but without the limit it is using huge amounts of memory and
takes many, many hours. Therefore, I would like to rewrite it to use paged
results. I can't get it to work, though...
I've been trying to modify several examples I found by googling, but I
allways seem to get all results on the first page. In the below example (I
am trying a more limited search here than I will do in the real script,
just to prove the concept to myself) I'm getting all 207 users in the
first page.
Am I missing something obvious here? Could it be that SunOne directory
doesn't support paged controls?
---------------------------
#!/usr/bin/perl
use Data::Dumper;
use Net::LDAP;
use Net::LDAP::Control::Paged;
use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED );
$ldap = Net::LDAP->new( "ldaphost", port=>10999 );
$search = $ldap->bind('username', password => 'password');
$page = Net::LDAP::Control::Paged->new( size => 30 );
@args = ( base => "ou=users,o=Broadband,o=no",
scope => "subtree",
filter => "(objectClass=top)",
callback => \&process_entry, # Call this sub for each entry
control => [ $page ],
);
my $cookie;
while(1) {
# Perform search
my $mesg = $ldap->search( @args );
print Dumper($mesg);
# Only continue on LDAP_SUCCESS
$mesg->code and last;
# Get cookie from paged control
my($resp) = $mesg->control( LDAP_CONTROL_PAGED ) or last;
$cookie = $resp->cookie or last;
# Set cookie in paged control
$page->cookie($cookie);
}
if ($cookie) {
# We had an abnormal exit, so let the server know we do not want any
more
$page->cookie($cookie);
$page->size(0);
$ldap->search( @args );
}
$ldap->unbind;
sub process_entry { $jeje++ and print $jeje . "\n" }
---------------------------
Here's some environment info:
OS: Solaris 10 (64 bit, Sparc)
Perl version: 5.8.4
Net::LDAP version: 0.34
Net::LDAP::Control version: 0.06
Net::LDAP::Control::Paged version: 0.02
I would be very grateful for any help, as I have allready spent quite a
few hours on this.