--- nfo/perl/libs/Data/Transfer/Sync/Core.pm 2003/06/25 23:03:57 1.10 +++ nfo/perl/libs/Data/Transfer/Sync/Core.pm 2004/06/19 01:45:08 1.12 @@ -1,6 +1,6 @@ ## ------------------------------------------------------------------------- ## -## $Id: Core.pm,v 1.10 2003/06/25 23:03:57 joko Exp $ +## $Id: Core.pm,v 1.12 2004/06/19 01:45:08 joko Exp $ ## ## Copyright (c) 2002 Andreas Motl ## @@ -8,6 +8,13 @@ ## ## ------------------------------------------------------------------------- ## $Log: Core.pm,v $ +## Revision 1.12 2004/06/19 01:45:08 joko +## introduced "local checksum"-mechanism +## moved _dumpCompact to ::Compare::Checksum +## +## Revision 1.11 2004/05/11 20:03:48 jonen +## bugfix[joko] related to Attribute Map +## ## Revision 1.10 2003/06/25 23:03:57 joko ## no debugging ## @@ -104,6 +111,7 @@ #use misc::HashExt; use Hash::Serializer; use Data::Mungle::Compare::Struct qw( getDifference isEmpty ); +use Data::Mungle::Transform::Deep qw( deep_copy expand ); use Data::Storage::Container; use DesignPattern::Object; use shortcuts::database qw( quotesql ); @@ -185,15 +193,14 @@ # get reference to node list from convenient method provided by CORE-HANDLE $results ||= $self->_getNodeList('source'); - #print Dumper($results); - # checkpoint: do we actually have a list to iterate through? if (!$results || !@{$results}) { $logger->notice( __PACKAGE__ . "->_run: No nodes to synchronize." ); return; } - + #print Dumper(@$results); + #exit; # check if we actually *have* a synchronization method if (!$self->{options}->{metadata}->{syncMethod}) { @@ -204,15 +211,18 @@ # dereference my @results = @{$results}; + #print Dumper(@results); # iterate through set foreach my $source_node_real (@results) { print ":" if $self->{verbose}; + #print Dumper($source_node_real); + $tc->{total}++; -#print "======================== iter", "\n"; + #print "=" x 80, "\n"; # clone object (in case we have to modify it here) # TODO: @@ -221,12 +231,13 @@ # - after all, just take care for now that this object doesn't get updated! # - so, just use its reference for now - if some cloning is needed in future, do this here! my $source_node = $source_node_real; + #my $source_node = expand($source_node_real); # modify entry - handle new style callbacks (the readers) # trace - #print Dumper($source_node); - #exit; + #print Dumper($source_node); + #exit; my $descent = 'source'; @@ -242,6 +253,8 @@ foreach my $node (keys %{$callbacks->{read}}) { + #print "cb_node: $node", "\n"; + my $object = $source_node; my $value; # = $source_node->{$node}; @@ -299,18 +312,17 @@ print "n" if $self->{verbose}; } -#print "checksum", "\n"; - - #print Dumper($self); - # determine status of entry by synchronization method if ( lc $self->{options}->{metadata}->{syncMethod} eq 'checksum' ) { #if ( $statOK && (lc $self->{args}->{method} eq 'checksum') ) { #if ( !$self->{node}->{status}->{new} && (lc $self->{args}->{method} eq 'checksum') ) { + # calculate local checksum of source node + $self->handleLocalChecksum('source'); + # calculate checksum of source node #$self->_calcChecksum('source'); - if (!$self->_readChecksum('source')) { + if (!$self->readChecksum('source')) { $logger->warning( __PACKAGE__ . "->_run: Could not find \"source\" entry with ident=\"$self->{node}->{source}->{ident}\"" ); $tc->{skip}++; print "s" if $self->{verbose}; @@ -318,9 +330,9 @@ } # get checksum from synchronization target - $self->_readChecksum('target'); - #if (!$self->_readChecksum('target')) { - # $logger->critical( __PACKAGE__ . "->_readChecksum: Could not find \"target\" entry with ident=\"$self->{node}->{source}->{ident}\"" ); + $self->readChecksum('target'); + #if (!$self->readChecksum('target')) { + # $logger->critical( __PACKAGE__ . "->readChecksum: Could not find \"target\" entry with ident=\"$self->{node}->{source}->{ident}\"" ); # next; #} @@ -337,7 +349,10 @@ # trace #print Dumper($self->{node}); #exit; + #print "LOCAL: ", $self->{node}->{source}->{checksum_local_storage}, " <-> ", $self->{node}->{source}->{checksum_local_calculated}, "\n"; + #print "REMOTE: ", $self->{node}->{source}->{checksum}, " <-> ", $self->{node}->{target}->{checksum}, "\n"; + # calculate new/dirty status $self->{node}->{status}->{new} = !$self->{node}->{target}->{checksum}; if (!$self->{node}->{status}->{new}) { $self->{node}->{status}->{dirty} = @@ -347,6 +362,12 @@ $self->{args}->{force}; } + # new 2004-06-17: also check if local checksum is inconsistent + if ($self->{node}->{source}->{checksum_local_storage} ne $self->{node}->{source}->{checksum_local_calculated}) { + $self->{node}->{status}->{dirty_local} = 1; + $self->{node}->{status}->{dirty} = 1; + } + } else { $logger->warning( __PACKAGE__ . "->_run: Synchronization method '$self->{options}->{metadata}->{syncMethod}' is not implemented" ); $tc->{skip}++; @@ -354,16 +375,27 @@ next; } + # new 2004-06-17: also update local checksum + if ($self->{node}->{status}->{dirty_local}) { + $tc->{locally_modified}++; + print "[lm]" if $self->{verbose}; + $self->_doModify_LocalChecksum('source'); + } + # first reaction on entry-status: continue with next entry if the current is already "in sync" if (!$self->{node}->{status}->{new} && !$self->{node}->{status}->{dirty}) { $tc->{in_sync}++; next; } + #print Dumper($self->{node}->{source}); + # build map to actually transfer the data from source to target if (!$self->buildAttributeMap()) { #$logger->warning( __PACKAGE__ . "->_run: Attribute Map could not be created. Will not insert or modify node."); - $tc->{skip}++; + push( @{$tc->{error_per_row}}, "Attribute Map could not be created. Will not insert or modify node $self->{node}->{source}->{ident}."); + #push( @{$tc->{error_per_row}}, "Attribute Map could not be created. Will not insert or modify node " . Dumper($self->{node}->{source}) . "."); + $tc->{error}++; print "e" if $self->{verbose}; next; } @@ -394,14 +426,14 @@ # asymmetry: refetch node from target to re-calculate new ident and checksum (TODO: is IdentAuthority of relevance here?) #print Dumper($self->{node}); $self->_statloadNode('target', $self->{node}->{target}->{ident}, 1); - $self->_readChecksum('target'); + $self->readChecksum('target'); } elsif ($self->{node}->{status}->{dirty}) { $tc->{attempt_modify}++; # asymmetry: get ident before updating (TODO: is IdentAuthority of relevance here?) $self->{node}->{target}->{ident} = $self->{node}->{map}->{$self->{meta}->{target}->{IdentProvider}->{arg}}; $self->_doTransferToTarget('update'); - $self->_readChecksum('target'); + $self->readChecksum('target'); } if ($self->{node}->{status}->{ok}) { @@ -429,6 +461,9 @@ #exit; $self->_doModifySource_IdentChecksum($self->{node}->{target}->{ident}); } + + #print "UNLOAD", "\n"; + #$self->{meta}->{source}->{storage}->unload( $self->{node}->{source}->{payload} ); } @@ -453,51 +488,6 @@ } -# refactor this as some core-function to do a generic dump resolving data-encapsulations of e.g. Set::Object -sub _dumpCompact { - my $self = shift; - - #my $vars = \@_; - my @data = (); - - my $count = 0; - foreach (@_) { - my $item = {}; - foreach my $key (keys %$_) { - my $val = $_->{$key}; - -#print Dumper($val); - - if (ref $val eq 'Set::Object') { - #print "========================= SET", "\n"; -#print Dumper($val); - #print Dumper($val->members()); - #$val = $val->members(); - #$vars->[$count]->{$key} = $val->members() if $val->can("members"); - #$item->{$key} = $val->members() if $val->can("members"); - $item->{$key} = $val->members(); - #print Dumper($vars->[$count]->{$key}); - - } else { - $item->{$key} = $val; - } - - } - push @data, $item; - $count++; - } - -#print "Dump:", Dumper(@data), "\n"; - - $Data::Dumper::Indent = 0; - my $result = Dumper(@data); - $Data::Dumper::Indent = 2; - return $result; - -} - - - sub _doTransferToTarget { my $self = shift; my $action = shift; @@ -530,7 +520,14 @@ $self->_modifyNode('source', 'update', $map); } - +sub _doModify_LocalChecksum { + my $self = shift; + my $descent = shift; + my $map = { + cs_local => $self->{node}->{$descent}->{checksum_local_calculated}, + }; + $self->_modifyNode($descent, 'update', $map); +} sub _prepareNode_MetaProperties { my $self = shift; @@ -566,10 +563,12 @@ } +# TODO: load column-metadata from reversed mapping-metadata sub _prepareNode_DummyIdent { my $self = shift; my $descent = shift; + #print Dumper($self->{options}); $logger->info( __PACKAGE__ . "->_prepareNode_DummyIdent( descent $descent )" ); my $list = $self->_getNodeList($descent); @@ -583,6 +582,7 @@ my $map = { $self->{meta}->{$descent}->{IdentProvider}->{arg} => $ident_dummy, cs => undef, + cs_local => undef, }; # diff lists and ... @@ -607,7 +607,7 @@ $i++; } - #print "\n" if $self->{verbose}; + print "\n" if $self->{verbose}; if (!$i) { $logger->warning( __PACKAGE__ . "->_prepareNode_DummyIdent: no nodes touched" );