File Coverage

blib/lib/DBIx/DataModel/Source/Join.pm
Criterion Covered Total %
statement 24 32 75.0
branch 2 6 33.3
condition 0 3 0.0
subroutine 7 8 87.5
pod 0 3 0.0
total 33 52 63.4


line stmt bran cond sub pod time code
1             package DBIx::DataModel::Source::Join;
2 20     20   134 use warnings;
  20         43  
  20         1273  
3 20     20   107 use strict;
  20         35  
  20         696  
4 20     20   97 use parent 'DBIx::DataModel::Source';
  20         32  
  20         146  
5 20     20   1145 use mro 'c3';
  20         123  
  20         117  
6             require 5.008; # for filehandle in memory
7 20     20   817 use DBIx::DataModel::Carp;
  20         138  
  20         160  
8              
9             sub db_from {
10 52     52 0 90 my $self = shift;
11              
12             # list of join components from the Meta::Join
13 52         147 my $db_from = $self->metadm->db_from;
14              
15             # if there is a db_schema, we must prefix each table in list with $db_schema.
16 52         151 my $db_schema = $self->schema->db_schema;
17 52 50       149 if ($db_schema) {
18             # The list is of shape: [-join => $table1, $join_spec1, $table2, $join_spec2 .... $table_n];
19             # therefore tables are at odd positions in the list. Tables already containing
20             # a '.' are left untouched.
21 0         0 my @copy = @$db_from;
22 0   0     0 for (my $i=1; $i < @copy && $copy[$i] !~ /\./; $i += 2) {
23 0         0 $copy[$i] =~ s/^/$db_schema./;
24             }
25              
26 0         0 $db_from = \@copy;
27             }
28              
29 52         1868 return $db_from;
30             }
31              
32              
33              
34              
35             # Support for Storable::{freeze,thaw} : just a stupid blank operation,
36             # but that will force Storable::thaw to try to reload the join class ...
37             # and then we can catch it and generate it on the fly (see @INC below)
38              
39             sub STORABLE_freeze {
40 0     0 0 0 my ($self, $is_cloning) = @_;
41              
42 0 0       0 return if $is_cloning;
43 0         0 my $copy = {%$self};
44 0         0 return Storable::freeze($copy);
45             }
46              
47             sub STORABLE_thaw {
48 3     3 0 46 my ($self, $is_cloning, $serialized) = @_;
49              
50 3 50       10 return if $is_cloning;
51 3         23 my $copy = Storable::thaw($serialized);
52 3         88 %$self = %$copy;
53             }
54              
55             # Add a coderef handler into @INC, so that when Storable::thaw tries to load
56             # a join, we take control, generate the Join on the fly, and return
57             # a fake file to load.
58              
59             push @INC, sub { # coderef into @INC: see L
60             my ($self_coderef, $filename) = @_;
61              
62             # did we try to load an AutoJoin ?
63             my ($schema, $join) = ($filename =~ m[^(.+?)/AutoJoin/(.+)$])
64             or return;
65              
66             # is it really an AutoJoin in DBIx::DataModel ?
67             $schema =~ s[/][::]g;
68             $schema->isa('DBIx::DataModel::Schema')
69             or return;
70              
71             # OK, this is really our business. Parse the join name into path items, i.e.
72             # qw/My::Table <=> path1 => path2 => .../
73             $join =~ s/\.pm$//;
74             my ($initial_table, @paths) = split /()/, $join;
75             $initial_table =~ s[/][::]g;
76              
77             # ask schema to create the Join
78             $schema->metadm->define_join($initial_table, @paths);
79              
80             # return a fake filehandle in memory so that "require" is happy
81             open my $fh, "<", \"1"; # pseudo-file just containing "1"
82              
83             return $fh;
84             };
85              
86              
87              
88              
89             1; # End of DBIx::DataModel::Source::Join
90              
91             __END__