File Coverage

blib/lib/DBIx/Class/_Util.pm
Criterion Covered Total %
statement 294 341 86.2
branch 114 188 60.6
condition 58 148 39.1
subroutine 59 67 88.0
pod 0 28 0.0
total 525 772 68.0


line stmt bran cond sub pod time code
1             package # hide from PAUSE
2             DBIx::Class::_Util;
3              
4             # load es early as we can, usually a noop
5 317     317   16342969 use DBIx::Class::StartupCheck;
  317         821  
  317         7930  
6              
7 317     317   1684 use warnings;
  317         1135  
  317         7175  
8 317     317   1600 use strict;
  317         606  
  317         13923  
9              
10             # For the love of everything that is crab-like: DO NOT reach into this
11             # The entire thing is really fragile and should not be screwed with
12             # unless absolutely and unavoidably necessary
13             our $__describe_class_query_cache;
14              
15 0         0 BEGIN {
16             package # hide from pause
17             DBIx::Class::_ENV_;
18              
19 317     317   1673 use Config;
  317         582  
  317         17568  
20              
21             use constant {
22 317         64697 PERL_VERSION => "$]",
23             OS_NAME => "$^O",
24 317     317   1892 };
  317         611  
25              
26             use constant {
27              
28             # but of course
29             BROKEN_FORK => (OS_NAME eq 'MSWin32') ? 1 : 0,
30              
31             BROKEN_GOTO => ( PERL_VERSION < 5.008003 ) ? 1 : 0,
32              
33             # perl -MScalar::Util=weaken -e 'weaken( $hash{key} = \"value" )'
34             BROKEN_WEAK_SCALARREF_VALUES => ( PERL_VERSION < 5.008003 ) ? 1 : 0,
35              
36             HAS_ITHREADS => $Config{useithreads} ? 1 : 0,
37              
38             TAINT_MODE => 0 + ${^TAINT}, # tri-state: 0, 1, -1
39              
40             UNSTABLE_DOLLARAT => ( PERL_VERSION < 5.013002 ) ? 1 : 0,
41              
42             ( map
43             #
44             # the "DBIC_" prefix below is crucial - this is what makes CI pick up
45             # all envvars without further adjusting its scripts
46             # DO NOT CHANGE to the more logical { $_ => !!( $ENV{"DBIC_$_"} ) }
47             #
48 2219         102537 { substr($_, 5) => !!( $ENV{$_} ) }
49             qw(
50             DBIC_SHUFFLE_UNORDERED_RESULTSETS
51             DBIC_ASSERT_NO_INTERNAL_INDIRECT_CALLS
52             DBIC_ASSERT_NO_ERRONEOUS_METAINSTANCE_USE
53             DBIC_ASSERT_NO_FAILING_SANITY_CHECKS
54             DBIC_ASSERT_NO_INCONSISTENT_RELATIONSHIP_RESOLUTION
55             DBIC_STRESSTEST_UTF8_UPGRADE_GENERATED_COLLAPSER_SOURCE
56             DBIC_STRESSTEST_COLUMN_INFO_UNAWARE_STORAGE
57             )
58             ),
59              
60             IV_SIZE => $Config{ivsize},
61 317 50   317   2140 };
  317         671  
  317         5644  
62              
63 317     317   1273 if ( PERL_VERSION < 5.009_005) {
64             require MRO::Compat;
65             constant->import( OLD_MRO => 1 );
66              
67             #
68             # Yes, I know this is a rather PHP-ish name, but please first read
69             # https://metacpan.org/source/BOBTFISH/MRO-Compat-0.12/lib/MRO/Compat.pm#L363-368
70             #
71             # Even if we are using Class::C3::XS it still won't work, as doing
72             # defined( *{ "SubClass::"->{$_} }{CODE} )
73             # will set pkg_gen to the same value for SubClass and *ALL PARENTS*
74             #
75             *DBIx::Class::_Util::get_real_pkg_gen = sub ($) {
76             require Digest::MD5;
77             require Math::BigInt;
78              
79             my $cur_class;
80 317     317   2197 no strict 'refs';
  317         703  
  317         173162  
81              
82             # the non-assign-unless-there-is-a-hash is deliberate
83             ( $__describe_class_query_cache->{'!internal!'} || {} )->{$_[0]}{gen} ||= (
84             Math::BigInt->new( '0x' . ( Digest::MD5::md5_hex( join "\0", map {
85              
86             ( $__describe_class_query_cache->{'!internal!'} || {} )->{$_}{methlist} ||= (
87              
88             $cur_class = $_
89              
90             and
91              
92             # RV to be hashed up and turned into a number
93             join "\0", (
94             $cur_class,
95             map
96             {(
97             # stringification should be sufficient, ignore names/refaddr entirely
98             $_,
99             do {
100             my @attrs;
101             local $@;
102             local $SIG{__DIE__} if $SIG{__DIE__};
103             # attributes::get may throw on blessed-false crefs :/
104             eval { @attrs = attributes::get( $_ ); 1 }
105             or warn "Unable to determine attributes of coderef $_ due to the following error: $@";
106             @attrs;
107             },
108             )}
109             map
110             {(
111             # skip dummy C::C3 helper crefs
112             ! ( ( $Class::C3::MRO{$cur_class} || {} )->{methods}{$_} )
113             and
114             (
115             ref(\ "${cur_class}::"->{$_} ) ne 'GLOB'
116             or
117             defined( *{ "${cur_class}::"->{$_} }{CODE} )
118             )
119             )
120             ? ( \&{"${cur_class}::$_"} )
121             : ()
122             }
123             keys %{ "${cur_class}::" }
124             )
125             )
126             } (
127              
128             @{
129             ( $__describe_class_query_cache->{'!internal!'} || {} )->{$_[0]}{linear_isa}
130             ||=
131             mro::get_linear_isa($_[0])
132             },
133              
134             ((
135             ( $__describe_class_query_cache->{'!internal!'} || {} )->{$_[0]}{is_universal}
136             ||=
137             mro::is_universal($_[0])
138             ) ? () : @{
139             ( $__describe_class_query_cache->{'!internal!'} || {} )->{UNIVERSAL}{linear_isa}
140             ||=
141             mro::get_linear_isa("UNIVERSAL")
142             } ),
143              
144             ) ) ) )
145             );
146             };
147             }
148             else {
149 317         16084 require mro;
150 317         39239 constant->import( OLD_MRO => 0 );
151 317         1207 *DBIx::Class::_Util::get_real_pkg_gen = \&mro::get_pkg_gen;
152             }
153              
154             # Both of these are no longer used for anything. However bring
155             # them back after they were purged in 08a8d8f1, as there appear
156             # to be outfits with *COPY PASTED* pieces of lib/DBIx/Class/Storage/*
157             # in their production codebases. There is no point in breaking these
158             # if whatever they used actually continues to work
159             my $sigh = sub {
160 0         0 DBIx::Class::_Util::emit_loud_diag(
161             skip_frames => 1,
162 0         0 msg => "The @{[ (caller(1))[3] ]} constant is no more - adjust your code"
163             );
164              
165 0         0 0;
166 317         12237 };
167 0     0   0 sub DBICTEST () { &$sigh }
168 0     0   0 sub PEEPEENESS () { &$sigh }
169             }
170              
171 317     317   2009 use constant SPURIOUS_VERSION_CHECK_WARNINGS => ( DBIx::Class::_ENV_::PERL_VERSION < 5.010 ? 1 : 0);
  317         828  
  317         18836  
172              
173             # FIXME - this is not supposed to be here
174             # Carp::Skip to the rescue soon
175 317     317   104835 use DBIx::Class::Carp '^DBIx::Class|^DBICTest';
  317         958  
  317         2652  
176              
177             # Ensure it is always there, in case we need to do a $schema-less throw()
178 317     317   93863 use DBIx::Class::Exception ();
  317         889  
  317         6060  
179              
180 317     317   2315 use B ();
  317         630  
  317         5942  
181 317     317   1618 use Carp 'croak';
  317         663  
  317         18371  
182 317     317   143254 use Storable 'nfreeze';
  317         884803  
  317         21596  
183 317     317   2584 use Scalar::Util qw(weaken blessed reftype refaddr);
  317         767  
  317         22654  
184 317     317   107962 use Sub::Name ();
  317         138625  
  317         7323  
185 317     317   110186 use attributes ();
  317         318613  
  317         10571  
186              
187             # Usually versions are not specified anywhere aside the Makefile.PL
188             # (writing them out in-code is extremely obnoxious)
189             # However without a recent enough Moo the quote_sub override fails
190             # in very puzzling and hard to detect ways: so add a version check
191             # just this once
192 317     317   100106 use Sub::Quote qw(qsub);
  317         1337434  
  317         19581  
193 317     317   16644 BEGIN { Sub::Quote->VERSION('2.002002') }
194              
195             # Already correctly prototyped: perlbrew exec perl -MStorable -e 'warn prototype \&Storable::dclone'
196 317     317   6934 BEGIN { *deep_clone = \&Storable::dclone }
197              
198 317     317   2282 use base 'Exporter';
  317         817  
  317         55530  
199             our @EXPORT_OK = qw(
200             sigwarn_silencer modver_gt_or_eq modver_gt_or_eq_and_lt fail_on_internal_call
201             refdesc refcount hrefaddr set_subname get_subname describe_class_methods
202             scope_guard detected_reinvoked_destructor emit_loud_diag
203             true false
204             is_exception dbic_internal_try dbic_internal_catch visit_namespaces
205             quote_sub qsub perlstring serialize deep_clone dump_value uniq bag_eq
206             parent_dir mkdir_p
207             UNRESOLVABLE_CONDITION DUMMY_ALIASPAIR
208             );
209              
210 317     317   2380 use constant UNRESOLVABLE_CONDITION => \ '1 = 0';
  317         674  
  317         27480  
211              
212 317         257979 use constant DUMMY_ALIASPAIR => (
213             foreign_alias => "!!!\xFF()!!!_DUMMY_FOREIGN_ALIAS_SHOULD_NEVER_BE_SEEN_IN_USE_!!!()\xFF!!!",
214             self_alias => "!!!\xFE()!!!_DUMMY_SELF_ALIAS_SHOULD_NEVER_BE_SEEN_IN_USE_!!!()\xFE!!!",
215 317     317   2096 );
  317         739  
216              
217             # Override forcing no_defer, and adding naming consistency checks
218             our %refs_closed_over_by_quote_sub_installed_crefs;
219             sub quote_sub {
220 80271 50 33 80271 0 1490075 Carp::confess( "Anonymous quoting not supported by the DBIC quote_sub override - supply a sub name" ) if
      33        
221             @_ < 2
222             or
223             ! defined $_[1]
224             or
225             length ref $_[1]
226             ;
227              
228 80271 50       501847 Carp::confess( "The DBIC quote_sub override expects sub name '$_[0]' to be fully qualified" )
229             unless (my $stash) = $_[0] =~ /^(.+)::/;
230              
231             Carp::confess(
232             "The DBIC sub_quote override does not support 'no_install'"
233             ) if (
234             $_[3]
235             and
236             $_[3]->{no_install}
237 80271 50 66     328477 );
238              
239             Carp::confess(
240             'The DBIC quote_sub override expects the namespace-part of sub name '
241             . "'$_[0]' to match the supplied package argument '$_[3]->{package}'"
242             ) if (
243             $_[3]
244             and
245             defined $_[3]->{package}
246             and
247             $stash ne $_[3]->{package}
248 80271 50 100     296707 );
      66        
249              
250 80271         403779 my @caller = caller(0);
251             my $sq_opts = {
252             package => $caller[0],
253             hints => $caller[8],
254             warning_bits => $caller[9],
255             hintshash => $caller[10],
256 80271 100       801332 %{ $_[3] || {} },
  80271         469436  
257              
258             # explicitly forced for everything
259             no_defer => 1,
260             };
261              
262             weaken (
263             # just use a growing counter, no need to perform neither compaction
264             # nor any special ithread-level handling
265             $refs_closed_over_by_quote_sub_installed_crefs
266             { scalar keys %refs_closed_over_by_quote_sub_installed_crefs }
267             = $_
268 80271         158035 ) for grep {
269 45836 50       308654 length ref $_
270             and
271             (
272             ! DBIx::Class::_ENV_::BROKEN_WEAK_SCALARREF_VALUES
273             or
274             ref $_ ne 'SCALAR'
275             )
276 80271 100       265055 } values %{ $_[2] || {} };
277              
278 80271   100     321214 Sub::Quote::quote_sub( $_[0], $_[1], $_[2]||{}, $sq_opts );
279             }
280              
281             sub sigwarn_silencer ($) {
282 108     108 0 6203289359 my $pattern = shift;
283              
284 108 50       7899 croak "Expecting a regexp" if ref $pattern ne 'Regexp';
285              
286 108   100 0   4449 my $orig_sig_warn = $SIG{__WARN__} || sub { CORE::warn(@_) };
  0         0  
287              
288 108 100   39   2078 return sub { &$orig_sig_warn unless $_[0] =~ $pattern };
  39         2309  
289             }
290              
291 64797     64797 0 504316 sub perlstring ($) { q{"}. quotemeta( shift ). q{"} };
292              
293 42750   50 42750 0 1713480 sub hrefaddr ($) { sprintf '0x%x', &refaddr||0 }
294              
295             sub refdesc ($) {
296 4079 50   4079 0 405602 croak "Expecting a reference" if ! length ref $_[0];
297              
298             # be careful not to trigger stringification,
299             # reuse @_ as a scratch-pad
300 4079 100       40775 sprintf '%s%s(0x%x)',
301             ( defined( $_[1] = blessed $_[0]) ? "$_[1]=" : '' ),
302             reftype $_[0],
303             refaddr($_[0]),
304             ;
305             }
306              
307             sub refcount ($) {
308 20945 50   20945 0 49603 croak "Expecting a reference" if ! length ref $_[0];
309              
310             # No tempvars - must operate on $_[0], otherwise the pad
311             # will count as an extra ref
312 20945         88993 B::svref_2object($_[0])->REFCNT;
313             }
314              
315             sub visit_namespaces {
316 1815 50   1815 0 66513 my $args = { (ref $_[0]) ? %{$_[0]} : @_ };
  0         0  
317              
318 1815         2841 my $visited_count = 1;
319              
320             # A package and a namespace are subtly different things
321 1815   100     3576 $args->{package} ||= 'main';
322 1815 50       4350 $args->{package} = 'main' if $args->{package} =~ /^ :: (?: main )? $/x;
323 1815         3279 $args->{package} =~ s/^:://;
324              
325 1815 100       4252 if ( $args->{action}->($args->{package}) ) {
326             my $ns =
327             ( ($args->{package} eq 'main') ? '' : $args->{package} )
328 1733 100       194613 .
329             '::'
330             ;
331              
332 1733         2388 $visited_count += visit_namespaces( %$args, package => $_ ) for
333             grep
334             # this happens sometimes on %:: traversal
335 1815         4026 { $_ ne '::main' }
336             map
337 34559 100       56284 { $_ =~ /^(.+?)::$/ ? "$ns$1" : () }
338 317     317   2536 do { no strict 'refs'; keys %$ns }
  317         803  
  317         294273  
  1733         10390  
339             ;
340             }
341              
342 1815         13110 $visited_count;
343             }
344              
345             # FIXME In another life switch these to a polyfill like the ones in namespace::clean
346             sub get_subname ($) {
347 26666     26666 0 14403238 my $gv = B::svref_2object( $_[0] )->GV;
348             wantarray
349 26666 50       184289 ? ( $gv->STASH->NAME, $gv->NAME )
350             : ( join '::', $gv->STASH->NAME, $gv->NAME )
351             ;
352             }
353             sub set_subname ($$) {
354              
355             # fully qualify name
356 490 100   490 0 3933 splice @_, 0, 1, caller(0) . "::$_[0]"
357             if $_[0] !~ /::|'/;
358              
359 490         575297 &Sub::Name::subname;
360             }
361              
362             sub serialize ($) {
363             # stable hash order
364 5257     5257 0 12975 local $Storable::canonical = 1;
365              
366             # explicitly false - there is nothing sensible that can come out of
367             # an attempt at CODE serialization
368 5257         8125 local $Storable::Deparse;
369              
370             # take no chances
371 5257         7528 local $Storable::forgive_me;
372              
373             # FIXME
374             # A number of codepaths *expect* this to be Storable.pm-based so that
375             # the STORABLE_freeze hooks in the metadata subtree get executed properly
376 5257         17984 nfreeze($_[0]);
377             }
378              
379             sub uniq {
380 169111     169111 0 327183 my( %seen, $seen_undef, $numeric_preserving_copy );
381 169111         289357 grep { not (
382             defined $_
383 359311 50       1551136 ? $seen{ $numeric_preserving_copy = $_ }++
384             : $seen_undef++
385             ) } @_;
386             }
387              
388             sub bag_eq ($$) {
389 19 50 33 19 0 176 croak "bag_eq() requiress two arrayrefs as arguments" if (
390             ref($_[0]) ne 'ARRAY'
391             or
392             ref($_[1]) ne 'ARRAY'
393             );
394              
395 19 50       37 return '' unless @{$_[0]} == @{$_[1]};
  19         44  
  19         62  
396              
397 19         46 my( %seen, $numeric_preserving_copy );
398              
399             ( defined $_
400             ? $seen{'value' . ( $numeric_preserving_copy = $_ )}++
401             : $seen{'undef'}++
402 19 50       45 ) for @{$_[0]};
  19         154  
403              
404             ( defined $_
405             ? $seen{'value' . ( $numeric_preserving_copy = $_ )}--
406             : $seen{'undef'}--
407 19 50       41 ) for @{$_[1]};
  19         128  
408              
409             return (
410 19 50       62 (grep { $_ } values %seen)
  24         199  
411             ? ''
412             : 1
413             );
414             }
415              
416             my $dd_obj;
417             sub dump_value ($) {
418 1518 100   1518 0 1628754 local $Data::Dumper::Indent = 1
419             unless defined $Data::Dumper::Indent;
420              
421             my $dump_str = (
422             $dd_obj
423             ||=
424 1518   66     8147 do {
425 18         5872 require Data::Dumper;
426 18         64373 my $d = Data::Dumper->new([])
427             ->Purity(0)
428             ->Pad('')
429             ->Useqq(1)
430             ->Terse(1)
431             ->Freezer('')
432             ->Quotekeys(0)
433             ->Bless('bless')
434             ->Pair(' => ')
435             ->Sortkeys(1)
436             ->Deparse(1)
437             ;
438              
439             # FIXME - this is kinda ridiculous - there ought to be a
440             # Data::Dumper->new_with_defaults or somesuch...
441             #
442 18 50       1489 if( modver_gt_or_eq ( 'Data::Dumper', '2.136' ) ) {
443 18         96 $d->Sparseseen(1);
444              
445 18 50       145 if( modver_gt_or_eq ( 'Data::Dumper', '2.153' ) ) {
446 18         95 $d->Maxrecurse(1000);
447              
448 18 50       239 if( modver_gt_or_eq ( 'Data::Dumper', '2.160' ) ) {
449 18         86 $d->Trailingcomma(1);
450             }
451             }
452             }
453              
454 18         209 $d;
455             }
456             )->Values([$_[0]])->Dump;
457              
458 1518         73715 $dd_obj->Reset->Values([]);
459              
460 1518         24307 $dump_str;
461             }
462              
463             my $seen_loud_screams;
464             sub emit_loud_diag {
465 5 50   5 0 33 my $args = { ref $_[0] eq 'HASH' ? %{$_[0]} : @_ };
  0         0  
466              
467 5 50 33     38 unless ( defined $args->{msg} and length $args->{msg} ) {
468 0         0 emit_loud_diag(
469             msg => "No 'msg' value supplied to emit_loud_diag()"
470             );
471 0         0 exit 70;
472             }
473              
474             my $msg = "\n" . join( ': ',
475             ( $0 eq '-e' ? () : $0 ),
476             $args->{msg}
477 5 50       48 );
478              
479             # when we die - we usually want to keep doing it
480             $args->{emit_dups} = !!$args->{confess}
481 5 100       21 unless exists $args->{emit_dups};
482              
483             local $Carp::CarpLevel =
484 5   50     32 ( $args->{skip_frames} || 0 )
485             +
486             $Carp::CarpLevel
487             +
488             # hide our own frame
489             1
490             ;
491              
492 5         793 my $longmess = Carp::longmess();
493              
494             # different object references will thwart deduplication without this
495 5         2074 ( my $key = "${msg}\n${longmess}" ) =~ s/\b0x[0-9a-f]+\b/0x.../gi;
496              
497             return $seen_loud_screams->{$key} if
498             $seen_loud_screams->{$key}++
499             and
500             ! $args->{emit_dups}
501 5 50 33     49 ;
502              
503 5 100       40 $msg .= $longmess
504             unless $msg =~ /\n\z/;
505              
506 5 50       206 print STDERR "$msg\n"
507             or
508             print STDOUT "\n!!!STDERR ISN'T WRITABLE!!!:$msg\n";
509              
510             return $seen_loud_screams->{$key}
511 5 50       47 unless $args->{confess};
512              
513             # increment *again*, because... Carp.
514 0         0 $Carp::CarpLevel++;
515              
516             # not $msg - Carp will reapply the longmess on its own
517 0         0 Carp::confess($args->{msg});
518             }
519              
520              
521             ###
522             ### This is *NOT* boolean.pm - deliberately not using a singleton
523             ###
524             {
525             package # hide from pause
526             DBIx::Class::_Util::_Bool;
527             use overload
528 0     0   0 bool => sub { ${$_[0]} },
  0         0  
529 317         3863 fallback => 1,
530 317     317   2667 ;
  317         807  
531             }
532 3     3 0 73 sub true () { my $x = 1; bless \$x, "DBIx::Class::_Util::_Bool" }
  3         13  
533 3     3 0 27 sub false () { my $x = 0; bless \$x, "DBIx::Class::_Util::_Bool" }
  3         6  
534              
535             sub scope_guard (&) {
536 1806 50   1806 0 865111 croak 'Calling scope_guard() in void context makes no sense'
537             if ! defined wantarray;
538              
539             # no direct blessing of coderefs - DESTROY is buggy on those
540 1806         9544 bless [ $_[0] ], 'DBIx::Class::_Util::ScopeGuard';
541             }
542             {
543             package #
544             DBIx::Class::_Util::ScopeGuard;
545              
546             sub DESTROY {
547 1806     1806   99737 &DBIx::Class::_Util::detected_reinvoked_destructor;
548              
549 1806         3140 local $@ if DBIx::Class::_ENV_::UNSTABLE_DOLLARAT;
550              
551 1806 50       3225 eval {
552 1806         8765 $_[0]->[0]->();
553 1806         98660 1;
554             }
555             or
556             DBIx::Class::_Util::emit_loud_diag(
557             emit_dups => 1,
558             msg => "Execution of scope guard $_[0] resulted in the non-trappable exception:\n\n$@\n "
559             );
560             }
561             }
562              
563              
564             sub is_exception ($) {
565 46729     46729 0 85936 my $e = $_[0];
566              
567             # FIXME
568             # this is not strictly correct - an eval setting $@ to undef
569             # is *not* the same as an eval setting $@ to ''
570             # but for the sake of simplicity assume the following for
571             # the time being
572 46729 50       103930 return 0 unless defined $e;
573              
574 46729         81525 my ($not_blank, $suberror);
575             {
576 46729 100       66813 local $SIG{__DIE__} if $SIG{__DIE__};
  46729         113434  
577 46729         73367 local $@;
578 46729 100       92789 eval {
579             # The ne() here is deliberate - a plain length($e), or worse "$e" ne
580             # will entirely obviate the need for the encolsing eval{}, as the
581             # condition we guard against is a missing fallback overload
582 46729         89219 $not_blank = ( $e ne '' );
583 46720         127553 1;
584             } or $suberror = $@;
585             }
586              
587 46729 100 100     247526 if (defined $suberror) {
    100          
588 9 50       41 if (length (my $class = blessed($e) )) {
589 9         71 carp_unique( sprintf(
590             'External exception class %s implements partial (broken) overloading '
591             . 'preventing its instances from being used in simple ($x eq $y) '
592             . 'comparisons. Given Perl\'s "globally cooperative" exception '
593             . 'handling this type of brokenness is extremely dangerous on '
594             . 'exception objects, as it may (and often does) result in silent '
595             . '"exception substitution". DBIx::Class tries to work around this '
596             . 'as much as possible, but other parts of your software stack may '
597             . 'not be even aware of this. Please submit a bugreport against the '
598             . 'distribution containing %s and in the meantime apply a fix similar '
599             . 'to the one shown at %s, in order to ensure your exception handling '
600             . 'is saner application-wide. What follows is the actual error text '
601             . "as generated by Perl itself:\n\n%s\n ",
602             $class,
603             $class,
604             'http://v.gd/DBIC_overload_tempfix/',
605             $suberror,
606             ));
607              
608             # workaround, keeps spice flowing
609 9         62 $not_blank = !!( length $e );
610             }
611             else {
612             # not blessed yet failed the 'ne'... this makes 0 sense...
613             # just throw further
614 0         0 die $suberror
615             }
616             }
617             elsif (
618             # a ref evaluating to '' is definitively a "null object"
619             ( not $not_blank )
620             and
621             length( my $class = ref $e )
622             ) {
623 20         146 carp_unique(
624             "Objects of external exception class '$class' stringify to '' (the "
625             . 'empty string), implementing the so called null-object-pattern. '
626             . 'Given Perl\'s "globally cooperative" exception handling using this '
627             . 'class of exceptions is extremely dangerous, as it may (and often '
628             . 'does) result in silent discarding of errors. DBIx::Class tries to '
629             . 'work around this as much as possible, but other parts of your '
630             . 'software stack may not be even aware of the problem. Please submit '
631             . "a bugreport against the distribution containing '$class'",
632             );
633              
634 20         571 $not_blank = 1;
635             }
636              
637 46729         159770 return $not_blank;
638             }
639              
640             {
641             my $callstack_state;
642              
643             # Recreate the logic of Try::Tiny, but without the crazy Sub::Name
644             # invocations and without support for finally() altogether
645             # ( yes, these days Try::Tiny is so "tiny" it shows *ON TOP* of most
646             # random profiles https://youtu.be/PYCbumw0Fis?t=1919 )
647             sub dbic_internal_try (&;@) {
648              
649 187541     187541 0 350643 my $try_cref = shift;
650 187541         322795 my $catch_cref = undef; # apparently this is a thing... https://rt.perl.org/Public/Bug/Display.html?id=119311
651              
652 187541         391641 for my $arg (@_) {
653              
654 76494 50       160557 croak 'dbic_internal_try() may not be followed by multiple dbic_internal_catch() blocks'
655             if $catch_cref;
656              
657 76494 50       261560 ($catch_cref = $$arg), next
658             if ref($arg) eq 'DBIx::Class::_Util::Catch';
659              
660 0 0       0 croak( 'Mixing dbic_internal_try() with Try::Tiny::catch() is not supported' )
661             if ref($arg) eq 'Try::Tiny::Catch';
662              
663 0 0       0 croak( 'dbic_internal_try() does not support finally{}' )
664             if ref($arg) eq 'Try::Tiny::Finally';
665              
666 0         0 croak(
667             'dbic_internal_try() encountered an unexpected argument '
668 0 0       0 . "'@{[ defined $arg ? $arg : 'UNDEF' ]}' - perhaps "
669             . 'a missing semi-colon before or ' # trailing space important
670             );
671             }
672              
673 187541         340291 my $wantarray = wantarray;
674 187541         298160 my $preexisting_exception = $@;
675              
676 187541         287626 my @ret;
677 187541         309537 my $saul_goodman = eval {
678 187541         296998 $@ = $preexisting_exception;
679              
680             local $callstack_state->{in_internal_try} = 1
681 187541 100       595811 unless $callstack_state->{in_internal_try};
682              
683             # always unset - someone may have snuck it in
684 187541 100       491569 local $SIG{__DIE__} if $SIG{__DIE__};
685              
686 187541 100       467573 if( $wantarray ) {
    100          
687 21464         58891 @ret = $try_cref->();
688             }
689             elsif( defined $wantarray ) {
690 133186         301079 $ret[0] = $try_cref->();
691             }
692             else {
693 32891         79587 $try_cref->();
694             }
695              
696 184857         7667847 1;
697             };
698              
699 187529         504851 my $exception = $@;
700 187529         304504 $@ = $preexisting_exception;
701              
702 187529 100       381622 if ( $saul_goodman ) {
    100          
703 184857 100       1035029 return $wantarray ? @ret : $ret[0]
704             }
705             elsif ( $catch_cref ) {
706 2395         6268 for ( $exception ) {
707 2395         9389 return $catch_cref->($exception);
708             }
709             }
710              
711 277         1173 return;
712             }
713              
714             sub dbic_internal_catch (&;@) {
715              
716 76494 50   76494 0 207521 croak( 'Useless use of bare dbic_internal_catch()' )
717             unless wantarray;
718              
719 76494 50       193463 croak( 'dbic_internal_catch() must receive exactly one argument at end of expression' )
720             if @_ > 1;
721              
722 76494         275227 bless(
723             \( $_[0] ),
724             'DBIx::Class::_Util::Catch'
725             ),
726             }
727              
728             sub in_internal_try () {
729             !! $callstack_state->{in_internal_try}
730 3500     3500 0 30307 }
731             }
732              
733             {
734             my $destruction_registry = {};
735              
736             sub DBIx::Class::__Util_iThreads_handler__::CLONE {
737             %$destruction_registry = map {
738 0 0   0   0 (defined $_)
  0         0  
739             ? ( refaddr($_) => $_ )
740             : ()
741             } values %$destruction_registry;
742              
743 0         0 weaken($_) for values %$destruction_registry;
744              
745             # Dummy NEXTSTATE ensuring the all temporaries on the stack are garbage
746             # collected before leaving this scope. Depending on the code above, this
747             # may very well be just a preventive measure guarding future modifications
748 0         0 undef;
749             }
750              
751             # This is almost invariably invoked from within DESTROY
752             # throwing exceptions won't work
753             sub detected_reinvoked_destructor {
754              
755             # quick "garbage collection" pass - prevents the registry
756             # from slowly growing with a bunch of undef-valued keys
757             defined $destruction_registry->{$_} or delete $destruction_registry->{$_}
758 15281   66 15281 0 101297 for keys %$destruction_registry;
759              
760 15281 50       112897 if (! length ref $_[0]) {
    100          
761 0         0 emit_loud_diag(
762             emit_dups => 1,
763             msg => (caller(0))[3] . '() expects a blessed reference'
764             );
765 0         0 return undef; # don't know wtf to do
766             }
767             elsif (! defined $destruction_registry->{ my $addr = refaddr($_[0]) } ) {
768 15280         77372 weaken( $destruction_registry->{$addr} = $_[0] );
769 15280         54199 return 0;
770             }
771             else {
772             emit_loud_diag( msg => sprintf (
773             'Preventing *MULTIPLE* DESTROY() invocations on %s - an *EXTREMELY '
774             . 'DANGEROUS* condition which is *ALMOST CERTAINLY GLOBAL* within your '
775             . 'application, affecting *ALL* classes without active protection against '
776             . 'this. Diagnose and fix the root cause ASAP!!!%s',
777             refdesc $_[0],
778 1 50 33     6 ( ( $INC{'Devel/StackTrace.pm'} and ! do { local $@; eval { Devel::StackTrace->VERSION(2) } } )
779 0         0 ? " (likely culprit Devel::StackTrace\@@{[ Devel::StackTrace->VERSION ]} found in %INC, http://is.gd/D_ST_refcap)"
780             : ''
781             )
782             ));
783              
784 1         17 return 1;
785             }
786             }
787             }
788              
789             my $module_name_rx = qr/ \A [A-Z_a-z] [0-9A-Z_a-z]* (?: :: [0-9A-Z_a-z]+ )* \z /x;
790             my $ver_rx = qr/ \A [0-9]+ (?: \. [0-9]+ )* (?: \_ [0-9]+ )* \z /x;
791              
792             sub modver_gt_or_eq ($$) {
793 625     625 0 2963 my ($mod, $ver) = @_;
794              
795 625 50 33     7837 croak "Nonsensical module name supplied"
796             if ! defined $mod or $mod !~ $module_name_rx;
797              
798 625 50 33     5953 croak "Nonsensical minimum version supplied"
799             if ! defined $ver or $ver !~ $ver_rx;
800              
801 625         1413 my $ver_cache = do {
802 317     317   400235 no strict 'refs';
  317         956  
  317         200161  
803 625   100     1126 ${"${mod}::__DBIC_MODULE_VERSION_CHECKS__"} ||= {}
  625         5513  
804             };
805              
806             ! defined $ver_cache->{$ver}
807             and
808 625 100       2471 $ver_cache->{$ver} = do {
809              
810 582         1335 local $SIG{__WARN__} = sigwarn_silencer( qr/\Qisn't numeric in subroutine entry/ )
811             if SPURIOUS_VERSION_CHECK_WARNINGS;
812              
813             # prevent captures by potential __WARN__ hooks or the like:
814             # there is nothing of value that can be happening here, and
815             # leaving a hook in-place can only serve to fail some test
816             local $SIG{__WARN__} if (
817             ! SPURIOUS_VERSION_CHECK_WARNINGS
818             and
819             $SIG{__WARN__}
820 582 100       2281 );
821              
822 582 50       8519 croak "$mod does not seem to provide a version (perhaps it never loaded)"
823             unless $mod->VERSION;
824              
825 582 50       3150 local $SIG{__DIE__} if $SIG{__DIE__};
826 582         1323 local $@;
827 582 50       1490 eval { $mod->VERSION($ver) } ? 1 : 0;
  582         7359  
828             };
829              
830 625         3347 $ver_cache->{$ver};
831             }
832              
833             sub modver_gt_or_eq_and_lt ($$$) {
834 4     4 0 340 my ($mod, $v_ge, $v_lt) = @_;
835              
836 4 50 33     105 croak "Nonsensical maximum version supplied"
837             if ! defined $v_lt or $v_lt !~ $ver_rx;
838              
839             return (
840 4 50 33     22 modver_gt_or_eq($mod, $v_ge)
841             and
842             ! modver_gt_or_eq($mod, $v_lt)
843             ) ? 1 : 0;
844             }
845              
846             {
847              
848             sub describe_class_methods {
849 126013 50 33 126013 0 1796932 my $args = (
    100          
850             ref $_[0] eq 'HASH' ? $_[0]
851             : ( @_ == 1 and ! length ref $_[0] ) ? { class => $_[0] }
852             : { @_ }
853             );
854              
855 126013         190516 my ($class, $requested_mro) = @{$args}{qw( class use_mro )};
  126013         273779  
856              
857 126013 50 33     1096584 croak "Expecting a class name either as the sole argument or a 'class' option"
858             if not defined $class or $class !~ $module_name_rx;
859              
860 126013         187485 croak(
861             "The supplied 'class' argument is tainted: this is *extremely* "
862             . 'dangerous, fix your code ASAP!!! ( for more details read through '
863             . 'https://is.gd/perl_mro_taint_wtf )'
864             ) if (
865             DBIx::Class::_ENV_::TAINT_MODE
866             and
867             Scalar::Util::tainted($class)
868             );
869              
870 126013   66     577457 $requested_mro ||= mro::get_mro($class);
871              
872             # mro::set_mro() does not bump pkg_gen - WHAT THE FUCK?!
873 126013         265278 my $query_cache_key = "$class|$requested_mro";
874              
875 126013 100       301041 my $internal_cache_key =
876             ( mro::get_mro($class) eq $requested_mro )
877             ? $class
878             : $query_cache_key
879             ;
880              
881             # use a cache on old MRO, since while we are recursing in this function
882             # nothing can possibly change (the speedup is immense)
883             # (yes, people could be tie()ing the stash and adding methods on access
884             # but there is a limit to how much crazy can be supported here)
885             #
886             # we use the cache for linear_isa lookups on new MRO as well - it adds
887             # a *tiny* speedup, and simplifies the code a lot
888             #
889             local $__describe_class_query_cache->{'!internal!'} = {}
890 126013 100       305362 unless $__describe_class_query_cache->{'!internal!'};
891              
892 126013         166308 my $my_gen = 0;
893              
894 126013 100 100     162377 $my_gen += get_real_pkg_gen($_) for ( my @full_ISA = (
895              
896             @{
897             $__describe_class_query_cache->{'!internal!'}{$internal_cache_key}{linear_isa}
898             ||=
899 126013   66     740165 mro::get_linear_isa($class, $requested_mro)
900             },
901              
902             ((
903             $__describe_class_query_cache->{'!internal!'}{$class}{is_universal}
904             ||=
905             mro::is_universal($class)
906             ) ? () : @{
907             $__describe_class_query_cache->{'!internal!'}{UNIVERSAL}{linear_isa}
908             ||=
909 60656   66     378207 mro::get_linear_isa("UNIVERSAL")
910             }),
911              
912             ));
913              
914 126013   100     316791 my $slot = $__describe_class_query_cache->{$query_cache_key} ||= {};
915              
916 126013 50 100     306883 unless ( ($slot->{cumulative_gen}||0) == $my_gen ) {
917              
918             # reset
919             %$slot = (
920             class => $class,
921 251713         560414 isa => { map { $_ => 1 } @full_ISA },
922             linear_isa => [
923 126013         2277199 @{ $__describe_class_query_cache->{'!internal!'}{$internal_cache_key}{linear_isa} }
924 126013 100       208700 [ 1 .. $#{$__describe_class_query_cache->{'!internal!'}{$internal_cache_key}{linear_isa}} ]
  126013         266861  
925             ],
926             mro => {
927             type => $requested_mro,
928             is_c3 => ( ($requested_mro eq 'c3') ? 1 : 0 ),
929             },
930             cumulative_gen => $my_gen,
931             );
932              
933             # remove ourselves from ISA
934 126013         242806 shift @full_ISA;
935              
936             # ensure the cache is populated for the parents, code below can then
937             # efficiently operate over the query_cache directly
938 126013         266657 describe_class_methods($_) for reverse @full_ISA;
939              
940 317     317   3203 no strict 'refs';
  317         823  
  317         226773  
941              
942             # combine full ISA-order inherited and local method list into a
943             # "shadowing stack"
944              
945             (
946 1532288         6569374 unshift @{ $slot->{methods}{$_->{name}} }, $_
947              
948             and
949              
950             (
951             $_->{via_class} ne $class
952             or
953             $slot->{methods_defined_in_class}{$_->{name}} = $_
954             )
955              
956             and
957              
958 1532288         3751098 @{ $slot->{methods}{$_->{name}} } > 1
959              
960             and
961              
962             $slot->{methods_with_supers}{$_->{name}} = $slot->{methods}{$_->{name}}
963              
964 126013   66     224350 ) for (
      33        
      66        
      66        
965              
966             # what describe_class_methods for @full_ISA produced above
967             ( map { values %{
968 125700         158627 $__describe_class_query_cache->{$_}{methods_defined_in_class} || {}
969 125700 100       442969 } } map { "$_|" . mro::get_mro($_) } reverse @full_ISA ),
  125700         421707  
970              
971             # our own non-cleaned subs + their attributes
972             ( map {
973             (
974             # need to account for dummy helper crefs under OLD_MRO
975             (
976             ! DBIx::Class::_ENV_::OLD_MRO
977             or
978             ! ( ( $Class::C3::MRO{$class} || {} )->{methods}{$_} )
979             )
980             and
981             # these 2 OR-ed checks are sufficient for 5.10+
982             (
983             ref(\ "${class}::"->{$_} ) ne 'GLOB'
984             or
985             defined( *{ "${class}::"->{$_} }{CODE} )
986             )
987             ) ? {
988             via_class => $class,
989             name => $_,
990 1923157 100 66     5988222 attributes => { map { $_ => 1 } do {
  19552         1670598  
991 768024         1225745 my @attrs;
992 768024         970887 local $@;
993 768024 50       1458620 local $SIG{__DIE__} if $SIG{__DIE__};
994             # attributes::get may throw on blessed-false crefs :/
995 768024 100       1138073 eval { @attrs = attributes::get( \&{"${class}::${_}"} ); 1 }
  768024         867124  
  768024         2836952  
  768020         11492087  
996             or warn "Unable to determine attributes of the \\&${class}::$_ method due to following error: $@";
997 768024         42000457 @attrs;
998             } },
999             }
1000             : ()
1001 126013         742602 } keys %{"${class}::"} )
1002             );
1003              
1004              
1005             # recalculate the pkg_gen on newer perls under Taint mode,
1006             # because of shit like:
1007             # perl -T -Mmro -e 'package Foo; sub bar {}; defined( *{ "Foo::"->{bar}}{CODE} ) and warn mro::get_pkg_gen("Foo") for (1,2,3)'
1008             #
1009 126013         325256 if (
1010             ! DBIx::Class::_ENV_::OLD_MRO
1011             and
1012             DBIx::Class::_ENV_::TAINT_MODE
1013             ) {
1014              
1015             $slot->{cumulative_gen} = 0;
1016             $slot->{cumulative_gen} += get_real_pkg_gen($_)
1017             for $class, @full_ISA;
1018             }
1019             }
1020              
1021             # RV
1022 126013         874535 +{ %$slot };
1023             }
1024             }
1025              
1026              
1027             #
1028             # Why not just use some higher-level module or at least File::Spec here?
1029             # Because:
1030             # 1) This is a *very* rarely used function, and the deptree is large
1031             # enough already as it is
1032             #
1033             # 2) (more importantly) Our tooling is utter shit in this area. There
1034             # is no comprehensive support for UNC paths in PathTools and there
1035             # are also various small bugs in representation across different
1036             # path-manipulation CPAN offerings.
1037             #
1038             # Since this routine is strictly used for logical path processing (it
1039             # *must* be able to work with not-yet-existing paths), use this seemingly
1040             # simple but I *think* complete implementation to feed to other consumers
1041             #
1042             # If bugs are ever uncovered in this routine, *YOU ARE URGED TO RESIST*
1043             # the impulse to bring in an external dependency. During runtime there
1044             # is exactly one spot that could potentially maybe once in a blue moon
1045             # use this function. Keep it lean.
1046             #
1047             sub parent_dir ($) {
1048 0 0 0 0 0   ( $_[0] =~ m{ [\/\\] ( \.{0,2} ) ( [\/\\]* ) \z }x )
    0 0        
1049             ? (
1050             $_[0]
1051             .
1052             ( ( length($1) and ! length($2) ) ? '/' : '' )
1053             .
1054             '../'
1055             )
1056             : (
1057             require File::Spec
1058             and
1059             File::Spec->catpath (
1060             ( File::Spec->splitpath( "$_[0]" ) )[0,1],
1061             '/',
1062             )
1063             )
1064             ;
1065             }
1066              
1067             sub mkdir_p ($) {
1068 0     0 0   require File::Path;
1069             # do not ask for a recent version, use 1.x API calls
1070 0           File::Path::mkpath([ "$_[0]" ]); # File::Path does not like objects
1071             }
1072              
1073              
1074             sub fail_on_internal_call {
1075 0     0 0   my $fr = [ CORE::caller(1) ];
1076              
1077             die "\nMethod $fr->[3] is not marked with the 'DBIC_method_is_indirect_sugar' attribute\n\n" unless (
1078              
1079             # unlikely but who knows...
1080             ! @$fr
1081              
1082             or
1083              
1084             # This is a weird-ass double-purpose method, only one branch of which is marked
1085             # as an illegal indirect call
1086             # Hence the 'indirect' attribute makes no sense
1087             # FIXME - likely need to mark this in some other manner
1088             $fr->[3] eq 'DBIx::Class::ResultSet::new'
1089              
1090             or
1091              
1092             # RsrcProxy stuff is special and not attr-annotated on purpose
1093             # Yet it is marked (correctly) as fail_on_internal_call(), as DBIC
1094             # itself should not call these methods as first-entry
1095             $fr->[3] =~ /^DBIx::Class::ResultSourceProxy::[^:]+$/
1096              
1097             or
1098              
1099             # FIXME - there is likely a more fine-graned way to escape "foreign"
1100             # callers, based on annotations... (albeit a slower one)
1101             # For the time being just skip in a dumb way
1102             $fr->[3] !~ /^DBIx::Class|^DBICx::|^DBICTest::/
1103              
1104             or
1105              
1106             grep
1107 0           { $_ eq 'DBIC_method_is_indirect_sugar' }
1108 317 0 0 317   2618 do { no strict 'refs'; attributes::get( \&{ $fr->[3] }) }
  317   0     778  
  317   0     77249  
  0   0        
  0            
  0            
1109             );
1110              
1111              
1112 0           my @fr2;
1113             # need to make allowance for a proxy-yet-direct call
1114             # or for an exception wrapper
1115 0 0 0       $fr = \@fr2 if (
      0        
      0        
      0        
1116             (
1117             $fr->[3] eq '(eval)'
1118             and
1119             @fr2 = (CORE::caller(2))
1120             )
1121             or
1122             (
1123             $fr->[0] eq 'DBIx::Class::ResultSourceProxy'
1124             and
1125             @fr2 = (CORE::caller(2))
1126             and
1127             (
1128             ( $fr->[3] =~ /([^:])+$/ )[0]
1129             eq
1130             ( $fr2[3] =~ /([^:])+$/ )[0]
1131             )
1132             )
1133             );
1134              
1135              
1136 0 0 0       if (
    0 0        
      0        
      0        
      0        
      0        
1137             defined $fr->[0]
1138             and
1139             $fr->[0] =~ /^(?:DBIx::Class|DBICx::)/
1140             and
1141             $fr->[1] !~ /\b(?:CDBICompat|ResultSetProxy)\b/ # no point touching there
1142             and
1143             # one step higher
1144             @fr2 = CORE::caller(@fr2 ? 3 : 2)
1145             and
1146             # if the frame that called us is an indirect itself - nothing to see here
1147             (! grep
1148 0           { $_ eq 'DBIC_method_is_indirect_sugar' }
1149             do {
1150 317     317   2545 no strict 'refs';
  317         825  
  317         49775  
1151 0           attributes::get( \&{ $fr2[3] })
  0            
1152             }
1153             )
1154             and
1155             (
1156             $fr->[3] ne 'DBIx::Class::ResultSet::search'
1157             or
1158             # these are explicit wantarray-passthrough callsites for search() due to old silly API choice
1159             $fr2[3] !~ /^DBIx::Class::Ordered::(?: _group_rs | (?: _ | next_ | previous_ )? siblings )/x
1160             )
1161             ) {
1162              
1163 0           my $argdesc;
1164              
1165             {
1166 0           package DB;
1167              
1168 0 0         my @throwaway = caller( @fr2 ? 2 : 1 );
1169              
1170             # screwing with $DB::args is rather volatile - be extra careful
1171 317     317   2817 no warnings 'uninitialized';
  317         763  
  317         38811  
1172              
1173 0 0         $argdesc =
    0          
1174             ( not defined $DB::args[0] ) ? 'UNAVAILABLE'
1175             : ( length ref $DB::args[0] ) ? DBIx::Class::_Util::refdesc($DB::args[0])
1176             : $DB::args[0] . ''
1177             ;
1178             };
1179              
1180             DBIx::Class::Exception->throw( sprintf (
1181             "Illegal internal call of indirect proxy-method %s() with argument '%s': examine the last lines of the proxy method deparse below to determine what to call directly instead at %s on line %d\n\n%s\n\n Stacktrace starts",
1182 0   0       $fr->[3], $argdesc, @{$fr}[1,2], ( $fr->[6] || do {
  0            
1183             require B::Deparse;
1184 317     317   2442 no strict 'refs';
  317         809  
  317         40166  
1185             B::Deparse->new->coderef2text(\&{$fr->[3]})
1186             }),
1187             ), 'with_stacktrace');
1188             }
1189             }
1190              
1191             if (DBIx::Class::_ENV_::ASSERT_NO_ERRONEOUS_METAINSTANCE_USE) {
1192              
1193 317     317   2300 no warnings 'redefine';
  317         759  
  317         101705  
1194              
1195             my $next_bless = defined(&CORE::GLOBAL::bless)
1196             ? \&CORE::GLOBAL::bless
1197             : sub { CORE::bless($_[0], $_[1]) }
1198             ;
1199              
1200             *CORE::GLOBAL::bless = sub {
1201             my $class = (@_ > 1) ? $_[1] : CORE::caller();
1202              
1203             # allow for reblessing (role application)
1204             return $next_bless->( $_[0], $class )
1205             if defined blessed $_[0];
1206              
1207             my $obj = $next_bless->( $_[0], $class );
1208              
1209             my $calling_sub = (CORE::caller(1))[3] || '';
1210              
1211             (
1212             # before 5.18 ->isa() will choke on the "0" package
1213             # which we test for in several obscure cases, sigh...
1214             !( DBIx::Class::_ENV_::PERL_VERSION < 5.018 )
1215             or
1216             $class
1217             )
1218             and
1219             (
1220             (
1221             $calling_sub !~ /^ (?:
1222             DBIx::Class::Schema::clone
1223             |
1224             DBIx::Class::DB::setup_schema_instance
1225             )/x
1226             and
1227             $class->isa("DBIx::Class::Schema")
1228             )
1229             or
1230             (
1231             $calling_sub ne 'DBIx::Class::ResultSource::new'
1232             and
1233             $class->isa("DBIx::Class::ResultSource")
1234             )
1235             )
1236             and
1237             local $Carp::CarpLevel = $Carp::CarpLevel + 1
1238             and
1239             Carp::confess("Improper instantiation of '$obj': you *MUST* call the corresponding constructor");
1240              
1241              
1242             $obj;
1243             };
1244             }
1245              
1246             1;