annotate lib/IMPL/ORM/Object.pm @ 416:cc2cf8c0edc2 ref20150831

sync
author cin
date Thu, 29 Oct 2015 03:50:25 +0300
parents c6e90e02dd17
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
407
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
1 package IMPL::ORM::Object;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
2 use strict;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
3 use warnings;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
4
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
5 use parent qw(IMPL::Object);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
6 use IMPL::Class::Property;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
7
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
8 require IMPL::ORM::Entity;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
9 require IMPL::ORM::Schema::Entity;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
10 require IMPL::ORM::Schema::Field;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
11 require IMPL::ORM::Schema::Relation::HasMany;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
12 require IMPL::ORM::Schema::Relation::HasOne;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
13 require IMPL::ORM::Schema::Relation::Subclass;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
14
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
15 BEGIN {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
16 private _direct property _entities => prop_all;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
17 public property objectType => prop_all, {type => 'String'};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
18
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
19 sub _PropertyImplementor {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
20 'IMPL::ORM::PropertyImplementor'
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
21 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
22 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
23
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
24 my %schemaCache;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
25
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
26 sub CTOR {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
27 my ($this) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
28
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
29 while ( my ($class,$schema) = $this->ormGetSchema ) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
30 $this->{$_entities}{$class} = new IMPL::ORM::Entity($class,$schema);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
31 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
32 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
33
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
34 sub ormStore {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
35 my ($this,$class,$prop,$value) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
36
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
37 die IMPL::InvalidOperationException("Cannot find entity for the specified class",$class) unless $this->{$_entities}{$class};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
38
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
39 $this->{$_entities}{$class}->Store($prop,$value);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
40 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
41
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
42 sub ormGet {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
43 my ($this,$class,$prop,$value) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
44
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
45 return $this->{$_entities}{$class} ? $this->{$_entities}{$class}->Get($prop,$value) : undef;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
46 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
47
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
48 sub entityName {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
49 (my $self = ref $_[0] || $_[0]) =~ s/^.*?(\w+)$/$1/;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
50 return $self;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
51 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
52
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
53 sub ormGetSchema {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
54 my ($self,$dataSchema,$surrogate) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
55
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
56 my $schema = $surrogate || IMPL::ORM::Schema::Entity->new($self->entityName);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
57
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
58 # для текущего класса, проходим по всем свойствам
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
59 foreach my $ormProp (
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
60 $self->get_meta(
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
61 'IMPL::Class::PropertyInfo',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
62 sub {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
63 UNIVERSAL::isa($_->Implementor, 'IMPL::ORM::PropertyImplementor' )
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
64 },
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
65 0
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
66 )
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
67 ){
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
68 if ($ormProp->Mutators & prop_list) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
69 # отношение 1 ко многим
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
70 my $type = $dataSchema->resolveType($ormProp->Type) or die new IMPL::InvalidOperationException("Failed to resolve a reference type due building schema for a class", $ormProp->Class, $ormProp->Name);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
71 $schema->appendChild( new IMPL::ORM::Schema::Relation::HasMany($ormProp->Name, $type->entityName) );
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
72 } elsif (my $type = $dataSchema->isValueType($ormProp->Type)) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
73 # поле
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
74 $schema->appendChild( new IMPL::ORM::Schema::Field($ormProp->Name,$ormProp->Type) );
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
75 } elsif (my $entity = $dataSchema->resolveType($ormProp->Type)) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
76 # отношение ссылка
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
77 $schema->appendChild( new IMPL::ORM::Schema::Relation::HasOne($ormProp->Name,$entity->entityName));
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
78 } else {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
79 # хз что. Скорее всего не удалось квалифицировать тип свойства не как ссылочный и как поле.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
80 die new IMPL::Exception('Uexpected error due building schema for a class', $ormProp->Class, $ormProp->Name,$ormProp->Type);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
81 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
82 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
83
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
84 # Формируем отношения наследования
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
85 {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
86 # локализуем прагму
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
87 no strict 'refs';
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
88
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
89 my $class = ref $self || $self;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
90
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
91 # по всем классам
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
92 foreach my $super (grep $_->isa(__PACKAGE__), @{"${class}::ISA"}) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
93 my $type = $dataSchema->resolveType($super) or die new IMPL::InvalidOperationException("Failed to resolve a super class due building schema for a class", $class, $super);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
94 $schema->appendChild(new IMPL::ORM::Schema::Relation::Subclass($type));
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
95 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
96 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
97
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
98 return $schema;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
99 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
100
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
101 1;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
102
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
103 __END__
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
104
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
105 =pod
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
106
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
107 =head1 DESCRIPTION
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
108
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
109 Базовый объект для реляционного отображения,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
110 содержит в себе реляционные записи представляющие данный объект.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
111
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
112 Каждый класс отображается в определенную сущность. Сущности хранят
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
113 состояние объектов в том виде в котором удобно записывать в реляционную базу.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
114
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
115 =cut