File Coverage

blib/lib/Class/DBI/Frozen/301/ColumnGrouper.pm
Criterion Covered Total %
statement 51 56 91.0
branch 17 22 77.2
condition 11 15 73.3
subroutine 16 17 94.1
pod 0 11 0.0
total 95 121 78.5


line stmt bran cond sub pod time code
1             package Class::DBI::ColumnGrouper;
2              
3             =head1 NAME
4              
5             Class::DBI::ColumnGrouper - Columns and Column Groups
6              
7             =head1 SYNOPSIS
8              
9             my $colg = Class::DBI::ColumnGrouper->new;
10             $colg->add_group(People => qw/star director producer/);
11              
12             my @cols = $colg->group_cols($group);
13              
14             my @all = $colg->all_columns;
15             my @pri_col = $colg->primary;
16             my @essential_cols = $colg->essential;
17              
18             =head1 DESCRIPTION
19              
20             Each Class::DBI class maintains a list of its columns as class data.
21             This provides an interface to that. You probably don't want to be dealing
22             with this directly.
23              
24             =head1 METHODS
25              
26             =cut
27              
28 24     24   155 use strict;
  24         49  
  24         1248  
29              
30 24     24   144 use Carp;
  24         48  
  24         3168  
31 24     24   58896 use Storable 'dclone';
  24         138329  
  24         8508  
32 24     24   420 use Class::DBI::Column;
  24         136  
  24         330  
33              
34             sub _unique {
35 4     4   10 my %seen;
36 4 50       12 map { $seen{$_}++ ? () : $_ } @_;
  8         92  
37             }
38              
39             sub _uniq {
40 1     1   22 my %tmp;
41 1         15 return grep !$tmp{$_}++, @_;
42             }
43              
44             =head2 new
45              
46             my $colg = Class::DBI::ColumnGrouper->new;
47              
48             A new blank ColumnnGrouper object.
49              
50             =head2 clone
51              
52             my $colg2 = $colg->clone;
53              
54             Clone an existing ColumnGrouper.
55              
56             =cut
57              
58             sub new {
59 24     24 0 67 my $class = shift;
60 24         287 bless {
61             _groups => {},
62             _cols => {},
63             }, $class;
64             }
65              
66             sub clone {
67 30     30 0 331 my ($class, $prev) = @_;
68 30         3722 return dclone $prev;
69             }
70              
71             =head2 add_column / find_column
72              
73             $colg->add_column($name);
74             my Class::DBI::Column $col = $colg->find_column($name);
75              
76             Add or return a Column object for the given column name.
77              
78             =cut
79              
80             sub add_column {
81 63     63 0 1546 my ($self, $name) = @_;
82 63 100       151 return $name if ref $name;
83 59   66     416 $self->{_allcol}->{ lc $name } ||= Class::DBI::Column->new($name);
84             }
85              
86             sub find_column {
87 64     64 0 391 my ($self, $name) = @_;
88 64 50       309 return $name if ref $name;
89 64 100       275 return unless $self->{_allcol}->{ lc $name };
90             }
91              
92             =head2 add_group
93              
94             $colg->add_group(People => qw/star director producer/);
95              
96             This adds a list of columns as a column group.
97              
98             =cut
99              
100             sub add_group {
101 32     32 0 91 my ($self, $group, @names) = @_;
102 32 100 100     249 $self->add_group(Primary => $names[0])
      100        
103             if ($group eq "All" or $group eq "Essential")
104             and not $self->group_cols('Primary');
105 32 50 66     125 $self->add_group(Essential => @names)
106             if $group eq "All"
107             and !$self->essential;
108 32 100       125 @names = _unique($self->primary, @names) if $group eq "Essential";
109              
110 32         111 my @cols = map $self->add_column($_), @names;
111 32         604 $_->add_group($group) foreach @cols;
112 32         5112 $self->{_groups}->{$group} = \@cols;
113 32         1273 return $self;
114             }
115              
116             =head2 group_cols / groups_for
117              
118             my @colg = $cols->group_cols($group);
119             my @groups = $cols->groups_for(@cols);
120              
121             This returns a list of all columns which are in the given group, or the
122             groups a given column is in.
123              
124             =cut
125              
126             sub group_cols {
127 54     54 0 113 my ($self, $group) = @_;
128 54 50       136 return $self->all_columns if $group eq "All";
129 54 100       63 @{ $self->{_groups}->{$group} || [] };
  54         1166  
130             }
131              
132             sub groups_for {
133 2     2 0 31 my ($self, @cols) = @_;
134 2         32 return _uniq(map $_->groups, @cols);
135             }
136              
137             =head2 columns_in
138              
139             my @cols = $colg->columns_in(@groups);
140              
141             This returns a list of all columns which are in the given groups.
142              
143             =cut
144              
145             sub columns_in {
146 0     0 0 0 my ($self, @groups) = @_;
147 0         0 return _uniq(map $self->group_cols($_), @groups);
148             }
149              
150             =head2 all_columns
151              
152             my @all = $colg->all_columns;
153              
154             This returns a list of all the real columns.
155              
156             =head2 primary
157              
158             my $pri_col = $colg->primary;
159              
160             This returns a list of the columns in the Primary group.
161              
162             =head2 essential
163              
164             my @essential_cols = $colg->essential;
165              
166             This returns a list of the columns in the Essential group.
167              
168             =cut
169              
170             sub all_columns {
171 10     10 0 99 my $self = shift;
172 10         17 return grep $_->in_database, values %{ $self->{_allcol} };
  10         74  
173             }
174              
175             sub primary {
176 29     29 0 187 my @cols = shift->group_cols('Primary');
177 29 50 33     102 if (!wantarray && @cols > 1) {
178 0         0 local ($Carp::CarpLevel) = 1;
179 0         0 confess(
180             "Multiple columns in Primary group (@cols) but primary called in scalar context"
181             );
182 0         0 return $cols[0];
183             }
184 29         96 return @cols;
185             }
186              
187             sub essential {
188 12     12 0 62 my $self = shift;
189 12         39 my @cols = $self->group_cols('Essential');
190 12 100       62 @cols = $self->primary unless @cols;
191 12         68 return @cols;
192             }
193              
194             1;