The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

DBIx::DataModel::Meta::Association - meta-information about an association

SYNOPSIS

  # create the assoc.; best called through $meta_schema->define_association(..)
  my $association = new (
    schema => $meta_schema,
    A      => {
      table        => $meta_table_instance,
      role         => $role_name,         # optional
      multiplicity => $multiplicity_spec, # ex. "1..*"
      join_cols    => [$col1, ...]        # optional
    },
    B      => $B_association_end, # same structure as 'A'
    name   => $association_name, #optional
    kind   => $kind, # one of : Association, Aggregation, Composition
  );

  # example
  my $path = $association->path_AB;
  # 

DESCRIPTION

An instance of this class represents a UML association between two instances of DBIx::DataModel::Meta::Source::Table.

The association also creates instances of DBIx::DataModel::Meta::Path for representing the directional paths between those sources. Perl methods are created within the DBIx::DataModel::Meta::Path class, so Perl symbol tables are not touched by the present class.

PUBLIC METHODS

new

Constructor method. Normally this will be called indirectly through

  $meta_schema->define_association(%args)

because the "define_association" in DBIx::DataModel::Meta::Schema method automatically adds its own invocant (the $meta_schema) into %args.

Named arguments to new() are :

schema

An instance of DBIx::DataModel::Meta::Schema.

A

A description of the first association end, which is composed of

table

An instance of DBIx::DataModel::Meta::Source::Table.

role

The role name of that source within the association. A Perl method of the same name will be defined in the remote source (the other end of the association). Besides, the role name is also used when building joins through

  $schema->join(qw/FirstTable role1 role2 .../)

One of the role names in the association can be anonymous (undef), but not both. If anonymous, there will be no Perl method and no possibility to join in that direction, so it defines a unidirectional association.

multiplicity

The multiplicity specification, i.e. the minimum and maximum number of occurrences of that association end, for any given instance of the other end (if not clear, see UML textbooks).

The multiplicity can be expressed either as an arrayref [$min, $max], or as a string "$min..$max". The $max can be '*' or 'n', which is interpreted as the maximum integer value. If expressed as a string, a mere '*' is interpreted as '0..*', and a mere '1' is interpreted as '1..1'.

join_cols

An arrayref of columns that participate in the database join, for this side of the association. The full database join will be built by creating a LEFT|INNER JOIN ... ON .. clause in which the left-hand and right-hand sides of the ON subclause come from the join_cols of both association ends.

This argument is optional: if absent, it will be filled by default by taking the primary key of the table with minimum multiplicity 1, for both sides of the association.

If the association is many-to-many (i.e. if the maximum multiplicity is greater than 1 on both sides), then join_cols takes a special meaning : it no longer represents database columns, but rather represents two role names (in the sense just defined above) to follow for reaching the remote end of the association. Therefore join_cols must contain exactly 2 items in that case : the path to the intermediate table, and the path from the intermediate table to the remote end. Here is again the example from "SYNOPSIS" in DBIx::DataModel :

  My::Schema->define_association(
    kind => 'Association',
    A    => {
      table        => My::Schema::Department->metadm,
      role         => 'departments',
      multiplicity => '*',
      join_cols    => [qw/activities department/],
    },
    B    => {
      table        => My::Schema::Employee->metadm,
      role         => 'employees',
      multiplicity => '*',
      join_cols    => [qw/activities employee/],
    },
  );
B

A description of the second association end, following exactly the same principles as for the 'A' end.

name

Optional name for the association (otherwise an implicit name will be built by default from the concatenation of the role names).

kind

A string describing the association kind, i.e. one of : Association, Aggregation or Composition.

Special behaviour is attached to the kind Composition :

  • the multiplicity must be 1-to-n

  • the 'B' end of the association (the "component" part) must not be component of another association (it can only be component of one single composite table).

  • this association can be used for auto-expanding the composite object (i.e. automatically fetching all component parts from the database) -- see "expand" in DBIx::DataModel::Source and "auto_expand" in DBIx::DataModel::Source

  • this association can be used for cascaded inserts like

      $source->insert({
        column1 => $val1,
        ...
        $component_name1 => [{$sub_object1}, ...],
        ...
       })

    see "insert" in DBIx::DataModel::Source

schema

returns the $meta_schema to which this association belongs

A

hashref decribing the 'A' end of the association

B

hashref decribing the 'B' end of the association

path_AB

An instance of DBIx::DataModel::Meta::Path for the path from A to B within this association (if any).

path_BA

An instance of DBIx::DataModel::Meta::Path for the path from B to A within this association (if any).

name

The association name.

kind

The association kind.

PRIVATE METHODS

_parse_multiplicity

For multiplicities given as strings, parse into an arrayref [$min, $max], including the rules for shorthands '*' and '1', as described above.

_install_path

Implementation for regular associations (1-to-n or 1-to-1): create a DBIx::DataModel::Meta::Path object from one side to the other.

_install_many_to_many

Implementation for many-to-many associations : just create navigation methods from one side to the other, relying on pre-existing paths through the intermediate table.

_check_composition

Checks that special conditions on compositions (described above) are fullfilled.