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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (hide annotations)
Fri Mar 28 03:08:17 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.5: +6 -2 lines
fix regarding namespace update

1 joko 1.6 ## $Id: Metadata.pm,v 1.5 2003/02/21 08:34:58 joko Exp $
2 joko 1.1 ##
3     ## Copyright (c) 2002 Andreas Motl <andreas.motl@ilo.de>
4     ##
5     ## See COPYRIGHT section in pod text below for usage and distribution rights.
6     ##
7     ## ----------------------------------------------------------------------------------------
8 joko 1.2 ## $Log: Metadata.pm,v $
9 joko 1.6 ## Revision 1.5 2003/02/21 08:34:58 joko
10     ## modified object hierarchy
11     ## renamed method
12     ##
13 joko 1.5 ## Revision 1.4 2003/02/14 14:06:20 joko
14     ## + minor fix to old metadata structure
15     ##
16 joko 1.4 ## Revision 1.3 2003/02/11 06:28:24 joko
17     ## + changes to metadata structure
18     ##
19 joko 1.3 ## Revision 1.2 2003/02/09 05:02:05 joko
20     ## + major structure changes
21     ## - refactored code to sister modules
22     ##
23 joko 1.2 ## Revision 1.1 2003/01/20 16:58:46 joko
24     ## + initial check-in: here they are....
25     ##
26 joko 1.1 ## Revision 1.1 2003/01/19 01:23:04 joko
27     ## + new from Data/Transfer/Sync.pm
28     ##
29     ## ----------------------------------------------------------------------------------------
30    
31    
32     package Data::Transfer::Sync::Metadata;
33    
34     use strict;
35     use warnings;
36    
37     use mixin::with qw( Data::Transfer::Sync );
38    
39    
40     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - main
41    
42 joko 1.3 use Data::Dumper;
43     use libdb qw( quotesql );
44 joko 1.6 use Data::Mungle::Code::Ref qw( ref_slot );
45 joko 1.3
46 joko 1.1 # get logger instance
47     my $logger = Log::Dispatch::Config->instance;
48    
49     # TODO: refactor (still)!!! take this list from already established/given metadata ....
50     # .... also internally: passing around and mungling these metadata doesn't make sense anymore.
51 joko 1.2 sub options2metadata {
52 joko 1.1 my $self = shift;
53    
54 joko 1.2 $logger->debug( __PACKAGE__ . "->transformMetadata" );
55    
56 joko 1.3 # trace
57     #print Dumper($self->{options});
58     #print Dumper($self->{args_raw});
59     #exit;
60 joko 1.1
61 joko 1.2 # decompose identifiers and write to metadata (for each descent)
62 joko 1.1 foreach ('source', 'target') {
63    
64     # get/set metadata for further processing
65    
66     $self->{options}->{$_}->{dbKey} ||= '';
67     $self->{options}->{$_}->{nodeType} ||= '';
68     $self->{options}->{$_}->{nodeName} ||= '';
69    
70 joko 1.2 # Partner and Node (compare the V1-notations: "L:Country" or "R:countries.csv")
71 joko 1.1 $self->{meta}->{$_}->{dbKey} = $self->{options}->{$_}->{dbKey};
72     $self->{meta}->{$_}->{nodeType} = $self->{options}->{$_}->{nodeType};
73     $self->{meta}->{$_}->{nodeName} = $self->{options}->{$_}->{nodeName};
74    
75     # Filter
76 joko 1.3 if (my $item_filter = $self->{options}->{$_}->{filter}) {
77 joko 1.1 $self->{meta}->{$_}->{filter} = $item_filter;
78     }
79    
80     # IdentProvider
81     if (my $item_ident = $self->{options}->{$_}->{ident}) {
82     my @item_ident = split(':', $item_ident);
83     $self->{meta}->{$_}->{IdentProvider} = { method => $item_ident[0], arg => $item_ident[1] };
84     }
85    
86     # TODO: ChecksumProvider
87 joko 1.2 # already inside {options} - get it out from there and put into {meta} here!
88 joko 1.1
89     # exclude properties/subnodes
90     if (my $item_exclude = $self->{options}->{$_}->{exclude}) {
91     $self->{meta}->{$_}->{subnodes_exclude} = $item_exclude;
92     }
93    
94     # TypeProvider
95 joko 1.3 # FIXME! this is still Vdeprecated!!!
96 joko 1.4 if (my $item_type = $self->{options}->{$_ . '_type'}) {
97 joko 1.1 my @item_type = split(':', $item_type);
98     $self->{meta}->{$_}->{TypeProvider} = { method => $item_type[0], arg => $item_type[1] };
99     }
100 joko 1.3
101     # trace
102     #print Dumper($self);
103     #exit;
104 joko 1.1
105     # Callbacks - writers (will be triggered _before_ writing to target)
106 joko 1.3 if (my $item_writers = $self->{options}->{$_}->{callbacks}->{write}) {
107 joko 1.1 my $descent = $_; # this is important since the following code inside the map wants to use its own context variables
108     map { $self->{meta}->{$descent}->{Callback}->{write}->{$_}++; } @$item_writers;
109     }
110    
111     # Callbacks - readers (will be triggered _after_ reading from source)
112 joko 1.3 if (my $item_readers = $self->{options}->{$_}->{callbacks}->{read}) {
113 joko 1.1 my $descent = $_;
114     map { $self->{meta}->{$descent}->{Callback}->{read}->{$_}++; } @$item_readers;
115     }
116    
117 joko 1.3 # resolve storage handles
118     $self->{meta}->{$_}->{storage} = $self->{options}->{$_}->{storage}->{handle};
119    
120     # transfer storage handle options to metadata
121     #map { $self->{meta}->{$_}->{isIdentAuthority} = 1 } @{$self->{id_authorities}};
122     #map { $self->{meta}->{$_}->{isChecksumAuthority} = 1; } @{$self->{checksum_authorities}};
123     #map { $self->{meta}->{$_}->{isWriteProtected} = 1; } @{$self->{write_protected}};
124     #print Dumper($self->{options}->{$_});
125     #exit;
126     $self->{meta}->{$_}->{isIdentAuthority} = $self->{options}->{$_}->{storage}->{handle}->{locator}->{sync}->{isIdentAuthority};
127     $self->{meta}->{$_}->{isWriteProtected} = $self->{options}->{$_}->{storage}->{handle}->{locator}->{sync}->{isWriteProtected};
128     $self->{meta}->{$_}->{isChecksumAuthority} = $self->{options}->{$_}->{storage}->{handle}->{locator}->{sync}->{isChecksumAuthority};
129    
130 joko 1.1 }
131    
132     #print Dumper($self->{meta});
133     return 1;
134    
135     }
136    
137    
138 joko 1.2 sub options2metadata_accessor {
139 joko 1.1 my $self = shift;
140    
141 joko 1.2 $logger->debug( __PACKAGE__ . "->_transformMetadata_accessor" );
142 joko 1.1
143 joko 1.2 # build accessor metadata (for each descent)
144     foreach my $descent ('source', 'target') {
145 joko 1.1
146 joko 1.2 # the database type plays a role here to handle special nodesets:
147     # there may be a) childless/non-strict nodesets (e.g. a CSV-file)
148     # or b) normal ones - here the node-name corresponds more or less directly to
149     # the physical location in the storage hierarchy below us (e.g. MAPI or LDAP)
150     # or c) sets of nodes which are physically mapped by node-type (e.g. a RDBMS or a ODBMS)
151     my $dbType = $self->{meta}->{$descent}->{storage}->{locator}->{type};
152    
153     # a, b and c are "accessor-type"s (of 'none', 'node-name', 'node-type')
154     # the following code resolves these types to '$accessorType'
155     # and properly sets '$accessorName'
156    
157     # don't continue for certain storage handlers
158     # HACK for DBD::CSV - re-enable for other DBDs
159     #next if $dbType eq 'DBI';
160    
161     # get nodename
162    
163     # get node-name
164     my $nodename = $self->{meta}->{$descent}->{node}; # V1
165     $nodename ||= $self->{meta}->{$descent}->{nodeName}; # V2
166    
167     # check if nodename is actually a CODEref, execute it to get a mapped/filtered target-nodename
168     #print "----", ref $nodename, "\n";
169     #if ($nodename =~ m/CODE/) {
170     # print Dumper($self);
171     # #exit;
172     # $nodename = $nodename->($nodename);
173     #}
174    
175     # determine nodeset accessor -type and -name
176     # defaults
177     my $accessorType = 'none';
178     my $accessorName = '';
179    
180     # if explicit address was given in options, just use it!
181     if (my $address = $self->{options}->{$descent}->{address}) {
182     $accessorType = 'direct-address';
183     $accessorName = $address;
184     }
185    
186     # c)
187     elsif (($dbType eq 'DBI' || $dbType eq 'Tangram') && $self->{meta}->{$descent}->{nodeType}) {
188     $accessorType = 'node-type';
189     $accessorName = $self->{meta}->{$descent}->{nodeType};
190     }
191    
192     # b)
193     elsif ($nodename) {
194     $accessorType = 'node-name';
195     $accessorName = $nodename;
196     }
197    
198     # write accessor information to metadata
199     $self->{meta}->{$descent}->{accessorType} = $accessorType;
200     $self->{meta}->{$descent}->{accessorName} = $accessorName;
201    
202     }
203    
204     # trace
205     #print Dumper($self->{meta});
206     #print Dumper($self->{options});
207     #exit;
208 joko 1.1
209     }
210    
211 joko 1.2
212    
213     sub buildAttributeMap {
214    
215     my $self = shift;
216    
217     # field-structure for building sql
218     # mapping of sql-fieldnames to object-attributes
219     $self->{node}->{map} = {};
220    
221     # manually set ...
222     # ... object-id
223     $self->{node}->{map}->{$self->{meta}->{target}->{IdentProvider}->{arg}} = $self->{node}->{source}->{ident};
224     # ... checksum
225     $self->{node}->{map}->{cs} = $self->{node}->{source}->{checksum};
226    
227     #print "sqlmap: ", Dumper($self->{node}->{map}), "\n";
228    
229     #print Dumper($self);
230     #exit;
231    
232     # for transferring flat structures via simple (1:1) mapping
233     # TODO: diff per property / property value
234    
235     #if ($self->{args}->{mapping}) {
236     # apply mapping from $self->{args}->{mapping} to $self->{node}->{map}
237     #foreach my $key (@{$self->{meta}->{source}->{childnodes}}) {
238     my @childnodes = @{$self->{meta}->{source}->{childnodes}};
239     for (my $mapidx = 0; $mapidx <= $#childnodes; $mapidx++) {
240     #my $map_right = $self->{args}->{mapping}->{$key};
241    
242     $self->{node}->{source}->{propcache} = {};
243     $self->{node}->{target}->{propcache} = {};
244    
245     # get property name
246     $self->{node}->{source}->{propcache}->{property} = $self->{meta}->{source}->{childnodes}->[$mapidx];
247     $self->{node}->{target}->{propcache}->{property} = $self->{meta}->{target}->{childnodes}->[$mapidx];
248     #print "map: $map_right", "\n";
249    
250     # get property value
251     my $value;
252    
253     # detect for callback - old style - (maybe the better???)
254     if (ref($self->{node}->{target}->{map}) eq 'CODE') {
255     #$value = &$map_right($objClone);
256     } else {
257     # plain (scalar?) value
258     #$value = $objClone->{$map_right};
259     $self->{node}->{source}->{propcache}->{value} = $self->{node}->{source}->{payload}->{$self->{node}->{source}->{propcache}->{property}};
260     }
261     #$self->{node}->{map}->{$key} = $value;
262    
263     # detect expression
264     # for transferring deeply nested structures described by expressions
265     #print "val: $self->{node}->{source}->{propcache}->{value}", "\n";
266     if ($self->{node}->{source}->{propcache}->{property} =~ s/^expr://) {
267    
268     # create an anonymous sub to act as callback target dispatcher
269     my $cb_dispatcher = sub {
270     #print "=============== CALLBACK DISPATCHER", "\n";
271     #print "ident: ", $self->{node}->{source}->{ident}, "\n";
272     #return $self->{node}->{source}->{ident};
273    
274     };
275    
276    
277     #print Dumper($self->{node});
278    
279     # build callback map for helper function
280     #my $cbmap = { $self->{meta}->{source}->{IdentProvider}->{arg} => $cb_dispatcher };
281     my $cbmap = {};
282 joko 1.5 my $value = ref_slot($self->{node}->{source}->{payload}, $self->{node}->{source}->{propcache}->{property}, $cbmap);
283 joko 1.2 $self->{node}->{source}->{propcache}->{value} = $value;
284     }
285    
286     # encode values dependent on type of underlying storage here - expand cases...
287     my $storage_type = $self->{meta}->{target}->{storage}->{locator}->{type};
288     if ($storage_type eq 'DBI') {
289     # ...for sql
290     # quotemeta?
291     $self->{node}->{source}->{propcache}->{value} = quotesql($self->{node}->{source}->{propcache}->{value});
292    
293     } elsif ($storage_type eq 'Tangram') {
294     # iso? utf8 already possible?
295    
296     } elsif ($storage_type eq 'LDAP') {
297     # TODO: encode utf8 here?
298    
299     }
300    
301     # store value to transfer map
302     $self->{node}->{map}->{$self->{node}->{target}->{propcache}->{property}} = $self->{node}->{source}->{propcache}->{value};
303    
304     }
305     #}
306    
307    
308     # TODO: $logger->dump( ... );
309     #$logger->debug( "sqlmap:" . "\n" . Dumper($self->{node}->{map}) );
310     #print "sqlmap: ", Dumper($self->{node}->{map}), "\n";
311     #print "entrystatus: ", Dumper($self->{node}), "\n";
312    
313     }
314 joko 1.1
315     1;

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