fixed busted replication trait
[catagits/Catalyst-Model-DBIC-Schema.git] / lib / Catalyst / Model / DBIC / Schema / Types.pm
CommitLineData
113354d6 1package # hide from PAUSE
2 Catalyst::Model::DBIC::Schema::Types;
0fbbc8d5 3
4cbe63e7 4use MooseX::Types -declare => [qw/
45b10191 5 ConnectInfo ConnectInfos Replicants SchemaClass CreateOption
d9bff0e4 6 Schema LoadedClass
4cbe63e7 7/];
0fbbc8d5 8
bd309c0c 9use Carp::Clan '^Catalyst::Model::DBIC::Schema';
2fa0a1f1 10use MooseX::Types::Moose qw/ArrayRef HashRef CodeRef Str ClassName/;
45b10191 11use MooseX::Types::LoadableClass qw/LoadableClass/;
0fbbc8d5 12use Scalar::Util 'reftype';
c4fee9b8 13use List::MoreUtils 'all';
d9bff0e4 14use Module::Runtime;
0fbbc8d5 15
16use 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
22subtype LoadedClass,
23 as ClassName;
24
25coerce LoadedClass,
26 from Str, # N.B. deliberate paranoia against $_ clobbering below
27 via { my $classname = $_; Module::Runtime::use_module($classname); $classname };
28
2fa0a1f1 29subtype SchemaClass,
45b10191 30 as LoadableClass,
2fa0a1f1 31 where { $_->isa('DBIx::Class::Schema') };
32
d816d7bf 33class_type Schema, { class => 'DBIx::Class::Schema' };
34
0fbbc8d5 35subtype ConnectInfo,
36 as HashRef,
2fa0a1f1 37 where { exists $_->{dsn} || exists $_->{dbh_maker} },
0fbbc8d5 38 message { 'Does not look like a valid connect_info' };
39
40coerce 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 55subtype ConnectInfos,
56 as ArrayRef[ConnectInfo],
57 message { "Not a valid array of connect_info's" };
58
59coerce 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
77subtype CreateOption,
78 as Str,
79 where { /^(?:static|dynamic)\z/ },
80 message { "Invalid create option, must be one of 'static' or 'dynamic'" };
81
c4fee9b8 82sub _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 129sub _coerce_connect_info_from_str {
130 +{ dsn => $_, user => '', password => '' }
131}
132
0fbbc8d5 1331;