File Coverage

blib/lib/Class/DBI/Plugin/PseudoColumns.pm
Criterion Covered Total %
statement 21 129 16.2
branch 1 56 1.7
condition 0 33 0.0
subroutine 7 14 50.0
pod 2 2 100.0
total 31 234 13.2


line stmt bran cond sub pod time code
1             package Class::DBI::Plugin::PseudoColumns;
2              
3 1     1   909 use strict;
  1         2  
  1         37  
4 1     1   6 use warnings;
  1         2  
  1         33  
5 1     1   16 use Carp;
  1         2  
  1         80  
6 1     1   3020 use Data::Dumper ();
  1         7059  
  1         25  
7 1     1   9 use vars qw($VERSION);
  1         2  
  1         88  
8             $VERSION = 0.03;
9              
10             sub import {
11 1     1   14 my $class = shift;
12 1         3 my $pkg = caller;
13              
14 1 50       29 return unless $pkg->isa('Class::DBI');
15 0 0         if ($pkg->isa('Class::DBI')) {
16 0           $pkg->mk_classdata('_p_column_groups');
17 0           $pkg->mk_classdata('_serializer');
18             }
19              
20 1     1   4 no strict 'refs';
  1         2  
  1         1367  
21              
22 0           *{"$pkg\::pseudo_columns"} = sub {
23 0     0     my $class = shift;
24 0 0         croak "You must set table before call pseudo_columns()"
25             unless defined $class->table;
26 0           my $parent_column = shift;
27 0           my $p_col_groups = $class->_p_column_groups;
28 0 0         if (defined $_[0]) {
    0          
29 0           my @colnames = @_;
30 0           $p_col_groups->{$class}->{$parent_column} = \@colnames;
31 0           $class->_p_column_groups($p_col_groups);
32 0           for my $p_column (@colnames) {
33 0           *{"$class\::$p_column"} = sub {
34 0           my $self = shift;
35 0           my $property = $self->__deserialize($parent_column);
36 0 0         if (@_) {
37 0           $property->{$p_column} = shift;
38 0           my $serialized =
39             $self->__serialize($parent_column => $property);
40 0           $self->$parent_column($serialized);
41             }
42 0           return $property->{$p_column};
43 0           };
44             }
45             }
46             elsif (defined $parent_column) {
47 0 0 0       return unless ref($p_col_groups) eq 'HASH' &&
      0        
48             ref($p_col_groups->{$class}) eq 'HASH' &&
49             ref($p_col_groups->{$class}->{$parent_column}) eq 'ARRAY';
50 0           return @{$p_col_groups->{$class}->{$parent_column}};
  0            
51             }
52             else {
53 0 0 0       return unless ref($p_col_groups) eq 'HASH' &&
54             ref($p_col_groups->{$class}) eq 'HASH';
55 0           my @pseudo_cols = ();
56 0           for my $col (keys %{$p_col_groups->{$class}}) {
  0            
57 0 0         next unless ref($p_col_groups->{$class}->{$col}) eq 'ARRAY';
58 0           push @pseudo_cols, @{$p_col_groups->{$class}->{$col}};
  0            
59             }
60 0           return @pseudo_cols;
61             }
62 0           };
63              
64 0           my $super_create = $pkg->can('create');
65 0 0         croak "create() method can not be called in $pkg" unless $super_create;
66 0           *{"$pkg\::create"} = sub {
67 0     0     my($class, $hashref) = @_;
68 0 0         croak "create needs a hashref" unless ref($hashref) eq 'HASH';
69 0 0         croak "You must set table before call create()"
70             unless defined $class->table;
71 0           my %cols_check = map { $_ => 1 } $class->pseudo_columns;
  0            
72 0           my %p_values = ();
73 0           for my $col (keys %$hashref) {
74 0 0         next unless $cols_check{$col};
75 0           $p_values{$col} = delete $hashref->{$col};
76             }
77 0           my $row = $class->$super_create($hashref); # create()
78 0 0         if (%p_values) {
79 0           for my $col (keys %p_values) {
80 0           $row->$col($p_values{$col});
81             }
82 0           $row->update;
83             }
84 0           return $row;
85 0           };
86              
87 0           my $super_set = $pkg->can('set');
88 0 0         croak "set() method can not be called in $pkg" unless $super_set;
89 0           *{"$pkg\::set"} = sub {
90 0     0     my $self = shift;
91 0           my $column_values = {@_};
92 0   0       my $class = ref($self) || $self;
93 0           my %cols_check = map { $_ => 1 } $class->pseudo_columns;
  0            
94 0           my %p_values = ();
95 0           for my $col (keys %$column_values) {
96 0 0         next unless $cols_check{$col};
97 0           $p_values{$col} = delete $column_values->{$col};
98             }
99 0 0         $self->$super_set(%$column_values) if %$column_values;
100 0 0         if (%p_values) {
101 0           for my $col (keys %p_values) {
102 0           $self->$col($p_values{$col});
103             }
104             }
105 0           };
106              
107 0           for my $export (qw(__serialize __deserialize serializer deserializer)) {
108 0           *{"$pkg\::$export"} = \&$export;
  0            
109             }
110             }
111              
112             sub serializer {
113 0     0 1   my($class, $parent_column, $subref) = @_;
114 0 0         croak "You must set table before call serializer()"
115             unless defined $class->table;
116 0           my $serializer = $class->_serializer;
117 0 0         if (ref($subref) eq 'CODE') {
118 0           $serializer->{serializer} = { $parent_column => $subref };
119 0           $class->_serializer($serializer);
120             }
121             else {
122 0           carp "Usage: __PACKAGE__->serializer(parent_column => \$subref)";
123             }
124             }
125              
126             sub deserializer {
127 0     0 1   my($class, $parent_column, $subref) = @_;
128 0 0         croak "You must set table before call deserializer()"
129             unless defined $class->table;
130 0           my $serializer = $class->_serializer;
131 0 0         if (ref($subref) eq 'CODE') {
132 0           $serializer->{deserializer} = { $parent_column => $subref };
133 0           $class->_serializer($serializer);
134             }
135             else {
136 0           carp "Usage: __PACKAGE__->deserializer(parent_column => \$subref)";
137             }
138             }
139              
140             sub __serialize {
141 0     0     my($self, $column, $var) = @_;
142 0   0       my $class = ref($self) || $self;
143 0 0         croak "Can't lookup the table name via table() method."
144             unless defined $class->table;
145 0           my $serializer = $class->_serializer;
146 0 0 0       if (ref($serializer->{serializer}) eq 'HASH' &&
      0        
147             exists $serializer->{serializer}->{$column} &&
148             ref($serializer->{serializer}->{$column}) eq 'CODE') {
149 0           return $serializer->{serializer}->{$column}->($var);
150             }
151             else {
152 0           local $Data::Dumper::Terse = 1;
153 0           local $Data::Dumper::Indent = 0;
154 0           return Data::Dumper::Dumper($var);
155             }
156             }
157              
158             sub __deserialize {
159 0     0     my($self, $column) = @_;
160 0   0       my $class = ref($self) || $self;
161 0 0         croak "Can't lookup the table name via table() method."
162             unless defined $class->table;
163 0           my $prop;
164 0           my $dumped = $self->$column;
165 0 0         if (defined $dumped) {
166 0           my $serializer = $class->_serializer;
167 0 0 0       if (ref($serializer->{deserializer}) eq 'HASH' &&
      0        
168             exists $serializer->{deserializer}->{$column} &&
169             ref($serializer->{deserializer}->{$column}) eq 'CODE') {
170 0           $prop = $serializer->{deserializer}->{$column}->($dumped);
171             }
172             else {
173 0           $prop = eval qq{ $dumped };
174             }
175             }
176 0 0 0       return $prop if defined $prop && ref($prop) eq 'HASH';
177 0           return {};
178             }
179              
180             1;
181              
182             __END__