--- nfo/perl/libs/Data/Transfer/Sync/API.pm 2003/02/09 04:59:27 1.3 +++ nfo/perl/libs/Data/Transfer/Sync/API.pm 2003/02/21 08:00:24 1.7 @@ -1,4 +1,4 @@ -## $Id: API.pm,v 1.3 2003/02/09 04:59:27 joko Exp $ +## $Id: API.pm,v 1.7 2003/02/21 08:00:24 joko Exp $ ## ## Copyright (c) 2002 Andreas Motl ## @@ -6,6 +6,19 @@ ## ## ---------------------------------------------------------------------------------------- ## $Log: API.pm,v $ +## Revision 1.7 2003/02/21 08:00:24 joko +## debugging +## +## Revision 1.6 2003/02/14 12:58:47 joko +## + re-enabled the erase-mechanism +## +## Revision 1.5 2003/02/11 05:26:04 joko +## + sub _tellWhatIWillDo +## + re-enabled "branch to execution path for special targets" mechanism +## +## Revision 1.4 2003/02/09 05:03:02 joko +## + minor fix regarding namespace of api versioning extension module +## ## Revision 1.3 2003/02/09 04:59:27 joko ## + api versioning mechanism ## + major structure changes @@ -55,7 +68,7 @@ $logger->debug( __PACKAGE__ . "->loadVersionExtensions( version='$syncVersion' )"); #print Dumper($self); #exit; - my $module = "Version::$syncVersion"; + my $module = "API::$syncVersion"; $self->load($module); } @@ -63,16 +76,10 @@ sub configure { my $self = shift; -#print "YAI\n"; -#print Dumper(@_); -#exit; - $logger->debug( __PACKAGE__ . "->configure"); my @args = @_; -#print Dumper(@args); - if (!isEmpty(\@args)) { my %properties = @_; # merge args to properties @@ -147,6 +154,7 @@ my $self = shift; my $args = shift; + #$logger->notice( "========================== " . __PACKAGE__ . "->syncNodes =============="); $logger->debug( __PACKAGE__ . "->syncNodes: starting" ); #print Dumper($self); @@ -155,7 +163,9 @@ #print Dumper($self->{options}); $self->_prepareOptions(); -#print Dumper($self->{options}); + # trace + #print Dumper($self->{options}); + #exit; if (!$self->checkOptions()) { $logger->critical( __PACKAGE__ . "->syncNodes: 'Data::Transfer::Sync::checkOptions' failed."); @@ -167,6 +177,8 @@ return; } + #print Dumper($args); + # remember arguments through the whole processing $self->{args} = $args; @@ -176,6 +188,8 @@ # hash to sum up results # TODO: re-implement! (sync-statistics???) + #print Dumper($self->{options}->{process}); + # detect synchronization method to determine which optical symbol (directed arrow) to use my $mode = $self->{args}->{mode}; # V1 $mode ||= $self->{options}->{process}->{mode}; # V2 @@ -196,15 +210,57 @@ $self->options2metadata(); $self->options2metadata_accessor(); + # branch to execution path for special targets + # detect for option 'handler' which could be a CODEref + if ($self->{options}->{handler} && ref $self->{options}->{handler} eq 'CODE') { + $logger->info( __PACKAGE__ . "->syncNodes: Running (special handler code - no generic sync!) on '$self->{options}->{target}->{dbKey}' with MODE $self->{options}->{process}->{mode}, NODE $self->{options}->{target}->{address}"); + #print Dumper($self); + #exit; + # don't do this any more - it wasn't very nice somehow ... + #$self->{options}->{handler}->($self->{app}, $self->{options}); + # .... now: better let the parent application scope handle this via callback + # not any more required for this: $self->{app} inside here (which isn't the app we mean here) + # required for this: getting the options out of here: establish some getter method! ($self->getOptions(...)) + # so.... + #$self->{__bridge}->{parent_ref}-> + + # ahh okay, DesignPattern::Bridge moves closer to some Class::Inner!??? + # so... + # similar like above - but it isn't very nice anyway ... (no privateness, but: who cares?) + #print Dumper($self->{__bridge}); + # just take the global application instance and + # throw it into the context of the mapping module - this is heavy! ;-) (but again, who cares...) + # TODO: handle this more abstract *sometime* + #$self->{options}->{handler}->($self->{__bridge}->{parent}->{app}, $self->{options}); + $self->{options}->{handler}->($self->{__bridge}->{parent}->{process}, $self->{options}); + + return; + } + + # TODO: execution path branch V2!!! + # option1: wrap this via callback to parent scope (like current impl. mechanism) + # option2: branch directly from here (this needs refactoring of the sub handler) + # tracing #print Dumper($self); #exit; - $logger->info( __PACKAGE__ . "->syncNodes: source=$self->{meta}->{source}->{dbKey}/$self->{meta}->{source}->{nodeName} [$self->{meta}->{source}->{nodeType}] $direction_arrow target=$self->{meta}->{target}->{dbKey}/$self->{meta}->{target}->{nodeName} [$self->{meta}->{target}->{nodeType}]" ); + # V1: + $logger->debug( __PACKAGE__ . "->syncNodes: source=$self->{meta}->{source}->{dbKey}/$self->{meta}->{source}->{nodeName} [$self->{meta}->{source}->{nodeType}] $direction_arrow target=$self->{meta}->{target}->{dbKey}/$self->{meta}->{target}->{nodeName} [$self->{meta}->{target}->{nodeType}]" ); + + # V2: + my $what = "$self->{meta}->{source}->{dbKey}/$self->{meta}->{source}->{nodeName} [$self->{meta}->{source}->{nodeType}] $direction_arrow $self->{meta}->{target}->{dbKey}/$self->{meta}->{target}->{nodeName} [$self->{meta}->{target}->{nodeType}]"; + #my $header = ("~.." x 7) . " " . $what . " " . ("~.." x 4); + #my $header = ("= " x 7) . " " . $what . " " . ("= " x 4); + #my $header = ("~=-_-=" x 3) . " " . $what . " " . ("~=-_-=" x 4); + my $header = ("_-=~=-" x 4) . " " . $what . " " . ("_-=~=-" x 4); + $logger->notice($header); + return if !$self->buildFieldmapping(); return if !$self->_touchNodeSet(); return if !$self->_prepare_sync(); + $self->_tellWhatIWillDo(); # tracing #print Dumper($self); @@ -220,6 +276,74 @@ } +my $c_string_default = ''; +sub c_string { + my $value = shift; + $value ||= "[$c_string_default]"; + return $value; +} + +sub _tellWhatIWillDo { + my $self = shift; + + +#return; + + # trace + #print Dumper($self->{meta}); + #exit; + + $c_string_default = 'n/a'; + my $source = c_string($self->{opt}->{'source'}); + my $source_node = c_string($self->{opt}->{'source-node'}); + my $source_type = c_string($self->{opt}->{'source-type'}); + my $target = c_string($self->{opt}->{'target'}); + my $target_node = c_string($self->{opt}->{'target-node'}); + my $target_type = c_string($self->{opt}->{'target-type'}); + + my $mapping_module = c_string($self->{opt}->{'mapping-module'}); + my $mode = uc c_string($self->{opt}->{'mode'}); + + #my $ql = "$mode INTO $source NODE $source_node TYPE $source_type SELECT NODE $target_node TYPE $target_type FROM $target USING MODULE $mapping_module;"; + #$logger->notice( __PACKAGE__ . ": $ql" ); + my $ql = <{meta}->{source}->{dbKey} + AT NODE $self->{meta}->{source}->{accessorName}.$self->{meta}->{source}->{nodeName} + USING IDENTIFIER $self->{meta}->{source}->{IdentProvider}->{method}.$self->{meta}->{source}->{IdentProvider}->{arg} + CONVERT DATA + CAST FROM $self->{meta}->{source}->{nodeType} TO $self->{meta}->{target}->{nodeType} + MAP ATTRIBUTES FROM @{$self->{meta}->{source}->{childnodes}} TO @{$self->{meta}->{target}->{childnodes}} + STORE DATA + TO STORAGE $self->{meta}->{target}->{dbKey} + AT NODE $self->{meta}->{target}->{accessorName}.$self->{meta}->{target}->{nodeName} + USING IDENTIFIER $self->{meta}->{target}->{IdentProvider}->{method}.$self->{meta}->{target}->{IdentProvider}->{arg} +EOT + + + chomp($ql); + $logger->info($ql); + + #exit; + return; + + my $actioning = ucfirst $self->{opt}->{'action'} . 'ing'; + + # FIXME: this is weird! + my $long = <notice( __PACKAGE__ . ": $long" ); + +} + + sub _prepareOptions { my $self = shift; @@ -308,10 +432,16 @@ # merging - V2 # merge local map with local opts + + # delete undef'd items in $map + # enable cloning # FIXME: do we really need cloning here? trade safety/encapsulation for speed? Hash::Merge::set_clone_behavior(1); Hash::Merge::set_behavior( 'RIGHT_PRECEDENT' ); + #Hash::Merge::set_behavior( 'STORAGE_PRECEDENT' ); + #Hash::Merge::set_behavior( 'RETAINMENT_PRECEDENT' ); + # TODO: add an option to Hash::Merge not to overwrite set items with undefined/empty/not assigned ones my $locals_merged = merge( $opts, $map ); # trace @@ -397,6 +527,8 @@ # TODO: introduce different mechanism to make more then two partners (descents) possible ($self->{meta}->{source}, $self->{meta}->{target}) = ($self->{meta}->{target}, $self->{meta}->{source}); + #($self->{options}->{source}, $self->{options}->{target}) = + # ($self->{options}->{target}, $self->{options}->{source}); } elsif (lc $self->{options}->{process}->{mode} eq 'full') { # TODO: @@ -410,7 +542,7 @@ # import flag means: prepare the source node to be syncable # this is useful if there are e.g. no "ident" or "checksum" columns yet inside a DBI like (row-based) storage - if ($self->{args}->{prepare}) { + if ($self->{options}->{process}->{prepare}) { $self->_prepareNode_MetaProperties('source'); $self->_prepareNode_DummyIdent('source'); #return; @@ -419,7 +551,7 @@ # erase flag means: erase the target #if ($opts->{erase}) { - if ($self->{args}->{erase}) { + if ($self->{options}->{process}->{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');