File Coverage

blib/lib/DBIx/Class/AuditAny/Util.pm
Criterion Covered Total %
statement 46 71 64.7
branch 3 22 13.6
condition 5 22 22.7
subroutine 8 11 72.7
pod 8 8 100.0
total 70 134 52.2


line stmt bran cond sub pod time code
1             package DBIx::Class::AuditAny::Util;
2              
3             # ABSTRACT: Util functions for DBIx::Class::AuditAny
4              
5             =head1 NAME
6              
7             DBIx::Class::AuditAny::Util - Util functions for DBIx::Class::AuditAny
8              
9             =head1 DESCRIPTION
10              
11             This package contains misc util funcs used in the L<DBIx::Class::AuditAny> codebase
12              
13             =head1 FUNCTIONS
14              
15             =cut
16              
17             #*CORE::GLOBAL::die = sub { require Carp; Carp::confess };
18              
19             require Exporter;
20 13     13   7002 use Term::ANSIColor qw(:constants);
  13         60980  
  13         9418  
21 13     13   2364 use Data::Dumper;
  13         18311  
  13         856  
22             require Module::Runtime;
23 13     13   66 use Try::Tiny;
  13         17  
  13         11308  
24              
25             our @ISA = qw(Exporter);
26             our @EXPORT = qw(
27             resolve_localclass package_exists try catch uniq
28             get_raw_source_rows
29             get_raw_source_related_rows
30             );
31              
32             # debug util funcs
33             push @EXPORT, qw(scream scream_color);
34              
35             =head2 scream
36              
37             Prints the supplied object/structure using Dumper
38              
39             =cut
40             sub scream {
41 0     0 1 0 local $_ = caller_data(3);
42 0         0 scream_color(YELLOW . BOLD,@_);
43             }
44              
45             =head2 scream_color
46              
47             Prints the supplied object/structure using Dumper. The first arg can be a color code.
48              
49             =cut
50             sub scream_color {
51             #return unless ($ENV{DEBUG}); ##<---- new: disabled without 'DEBUG'
52 0     0 1 0 my $color = shift;
53             local $_ = caller_data(3) unless (
54             $_ eq 'no_caller_data' or (
55             ref($_) eq 'ARRAY' and
56             scalar(@$_) == 3 and
57             ref($_->[0]) eq 'HASH' and
58             defined $_->[0]->{package}
59             )
60 0 0 0     0 );
      0        
      0        
      0        
61            
62 0         0 my $data = $_[0];
63 0 0       0 $data = \@_ if (scalar(@_) > 1);
64 0 0       0 $data = Dumper($data) if (ref $data);
65 0 0       0 $data = ' ' . UNDERLINE . 'undef' unless (defined $data);
66              
67 0         0 my $pre = '';
68             $pre = BOLD . ($_->[2]->{subroutine} ? $_->[2]->{subroutine} . ' ' : '') .
69 0 0       0 '[line ' . $_->[1]->{line} . ']: ' . CLEAR . "\n" unless ($_ eq 'no_caller_data');
    0          
70            
71 0         0 print STDERR $pre . $color . $data . CLEAR . "\n";
72             }
73              
74             =head2 caller_data
75              
76             Returns an arrayref of hashes containing standard 'caller' function data
77             with named properties
78              
79             =cut
80             sub caller_data {
81 0   0 0 1 0 my $depth = shift || 1;
82            
83 0         0 my @list = ();
84 0         0 for(my $i = 0; $i < $depth; $i++) {
85 0         0 my $h = {};
86             ($h->{package}, $h->{filename}, $h->{line}, $h->{subroutine}, $h->{hasargs},
87 0         0 $h->{wantarray}, $h->{evaltext}, $h->{is_require}, $h->{hints}, $h->{bitmask}) = caller($i);
88 0 0       0 push @list,$h if($h->{package});
89             }
90            
91 0         0 return \@list;
92             }
93              
94             =head2 package_exists
95              
96             Check if the package exists
97              
98             =cut
99             #unmht://www.develop-help.com.unmht/http.5/perl/examples/havepack.mhtml/
100             sub package_exists(@) {
101 50     50 1 72 my ($pack) = @_;
102 50   50     254 my $base ||= \%::;
103 50   66     451 while ($pack =~ /(.*?)::(.*)/m && exists($base->{$1."::"})) {
104 340         233 $base = *{$base->{$1."::"}}{HASH};
  340         804  
105 340         1715 $pack = $2;
106             }
107 50         215 return exists $base->{$pack."::"};
108             }
109              
110             =head2 resolve_localclass
111              
112             Loads the class name, relative to DBIx::Class::AuditAny:: or absolute when
113             prefixed with '+'
114              
115             =cut
116             sub resolve_localclass($) {
117 554     554 1 624 my $class = shift;
118 554 50       1743 $class = $class =~ /^\+(.*)$/ ? $1 : "DBIx::Class::AuditAny::$class";
119 554         1471 Module::Runtime::require_module($class);
120 554         10133 return $class;
121             }
122              
123              
124             =head2 uniq
125              
126             Returns a list with duplicates removed. If passed a single arrayref, duplicates are
127             removed from the arrayref in place, and the new list (contents) are returned.
128              
129             =cut
130             sub uniq {
131 112     112 1 207 my %seen = ();
132 112 50 66     491 return grep { !$seen{$_}++ } @_ unless (@_ == 1 and ref($_[0]) eq 'ARRAY');
  496         942  
133 0 0       0 return () unless (@{$_[0]} > 0);
  0         0  
134             # we add the first element to the end of the arg list to prevetn deep recursion in the
135             # case of nested single element arrayrefs
136 0         0 @{$_[0]} = uniq(@{$_[0]},$_[0]->[0]);
  0         0  
  0         0  
137 0         0 return @{$_[0]};
  0         0  
138             }
139              
140              
141             =head2 get_raw_source_rows
142              
143             logic adapted from L<DBIx::Class::Storage#insert>
144              
145             =cut
146             sub get_raw_source_rows {
147 47     47 1 74 my $Source = shift;
148 47         61 my $cond = shift;
149              
150 47         76 my @rows = ();
151 47         156 my @cols = $Source->columns;
152            
153 47         694 my $cur = DBIx::Class::ResultSet->new($Source, {
154             where => $cond,
155             select => \@cols,
156             })->cursor;
157            
158 47         21662 while(my @data = $cur->next) {
159 49         50421 my %returned_cols = ();
160 49         239 @returned_cols{@cols} = @data;
161 49         220 push @rows, \%returned_cols;
162             }
163              
164 47         1020 return \@rows;
165             }
166              
167              
168             =head2 get_raw_source_related_rows
169              
170             =cut
171             sub get_raw_source_related_rows {
172 8     8 1 14 my $Source = shift;
173 8         9 my $rel = shift;
174 8         9 my $cond = shift;
175            
176 8 50       31 my $RelSource = $Source->related_source($rel)
177             or die "Bad relationship name '$rel'";
178            
179 8         866 my $Rs = DBIx::Class::ResultSet->new($Source, {
180             where => $cond
181             })->as_subselect_rs; #<-- need to wrap in subselect to prevent possible ambiguous col errs
182            
183 8         8153 my @rows = ();
184 8         116 my @cols = $RelSource->columns;
185            
186 8         90 my $cur = $Rs->search_related_rs($rel,undef,{
187             select => \@cols,
188             })->cursor;
189            
190 8         12927 while(my @data = $cur->next) {
191 16         20736 my %returned_cols = ();
192 16         53 @returned_cols{@cols} = @data;
193 16         55 push @rows, \%returned_cols;
194             }
195              
196 8         4177 return \@rows;
197             }
198              
199              
200             1;
201              
202             __END__
203              
204             =head1 SEE ALSO
205              
206             =over
207              
208             =item *
209              
210             L<DBIx::Class::AuditAny>
211              
212             =item *
213              
214             L<DBIx::Class>
215              
216             =back
217              
218             =head1 SUPPORT
219            
220             IRC:
221            
222             Join #rapidapp on irc.perl.org.
223              
224             =head1 AUTHOR
225              
226             Henry Van Styn <vanstyn@cpan.org>
227              
228             =head1 COPYRIGHT AND LICENSE
229              
230             This software is copyright (c) 2012-2015 by IntelliTree Solutions llc.
231              
232             This is free software; you can redistribute it and/or modify it under
233             the same terms as the Perl 5 programming language system itself.
234              
235             =cut