annotate lib/IMPL/ORM/Schema.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::Schema;
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::DOM::Document);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
6 use IMPL::Class::Property;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
7 require IMPL::ORM::Schema::Entity;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
8 require IMPL::ORM::Schema::ValueType;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
9
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
10 our %CTOR = (
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
11 'IMPL::DOM::Document' => sub { nodeName => 'ORMSchema' }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
12 );
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
13
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
14 BEGIN {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
15 public property mapValueTypes => prop_get | owner_set;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
16 public property mapReferenceTypes => prop_get | owner_set;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
17 public property mapPending => prop_get | owner_set;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
18 public property prefix => prop_get | owner_set;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
19 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
20
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
21 sub CTOR {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
22 my ($this ) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
23 $this->mapValueTypes({});
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
24 $this->mapReferenceTypes({});
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
25 $this->mapPending({});
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
26 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
27
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
28 # return an entity for the specified typename
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
29 # makes forward declaration if nesessary
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
30 sub resolveType {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
31 my ($this,$typeName) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
32
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
33 $this = ref $this ? $this : $this->instance;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
34
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
35 if (my $entity = $this->mapReferenceTypes->{$typeName}) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
36 return $entity;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
37 } elsif (UNIVERSAL::isa($typeName,'IMPL::ORM::Object')) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
38 return $this->declareReferenceType($typeName);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
39 } else {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
40 return undef;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
41 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
42 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
43
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
44 sub declareReferenceType {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
45 my ($this,$typeName) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
46
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
47 my $entity = new IMPL::ORM::Schema::Entity($typeName->entityName);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
48
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
49 $this->mapPending->{$typeName} = $entity;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
50
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
51 $this->appendChild($entity);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
52
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
53 return $this->mapReferenceTypes->{$typeName} = $entity;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
54 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
55
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
56 sub _addReferenceType {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
57 my ($this,$className) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
58
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
59 if ( my $entity = delete $this->mapPending->{$className} ) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
60 $className->ormGetSchema($this,$entity);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
61 } else {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
62 return $this->appendChild( $this->mapReferenceTypes->{$className} = $className->ormGetSchema($this) );
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
63 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
64
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
65 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
66
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
67 # returns valuetype name
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
68 sub isValueType {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
69 my ($this,$typeName) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
70
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
71 $this = ref $this ? $this : $this->instance;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
72
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
73 return $this->mapValueTypes->{$typeName};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
74 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
75
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
76 my %instances;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
77 sub instance {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
78 my ($class) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
79
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
80 return ($instances{$class} || ($instances{$class} = $class->new));
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 sub ValueTypes {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
84 my ($this,%classes) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
85
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
86 $this = ref $this ? $this : $this->instance;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
87
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
88 while ( my ($typeName,$typeReflected) = each %classes ) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
89 $this->mapValueTypes->{$typeName} = $typeReflected;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
90 $this->appendChild(IMPL::ORM::Schema::ValueType->new($typeName,$typeReflected));
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
91 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
92 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
93
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
94 sub Classes {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
95 my ($this,@classNames) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
96
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
97 $this = ref $this ? $this : $this->instance;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
98
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
99 $this->_addReferenceType($this->prefix . $_) foreach @classNames;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
100 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
101
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
102 sub usePrefix {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
103 my ($this,$prefix) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
104
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
105 $prefix .= '::' if $prefix and $prefix !~ /::$/;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
106
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
107 (ref $this ? $this : $this->instance)->prefix($prefix);
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 sub CompleteSchema {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
111 my ($this) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
112
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
113 $this = ref $this ? $this : $this->instance;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
114
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
115 $_->ormGetSchema($this,delete $this->mapPending->{$_}) foreach (keys %{$this->mapPending});
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
116 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
117
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
118 1;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
119
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
120 __END__
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
121
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
122 =pod
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
123
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
124 =head1 NAME
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
125
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
126 C<IMPL::ORM::Schema> Схема отображения классов в реляционную структуру.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
127
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
128 =head1 DESCRIPTION
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
129
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
130 Схема данных, представляет собой DOM документ, элементами которой
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
131 являются сущности.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
132
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
133 Каждый узел - это описание сущности.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
134
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
135 =begin code xml
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
136
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
137 <Schema>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
138 <Entity entityName="My_Data_Foo">
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
139 <Field fieldName="Doo" fieldType="String"/>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
140 <HasMany name="Boxes" target="My_Data_Box"/>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
141 </Entity>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
142 <Entity entityName="My_Data_Bar">
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
143 <Subclass base="My_Data_Foo"/>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
144 <Field fieldName="Timestamp" fieldType="Integer"/>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
145 </Entity>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
146 <Entity entityName="My_Data_Box">
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
147 <Field fieldName="Capacity" fieldType="Integer"/>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
148 </Entity>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
149 </Schema>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
150
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
151 =end code xml
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
152
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
153 =cut