use warnings;
use base 'DBIx::Class';
-use mro 'c3';
use DBIx::Class::Carp;
use Try::Tiny;
my $rs_class = ref ($_[0]) || $_[0];
return dbic_internal_try {
- $rs_class->result_source_instance
+ $rs_class->result_source
} catch {
$me->throw_exception (
"Attempt to load_namespaces() class $rs_class failed - are you sure this is a real Result Class?: $_"
||
$self->throw_exception( "Can't find source for ${source_name}" )
;
+
+ # DO NOT REMOVE:
+ # We need to prevent alterations of pre-existing $@ due to where this call
+ # sits in the overall stack ( *unless* of course there is an actual error
+ # to report ). set_mro does alter $@ (and yes - it *can* throw an exception)
+ # We do not use local because set_mro *can* throw an actual exception
+ # We do not use a try/catch either, as on one hand it would slow things
+ # down for no reason (we would always rethrow), but also because adding *any*
+ # try/catch block below will segfault various threading tests on older perls
+ # ( which in itself is a FIXME but ENOTIMETODIG )
+ my $old_dollarat = $@;
+
+ no strict 'refs';
+ mro::set_mro($_, 'c3') for
+ grep
+ {
+ # some pseudo-sources do not have a result/resultset yet
+ defined $_
+ and
+ (
+ (
+ ${"${_}::__INITIAL_MRO_UPON_DBIC_LOAD__"}
+ ||= mro::get_mro($_)
+ )
+ ne
+ 'c3'
+ )
+ }
+ map
+ { length ref $_ ? ref $_ : $_ }
+ ( $rsrc, $rsrc->result_class, $rsrc->resultset_class )
+ ;
+
+ # DO NOT REMOVE - see comment above
+ $@ = $old_dollarat;
+
+ $rsrc;
}
=head2 class
my $target_class = "${target}::${source_name}";
$self->inject_base($target_class, $orig_source->result_class, ($base || ()) );
- # register_source examines result_class, and then returns us a clone
- my $new_source = $schema->register_source($source_name, bless
- { %$orig_source, result_class => $target_class },
- ref $orig_source,
+ $schema->register_source(
+ $source_name,
+ $orig_source->clone(
+ result_class => $target_class
+ ),
);
-
- if ($target_class->can('result_source_instance')) {
- # give the class a schema-less source copy
- $target_class->result_source_instance( bless
- { %$new_source, schema => ref $new_source->{schema} || $new_source->{schema} },
- ref $new_source,
- );
- }
}
# Legacy stuff, not inserting INDIRECT assertions
Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
+ # Give each composed class yet another *schema-less* source copy
+ # this is used for the freeze/thaw cycle
+ #
+ # This is not covered by any tests directly, but is indirectly exercised
+ # in t/cdbi/sweet/08pager by re-setting the schema on an existing object
+ # FIXME - there is likely a much cheaper way to take care of this
+ for my $source_name ($self->sources) {
+
+ my $target_class = "${target}::${source_name}";
+
+ $target_class->result_source_instance(
+ $self->source($source_name)->clone(
+ result_class => $target_class,
+ schema => ( ref $schema || $schema ),
+ )
+ );
+ }
+
return $schema;
}
$self->class_mappings({ %{$from->class_mappings} });
$self->source_registrations({ %{$from->source_registrations} });
- foreach my $source_name ($from->sources) {
- my $source = $from->source($source_name);
- my $new = $source->new($source);
- # we use extra here as we want to leave the class_mappings as they are
- # but overwrite the source_registrations entry with the new source
- $self->register_extra_source($source_name => $new);
- }
+ # we use extra here as we want to leave the class_mappings as they are
+ # but overwrite the source_registrations entry with the new source
+ $self->register_extra_source( $_ => $from->source($_) )
+ for $from->sources;
if ($from->storage) {
$self->storage($from->storage);
Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
calling:
- $schema->register_source($source_name, $component_class->result_source_instance);
+ $schema->register_source($source_name, $component_class->result_source);
=cut
sub register_class {
my ($self, $source_name, $to_register) = @_;
- $self->register_source($source_name => $to_register->result_source_instance);
+ $self->register_source($source_name => $to_register->result_source);
}
=head2 register_source
sub _register_source {
my ($self, $source_name, $supplied_rsrc, $params) = @_;
- my $derived_rsrc = $supplied_rsrc->new({
- %$supplied_rsrc,
+ my $derived_rsrc = $supplied_rsrc->clone({
source_name => $source_name,
});
my $source = $schema->source($source_name);
my $class = $source->result_class;
#warn "$source_name $class $source ".$source->storage;
- $class->mk_classaccessor(result_source_instance => $source);
+
+ $class->mk_group_accessors( inherited => [ result_source_instance => '_result_source' ] );
+ # explicit set-call, avoid mro update lag
+ $class->set_inherited( result_source_instance => $source );
+
$class->mk_classaccessor(resultset_instance => $source->resultset);
$class->mk_classaccessor(class_resolver => $schema);
}