| Persistence-Entity documentation | Contained in the Persistence-Entity distribution. |
Persistence::Relationship::ManyToMany - Many to many relationship
Persistence::Relationship
|
+----Persistence::Relationship::ManyToMany
use Persistence::Relationship::ManyToMany ':all';
#.... entities definition
my $entity_manager = Persistence::Entity::Manager->new(name => 'my_manager', connection_name => 'test');
my $emp_project_entity = Persistence::Entity->new(
name => 'emp_project',
alias => 'ep',
primary_key => ['projno', 'empno'],
columns => [
sql_column(name => 'projno'),
sql_column(name => 'empno'),
sql_column(name => 'leader'),
],
);
my $emp_entity = Persistence::Entity->new(
name => 'emp',
alias => 'ep',
primary_key => ['empno'],
columns => [
sql_column(name => 'empno'),
sql_column(name => 'ename', unique => 1),
sql_column(name => 'job'),
sql_column(name => 'deptno'),
],
value_generators => {empno => 'emp_gen'},
to_many_relationships => [
sql_relationship(target_entity => $emp_project_entity,
join_columns => ['empno'], order_by => 'empno, projno')
]
);
my $project_entity = Persistence::Entity->new(
name => 'project',
alias => 'pr',
primary_key => ['projno'],
columns => [
sql_column(name => 'projno'),
sql_column(name => 'name', unique => 1),
],
value_generators => {projno => 'project_gen'},
to_many_relationships => [
sql_relationship(target_entity => $emp_project_entity,
join_columns => ['projno'], order_by => 'projno, empno')
]
);
$entity_manager->add_entities($emp_project_entity, $emp_entity, $project_entity);
# object mapping
package Project;
use Abstract::Meta::Class ':all';
use Persistence::Entity ':all';
use Persistence::ORM ':all';
entity 'project';
column projno => has('$.id');
column name => has('$.name');
package Employee;
use Abstract::Meta::Class ':all';
use Persistence::Entity ':all';
use Persistence::ORM ':all';
entity 'emp';
column empno=> has('$.id');
column ename => has('$.name');
column job => has '$.job';
many_to_many 'project' => (
attribute => has('%.projects' => (associated_class => 'Project'), index_by => 'name'),
join_entity_name => 'emp_project',
fetch_method => LAZY,
cascade => ALL,
);
Represents many to many relationship. Supports eager, lazy fetch, cascading operation (inert/update/delete).
many_to_many by ':all' tag.
Join entity name.
Deserialises relation attribute
Inserts relationship data.
Merges relationship data.
Deletes many to many association.
The Persistence::ManyToManyRelationship module is free software. You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.
Adrian Witas, adrian@webapp.strefa.pl
| Persistence-Entity documentation | Contained in the Persistence-Entity distribution. |
package Persistence::Relationship::ManyToMany; use strict; use warnings; use vars qw(@EXPORT_OK %EXPORT_TAGS $VERSION); use Abstract::Meta::Class ':all'; use base qw (Exporter Persistence::Relationship); use Carp 'confess'; $VERSION = 0.01; @EXPORT_OK = qw(many_to_many); %EXPORT_TAGS = (all => \@EXPORT_OK);
has '$.join_entity_name' => (required => 1);
sub many_to_many { my $package = caller(); __PACKAGE__->add_relationship($package, @_); }
sub deserialise_attribute { my ($self, $object, $entity_manager, $orm) = @_; my $entity = $entity_manager->entity($orm->entity_name); my $target_entity = $entity_manager->entity($self->name) or confess "cant find entity" . $self->name; my $join_entity = $entity_manager->entity($self->join_entity_name); my $relation = $entity->to_many_relationship($self->join_entity_name); my %fields_values = $orm->column_values($object); my %join_values = $entity->_join_columns_values($relation, \%fields_values); return unless(map {$join_values{$_} ? ($_) : () } keys %join_values); my $condition = SQL::Entity::Condition->struct_to_condition(map {$join_entity->column($_), $join_values{$_}} keys %join_values); my $attribute = $self->attribute; my @rows = $target_entity->find($attribute->associated_class, $condition); if (@rows) { my $mutator = $attribute->mutator; $object->$mutator(\@rows); } }
sub insert { my ($self, $orm, $entity, $unique_values, $object) = @_; $self->_associate_relationship_data($orm, $entity, $unique_values, $object, 'insert'); }
sub merge { my ($self, $orm, $entity, $unique_values, $object) = @_; $self->_associate_relationship_data($orm, $entity, $unique_values, $object, 'merge'); }
sub delete { my ($self, $orm, $entity, $unique_values, $object) = @_; my $join_entity_name = $self->join_entity_name; my $attribute = $self->attribute; my $values = $self->values($object); my $entity_manager = $entity->entity_manager; my $target_entity = $entity_manager->entity($self->name); my $reflective_orm = $entity_manager->find_entity_mappings($attribute->associated_class); my $join_values = $orm->join_columns_values($entity, $join_entity_name, $object); my $join_entity = $entity_manager->entity($join_entity_name); foreach my $association_object (@$values) { $join_entity->delete( %$join_values, $reflective_orm->join_columns_values($target_entity, $join_entity_name, $association_object) ); } }
sub _associate_relationship_data { my ($self, $orm, $entity, $unique_values, $object, $operation) = @_; my $join_entity_name = $self->join_entity_name; my $attribute = $self->attribute; my $values = $self->values($object); my $entity_manager = $entity->entity_manager; my $target_entity = $entity_manager->entity($self->name); my $reflective_orm = $entity_manager->find_entity_mappings($attribute->associated_class); my $join_values = $orm->join_columns_values($entity, $join_entity_name, $object); my $reflective_relation = $target_entity->to_many_relationship($join_entity_name); my $join_entity = $entity_manager->entity($join_entity_name); foreach my $association_object (@$values) { $entity_manager->merge($association_object); $join_entity->$operation( %$join_values, $reflective_orm->join_columns_values($target_entity, $join_entity_name, $association_object) ); } } 1; __END__
1;