/[cvs]/nfo/perl/libs/Data/Transfer/Sync/API.pm
ViewVC logotype

Annotation of /nfo/perl/libs/Data/Transfer/Sync/API.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (hide annotations)
Sat Jun 19 01:43:03 2004 UTC (20 years ago) by joko
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +89 -80 lines
code from _prepareOptions now split into _prepareMap and _mergeOptions

1 joko 1.9 ## -------------------------------------------------------------------------
2     ##
3 joko 1.10 ## $Id: API.pm,v 1.9 2003/05/13 08:16:44 joko Exp $
4 joko 1.1 ##
5     ## Copyright (c) 2002 Andreas Motl <andreas.motl@ilo.de>
6     ##
7 joko 1.9 ## See COPYRIGHT section in associated pod text
8     ## or below for usage and distribution rights.
9 joko 1.1 ##
10 joko 1.9 ## -------------------------------------------------------------------------
11 joko 1.2 ## $Log: API.pm,v $
12 joko 1.10 ## Revision 1.9 2003/05/13 08:16:44 joko
13     ## minor update: modified header
14     ##
15 joko 1.9 ## Revision 1.8 2003/03/27 15:31:15 joko
16     ## fixes to modules regarding new namespace(s) below Data::Mungle::*
17     ##
18 joko 1.8 ## Revision 1.7 2003/02/21 08:00:24 joko
19     ## debugging
20     ##
21 joko 1.7 ## Revision 1.6 2003/02/14 12:58:47 joko
22     ## + re-enabled the erase-mechanism
23     ##
24 joko 1.6 ## Revision 1.5 2003/02/11 05:26:04 joko
25     ## + sub _tellWhatIWillDo
26     ## + re-enabled "branch to execution path for special targets" mechanism
27     ##
28 joko 1.5 ## Revision 1.4 2003/02/09 05:03:02 joko
29     ## + minor fix regarding namespace of api versioning extension module
30     ##
31 joko 1.4 ## Revision 1.3 2003/02/09 04:59:27 joko
32     ## + api versioning mechanism
33     ## + major structure changes
34     ## - refactored code to sister modules
35     ##
36 joko 1.3 ## Revision 1.2 2003/01/20 16:59:48 joko
37     ## + cosmetics and debugging
38     ##
39 joko 1.2 ## Revision 1.1 2003/01/19 01:23:04 joko
40     ## + new from Data/Transfer/Sync.pm
41     ##
42 joko 1.1 ## ----------------------------------------------------------------------------------------
43    
44    
45 joko 1.2 package Data::Transfer::Sync::API;
46    
47 joko 1.1 use strict;
48     use warnings;
49 joko 1.2
50 joko 1.3 use base qw( DesignPattern::Bridge );
51    
52 joko 1.1 use mixin::with qw( Data::Transfer::Sync );
53 joko 1.2
54 joko 1.1
55     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - main
56 joko 1.2
57     use Data::Dumper;
58 joko 1.3 use Hash::Merge qw( merge );
59 joko 1.2
60 joko 1.8 use Data::Mungle::Compare::Struct qw( isEmpty );
61 joko 1.2
62 joko 1.1 # get logger instance
63     my $logger = Log::Dispatch::Config->instance;
64 joko 1.2
65 joko 1.3
66     sub api_constructor {
67 joko 1.1 my $self = shift;
68 joko 1.3 $logger->debug( __PACKAGE__ . "->api_constructor: Loading API");
69     $self->_loadVersionExtensions();
70 joko 1.1 }
71 joko 1.2
72 joko 1.3
73     sub _loadVersionExtensions {
74 joko 1.1 my $self = shift;
75 joko 1.3 my $syncVersion = $self->{sync_version};
76     $syncVersion ||= '';
77     $logger->debug( __PACKAGE__ . "->loadVersionExtensions( version='$syncVersion' )");
78     #print Dumper($self);
79     #exit;
80 joko 1.4 my $module = "API::$syncVersion";
81 joko 1.3 $self->load($module);
82     }
83    
84    
85     sub configure {
86     my $self = shift;
87    
88     $logger->debug( __PACKAGE__ . "->configure");
89    
90     my @args = @_;
91    
92     if (!isEmpty(\@args)) {
93     my %properties = @_;
94     # merge args to properties
95     #map { $self->{$_} = $properties{$_}; } keys %properties;
96     #print Dumper($self);
97     #print Dumper(\%properties);
98     if ($self->{options}) {
99     my $options_new = merge($self->{options}, \%properties);
100     #print Dumper($options_new);
101     $self->{options} = $options_new;
102     #print Dumper($self->{options});
103     } else {
104     $self->{options} = \%properties;
105     }
106     $self->_init();
107     #$self->_initV1();
108     } else {
109     #print "no args!", "\n";
110 joko 1.1 }
111    
112 joko 1.3 #print Dumper($self);
113     #exit;
114    
115     $self->{state}->{configured} = 1;
116     return 1;
117 joko 1.1 }
118 joko 1.2
119 joko 1.3
120     sub setArguments {
121 joko 1.1 my $self = shift;
122 joko 1.3 my $args_raw = shift;
123     $self->{args_raw} = $args_raw;
124     }
125 joko 1.1
126 joko 1.3 sub readArguments {
127     my $self = shift;
128 joko 1.1
129 joko 1.3 my %syncConfig;
130     tie %syncConfig, 'Tie::IxHash';
131     %syncConfig = (
132     map => {
133     moduleName => $self->{args_raw}->{'mapping-module'},
134     },
135     source => {
136     dbKey => $self->{args_raw}->{source},
137     nodeType => $self->{args_raw}->{'source-type'},
138     nodeName => $self->{args_raw}->{'source-node'},
139 joko 1.10 ident => $self->{args_raw}->{'source-ident'},
140 joko 1.3 },
141     target => {
142     dbKey => $self->{args_raw}->{target},
143     nodeName => $self->{args_raw}->{'target-node'},
144     },
145     process => {
146     mode => $self->{args_raw}->{mode},
147     erase => $self->{args_raw}->{erase},
148     import => $self->{args_raw}->{import},
149     prepare => $self->{args_raw}->{prepare},
150     },
151     # metadata => {
152     # config => $self->{config_metadata},
153     # }
154     );
155 joko 1.1
156 joko 1.3 $self->{args} = \%syncConfig;
157 joko 1.1
158     }
159    
160 joko 1.2
161 joko 1.3 # TODO: some feature to show off the progress of synchronization (cur/max * 100)
162     sub syncNodes {
163 joko 1.1
164     my $self = shift;
165 joko 1.3 my $args = shift;
166    
167 joko 1.7 #$logger->notice( "========================== " . __PACKAGE__ . "->syncNodes ==============");
168 joko 1.3 $logger->debug( __PACKAGE__ . "->syncNodes: starting" );
169 joko 1.1
170 joko 1.3 #print Dumper($self);
171 joko 1.1 #exit;
172    
173 joko 1.3 #print Dumper($self->{options});
174     $self->_prepareOptions();
175 joko 1.1
176 joko 1.6 # trace
177     #print Dumper($self->{options});
178     #exit;
179 joko 1.1
180 joko 1.3 if (!$self->checkOptions()) {
181     $logger->critical( __PACKAGE__ . "->syncNodes: 'Data::Transfer::Sync::checkOptions' failed.");
182 joko 1.1 return;
183     }
184    
185 joko 1.3 if (!$self->{state}->{configured}) {
186     $logger->critical( __PACKAGE__ . "->syncNodes: Synchronization object is not configured/initialized correctly." );
187 joko 1.1 return;
188     }
189    
190 joko 1.5 #print Dumper($args);
191    
192 joko 1.3 # remember arguments through the whole processing
193     $self->{args} = $args;
194 joko 1.1
195 joko 1.3 # hash to hold and/or fill in metadata required for the processing
196     $self->{meta} = {};
197 joko 1.1
198 joko 1.3 # hash to sum up results
199     # TODO: re-implement! (sync-statistics???)
200 joko 1.1
201 joko 1.6 #print Dumper($self->{options}->{process});
202    
203 joko 1.3 # detect synchronization method to determine which optical symbol (directed arrow) to use
204     my $mode = $self->{args}->{mode}; # V1
205     $mode ||= $self->{options}->{process}->{mode}; # V2
206     my $direction_arrow = $self->_getDirectedArrow($mode);
207 joko 1.1
208 joko 1.3 # determine code versions
209     my $code_metadata_version;
210     # first, try to use version supplied by mapping-metadata
211     $code_metadata_version = $self->{options}->{metadata}->{version};
212     # if not set, inherit from global 'sync_version'
213     $code_metadata_version ||= $self->{sync_version};
214    
215     # load additional code from versioned namespace into current instance
216     my $dynModule = "Metadata::$code_metadata_version";
217     $self->load($dynModule);
218    
219     # build metadata using versioned code and stuff
220     $self->options2metadata();
221     $self->options2metadata_accessor();
222    
223 joko 1.5 # branch to execution path for special targets
224     # detect for option 'handler' which could be a CODEref
225     if ($self->{options}->{handler} && ref $self->{options}->{handler} eq 'CODE') {
226     $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}");
227     #print Dumper($self);
228     #exit;
229     # don't do this any more - it wasn't very nice somehow ...
230     #$self->{options}->{handler}->($self->{app}, $self->{options});
231     # .... now: better let the parent application scope handle this via callback
232     # not any more required for this: $self->{app} inside here (which isn't the app we mean here)
233     # required for this: getting the options out of here: establish some getter method! ($self->getOptions(...))
234     # so....
235     #$self->{__bridge}->{parent_ref}->
236    
237     # ahh okay, DesignPattern::Bridge moves closer to some Class::Inner!???
238     # so...
239     # similar like above - but it isn't very nice anyway ... (no privateness, but: who cares?)
240     #print Dumper($self->{__bridge});
241     # just take the global application instance and
242     # throw it into the context of the mapping module - this is heavy! ;-) (but again, who cares...)
243 joko 1.6 # TODO: handle this more abstract *sometime*
244 joko 1.5 #$self->{options}->{handler}->($self->{__bridge}->{parent}->{app}, $self->{options});
245     $self->{options}->{handler}->($self->{__bridge}->{parent}->{process}, $self->{options});
246    
247     return;
248     }
249    
250     # TODO: execution path branch V2!!!
251     # option1: wrap this via callback to parent scope (like current impl. mechanism)
252     # option2: branch directly from here (this needs refactoring of the sub handler)
253    
254 joko 1.3 # tracing
255     #print Dumper($self);
256     #exit;
257 joko 1.1
258 joko 1.7 # V1:
259     $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}]" );
260    
261     # V2:
262     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}]";
263     #my $header = ("~.." x 7) . " " . $what . " " . ("~.." x 4);
264     #my $header = ("= " x 7) . " " . $what . " " . ("= " x 4);
265     #my $header = ("~=-_-=" x 3) . " " . $what . " " . ("~=-_-=" x 4);
266     my $header = ("_-=~=-" x 4) . " " . $what . " " . ("_-=~=-" x 4);
267     $logger->notice($header);
268    
269 joko 1.1
270 joko 1.3 return if !$self->buildFieldmapping();
271     return if !$self->_touchNodeSet();
272     return if !$self->_prepare_sync();
273 joko 1.5 $self->_tellWhatIWillDo();
274 joko 1.3
275     # tracing
276     #print Dumper($self);
277     #print Dumper($self->{args});
278     #print Dumper($self->{options});
279     #print Dumper($self->{meta});
280     #print Dumper($self->{metadata});
281     #exit;
282 joko 1.1
283 joko 1.3 # finally, tell the core to start the synchronization process
284     $self->_run();
285    
286     }
287 joko 1.1
288 joko 1.2
289 joko 1.5 my $c_string_default = '';
290     sub c_string {
291     my $value = shift;
292     $value ||= "[$c_string_default]";
293     return $value;
294     }
295    
296     sub _tellWhatIWillDo {
297     my $self = shift;
298    
299    
300     #return;
301    
302     # trace
303     #print Dumper($self->{meta});
304     #exit;
305    
306     $c_string_default = 'n/a';
307     my $source = c_string($self->{opt}->{'source'});
308     my $source_node = c_string($self->{opt}->{'source-node'});
309     my $source_type = c_string($self->{opt}->{'source-type'});
310     my $target = c_string($self->{opt}->{'target'});
311     my $target_node = c_string($self->{opt}->{'target-node'});
312     my $target_type = c_string($self->{opt}->{'target-type'});
313    
314     my $mapping_module = c_string($self->{opt}->{'mapping-module'});
315     my $mode = uc c_string($self->{opt}->{'mode'});
316    
317     #my $ql = "$mode INTO $source NODE $source_node TYPE $source_type SELECT NODE $target_node TYPE $target_type FROM $target USING MODULE $mapping_module;";
318     #$logger->notice( __PACKAGE__ . ": $ql" );
319     my $ql = <<EOT;
320    
321     FETCH DATA
322     FROM STORAGE $self->{meta}->{source}->{dbKey}
323     AT NODE $self->{meta}->{source}->{accessorName}.$self->{meta}->{source}->{nodeName}
324     USING IDENTIFIER $self->{meta}->{source}->{IdentProvider}->{method}.$self->{meta}->{source}->{IdentProvider}->{arg}
325     CONVERT DATA
326     CAST FROM $self->{meta}->{source}->{nodeType} TO $self->{meta}->{target}->{nodeType}
327     MAP ATTRIBUTES FROM @{$self->{meta}->{source}->{childnodes}} TO @{$self->{meta}->{target}->{childnodes}}
328     STORE DATA
329     TO STORAGE $self->{meta}->{target}->{dbKey}
330     AT NODE $self->{meta}->{target}->{accessorName}.$self->{meta}->{target}->{nodeName}
331     USING IDENTIFIER $self->{meta}->{target}->{IdentProvider}->{method}.$self->{meta}->{target}->{IdentProvider}->{arg}
332     EOT
333    
334    
335 joko 1.7 chomp($ql);
336     $logger->info($ql);
337 joko 1.5
338     #exit;
339     return;
340    
341     my $actioning = ucfirst $self->{opt}->{'action'} . 'ing';
342    
343     # FIXME: this is weird!
344     my $long = <<EOT;
345    
346     - $actioning data of type $target_type and
347     filtered by $target_node from the storage named $target
348     to the storage named $source - filtered by $source_node.
349     - Will attempt to convert the data to $source_type.
350     EOT
351     chomp($long);
352     $logger->notice( __PACKAGE__ . ": $long" );
353    
354     }
355    
356    
357 joko 1.3 sub _prepareOptions {
358 joko 1.1
359     my $self = shift;
360 joko 1.3
361     my $opts = $self->{args};
362 joko 1.1
363     # patch options
364 joko 1.3 $opts->{source}->{nodeName} ||= '';
365     $opts->{target}->{nodeName} ||= '';
366 joko 1.1 $opts->{process}->{mode} ||= '';
367 joko 1.3 $opts->{process}->{erase} ||= 0;
368 joko 1.1 $opts->{process}->{prepare} ||= 0;
369 joko 1.3
370     # defaults (mostly for backward-compatibility to V1 -
371     # but code mungled here out of prepareOptions_V1 from Version::V1)
372     $opts->{metadata}->{syncMethod} ||= 'checksum'; # | timestamp
373     $opts->{source}->{ident} ||= 'storage_method:id';
374     $opts->{source}->{exclude} ||= [qw( cs )];
375     $opts->{target}->{ident} ||= 'property:oid';
376     #$map->{source_node} ||= $source_node_name;
377     #$map->{direction} ||= $opts->{mode}; # | PUSH | PULL | FULL
378 joko 1.1
379     # pre-check options
380     if (!$self->_preCheckOptions($opts)) {
381 joko 1.3 $logger->error( __PACKAGE__ . "->_prepareOptions: _preCheckOptions failed.");
382 joko 1.1 return;
383     }
384    
385     # inform user about option preparation
386 joko 1.3 $logger->debug( __PACKAGE__ . "->_prepareOptions( source.node='$opts->{source}->{nodeName}', target.node='$opts->{target}->{nodeName}', mode='$opts->{process}->{mode}', e='$opts->{process}->{erase}', p='$opts->{process}->{prepare}' )");
387 joko 1.1
388 joko 1.10 my $map = {};
389     $map = $self->_prepareMap($opts) if not $opts->{process}->{prepare};
390     #$map = $self->_prepareMap($opts);
391    
392     # merge all together
393     $self->_mergeOptions($opts, $map);
394     #print Dumper($self->{options});
395    
396     $self->{state}->{options_ready} = 1;
397 joko 1.1
398 joko 1.10 return 1;
399 joko 1.1
400 joko 1.10 }
401 joko 1.1
402 joko 1.10 sub _prepareMap {
403     my $self = shift;
404     my $opts = shift;
405    
406     # 1. try to load mapping-metadata-container
407 joko 1.1
408 joko 1.10 # How? Create a new instance of the given
409     # perl module/package name in ->{...}->{moduleName}.
410     # This instance is used later in the innards of the sync,
411     # that's why the module (class) should have a certain layout
412     # enabling the core to use it for gathering metadata while processing.
413     my $mapObject = DesignPattern::Object->fromPackage($opts->{map}->{moduleName});
414    
415 joko 1.3
416 joko 1.10 # 2. try to resolve map from metadata-container
417 joko 1.1
418 joko 1.10 # type of the item/node
419     my $source_nodeType = $opts->{source}->{nodeType};
420 joko 1.3
421 joko 1.10 # check if mapping for certain node is contained in mapping object
422     if (!$mapObject || !$mapObject->can($source_nodeType)) {
423     $logger->warning( __PACKAGE__ . "->_prepareOptions: Can't access mapping for source-type=\"$source_nodeType\" - please check \"$opts->{map}->{moduleName}\".");
424     return;
425     }
426 joko 1.3
427 joko 1.10 # get map
428     my $map = $mapObject->$source_nodeType;
429     #print Dumper($map);
430    
431     my $map_version = $map->{metadata}->{version};
432     # FIXME: backward compatibility
433     if (!$map_version) {
434     $self->options_to_V2($map);
435     }
436 joko 1.3
437 joko 1.10 # trace
438     #print Dumper($map);
439     #exit;
440     #print "ref: ", ref $map->{target}, "\n";
441     #print "target: ", $map->{target}, "\n";
442    
443     # check here if "target" is actually a CODEref - in this case: resolve it - deprecated!!! ???
444     if (ref $map->{target}->{address} eq 'CODE') {
445     $map->{target}->{address} = $map->{target}->{address}->($source_nodeType);
446     }
447 joko 1.3
448 joko 1.10 # resolve expressions (on nodename-level) here
449     elsif ($map->{target}->{address} =~ m/^(code|expr):(.+?)$/) {
450     my $target_dynamic_type = $1;
451     my $target_dynamic_expression = $2;
452     if (lc $target_dynamic_type eq 'code') {
453     $map->{target} = $mapObject->$target_dynamic_expression($map);
454     }
455     }
456    
457     return $map;
458 joko 1.3
459 joko 1.10 }
460 joko 1.1
461 joko 1.10 sub _mergeOptions {
462     my $self = shift;
463     my $opts = shift;
464     my $map = shift;
465 joko 1.1
466 joko 1.10 # 1. merge local map with local opts
467    
468     # delete undef'd items in $map
469 joko 1.1
470 joko 1.10 # enable cloning
471     # FIXME: do we really need cloning here? trade safety/encapsulation for speed?
472     Hash::Merge::set_clone_behavior(1);
473     Hash::Merge::set_behavior( 'RIGHT_PRECEDENT' );
474     #Hash::Merge::set_behavior( 'STORAGE_PRECEDENT' );
475     #Hash::Merge::set_behavior( 'RETAINMENT_PRECEDENT' );
476     # TODO: add an option to Hash::Merge not to overwrite set items with undefined/empty/not assigned ones
477     my $locals_merged = merge( $opts, $map );
478    
479     # 2. merge local-merged ones with instance-wide options
480     Hash::Merge::set_clone_behavior(0);
481     $self->{options} = merge( $self->{options}, $locals_merged );
482 joko 1.1 }
483 joko 1.2
484 joko 1.3 sub _preCheckOptions {
485    
486 joko 1.1 my $self = shift;
487 joko 1.3 my $opts = shift;
488    
489     # trace
490     #print Dumper($opts);
491     #exit;
492    
493 joko 1.10 if (!$opts->{process}->{mode} and !$opts->{process}->{prepare}) {
494     $logger->error( __PACKAGE__ . "->_preCheckOptions failed: Please specify \"--action=(load|save)\" or \"--prepare\".");
495 joko 1.3 return;
496 joko 1.1 }
497    
498 joko 1.3 # the type of the to-be-synced item
499     if (!$opts->{source}->{nodeType}) {
500     $logger->error( __PACKAGE__ . "->_preCheckOptions failed: Please specify \"source-type\".");
501     return;
502 joko 1.1 }
503 joko 1.3 # the name of the (container-) node the items are listed in
504     if (!$opts->{source}->{nodeName}) {
505     $logger->error( __PACKAGE__ . "->_preCheckOptions failed: Please specify \"source-node\".");
506     return;
507 joko 1.2 }
508 joko 1.1
509 joko 1.3 # a "map"-declaration which module to use for mapping- and/or lookup-purposes
510     if (!$opts->{map}) {
511     $logger->warning( __PACKAGE__ . "->_preCheckOptions: No mapping supplied - please check key 'map|mappings' in global configuration or specify additional argument '--mapping-module'.");
512 joko 1.1 return;
513     }
514 joko 1.10 if (!$opts->{map}->{moduleName} and !$opts->{process}->{prepare}) {
515 joko 1.3 $logger->warning( __PACKAGE__ . "->_preCheckOptions: Currently only perl-modules can provide mappings: Please specify one with '--mapping-module=My::Mapping::Module'.");
516     return;
517 joko 1.1 }
518    
519 joko 1.3 return 1;
520 joko 1.2
521     }
522 joko 1.1
523    
524 joko 1.2
525 joko 1.3 sub _prepare_sync {
526 joko 1.2
527     my $self = shift;
528 joko 1.1
529     # TODO:
530     # + if action == PUSH: start processing
531     # -+ if action == PULL: swap metadata and start processing
532     # - if action == FULL: start processing, then swap metadata and (re-)start processing
533    
534 joko 1.3 #print "dir: ", $self->{args}->{direction}, "\n";
535    
536 joko 1.1 # manipulate metainfo according to direction of synchronization
537 joko 1.3 if (lc $self->{options}->{process}->{mode} eq 'push') {
538     # just do it ... (don't modify any metadata)
539    
540     } elsif (lc $self->{options}->{process}->{mode} eq 'pull') {
541     # swap source and target metadata
542     # TODO: introduce different mechanism to make more then two partners (descents) possible
543 joko 1.1 ($self->{meta}->{source}, $self->{meta}->{target}) =
544     ($self->{meta}->{target}, $self->{meta}->{source});
545 joko 1.5 #($self->{options}->{source}, $self->{options}->{target}) =
546     # ($self->{options}->{target}, $self->{options}->{source});
547 joko 1.3
548     } elsif (lc $self->{options}->{process}->{mode} eq 'full') {
549     # TODO:
550     # do a pull first and a push afterwards
551     # this requires us to be called somehow recursively - just one recursion level ;-)
552    
553 joko 1.1 } else {
554 joko 1.3 # TODO: are there any other synchronization modes besides PULL, PUSH, FULL?
555    
556 joko 1.1 }
557    
558     # import flag means: prepare the source node to be syncable
559     # this is useful if there are e.g. no "ident" or "checksum" columns yet inside a DBI like (row-based) storage
560 joko 1.6 if ($self->{options}->{process}->{prepare}) {
561 joko 1.1 $self->_prepareNode_MetaProperties('source');
562     $self->_prepareNode_DummyIdent('source');
563 joko 1.10 return;
564 joko 1.1 #$self->_erase_all($opts->{source_node});
565     }
566    
567     # erase flag means: erase the target
568     #if ($opts->{erase}) {
569 joko 1.6 if ($self->{options}->{process}->{erase}) {
570 joko 1.1 # TODO: move this method to the scope of the synchronization core and wrap it around different handlers
571     #print "ERASE", "\n";
572     $self->_erase_all('target');
573     }
574 joko 1.2
575     return 1;
576 joko 1.1
577 joko 1.3 }
578    
579     sub _getDirectedArrow {
580     my $self = shift;
581     my $mode = shift;
582     $mode ||= '';
583    
584     if (lc $mode eq 'push') {
585     return '->';
586     } elsif (lc $mode eq 'pull') {
587     return '<-';
588     } elsif (lc $mode eq 'full') {
589     return '<->';
590     } else {
591     return '';
592     }
593 joko 1.1 }
594    
595     1;

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed