the schema classname. To specify a fully-qualified name, prefix it
with a literal C<+>. For example, C<+Other::NameSpace::Result>.
+Experimental: It is also possible to load the result source classes when they
+are requested by L</source>. Giving C<lazy_load> as an argument to
+L</load_namespaces> will enable this. This will decrease start up time if you
+have large schemas.
+
=head3 Warnings
You will be warned if ResultSet classes are discovered for which there
resultset_namespace => '+Another::Place::RSets',
);
+ # Postpone loading of result sources
+ My::Schema->load_namespaces(
+ lazy_load => 1,
+ # ...
+ );
+
To search multiple namespaces for either Result or ResultSet classes,
use an arrayref of namespaces for that option. In the case that the
same result (or resultset) class exists in multiple namespaces, later
my $result_namespace = delete $args{result_namespace} || 'Result';
my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
my $default_resultset_class = delete $args{default_resultset_class};
+ my $lazy_load = delete $args{lazy_load};
$class->throw_exception('load_namespaces: unknown option(s): '
. join(q{,}, map { qq{'$_'} } keys %args))
my %results = $class->_map_namespaces(@$result_namespace);
my %resultsets = $class->_map_namespaces(@$resultset_namespace);
+ if($lazy_load) {
+ # abusing the attribute to store $moniker => [@classnames] information
+ $class->class_mappings->{$_} = [ $results{$_}, $resultsets{$_} || $default_resultset_class ] for keys %results;
+ return;
+ }
+
my @to_register;
+
{
no warnings qw/redefine/;
local *Class::C3::reinitialize = sub { } if DBIx::Class::_ENV_::OLD_MRO;
my $sreg = $self->source_registrations;
return $sreg->{$source_name} if exists $sreg->{$source_name};
- # if we got here, they probably passed a full class name
+ # if we got here, they probably passed a full class name or something to lazy load
my $mapped = $self->class_mappings->{$source_name};
- $self->throw_exception("Can't find source for ${source_name}")
- unless $mapped && exists $sreg->{$mapped};
+
+ # if we got here, they probably passed a full class name
+ if(!$mapped) {
+ my $last;
+ for(%{ $self->class_mappings }) {
+ next unless ref $_ and $_->[0] eq $source_name;
+ $mapped = $_;
+ last;
+ }
+ }
+ if(ref $mapped eq 'ARRAY') {
+ my $source_class = $mapped->[0];
+ $self->ensure_class_loaded($source_class);
+ $source_class->resultset_class($mapped->[1]) if $mapped->[1];
+ $self->register_class($source_name, $source_class);
+ $mapped = $source_name;
+ $sreg = $self->source_registrations; # jhthorsen: No idea why data is copied all over the place instead of just changing the ref...
+ }
+
+ if(!$mapped or !exists $sreg->{$mapped}) {
+ $self->throw_exception("Can't find source for ${source_name}");
+ }
+
return $sreg->{$mapped};
}
};
bless $clone, (ref $self || $self);
- $clone->$_(undef) for qw/class_mappings source_registrations storage/;
+ $clone->$_(undef) for qw/class_mappings source_registrations storage /;
$clone->_copy_state_from($self);
--- /dev/null
+use strict;
+use warnings;
+use Test::More;
+
+use lib qw(t/lib);
+use DBICTest; # do not remove even though it is not used
+
+plan tests => 9;
+
+my $warnings;
+eval {
+ local $SIG{__WARN__} = sub { $warnings .= shift };
+ package DBICNSTest;
+ use base qw/DBIx::Class::Schema/;
+ __PACKAGE__->load_namespaces(lazy_load => 1, default_resultset_class => 'RSBase');
+};
+ok !$@ or diag $@;
+ok !$warnings, 'no warnings';
+
+is int DBICNSTest->sources, 0, 'zero sources loaded';
+
+my $source_b = DBICNSTest->source('R');
+isa_ok($source_b, 'DBIx::Class::ResultSource::Table');
+my $rset_b = DBICNSTest->resultset('R');
+isa_ok($rset_b, 'DBICNSTest::RSBase');
+ok ref $source_b->related_source('a'), 'managed to load related';
+
+my $source_a = DBICNSTest->source('A');
+isa_ok($source_a, 'DBIx::Class::ResultSource::Table');
+my $rset_a = DBICNSTest->resultset('A');
+isa_ok($rset_a, 'DBICNSTest::ResultSet::A');
+
+
+is int DBICNSTest->sources, 3, 'two sources loaded';