Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 741)
+++ trunk/DNSDB.pm	(revision 744)
@@ -146,5 +146,5 @@
 		domain	=> 'domain_id',
 		revzone	=> 'rdns_id',
-		record	=> 'record_id'
+		record	=> 'record_id',
 	);
 my %par_col = (
@@ -456,6 +456,8 @@
 #  group_id, log entry
 # and optionally one or more of:
-#  domain_id, rdns_id
+#  domain_id, rdns_id, logparent
 # The %userdata hash provides the user ID, username, and fullname
+# Returns the log entry ID, mainly for use in bulk operations to allow a "parent" log entry
+# and a set of child entries (eg, domain add and the individual default-record-copy entries)
 sub _log {
   my $self = shift;
@@ -466,11 +468,17 @@
   $args{rdns_id} = 0 if !$args{rdns_id};
   $args{domain_id} = 0 if !$args{domain_id};
+  $args{logparent} = 0 if !$args{logparent};
 
 ##fixme:  farm out the actual logging to different subs for file, syslog, internal, etc based on config
 #  if ($self->{log_channel} eq 'sql') {
-  $dbh->do("INSERT INTO log (domain_id,rdns_id,group_id,entry,user_id,email,name) VALUES (?,?,?,?,?,?,?)",
+  $dbh->do("INSERT INTO log (domain_id,rdns_id,group_id,logparent,entry,user_id,email,name) ".
+	"VALUES (?,?,?,?,?,?,?,?)",
 	undef,
-	($args{domain_id}, $args{rdns_id}, $args{group_id}, $args{entry},
+	($args{domain_id}, $args{rdns_id}, $args{group_id}, $args{logparent}, $args{entry},
 		$self->{loguserid}, $self->{logusername}, $self->{logfullname}) );
+
+  my ($log_id) = $dbh->selectrow_array("SELECT currval('log_log_id_seq')");
+  return $log_id;
+
 #  } elsif ($self->{log_channel} eq 'file') {
 #  } elsif ($self->{log_channel} eq 'syslog') {
@@ -2374,5 +2382,5 @@
 	undef, ($domain, $defloc));
 
-    $self->_log(domain_id => $dom_id, group_id => $group,
+    my $logparent = $self->_log(domain_id => $dom_id, group_id => $group,
 	entry => "Added ".($state ? 'active' : 'inactive')." domain $domain");
 
@@ -2390,5 +2398,5 @@
 	my @tmp1 = split /:/, $host;
 	my @tmp2 = split /:/, $val;
-	$self->_log(domain_id => $dom_id, group_id => $group,
+	$self->_log(domain_id => $dom_id, group_id => $group, logparent => $logparent,
 		entry => "[new $domain] Added SOA record [contact $tmp1[0]] [master $tmp1[1]] ".
 		"[refresh $tmp2[0]] [retry $tmp2[1]] [expire $tmp2[2]] [minttl $tmp2[3]], TTL $ttl");
@@ -2397,5 +2405,5 @@
 	$logentry .= " [distance $dist]" if $typemap{$type} eq 'MX';
 	$logentry .= " [priority $dist] [weight $weight] [port $port]" if $typemap{$type} eq 'SRV';
-	$self->_log(domain_id => $dom_id, group_id => $group,
+	$self->_log(domain_id => $dom_id, group_id => $group, logparent => $logparent,
 		entry => $logentry." $val', TTL $ttl");
       }
@@ -4867,5 +4875,6 @@
     $sql = "SELECT count(*) FROM log l ";
   } else {
-    $sql = "SELECT l.user_id AS userid, l.name AS userfname, d.domain, l.domain_id, r.revnet AS revzone, ".
+    $sql = "SELECT l.log_id AS logparent, l.user_id AS userid, l.name AS userfname, d.domain, l.domain_id, ".
+        "r.revnet AS revzone, ".
         "l.rdns_id, l.entry AS logentry, date_trunc('second',l.stamp) AS logtime ".
         "FROM log l ".
@@ -4884,4 +4893,7 @@
   }
 
+  # trim log "subentries" - we'll figure out where to stash these later
+  $sql .= " AND logparent = 0";
+
   # add the entry filter, if any
   $sql .= ($args{filter} ? " AND entry ~* ?" : '');
@@ -4903,7 +4915,15 @@
     $sql .= " ORDER BY $args{sortby} $args{sortorder}, log_id $args{sortorder}".
 	($args{offset} eq 'all' ? '' : " LIMIT $self->{perpage} OFFSET ".$args{offset}*$self->{perpage});
-    my $loglist = $dbh->selectall_arrayref($sql, { Slice => {} }, ($idarg, @filterargs) );
-    $errstr = $dbh->errstr if !$loglist;
-    return $loglist;
+    my @loglist;
+    my $sth = $dbh->prepare($sql);
+    my $logchild = $dbh->prepare("SELECT entry FROM log WHERE logparent = ? ORDER BY log_id");
+    $sth->execute($idarg, @filterargs);
+    while (my $row = $sth->fetchrow_hashref) {
+      $logchild->execute($row->{logparent});
+      my $childlist = $logchild->fetchall_arrayref({});
+      $row->{childentries} = $childlist;
+      push @loglist, $row;
+    }
+    return \@loglist;
   }
 
@@ -5510,4 +5530,6 @@
   eval {
 
+    my $logparent;
+
     if ($rev eq 'n') {
 ##fixme:  serial
@@ -5517,5 +5539,5 @@
       ($zone_id) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')");
       $domain_id = $zone_id;
-      $self->_log(group_id => $group, domain_id => $domain_id,
+      $logparent = $self->_log(group_id => $group, domain_id => $domain_id,
 		entry => "[Added ".($args{status} ? 'active' : 'inactive')." domain $zone via AXFR]");
     } else {
@@ -5526,5 +5548,5 @@
       ($zone_id) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')");
       $rdns_id = $zone_id;
-      $self->_log(group_id => $group, rdns_id => $rdns_id,
+      $logparent = $self->_log(group_id => $group, rdns_id => $rdns_id,
 		entry => "[Added ".($args{status} ? 'active' : 'inactive')." reverse zone $cidr via AXFR]");
     }
@@ -5778,5 +5800,6 @@
 	$logentry .= " ".($rev eq 'y' ? $host : $val)."', TTL $ttl";
       }
-      $self->_log(group_id => $group, domain_id => $domain_id, rdns_id => $rdns_id, entry => $logentry);
+      $self->_log(group_id => $group, domain_id => $domain_id, rdns_id => $rdns_id,
+	logparent => $logparent, entry => $logentry);
 
     } # while axfr_next
