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