Some cleanups around loading/use of DBIx::Class::Exception (no func. changes)
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSourceHandle.pm
CommitLineData
aec3eff1 1package DBIx::Class::ResultSourceHandle;
2
3use strict;
4use warnings;
aec3eff1 5
6use base qw/DBIx::Class/;
7
4376a157 8use Try::Tiny;
4376a157 9use namespace::clean;
10
aec3eff1 11use overload
3441fd57 12 q/""/ => sub { __PACKAGE__ . ":" . shift->source_moniker; },
aec3eff1 13 fallback => 1;
14
4376a157 15__PACKAGE__->mk_group_accessors('simple' => qw/schema source_moniker _detached_source/);
aec3eff1 16
4146e3da 17# Schema to use when thawing.
18our $thaw_schema;
19
aec3eff1 20=head1 NAME
21
4376a157 22DBIx::Class::ResultSourceHandle - Serializable pointers to ResultSource instances
aec3eff1 23
24=head1 DESCRIPTION
25
4376a157 26Currently instances of this class are used to allow proper serialization of
27L<ResultSources|DBIx::Class::ResultSource> (which may contain unserializable
28elements like C<CODE> references).
aec3eff1 29
4376a157 30Originally this module was used to remove the fixed link between
31L<Rows|DBIx::Class::Row>/L<ResultSets|DBIx::Class::ResultSet> and the actual
32L<result source objects|DBIx::Class::ResultSource> in order to obviate the need
33of keeping a L<schema instance|DBIx::Class::Schema> constantly in scope, while
34at the same time avoiding leaks due to circular dependencies. This is however
35no longer needed after introduction of a proper mutual-assured-destruction
36contract between a C<Schema> instance and its C<ResultSource> registrants.
aec3eff1 37
38=head1 METHODS
39
40=head2 new
41
42=cut
43
44sub new {
4376a157 45 my ($class, $args) = @_;
46 my $self = bless $args, ref $class || $class;
aec3eff1 47
4376a157 48 unless( ($self->{schema} || $self->{_detached_source}) && $self->{source_moniker} ) {
49 my $err = 'Expecting a schema instance and a source moniker';
50 $self->{schema}
51 ? $self->{schema}->throw_exception($err)
52 : DBIx::Class::Exception->throw($err)
53 }
aec3eff1 54
4376a157 55 $self;
aec3eff1 56}
57
58=head2 resolve
59
3441fd57 60Resolve the moniker into the actual ResultSource object
aec3eff1 61
62=cut
63
4376a157 64sub resolve {
65 return $_[0]->{schema}->source($_[0]->source_moniker) if $_[0]->{schema};
66
67 $_[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 'http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class.pm#GETTING_HELP/SUPPORT',
72 ), 'full_stacktrace');
73}
aec3eff1 74
7137528d 75=head2 STORABLE_freeze
76
77Freezes a handle.
78
79=cut
80
aec3eff1 81sub STORABLE_freeze {
4376a157 82 my ($self, $cloning) = @_;
4146e3da 83
4376a157 84 my $to_serialize = { %$self };
d4daee7b 85
4376a157 86 delete $to_serialize->{schema};
87 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 ;
7cfda9a6 92
3b80fa31 93 Storable::nfreeze($to_serialize);
aec3eff1 94}
95
7137528d 96=head2 STORABLE_thaw
97
4146e3da 98Thaws frozen handle. Resets the internal schema reference to the package
8273e845 99variable C<$thaw_schema>. The recommended way of setting this is to use
323e0bd0 100C<< $schema->thaw($ice) >> which handles this for you.
7137528d 101
102=cut
103
aec3eff1 104sub STORABLE_thaw {
4376a157 105 my ($self, $cloning, $ice) = @_;
3b80fa31 106 %$self = %{ Storable::thaw($ice) };
4376a157 107
108 my $from_class = delete $self->{_frozen_from_class};
109
110 if( $thaw_schema ) {
111 $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 if( my $s = try { $rs->schema } ) {
116 $self->schema( $s );
3a81f59b 117 }
118 else {
4376a157 119 $rs->source_name( $self->source_moniker );
120 $rs->{_detached_thaw} = 1;
121 $self->_detached_source( $rs );
3a81f59b 122 }
4376a157 123 }
124 else {
125 DBIx::Class::Exception->throw(
126 "Thaw failed - original result class '$from_class' does not exist on this system"
127 );
128 }
aec3eff1 129}
130
4146e3da 131=head1 AUTHOR
132
133Ash Berlin C<< <ash@cpan.org> >>
134
135=cut
136
aec3eff1 1371;