Re: LDIF file instead of updating directory

Peter Marschall <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.ldap
Organization ADPM
Message-ID <[email protected]>
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
[email protected]
0001-extend-Net-LDAP-Entry-update-to-take-LDIF-objects.patch (text/x-patch, 4.4 KB)
From bce3842056339ebdbbaaebd46857b13eadc68759 Mon Sep 17 00:00:00 2001
From: Peter Marschall <[email protected]>
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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.