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   2267 use strict;
  379         744  
  379         10691  
4 379     379   1576 use warnings;
  379         744  
  379         11080  
5              
6 379     379   1551 use base qw/DBIx::Class/;
  379         767  
  379         26665  
7              
8 379     379   1806 use Try::Tiny;
  379         779  
  379         19851  
9 379     379   1727 use namespace::clean;
  379         772  
  379         2110  
10              
11             use overload
12 2     2   9 q/""/ => sub { __PACKAGE__ . ":" . shift->source_moniker; },
13 379     379   88200 fallback => 1;
  379         985  
  379         4384  
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 (which may contain unserializable
28             elements like C references).
29              
30             Originally this module was used to remove the fixed link between
31             L/L and the actual
32             L in order to obviate the need
33             of keeping a L 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 instance and its C registrants.
37              
38             =head1 METHODS
39              
40             =head2 new
41              
42             =cut
43              
44             sub new {
45 206     206 1 255 my ($class, $args) = @_;
46 206   33     852 my $self = bless $args, ref $class || $class;
47              
48 206 50 33     2133 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         548 $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 2825 return $_[0]->{schema}->source($_[0]->source_moniker) if $_[0]->{schema};
66              
67 57 50       681 $_[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 2806 my ($self, $cloning) = @_;
83              
84 207         574 my $to_serialize = { %$self };
85              
86 207         289 delete $to_serialize->{schema};
87 207         191 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       859 ;
92              
93 207         479 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 1846 my ($self, $cloning, $ice) = @_;
106 207         186 %$self = %{ Storable::thaw($ice) };
  207         345  
107              
108 207         2780 my $from_class = delete $self->{_frozen_from_class};
109              
110 207 100       4218 if( $thaw_schema ) {
    50          
111 22         104 $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   2938 if( my $s = try { $rs->schema } ) {
  185         4883  
116 127         1910 $self->schema( $s );
117             }
118             else {
119 58         716 $rs->source_name( $self->source_moniker );
120 58         61 $rs->{_detached_thaw} = 1;
121 58         486 $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.
134              
135             =head1 COPYRIGHT AND LICENSE
136              
137             This module is free software L
138             by the L. You can
139             redistribute it and/or modify it under the same terms as the
140             L.
141              
142             =cut
143              
144             1;