Hi,

I always found it quite annoying that one needs two different
objects/methods when writing a Net:LLDAP:Entry to either a directory server
or an LDIF file.
With directory servers you can do
        $entry->update($ldap)
while with LDIF you need
        $ldif->write_entry($entry)

This always requires a distinction in the code path in the perl scripts
although LDIF makes a nice output when doing a "dry run", and Perl
should be able to do the RightThing(tm).

I have attached a patch that extends Net::LDAP::Entry->update
by accepting an Net::LDAP::LDIF object as a parameter too.

It would be great if this patch would make it into the next release
of perl-ldap.

Best regards
Peter

-- 
Peter Marschall
pe...@adpm.de
From bce3842056339ebdbbaaebd46857b13eadc68759 Mon Sep 17 00:00:00 2001
From: Peter Marschall <pe...@adpm.de>
Date: Sun, 9 Jan 2011 19:47:55 +0100
Subject: [PATCH] extend Net::LDAP::Entry->update() to take LDIF objects

Extend Net::LDAP::Entry.pm's update() method so that it can take
Net::LDAP::LDIF objects as handles too, and append the entry's
data to the LDIF.

For LDIF arguments also return a Net::LDAP::Message argument:
on success return LDAP_SUCCESS, on error return LDAP_OTHER.

One might argue that tis is against the standards, but
Net::LDAP::Entry->update() is not covered in any standard.

The big plus is, it allows clients to have one common code path for
directory servers and LDIF files (except for startup/shutdown)
which makes using LDIF as "dry-run" output for servers really simple.

Especially for the result value, it s a lot more convenient than any other
combination of Net::LDAP::entry->update() and Net::LDAP::Entry->ldif().

Signed-off-by: Peter Marschall <pe...@adpm.de>
---
 lib/Net/LDAP/Entry.pm   |   50 +++++++++++++++++++++++++++-------------------
 lib/Net/LDAP/Message.pm |    4 +-
 2 files changed, 31 insertions(+), 23 deletions(-)

diff --git a/lib/Net/LDAP/Entry.pm b/lib/Net/LDAP/Entry.pm
index 118428e..f7c8df8 100644
--- a/lib/Net/LDAP/Entry.pm
+++ b/lib/Net/LDAP/Entry.pm
@@ -6,7 +6,7 @@ package Net::LDAP::Entry;
 
 use strict;
 use Net::LDAP::ASN qw(LDAPEntry);
-use Net::LDAP::Constant qw(LDAP_LOCAL_ERROR);
+use Net::LDAP::Constant qw(LDAP_LOCAL_ERROR LDAP_OTHER);
 use vars qw($VERSION);
 
 use constant CHECK_UTF8 => $] > 5.007;
@@ -258,33 +258,41 @@ sub delete {
 
 sub update {
   my $self = shift;
-  my $ldap = shift;
+  my $target = shift;	# a Net::LDAP or a Net::LDAP::LDIF object
   my %opt = @_;
   my $mesg;
   my $user_cb = delete $opt{callback};
   my $cb = sub { $self->changetype('modify') unless $_[0]->code;
                  $user_cb->(@_) if $user_cb };
 
-  if ($self->{'changetype'} eq 'add') {
-    $mesg = $ldap->add($self, 'callback' => $cb, %opt);
-  }
-  elsif ($self->{'changetype'} eq 'delete') {
-    $mesg = $ldap->delete($self, 'callback' => $cb, %opt);
-  }
-  elsif ($self->{'changetype'} =~ /modr?dn/o) {
-    my @args = (newrdn => $self->get_value('newrdn') || undef,
-                deleteoldrdn => $self->get_value('deleteoldrdn') || undef);
-    my $newsuperior = $self->get_value('newsuperior');
-    push(@args, newsuperior => $newsuperior) if $newsuperior;
-    $mesg = $ldap->moddn($self, @args, 'callback' => $cb, %opt);
-  }
-  elsif (@{$self->{'changes'}}) {
-    $mesg = $ldap->modify($self, 'changes' => $self->{'changes'}, 'callback' => $cb, %opt);
+  if (ref($target) && UNIVERSAL::isa($target, 'Net::LDAP')) {
+    if ($self->{'changetype'} eq 'add') {
+      $mesg = $target->add($self, 'callback' => $cb, %opt);
+    }
+    elsif ($self->{'changetype'} eq 'delete') {
+      $mesg = $target->delete($self, 'callback' => $cb, %opt);
+    }
+    elsif ($self->{'changetype'} =~ /modr?dn/o) {
+      my @args = (newrdn => $self->get_value('newrdn') || undef,
+                  deleteoldrdn => $self->get_value('deleteoldrdn') || undef);
+      my $newsuperior = $self->get_value('newsuperior');
+      push(@args, newsuperior => $newsuperior) if $newsuperior;
+      $mesg = $target->moddn($self, @args, 'callback' => $cb, %opt);
+    }
+    elsif (@{$self->{'changes'}}) {
+      $mesg = $target->modify($self, 'changes' => $self->{'changes'}, 'callback' => $cb, %opt);
+    }
+    else {
+      require Net::LDAP::Message;
+      $mesg = Net::LDAP::Message->new( $target );
+      $mesg->set_error(LDAP_LOCAL_ERROR,"No attributes to update");
+    }
   }
-  else {
-    require Net::LDAP::Message;
-    $mesg = Net::LDAP::Message->new( $ldap );
-    $mesg->set_error(LDAP_LOCAL_ERROR,"No attributes to update");
+  elsif (ref($target) && UNIVERSAL::isa($target, 'Net::LDAP::LDIF')) {
+    $target->write_entry($self);
+    $mesg = Net::LDAP::Message::Dummy->new();
+    $mesg->set_error(LDAP_OTHER, $target->error())
+      if ($target->error());
   }
 
   return $mesg;
diff --git a/lib/Net/LDAP/Message.pm b/lib/Net/LDAP/Message.pm
index 7df478d..569a376 100644
--- a/lib/Net/LDAP/Message.pm
+++ b/lib/Net/LDAP/Message.pm
@@ -254,8 +254,8 @@ sub Net::LDAP::Compare::is_error {
   sub sync    { shift }
   sub decode  { shift }
   sub abandon { shift }
-  sub code { 0 }
-  sub error { "" }
+  sub code { $self->{resultcode} || LDAP_SUCCESS }
+  sub error { $self->{errorMessage} || "" }
   sub dn { "" }
   sub done { 1 }
 }
-- 
1.7.2.3

Reply via email to