Commit | Line | Data |
75d07914 |
1 | package # hide from PAUSE |
c0e7b4e5 |
2 | DBIx::Class::Componentised; |
227d4dee |
3 | |
bf5ecff9 |
4 | use strict; |
5 | use warnings; |
6 | |
147dd158 |
7 | use Class::C3; |
c037c03a |
8 | use Class::Inspector; |
147dd158 |
9 | |
227d4dee |
10 | sub inject_base { |
11 | my ($class, $target, @to_inject) = @_; |
12 | { |
13 | no strict 'refs'; |
eb47985e |
14 | foreach my $to (reverse @to_inject) { |
df88a29c |
15 | my @comps = qw(DigestColumns ResultSetManager Ordered UTF8Columns); |
16 | # Add components here that need to be loaded before Core |
17 | foreach my $first_comp (@comps) { |
18 | if ($to eq 'DBIx::Class::Core' && |
19 | $target->isa("DBIx::Class::${first_comp}")) { |
20 | warn "Possible incorrect order of components in ". |
21 | "${target}::load_components($first_comp) call: Core loaded ". |
22 | "before $first_comp. See the documentation for ". |
23 | "DBIx::Class::$first_comp for more information"; |
24 | } |
25 | } |
26 | unshift( @{"${target}::ISA"}, $to ) |
27 | unless ($target eq $to || $target->isa($to)); |
eb47985e |
28 | } |
227d4dee |
29 | } |
20518cb4 |
30 | |
31 | # Yes, this is hack. But it *does* work. Please don't submit tickets about |
32 | # it on the basis of the comments in Class::C3, the author was on #dbix-class |
33 | # while I was implementing this. |
34 | |
9a15732e |
35 | my $table = { Class::C3::_dump_MRO_table }; |
75a23b3e |
36 | eval "package $target; import Class::C3;" unless exists $table->{$target}; |
227d4dee |
37 | } |
38 | |
39 | sub load_components { |
40 | my $class = shift; |
7411204b |
41 | my $base = $class->component_base_class; |
6db94aca |
42 | my @comp = map { /^\+(.*)$/ ? $1 : "${base}::$_" } grep { $_ !~ /^#/ } @_; |
227d4dee |
43 | $class->_load_components(@comp); |
971c0085 |
44 | Class::C3::reinitialize(); |
227d4dee |
45 | } |
46 | |
47 | sub load_own_components { |
48 | my $class = shift; |
49 | my @comp = map { "${class}::$_" } grep { $_ !~ /^#/ } @_; |
50 | $class->_load_components(@comp); |
51 | } |
52 | |
53 | sub _load_components { |
54 | my ($class, @comp) = @_; |
55 | foreach my $comp (@comp) { |
c037c03a |
56 | $class->ensure_class_loaded($comp); |
227d4dee |
57 | } |
58 | $class->inject_base($class => @comp); |
59 | } |
60 | |
efe6365b |
61 | # Given a class name, tests to see if it is already loaded or otherwise |
62 | # defined. If it is not yet loaded, the package is require'd, and an exception |
63 | # is thrown if the class is still not loaded. |
64 | # |
c037c03a |
65 | # TODO: handle ->has_many('rel', 'Class'...) instead of |
66 | # ->has_many('rel', 'Some::Schema::Class'...) |
67 | sub ensure_class_loaded { |
68 | my ($class, $f_class) = @_; |
69 | eval "require $f_class"; |
70 | my $err = $@; |
71 | Class::Inspector->loaded($f_class) |
efe6365b |
72 | or $class->throw_exception($err || "`require $f_class' was successful". |
73 | "but the package is not defined"); |
74 | } |
75 | |
76 | # Returns true if the specified class is installed or already loaded, false |
77 | # otherwise |
78 | sub ensure_class_found { |
79 | my ($class, $f_class) = @_; |
80 | return Class::Inspector->loaded($f_class) || |
81 | Class::Inspector->installed($f_class); |
82 | } |
83 | |
84 | # Returns a true value if the specified class is installed and loaded |
85 | # successfully, throws an exception if the class is found but not loaded |
86 | # successfully, and false if the class is not installed |
87 | sub load_optional_class { |
88 | my ($class, $f_class) = @_; |
89 | if ($class->ensure_class_found($f_class)) { |
90 | $class->ensure_class_loaded($f_class); |
91 | return 1; |
92 | } else { |
93 | return 0; |
94 | } |
c037c03a |
95 | } |
96 | |
227d4dee |
97 | 1; |