File Coverage

lib/AutoCode/ModuleFactory.pm
Criterion Covered Total %
statement 87 87 100.0
branch 11 14 78.5
condition 4 5 80.0
subroutine 16 16 100.0
pod 0 1 0.0
total 118 123 95.9


line stmt bran cond sub pod time code
1             package AutoCode::ModuleFactory;
2 5     5   1206 use strict;
  5         10  
  5         165  
3 5     5   1218 use AutoCode::Root;
  5         10  
  5         41  
4             our @ISA=qw(AutoCode::Root);
5 5     5   1355 use AutoCode::ModuleModel;
  5         14  
  5         42  
6             # use AutoCode::Initializer;
7 5     5   1260 use AutoCode::Plurality;
  5         12  
  5         39  
8              
9 5     5   26 use AutoCode::AccessorMaker('$'=>[qw(schema package_prefix)]);
  5         10  
  5         63  
10              
11 5     5   1890 use AutoCode::Compare;
  5         15  
  5         42  
12              
13             sub _initialize {
14 5     5   23 my ($self, @args)=@_;
15              
16 5         52 my ($schema, $package_prefix)=
17             $self->_rearrange([qw(SCHEMA PACKAGE_PREFIX)], @args);
18 5 50       75 defined $schema or $self->throw("NO Schema set");
19 5         39 $self->schema($schema);
20 5   66     52 $package_prefix ||= $schema->package_prefix;
21 5   100     26 $package_prefix ||= 'AutoCode';
22 5         31 $self->package_prefix($package_prefix);
23             }
24              
25             # *make_virtual_module = \&make_module;
26              
27             sub make_module {
28 18     18 0 781 my ($self, $type, $isa) =@_;
29             ## this is added due to AutoSQL::ModuleFactory
30 18 50       57 $isa='AutoCode::Root' unless defined $isa;
31 18         78 my $schema=$self->schema;
32 18         51 my $package_prefix=$self->package_prefix;
33 18         51 my $vp = $self->_get_virtual_package($type);
34            
35 18         93 my $model = $schema->get_module_model($type);
36             # generate its parents modules if any.
37 18         52 my @isa=$model->get_isas($type);
38 18 100       54 if(@isa){
39 5     5   31 no strict 'refs';
  5         6  
  5         425  
40 10         25 foreach(@isa){
41 10         14 push @{"$vp\::ISA"}, $self->make_module($_);
  10         156  
42             }
43             }
44              
45             # virtual package is with the consideration of schema name and type.
46 18         45 my $vp = $self->_get_virtual_package($type);
47 5     5   25 no strict 'refs';
  5         17  
  5         2236  
48 18 100       25 push @{"$vp\::ISA"}, $isa unless grep /^$isa$/, @{"$vp\::ISA"};
  14         167  
  18         217  
49             # $self->_add_scalar_accessor(@scalar_accessors);
50 18         130 $self->debug("making $type in $vp");
51            
52             # map {*{"$vp\::$_"} = \&{__PACKAGE__."::$_"}} @scalar_accessors;
53 18         46 map {AutoCode::AccessorMaker->make_scalar_accessor($_, $vp);}
  39         131  
54             $model->get_scalar_attributes;
55 18         62 map {AutoCode::AccessorMaker->make_array_accessor(
  14         76  
56             [$_, $schema->get_plural($_)], $vp);
57             } $model->get_array_attributes;
58 18         53 $self->_make_initialize($type, $vp);
59 18         92 $self->_make_friends($type, $vp);
60 18         169 return $vp;
61             }
62              
63              
64             sub _make_initialize {
65 18     18   31 my ($self, $type, $pkg)=@_;
66 18         43 my $schema = $self->schema;
67 18         52 my $package_prefix=$self->package_prefix;
68 18         47 my $model = $self->schema->get_module_model($type);
69 18         43 my $pkg=$self->_get_virtual_package($type);
70 18         67 AutoCode::AccessorMaker->make_initialize_by_model($model, $pkg);
71             }
72              
73             sub _make_friends {
74 18     18   35 my ($self, $type, $pkg)=@_;
75 18         49 my $schema = $self->schema;
76 18         95 my @friends=$schema->find_friends($type);
77 18         40 foreach my $friend_nickname (@friends){
78             # print STDERR "$_ as a friend\n\L$_\n";
79 8         44 AutoCode::AccessorMaker->make_hash_accessor("$friend_nickname", $pkg);
80 8         28 $self->_make_friend_add($type, $friend_nickname, $pkg);
81            
82             }
83             }
84              
85             sub _make_friend_add {
86 8     8   18 my ($self, $my_nickname, $friend_nickname, $pkg)=@_;
87            
88 8         57 my $glob="$pkg\::get_". AutoCode::Plurality->query_plural($friend_nickname);
89 8         24 $glob="$pkg\::add_$friend_nickname";
90 8         22 my $slot="$pkg\::$friend_nickname\_\%";
91 5     5   29 no strict 'refs';
  5         6  
  5         1267  
92             *$glob=sub{
93 2     2   6 my ($self, $friend, $extra)=@_;
94 2 50       6 return unless defined $friend;
95 2 100       15 $self->{$slot}={} unless exists $self->{$slot};
96 2         7 $self->{$slot}->{$friend}=$extra;
97             # add itself to its friend as friend.
98 2         7 my $method="get_". AutoCode::Plurality->query_plural($my_nickname);
99 2         8 my %hash=$friend->$method();
100 2 100       12 unless(grep {AutoCode::Compare->equal($_, "$self")} keys %hash){
  1         10  
101 1         3 my $my_method="add_$my_nickname";
102 1         3 $friend->$my_method($self, $extra);
103             }
104 8         119 };
105             }
106              
107             sub _get_virtual_package {
108 54     54   87 my ($self, $type)=@_;
109 54         116 my $package_prefix=$self->package_prefix;
110 54         183 return "$package_prefix\::Virtual::$type"; # 'virtual package'
111             }
112              
113             1;