File Coverage

blib/lib/Persistence/Meta/XML.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Persistence::Meta::XML;
2              
3 4     4   471807 use strict;
  4         11  
  4         205  
4 4     4   24 use warnings;
  4         8  
  4         148  
5 4     4   177 use vars qw($VERSION);
  4         10  
  4         210  
6              
7 4     4   25 use Abstract::Meta::Class ':all';
  4         6  
  4         815  
8 4     4   22 use Carp 'confess';
  4         7  
  4         204  
9 4     4   1579 use Persistence::Entity::Manager;
  0            
  0            
10             use Persistence::Entity ':all';
11             use Persistence::ORM;
12             use Persistence::Meta::Injection;
13             use Persistence::Relationship;
14             use Persistence::Relationship::ToOne;
15             use Persistence::Relationship::OneToMany;
16             use Persistence::Relationship::ManyToMany;
17             use SQL::Entity::Condition;
18             use Simple::SAX::Serializer;
19             use Simple::SAX::Serializer::Handler ':all';
20              
21              
22             $VERSION = 0.04;
23              
24             =head1 NAME
25              
26             Persistence::Meta::XML - Persistence meta object xml injection
27              
28             =cut
29              
30             =head1 SYNOPSIS
31              
32             use Persistence::Meta::XML;
33             my $meta = Persistence::Meta::XML->new(persistence_dir => 'meta/');
34             my $entity_manager = $meta->inject('my_persistence.xml');
35             #or
36             # $meta->inject('my_persistence.xml');
37             # my $entity_manager = Persistence::Entity::Manager->manager('manager_name');
38              
39              
40             =head1 DESCRIPTION
41              
42             Loads xml files that containt meta persistence definition.
43              
44             persistence.xml
45            
46            
47            
48            
49            
50            
51            
52            
53            
54            
55            
56              
57             emp.xml
58            
59            
60             empno
61            
62            
63            
64            
65            
66            
67            
68            
69            
70            
71            
72              
73             dept.xml
74            
75            
76             deptno
77            
78            
79            
80            
81            
82            
83            
84             deptno
85            
86            
87            
88              
89             Employee.xml
90            
91            
92            
93            
94            
95            
96            
97            
98              
99             Department.xml
100            
101            
102            
103            
104            
105            
106            
107              
108              
109             package Employee;
110             use Abstract::Meta::Class ':all';
111              
112             has '$.id';
113             has '$.name';
114             has '$.job';
115             has '$.dept_name';
116             has '$.dept' => (associated_class => 'Department');
117              
118             package Department;
119             use Abstract::Meta::Class ':all';
120              
121             has '$.id';
122             has '$.name';
123             has '$.location';
124             has '@.employees' => (associated_class => 'Employee');
125              
126             my $meta = Persistence::Meta::XML->new(persistence_dir => $dir);
127             my $entity_manager = $meta->inject('persistence.xml');
128              
129             my ($dept) = $entity_manager->find(dept => 'Department', name => 'dept3');
130              
131             my $enp = Employee->new(id => 88, name => 'emp88');
132             $enp->set_dept(Department->new(id => 99, name => 'd99'));
133             $entity_manager->insert($enp);
134              
135             =head1 EXPORT
136              
137             None
138              
139             =head2 ATTRIBUTES
140              
141             =over
142              
143             =item cache_dir
144              
145             Containts cache directory.
146              
147             =cut
148              
149             has '$.cache_dir';
150              
151              
152             =item use_cache
153              
154             Flag that indicates if cache is used.
155              
156             =cut
157              
158             has '$.use_cache' => (default => 0);
159              
160              
161             =item persistence_dir
162              
163             Directory for xml meta persistence definition.
164              
165             =cut
166              
167             has '$.persistence_dir';
168              
169              
170             =item persistence_dir
171              
172             Contains directory of xml files that contain persistence object definition.
173              
174             =cut
175              
176              
177             =item injection
178              
179             =cut
180              
181             has '$.injection';
182              
183              
184             =back
185              
186             =head2 METHODS
187              
188             =over
189              
190             =item initialise
191              
192             =cut
193              
194             sub initialise {
195             my ($self) = @_;
196             $self->set_cache_dir($self->persistence_dir)
197             if ($self->use_cache && ! $self->cache_dir);
198             }
199              
200              
201             =item inject
202              
203             Injects persistence xml definition.
204             Takes xml file definition
205              
206              
207             my $meta = Persistence::Meta::XML->new(persistence_dir => $dir);
208             my $entity_manager = $meta->inject('persistence.xml');
209              
210              
211             =cut
212              
213             sub inject {
214             my ($self, $file) = @_;
215             my $injection;
216             my $prefix_dir = $self->persistence_dir;
217             my $file_name = $prefix_dir . $file;
218             if($self->use_cache) {
219             my $cached_injection = Persistence::Meta::Injection->load_from_cache($self, $file_name);
220             $injection = $cached_injection
221             if $cached_injection && $cached_injection->can_use_cache;
222             }
223              
224             $injection ||= Persistence::Meta::Injection->new;
225             $self->set_injection($injection);
226             unless ($injection->cached_version) {
227             $injection->add_file_stat($file_name);
228             my $xml = $self->persistence_xml_handler;
229             $xml->parse_file($prefix_dir . $file);
230             }
231             $self->injection->load_persistence_context($self, $file);
232             }
233              
234              
235             =item persistence_xml_handler
236              
237             Retunds xml handlers that will transform the persistence xml into objects.
238             Persistence node is mapped to the Persistence::Entity::Manager;
239              
240            
241            
242            
243            
244            
245            
246            
247            
248            
249            
250            
251            
252            
253              
254            
255            
256            
257            
258            
259            
260            
261            
262            
263            
264            
265            
266            
267            
268              
269              
270              
271             =cut
272              
273             sub persistence_xml_handler {
274             my ($self) = @_;
275             my $xml = Simple::SAX::Serializer->new;
276             $self->add_xml_persistence_handlers($xml);
277             $xml;
278             }
279              
280              
281             =item add_xml_persistence_handlers
282              
283             Adds persistence xml handlers/
284             Takes Simple::SAX::Serializer object as parameter.
285              
286             =cut
287              
288             sub add_xml_persistence_handlers {
289             my ($self, $xml) = @_;
290             my $temp_data = {};
291             $xml->handler('persistence', root_object_handler('Persistence::Entity::Manager' , sub {
292             my ($result) = @_;
293             my $injection = $self->injection;
294             $injection->set_entity_manager($result);
295             $injection->set_orm_files(\@{$temp_data->{orm}});
296             $injection->set_entities_files(\@{$temp_data->{entities}});
297             $injection->set_sequence_generators(\@{$temp_data->{sequence_generators}});
298             $injection->set_table_generators(\@{$temp_data->{table_generators}});
299             delete $temp_data->{$_} for qw(entities orm sequence_generators table_generators);
300             $result;
301             })),
302              
303             $xml->handler('entities', ignore_node_handler());
304             $xml->handler('value_generators', ignore_node_handler());
305             $xml->handler('to_many_relationships', ignore_node_handler());
306             $xml->handler('entity_file', custom_array_handler($temp_data, undef, undef, 'entities'));
307             $xml->handler('filter_condition_values', hash_handler());
308             $xml->handler('dml_filter_values', hash_handler());
309             $xml->handler('mapping_rules', ignore_node_handler());
310             $xml->handler('orm_file', custom_array_handler($temp_data, undef, undef, 'orm'));
311             $xml->handler('sequence_generator', custom_array_handler($temp_data, undef, undef, 'sequence_generators'));
312             $xml->handler('table_generator', custom_array_handler($temp_data, undef, undef, 'table_generators'));
313             }
314              
315              
316             =item orm_xml_handler
317              
318            
319            
320            
321            
322            
323            
324            
325            
326            
327              
328            
329            
330            
331            
332            
333            
334              
335             many_to_many 'project' => (
336             attribute => has('%.projects' => (associated_class => 'Project'), index_by => 'name'),
337             join_entity_name => 'emp_project',
338             fetch_method => LAZY,
339             cascade => ALL,
340             );
341              
342              
343             =item orm_xml_handler
344              
345             Retunds xml handlers that will transform the orm xml into Persistence::ORM object
346              
347             =cut
348              
349             sub orm_xml_handler {
350             my ($self) = @_;
351             my $xml = Simple::SAX::Serializer->new;
352             $self->add_orm_xml_handlers($xml);
353             $xml;
354             }
355              
356              
357             =item add_orm_xml_handlers
358              
359             Adds orm xml handler to Simple::SAX::Serializer object.
360              
361             =cut
362              
363             sub add_orm_xml_handlers {
364             my ($self, $xml) = @_;
365             my $temp_data = {};
366             $xml->handler('orm', sub {
367             my ($this, $element, $parent) = @_;
368             my $injection = $self->injection;
369             my $orm_mapping = $injection->_orm_mapping;
370             my $attributes = $element->attributes;
371             my $children_result = $element->children_result || {};
372             push @$orm_mapping, {%$attributes}, {%$children_result};
373             });
374             $xml->handler('column', hash_of_array_handler(undef, undef, 'columns'));
375             $xml->handler('lob', hash_of_array_handler(undef, undef, 'lobs'));
376             $xml->handler('to_one_relationship', hash_of_array_handler(undef, undef, 'to_one_relationships'));
377             $xml->handler('one_to_many_relationship', hash_of_array_handler(undef, undef, 'one_to_many_relationships'));
378             $xml->handler('many_to_many_relationship', hash_of_array_handler(undef, undef, 'many_to_many_relationships'));
379             }
380              
381              
382             =item entity_xml_handler
383              
384             Retunds xml handlers that will transform the enity xml into Persistence::Entity
385              
386            
387             filter_condition_value+ .dml_filter_value+, to_one_relationships? to_many_relationships?, value_generators*)>
388            
389            
390            
391            
392            
393            
394            
395            
396            
397            
398            
399            
400            
401            
402            
403            
404            
405            
406            
407            
408            
409            
410            
411            
412            
413            
414            
415              
416             For instnace.
417            
418            
419             empno
420            
421            
422             ename
423            
424            
425             empno
426            
427            
428            
429            
430            
431            
432            
433            
434            
435            
436            
437            
438            
439            
440             deptno
441            
442            
443            
444              
445             =cut
446              
447             sub entity_xml_handler {
448             my ($self) = @_;
449             my $xml = Simple::SAX::Serializer->new;
450             $self->add_entity_xml_handlers($xml);
451             $xml;
452             }
453              
454              
455             =item add_entity_xml_handlers
456              
457             Adds entity xml handler to the Simple::SAX::Serializer object.
458              
459             =cut
460              
461             sub add_entity_xml_handlers {
462             my ($self, $xml) = @_;
463             my $temp_data = {};
464             $xml->handler('entity', root_object_handler('Persistence::Entity' , sub {
465             my ($result) = @_;
466             my $id = $result->id;
467             my $injection = $self->injection;
468             my $entities_subquery_columns = $injection->_entities_subquery_columns;
469             my $entities_to_many_relationships = $injection->_entities_to_many_relationships;
470             my $entities_to_one_relationships = $injection->_entities_to_one_relationships;
471             $entities_subquery_columns->{$id} = \@{$temp_data->{subquery_columns}};
472             $entities_to_many_relationships->{$id} = \@{$temp_data->{to_many_relationships}};
473             $entities_to_one_relationships->{$id} = \@{$temp_data->{to_one_relationships}};
474             delete $temp_data->{$_} for qw(subquery_columns to_many_relationships to_one_relationships);
475             $result;
476             })),
477             $xml->handler('columns', hash_item_of_child_value_handler());
478             $xml->handler('columns/column', array_of_objects_handler(\&sql_column));
479             $xml->handler('lobs', hash_item_of_child_value_handler());
480             $xml->handler('lobs/lob', array_of_objects_handler(\&sql_lob));
481             $xml->handler('indexes', hash_item_of_child_value_handler());
482             $xml->handler('index', array_of_objects_handler(\&sql_index));
483             $xml->handler('index_column', array_handler('columns'));
484             $xml->handler('primary_key', array_handler());
485             $xml->handler('value_generator', hash_handler('value_generators', 'column'));
486             $xml->handler('filter_condition_values', hash_handler());
487             $xml->handler('dml_filter_values', hash_handler());
488             $xml->handler('subquery_columns', ignore_node_handler());
489             $xml->handler('subquery_column', custom_array_handler($temp_data, undef, undef, 'subquery_columns'));
490             $xml->handler('to_one_relationships', ignore_node_handler());
491             $xml->handler('to_many_relationships', ignore_node_handler());
492             $xml->handler('to_many_relationships/relationship', custom_array_handler($temp_data, undef, undef, 'to_many_relationships'));
493             $xml->handler('to_one_relationships/relationship', custom_array_handler($temp_data, undef, undef, 'to_one_relationships'));
494             $xml->handler('join_column', array_handler('join_columns'));
495             $xml->handler('condition', object_handler('SQL::Entity::Condition'));
496             $xml->handler('condition/condition', hash_of_object_array_handler('SQL::Entity::Condition', undef, undef, 'conditions'));
497             }
498              
499              
500             =item cache_file_name
501              
502             Returns fulle path to cache file, takes persistence file name.
503              
504             =cut
505              
506             sub cache_file_name {
507             my ($self, $file) = @_;
508             my ($file_name) = $file =~ /([\w]+)\.xml$/i;
509             $self->cache_dir . $file_name .'.cache';
510             }
511              
512              
513             1;
514              
515             __END__