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