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