sub
new {
my
(
$class
,
$schema
,
$fk_info
,
$inflect_pl
,
$inflect_singular
) =
@_
;
my
$self
= {
schema
=>
$schema
,
fk_info
=>
$fk_info
,
inflect_plural
=>
$inflect_pl
,
inflect_singular
=>
$inflect_singular
,
};
bless
$self
=>
$class
;
$self
;
}
sub
_inflect_plural {
my
(
$self
,
$relname
) =
@_
;
if
(
ref
$self
->{inflect_plural} eq
'HASH'
) {
return
$self
->{inflect_plural}->{
$relname
}
if
exists
$self
->{inflect_plural}->{
$relname
};
}
elsif
(
ref
$self
->{inflect_plural} eq
'CODE'
) {
my
$inflected
=
$self
->{inflect_plural}->(
$relname
);
return
$inflected
if
$inflected
;
}
return
$self
->{legacy_default_inflections}
? Lingua::EN::Inflect::PL(
$relname
)
: Lingua::EN::Inflect::Number::to_PL(
$relname
);
}
sub
_inflect_singular {
my
(
$self
,
$relname
) =
@_
;
if
(
ref
$self
->{inflect_singular} eq
'HASH'
) {
return
$self
->{inflect_singular}->{
$relname
}
if
exists
$self
->{inflect_singular}->{
$relname
};
}
elsif
(
ref
$self
->{inflect_singular} eq
'CODE'
) {
my
$inflected
=
$self
->{inflect_singular}->(
$relname
);
return
$inflected
if
$inflected
;
}
return
$self
->{legacy_default_inflections}
?
$relname
: Lingua::EN::Inflect::Number::to_S(
$relname
);
}
sub
generate_code {
my
$self
=
shift
;
my
$all_code
= {};
foreach
my
$local_moniker
(
keys
%{
$self
->{fk_info}}) {
my
$local_table
=
$self
->{schema}->source(
$local_moniker
)->from;
my
$local_class
=
$self
->{schema}->class(
$local_moniker
);
my
$rels
=
$self
->{fk_info}->{
$local_moniker
};
my
%counters
;
foreach
my
$rel
(
@$rels
) {
next
if
!
$rel
->{remote_source};
$counters
{
$rel
->{remote_source}}++;
}
foreach
my
$rel
(
@$rels
) {
next
if
!
$rel
->{remote_source};
my
$local_cols
=
$rel
->{local_columns};
my
$remote_cols
=
$rel
->{remote_columns};
my
$remote_moniker
=
$rel
->{remote_source};
my
$remote_obj
=
$self
->{schema}->source(
$remote_moniker
);
my
$remote_class
=
$self
->{schema}->class(
$remote_moniker
);
my
$remote_table
=
$remote_obj
->from;
$remote_cols
||= [
$remote_obj
->primary_columns ];
if
(
$#$local_cols
!=
$#$remote_cols
) {
croak
"Column count mismatch: $local_moniker (@$local_cols) "
.
"$remote_moniker (@$remote_cols)"
;
}
my
%cond
;
foreach
my
$i
(0 ..
$#$local_cols
) {
$cond
{
$remote_cols
->[
$i
]} =
$local_cols
->[
$i
];
}
my
$local_relname
;
if
(
$counters
{
$remote_moniker
} > 1) {
$local_relname
=
$self
->_inflect_plural(
lc
(
$local_table
) .
q{_}
.
join
(
q{_}
,
@$local_cols
)
);
}
else
{
$local_relname
=
$self
->_inflect_plural(
lc
$local_table
);
}
my
$remote_relname
;
if
(
scalar
keys
%cond
== 1) {
my
(
$col
) =
keys
%cond
;
$remote_relname
=
$self
->_inflect_singular(
$cond
{
$col
});
}
else
{
$remote_relname
=
$self
->_inflect_singular(
lc
$remote_table
);
}
my
%rev_cond
=
reverse
%cond
;
for
(
keys
%rev_cond
) {
$rev_cond
{
"foreign.$_"
} =
"self."
.
$rev_cond
{
$_
};
delete
$rev_cond
{
$_
};
}
push
(@{
$all_code
->{
$local_class
}},
{
method
=>
'belongs_to'
,
args
=> [
$remote_relname
,
$remote_moniker
,
\
%cond
,
],
}
);
push
(@{
$all_code
->{
$remote_class
}},
{
method
=>
'has_many'
,
args
=> [
$local_relname
,
$local_moniker
,
\
%rev_cond
,
],
}
);
}
}
return
$all_code
;
}
1;