DBIx-DataModel

 view release on metacpan or  search on metacpan

lib/DBIx/DataModel/Meta/Path.pm  view on Meta::CPAN

package DBIx::DataModel::Meta::Path;
use strict;
use warnings;
use parent "DBIx::DataModel::Meta";
use DBIx::DataModel;
use DBIx::DataModel::Meta::Utils qw/define_readonly_accessors/;
use DBIx::DataModel::Carp;

use Scalar::Util                 qw/looks_like_number weaken/;
use Params::Validate             qw/validate_with SCALAR HASHREF ARRAYREF OBJECT/;
use namespace::clean;

{no strict 'refs'; *CARP_NOT = \@DBIx::DataModel::CARP_NOT;}

my $path_spec = {
  name         => {type => SCALAR},
  from         => {isa  => 'DBIx::DataModel::Meta::Source::Table'},
  to           => {isa  => 'DBIx::DataModel::Meta::Source::Table'},
  on           => {type => HASHREF}, # join condition
  multiplicity => {type => ARRAYREF},
  association  => {type => OBJECT,
                   isa  => "DBIx::DataModel::Meta::Association"},
  direction    => {type => SCALAR, regex => qr/^(AB|BA)$/},
};

sub new {
  my $class = shift;

  # parse arguments and create $self
  my $self = validate_with(
    params      => \@_,
    spec        => $path_spec,
    allow_extra => 0,
   );

  my $path = $self->{name};
  weaken $self->{$_} for qw/from to association/;

  # add this path into the 'from' metaclass
  not $self->{from}{path}{$path}
    or croak "$self->{from}{class} already has a path '$path'";
  $self->{from}{path}{$path} = $self;

  # if this is a composition path, remember it in the 'components' array
  push @{$self->{from}{components}}, $path
    if $self->{association}{kind} eq 'Composition' && $self->{direction} eq 'AB';

  # install a navigation method into the 'from' table class
  my @navigation_args = ($self->{name},  # method name
                         $self->{name}); # path to follow
  push @navigation_args, {-result_as => "firstrow"}
    if $self->{multiplicity}[1] == 1;
  $self->{from}->define_navigation_method(@navigation_args);

  bless $self, $class;
}

define_readonly_accessors(__PACKAGE__, keys %$path_spec);


sub opposite {
  my $self = shift;
  my $opposite_direction = reverse $self->direction;
  my $opposite_path      = "path_".$opposite_direction;
  return $self->association->$opposite_path;
}


1;


__END__

=head1 NAME

DBIx::DataModel::Meta::Path - meta-information about a path

=head1 SYNOPSIS

  # create the path; best called through $assoc->_install_path(...)
  my $path = new (
    name         => $role_name,
    from         => $source_meta_table,
    to           => $destination_meta_table,
    on           => \%condition,         # in SQL::Abstract::More format
    multiplicity => [$min, $max],
    association  => $association,
    direction    => $direction,          # either 'AB' or 'BA'
  );

=head1 DESCRIPTION

This class is closely related to L<DBIx::DataModel::Meta::Association>.
A I<path> corresponds to one possible database join between
two tables.

=head1 PUBLIC METHODS



( run in 0.799 second using v1.01-cache-2.11-cpan-39bf76dae61 )