--- nfo/perl/libs/Data/Transfer/Sync.pm 2002/11/29 04:45:50 1.1 +++ nfo/perl/libs/Data/Transfer/Sync.pm 2002/12/01 04:43:25 1.2 @@ -1,4 +1,4 @@ -## $Id: Sync.pm,v 1.1 2002/11/29 04:45:50 joko Exp $ +## $Id: Sync.pm,v 1.2 2002/12/01 04:43:25 joko Exp $ ## ## Copyright (c) 2002 Andreas Motl ## @@ -6,6 +6,14 @@ ## ## ---------------------------------------------------------------------------------------- ## $Log: Sync.pm,v $ +## Revision 1.2 2002/12/01 04:43:25 joko +## + mapping deatil entries may now be either an ARRAY or a HASH +## + erase flag is used now (for export-operations) +## + expressions to refer to values inside deep nested structures +## - removed old mappingV2-code +## + cosmetics +## + sub _erase_all +## ## Revision 1.1 2002/11/29 04:45:50 joko ## + initial check in ## @@ -23,7 +31,7 @@ use misc::HashExt; use libp qw( md5_base64 ); use libdb qw( quotesql hash2Sql ); -use Data::Transform::OO qw( hash2object ); +use Data::Transform::Deep qw( hash2object refexpr2perlref ); use Data::Compare::Struct qw( getDifference isEmpty ); # get logger instance @@ -147,11 +155,28 @@ $logger->info( __PACKAGE__ . "->syncNodes: source=$self->{meta}->{source}->{dbkey}/$self->{meta}->{source}->{node} $direction_arrow target=$self->{meta}->{target}->{dbkey}/$self->{meta}->{target}->{node}" ); # build mapping + # incoming: and Array of node map entries (Array or Hash) - e.g. + # [ 'source:item_name' => 'target:class_val' ] + # { source => 'event->startDateTime', target => 'begindate' } foreach (@{$self->{args}->{mapping}}) { - my @key1 = split(':', $_->[0]); - my @key2 = split(':', $_->[1]); - push @{$self->{meta}->{$key1[0]}->{childnodes}}, $key1[1]; - push @{$self->{meta}->{$key2[0]}->{childnodes}}, $key2[1]; + if (ref $_ eq 'ARRAY') { + my @entry1 = split(':', $_->[0]); + my @entry2 = split(':', $_->[1]); + my $descent = []; + my $node = []; + $descent->[0] = $entry1[0]; + $descent->[1] = $entry2[0]; + $node->[0] = $entry1[1]; + $node->[1] = $entry2[1]; + push @{$self->{meta}->{$descent->[0]}->{childnodes}}, $node->[0]; + push @{$self->{meta}->{$descent->[1]}->{childnodes}}, $node->[1]; + } elsif (ref $_ eq 'HASH') { + foreach my $entry_key (keys %$_) { + my $entry_val = $_->{$entry_key}; + push @{$self->{meta}->{$entry_key}->{childnodes}}, $entry_val; + } + } + } # check partners/nodes: does partner exist / is node available? @@ -192,6 +217,14 @@ #$self->_erase_all($opts->{source_node}); } + # erase flag means: erase the target + #if ($opts->{erase}) { + if ($self->{args}->{erase}) { + # TODO: move this method to the scope of the synchronization core and wrap it around different handlers + #print "ERASE", "\n"; + $self->_erase_all('target'); + } + $self->_syncNodes(); } @@ -431,7 +464,7 @@ if ($tc->{error_per_row}) { $msg .= "\n"; - $msg .= "errors:" . "\n"; + $msg .= "errors from \"error_per_row\":" . "\n"; $msg .= Dumper($tc->{error_per_row}); } @@ -572,6 +605,9 @@ for (my $mapidx = 0; $mapidx <= $#childnodes; $mapidx++) { #my $map_right = $self->{args}->{mapping}->{$key}; + $self->{node}->{source}->{propcache} = {}; + $self->{node}->{target}->{propcache} = {}; + # get property name $self->{node}->{source}->{propcache}->{property} = $self->{meta}->{source}->{childnodes}->[$mapidx]; $self->{node}->{target}->{propcache}->{property} = $self->{meta}->{target}->{childnodes}->[$mapidx]; @@ -589,13 +625,39 @@ $self->{node}->{source}->{propcache}->{value} = $self->{node}->{source}->{payload}->{$self->{node}->{source}->{propcache}->{property}}; } #$self->{node}->{map}->{$key} = $value; + + # detect expression + # for transferring deeply nested structures described by expressions + #print "val: $self->{node}->{source}->{propcache}->{value}", "\n"; + if ($self->{node}->{source}->{propcache}->{property} =~ s/^expr://) { + + # create an anonymous sub to act as callback target dispatcher + my $cb_dispatcher = sub { + #print "=============== CALLBACK DISPATCHER", "\n"; + #print "ident: ", $self->{node}->{source}->{ident}, "\n"; + #return $self->{node}->{source}->{ident}; + + }; + + +#print Dumper($self->{node}); + + # build callback map for helper function + #my $cbmap = { $self->{meta}->{source}->{IdentProvider}->{arg} => $cb_dispatcher }; + my $cbmap = {}; + my $value = refexpr2perlref($self->{node}->{source}->{payload}, $self->{node}->{source}->{propcache}->{property}, $cbmap); + $self->{node}->{source}->{propcache}->{value} = $value; + } # encode values dependent on type of underlying storage here - expand cases... my $storage_type = $self->{meta}->{target}->{storage}->{locator}->{type}; if ($storage_type eq 'DBI') { # ...for sql $self->{node}->{source}->{propcache}->{value} = quotesql($self->{node}->{source}->{propcache}->{value}); - } elsif ($storage_type eq 'Tangram') { + } + elsif ($storage_type eq 'Tangram') { + # iso? utf8 already possible? + } elsif ($storage_type eq 'LDAP') { # TODO: encode utf8 here? } @@ -606,35 +668,6 @@ } } -#print "self->{entry}: ", Dumper($self->{node}), "\n"; exit; - - # for transferring deeply nested structures described by expressions - # this currently does not work! - # TODO: re-enable this! - if ($self->{args}->{mappingV2}) { - - # apply mapping from $self->{args}->{mappingV2} to $self->{node}->{map} - foreach my $mapStep (@{$self->{args}->{mappingV2}}) { - - # prepare left/right keys/values - my $left_key = $mapStep->{left}; - my $left_val = _resolveMapStepExpr( $self->{node}->{source}->{payload}, $mapStep->{left} ); - my $right_key = $mapStep->{right}; - my $right_val = ( $mapStep->{right} ); - #print "map: $map_right", "\n"; - - if ($mapStep->{method}) { - if ($mapStep->{method} eq 'v:1') { - $left_val = $left_key; - } - } - - #$self->{node}->{map}->{$key} = $value; - #if ( grep(!/$right_key/, @{$self->{args}->{exclude}}) ) { - $self->{node}->{map}->{$right_key} = $self->{R}->quoteSql($left_val); - #} - } - } # TODO: $logger->dump( ... ); #$logger->debug( "sqlmap:" . "\n" . Dumper($self->{node}->{map}) ); @@ -1063,12 +1096,20 @@ # TODO: handle this in an abstract way (wipe out use of 'source' and/or 'target' inside core) sub _otherSide { my $self = shift; - my $side = shift; - return 'source' if $side eq 'target'; - return 'target' if $side eq 'source'; + my $descent = shift; + return 'source' if $descent eq 'target'; + return 'target' if $descent eq 'source'; return ''; } +sub _erase_all { + my $self = shift; + my $descent = shift; + #my $node = shift; + my $node = $self->{meta}->{$descent}->{node}; + $self->{meta}->{$descent}->{storage}->eraseAll($node); +} + =pod