Commit | Line | Data |
113354d6 |
1 | package # hide from PAUSE |
2 | Catalyst::Model::DBIC::Schema::Types; |
0fbbc8d5 |
3 | |
4cbe63e7 |
4 | use MooseX::Types -declare => [qw/ |
45b10191 |
5 | ConnectInfo ConnectInfos Replicants SchemaClass CreateOption |
d9bff0e4 |
6 | Schema LoadedClass |
4cbe63e7 |
7 | /]; |
0fbbc8d5 |
8 | |
bd309c0c |
9 | use Carp::Clan '^Catalyst::Model::DBIC::Schema'; |
2fa0a1f1 |
10 | use MooseX::Types::Moose qw/ArrayRef HashRef CodeRef Str ClassName/; |
45b10191 |
11 | use MooseX::Types::LoadableClass qw/LoadableClass/; |
0fbbc8d5 |
12 | use Scalar::Util 'reftype'; |
c4fee9b8 |
13 | use List::MoreUtils 'all'; |
d9bff0e4 |
14 | use Module::Runtime; |
0fbbc8d5 |
15 | |
16 | use namespace::clean -except => 'meta'; |
17 | |
d9bff0e4 |
18 | # So I restored the custom Type LoadedClass because 'LoadableClass' doesn't really |
19 | # exactly do the same thing, which busted the Replication trait. Please don't |
20 | # "clean this up" -JNAP |
21 | |
22 | subtype LoadedClass, |
23 | as ClassName; |
24 | |
25 | coerce LoadedClass, |
26 | from Str, # N.B. deliberate paranoia against $_ clobbering below |
27 | via { my $classname = $_; Module::Runtime::use_module($classname); $classname }; |
28 | |
2fa0a1f1 |
29 | subtype SchemaClass, |
45b10191 |
30 | as LoadableClass, |
2fa0a1f1 |
31 | where { $_->isa('DBIx::Class::Schema') }; |
32 | |
d816d7bf |
33 | class_type Schema, { class => 'DBIx::Class::Schema' }; |
34 | |
0fbbc8d5 |
35 | subtype ConnectInfo, |
36 | as HashRef, |
2fa0a1f1 |
37 | where { exists $_->{dsn} || exists $_->{dbh_maker} }, |
0fbbc8d5 |
38 | message { 'Does not look like a valid connect_info' }; |
39 | |
40 | coerce ConnectInfo, |
41 | from Str, |
7b1fe8c2 |
42 | via(\&_coerce_connect_info_from_str), |
0fbbc8d5 |
43 | from ArrayRef, |
2fa0a1f1 |
44 | via(\&_coerce_connect_info_from_arrayref), |
45 | from CodeRef, |
46 | via { +{ dbh_maker => $_ } }, |
47 | ; |
0fbbc8d5 |
48 | |
49 | # { connect_info => [ ... ] } coercion would be nice, but no chained coercions |
c4fee9b8 |
50 | # yet. |
51 | # Also no coercion from base type (yet,) but in Moose git already. |
0fbbc8d5 |
52 | # from HashRef, |
53 | # via { $_->{connect_info} }, |
54 | |
c4fee9b8 |
55 | subtype ConnectInfos, |
56 | as ArrayRef[ConnectInfo], |
57 | message { "Not a valid array of connect_info's" }; |
58 | |
59 | coerce ConnectInfos, |
60 | from Str, |
2fa0a1f1 |
61 | via { [ _coerce_connect_info_from_str() ] }, |
62 | from CodeRef, |
63 | via { [ +{ dbh_maker => $_ } ] }, |
61fed351 |
64 | from HashRef, |
65 | via { [ $_ ] }, |
7b1fe8c2 |
66 | from ArrayRef, |
67 | via { [ map { |
68 | !ref $_ ? _coerce_connect_info_from_str() |
69 | : reftype $_ eq 'HASH' ? $_ |
2fa0a1f1 |
70 | : reftype $_ eq 'CODE' ? +{ dbh_maker => $_ } |
7b1fe8c2 |
71 | : reftype $_ eq 'ARRAY' ? _coerce_connect_info_from_arrayref() |
2fa0a1f1 |
72 | : croak 'invalid connect_info' |
7b1fe8c2 |
73 | } @$_ ] }; |
c4fee9b8 |
74 | |
4cbe63e7 |
75 | # Helper stuff |
76 | |
77 | subtype CreateOption, |
78 | as Str, |
79 | where { /^(?:static|dynamic)\z/ }, |
80 | message { "Invalid create option, must be one of 'static' or 'dynamic'" }; |
81 | |
c4fee9b8 |
82 | sub _coerce_connect_info_from_arrayref { |
83 | my %connect_info; |
84 | |
7b1fe8c2 |
85 | # make a copy |
86 | $_ = [ @$_ ]; |
87 | |
2fa0a1f1 |
88 | my $slurp_hashes = sub { |
c4fee9b8 |
89 | for my $i (0..1) { |
90 | my $extra = shift @$_; |
91 | last unless $extra; |
2fa0a1f1 |
92 | croak "invalid connect_info" |
93 | unless ref $extra && reftype $extra eq 'HASH'; |
c4fee9b8 |
94 | |
95 | %connect_info = (%connect_info, %$extra); |
96 | } |
2fa0a1f1 |
97 | }; |
c4fee9b8 |
98 | |
2fa0a1f1 |
99 | if (!ref $_->[0]) { # array style |
100 | $connect_info{dsn} = shift @$_; |
101 | $connect_info{user} = shift @$_ if !ref $_->[0]; |
102 | $connect_info{password} = shift @$_ if !ref $_->[0]; |
103 | |
104 | $slurp_hashes->(); |
105 | |
106 | croak "invalid connect_info" if @$_; |
107 | } elsif (ref $_->[0] && reftype $_->[0] eq 'CODE') { |
108 | $connect_info{dbh_maker} = shift @$_; |
109 | |
110 | $slurp_hashes->(); |
111 | |
112 | croak "invalid connect_info" if @$_; |
113 | } elsif (@$_ == 1 && ref $_->[0] && reftype $_->[0] eq 'HASH') { |
c4fee9b8 |
114 | return $_->[0]; |
115 | } else { |
2fa0a1f1 |
116 | croak "invalid connect_info"; |
c4fee9b8 |
117 | } |
118 | |
2fa0a1f1 |
119 | unless ($connect_info{dbh_maker}) { |
120 | for my $key (qw/user password/) { |
121 | $connect_info{$key} = '' |
122 | if not defined $connect_info{$key}; |
123 | } |
7b1fe8c2 |
124 | } |
125 | |
c4fee9b8 |
126 | \%connect_info; |
127 | } |
128 | |
7b1fe8c2 |
129 | sub _coerce_connect_info_from_str { |
130 | +{ dsn => $_, user => '', password => '' } |
131 | } |
132 | |
0fbbc8d5 |
133 | 1; |