File Coverage

blib/lib/DBIx/Class/ResultSourceHandle.pm
Criterion Covered Total %
statement 43 46 93.4
branch 10 16 62.5
condition 3 9 33.3
subroutine 12 12 100.0
pod 4 4 100.0
total 72 87 82.7


line stmt bran cond sub pod time code
1             package DBIx::Class::ResultSourceHandle;
2              
3 379     379   4049 use strict;
  379         1223  
  379         13806  
4 379     379   2307 use warnings;
  379         1278  
  379         11431  
5              
6 379     379   2256 use base qw/DBIx::Class/;
  379         1186  
  379         37929  
7              
8 379     379   2796 use Try::Tiny;
  379         1334  
  379         21536  
9 379     379   2892 use namespace::clean;
  379         1423  
  379         2760  
10              
11             use overload
12 2     2   13 q/""/ => sub { __PACKAGE__ . ":" . shift->source_moniker; },
13 379     379   107670 fallback => 1;
  379         1416  
  379         4718  
14              
15             __PACKAGE__->mk_group_accessors('simple' => qw/schema source_moniker _detached_source/);
16              
17             # Schema to use when thawing.
18             our $thaw_schema;
19              
20             =head1 NAME
21              
22             DBIx::Class::ResultSourceHandle - Serializable pointers to ResultSource instances
23              
24             =head1 DESCRIPTION
25              
26             Currently instances of this class are used to allow proper serialization of
27             L<ResultSources|DBIx::Class::ResultSource> (which may contain unserializable
28             elements like C<CODE> references).
29              
30             Originally this module was used to remove the fixed link between
31             L<Rows|DBIx::Class::Row>/L<ResultSets|DBIx::Class::ResultSet> and the actual
32             L<result source objects|DBIx::Class::ResultSource> in order to obviate the need
33             of keeping a L<schema instance|DBIx::Class::Schema> constantly in scope, while
34             at the same time avoiding leaks due to circular dependencies. This is however
35             no longer needed after introduction of a proper mutual-assured-destruction
36             contract between a C<Schema> instance and its C<ResultSource> registrants.
37              
38             =head1 METHODS
39              
40             =head2 new
41              
42             =cut
43              
44             sub new {
45 206     206 1 543 my ($class, $args) = @_;
46 206   33     1021 my $self = bless $args, ref $class || $class;
47              
48 206 50 33     2958 unless( ($self->{schema} || $self->{_detached_source}) && $self->{source_moniker} ) {
      33        
49 0         0 my $err = 'Expecting a schema instance and a source moniker';
50             $self->{schema}
51 0 0       0 ? $self->{schema}->throw_exception($err)
52             : DBIx::Class::Exception->throw($err)
53             }
54              
55 206         805 $self;
56             }
57              
58             =head2 resolve
59              
60             Resolve the moniker into the actual ResultSource object
61              
62             =cut
63              
64             sub resolve {
65 206 100   206 1 4385 return $_[0]->{schema}->source($_[0]->source_moniker) if $_[0]->{schema};
66              
67 57 50       853 $_[0]->_detached_source || DBIx::Class::Exception->throw( sprintf (
68             # vague error message as this is never supposed to happen
69             "Unable to resolve moniker '%s' - please contact the dev team at %s",
70             $_[0]->source_moniker,
71             DBIx::Class::_ENV_::HELP_URL,
72             ), 'full_stacktrace');
73             }
74              
75             =head2 STORABLE_freeze
76              
77             Freezes a handle.
78              
79             =cut
80              
81             sub STORABLE_freeze {
82 207     207 1 5057 my ($self, $cloning) = @_;
83              
84 207         690 my $to_serialize = { %$self };
85              
86 207         469 delete $to_serialize->{schema};
87 207         382 delete $to_serialize->{_detached_source};
88             $to_serialize->{_frozen_from_class} = $self->{schema}
89             ? $self->{schema}->class($self->source_moniker)
90             : $self->{_detached_source}->result_class
91 207 50       1148 ;
92              
93 207         622 Storable::nfreeze($to_serialize);
94             }
95              
96             =head2 STORABLE_thaw
97              
98             Thaws frozen handle. Resets the internal schema reference to the package
99             variable C<$thaw_schema>. The recommended way of setting this is to use
100             C<< $schema->thaw($ice) >> which handles this for you.
101              
102             =cut
103              
104             sub STORABLE_thaw {
105 207     207 1 2950 my ($self, $cloning, $ice) = @_;
106 207         326 %$self = %{ Storable::thaw($ice) };
  207         462  
107              
108 207         4529 my $from_class = delete $self->{_frozen_from_class};
109              
110 207 100       4970 if( $thaw_schema ) {
    50          
111 22         134 $self->schema( $thaw_schema );
112             }
113             elsif( my $rs = $from_class->result_source_instance ) {
114             # in the off-chance we are using CDBI-compat and have leaked $schema already
115 185 100   185   4543 if( my $s = try { $rs->schema } ) {
  185         7169  
116 127         2571 $self->schema( $s );
117             }
118             else {
119 58         1128 $rs->source_name( $self->source_moniker );
120 58         120 $rs->{_detached_thaw} = 1;
121 58         640 $self->_detached_source( $rs );
122             }
123             }
124             else {
125 0           DBIx::Class::Exception->throw(
126             "Thaw failed - original result class '$from_class' does not exist on this system"
127             );
128             }
129             }
130              
131             =head1 FURTHER QUESTIONS?
132              
133             Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
134              
135             =head1 COPYRIGHT AND LICENSE
136              
137             This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
138             by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
139             redistribute it and/or modify it under the same terms as the
140             L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
141              
142             =cut
143              
144             1;