annotate Lib/Schema/DataSource/CDBIBuilder.pm @ 16:75d55f4ee263

Окончательная концепция описания схем и построения DOM документов
author Sergey
date Tue, 08 Sep 2009 17:29:07 +0400
parents 03e58a454b20
children 16ada169ca75
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
1 use strict;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
2 package Schema::DataSource::CDBIBuilder;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
3 use Schema::DataSource::TypeMapping;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
4 use Common;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
5 our @ISA = qw(Object);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
6
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
7 BEGIN {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
8 DeclareProperty ClassMappings => ACCESS_NONE;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
9 DeclareProperty TypeMapping => ACCESS_READ;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
10 DeclareProperty ValueTypeReflections => ACCESS_READ;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
11 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
12
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
13 sub CTOR {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
14 my ($this,%args) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
15
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
16 $this->{$TypeMapping} = $args{'TypeMapping'} || Schema::DataSource::TypeMapping::Std->new;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
17 $this->{$ValueTypeReflections} = { DateTime => 'DateTime'};
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
18 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
19
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
20 sub ReflectValueType {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
21 my ($this,$Type) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
22 return $this->{$ValueTypeReflections}{$Type->Name->Simple};
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
23 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
24
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
25 sub GetClassMapping {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
26 my ($this,$type) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
27
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
28 if (my $mapping = $this->{$ClassMappings}->{$type->Name->Canonical}) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
29 return $mapping;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
30 } else {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
31 $mapping = new Schema::DataSource::CDBIBuilder::ClassMapping(Class => $type,Parent => $this);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
32 $this->{$ClassMappings}{$type->Name->Canonical} = $mapping;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
33 return $mapping
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
34 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
35 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
36
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
37 sub EnumClassMappings {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
38 my ($this) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
39 return $this->{$ClassMappings} ? values %{$this->{$ClassMappings}} : ();
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
40 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
41
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
42 sub AddType {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
43 my ($this,$type) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
44 $this->GetClassMapping($type);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
45 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
46
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
47 sub BuildDBSchema {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
48 my ($this) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
49
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
50 my $schemaDB = new Schema::DB(Name => 'auto', Version => time);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
51
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
52 if ($this->{$ClassMappings}) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
53 $_->CreateTable($schemaDB) foreach values %{ $this->{$ClassMappings} };
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
54 $_->CreateConstraints($schemaDB) foreach values %{ $this->{$ClassMappings} };
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
55 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
56
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
57 return $schemaDB;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
58 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
59
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
60 sub WriteModules {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
61 my ($this,$fileName,$prefix) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
62
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
63 my $text;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
64 $text = <<ModuleHeader;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
65 #autogenerated script don't edit
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
66 package ${prefix}DBI;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
67 use base 'Class::DBI';
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
68
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
69 require DateTime;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
70
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
71 our (\$DSN,\$User,\$Password,\$Init);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
72 \$DSN ||= 'DBI:null'; # avoid warning
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
73
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
74 __PACKAGE__->connection(\$DSN,\$User,\$Password);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
75
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
76 # initialize
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
77 foreach my \$action (ref \$Init eq 'ARRAY' ? \@{\$Init} : \$Init) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
78 next unless \$action;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
79
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
80 if (ref \$action eq 'CODE') {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
81 \$action->(__PACKAGE__->db_Main);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
82 } elsif (not ref \$action) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
83 __PACKAGE__->db_Main->do(\$action);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
84 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
85 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
86
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
87 ModuleHeader
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
88
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
89 if ($this->{$ClassMappings}) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
90 $text .= join ("\n\n", map $_->GenerateText($prefix.'DBI',$prefix), sort {$a->Class->Name->Canonical cmp $b->Class->Name->Canonical } values %{ $this->{$ClassMappings} } );
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
91 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
92
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
93 $text .= "\n1;";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
94
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
95 open my $out, ">$fileName" or die new Exception("Failed to open file",$fileName,$!);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
96 print $out $text;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
97 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
98
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
99 sub Dispose {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
100 my ($this) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
101
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
102 delete @$this{$ClassMappings,$TypeMapping,$ValueTypeReflections};
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
103
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
104 $this->SUPER::Dispose;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
105 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
106
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
107 package Schema::DataSource::CDBIBuilder::ClassMapping;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
108 use Common;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
109 use Schema;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
110 our @ISA = qw(Object);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
111
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
112 BEGIN {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
113 DeclareProperty Table => ACCESS_READ;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
114 DeclareProperty PropertyTables => ACCESS_READ;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
115 DeclareProperty PropertyMappings => ACCESS_READ;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
116
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
117 DeclareProperty Class => ACCESS_READ;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
118 DeclareProperty Parent => ACCESS_NONE;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
119 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
120
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
121 sub CTOR {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
122 my ($this,%args) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
123
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
124 $this->{$Class} = $args{'Class'} or die new Exception('The class must be specified');
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
125 $this->{$Parent} = $args{'Parent'} or die new Exception('The parent must be specified');
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
126
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
127 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
128
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
129 sub PropertyMapping {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
130 my ($this,%args) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
131 $this->{$PropertyMappings}{$args{'name'}} = { Column => $args{'Column'},DBType => $args{'DBType'} };
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
132 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
133
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
134 sub CreateTable {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
135 my ($this,$schemaDB) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
136
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
137 return if $this->{$Class}->isTemplate or $this->{$Class}->GetAttribute('ValueType') or $this->{$Class}->Name->Simple eq 'Set';
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
138
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
139 # CreateTable
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
140 my $table = $schemaDB->AddTable({Name => $this->{$Class}->Name->Canonical});
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
141 $table->InsertColumn({
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
142 Name => '_id',
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
143 Type => $this->{$Parent}->TypeMapping->DBIdentifierType,
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
144 Tag => ['AUTO_INCREMENT']
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
145 });
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
146 $table->SetPrimaryKey('_id');
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
147 foreach my $prop ( grep { UNIVERSAL::isa($_,'Schema::Property') } $this->{$Class}->ListMembers ) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
148 if ($prop->Type->Name->Name eq 'Set') {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
149 # special case for multiple values
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
150 my $propTable = $this->CreatePropertyTable($schemaDB,$prop);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
151 $propTable->LinkTo($table,'parent');
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
152 } else {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
153 $table->InsertColumn({
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
154 Name => $prop->Name,
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
155 Type => $this->{$Parent}->TypeMapping->MapType($prop->Type),
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
156 CanBeNull => 1
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
157 });
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
158 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
159 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
160 $this->{$Table} = $table;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
161 return $table;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
162 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
163
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
164 sub CreatePropertyTable {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
165 my ($this,$schemaDB,$property) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
166
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
167 my $table = $schemaDB->AddTable({Name => $this->{$Class}->Name->Canonical.'_'.$property->Name});
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
168 $table->InsertColumn({
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
169 Name => '_id',
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
170 Type => $this->{$Parent}->TypeMapping->DBIdentifierType,
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
171 Tag => ['AUTO_INCREMENT']
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
172 });
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
173 $table->SetPrimaryKey('_id');
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
174
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
175 $table->InsertColumn({
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
176 Name => 'parent',
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
177 Type => $this->{$Parent}->TypeMapping->DBIdentifierType
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
178 });
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
179
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
180 $table->InsertColumn({
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
181 Name => 'value',
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
182 Type => $this->{$Parent}->TypeMapping->MapType($property->Type->GetAttribute('TemplateInstance')->{'Parameters'}{'T'}),
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
183 CanBeNull => 1
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
184 });
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
185
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
186 $this->{$PropertyTables}->{$property->Name} = $table;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
187
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
188 return $table;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
189 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
190
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
191 sub CreateConstraints {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
192 my ($this,$schemaDB) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
193 return if $this->{$Class}->isTemplate or $this->{$Class}->GetAttribute('ValueType') or $this->{$Class}->Name->Simple eq 'Set';
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
194
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
195 foreach my $prop ( grep { UNIVERSAL::isa($_,'Schema::Property') } $this->{$Class}->ListMembers ) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
196 if ($prop->Type->Name->Name eq 'Set' ) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
197 # special case for multiple values
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
198 if (not $prop->Type->GetAttribute('TemplateInstance')->{'Parameters'}{'T'}->GetAttribute('ValueType')) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
199 $this->{$PropertyTables}->{$prop->Name}->LinkTo(
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
200 $this->{$Parent}->GetClassMapping($prop->Type->GetAttribute('TemplateInstance')->{'Parameters'}{'T'})->Table,
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
201 'value'
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
202 );
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
203 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
204 } elsif (not $prop->Type->GetAttribute('ValueType')) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
205 $this->{$Table}->LinkTo(
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
206 scalar($this->{$Parent}->GetClassMapping($prop->Type)->Table),
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
207 $prop->Name
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
208 );
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
209 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
210 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
211 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
212
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
213 sub GeneratePropertyTableText {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
214 my ($this,$prop,$baseModule,$prefix) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
215
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
216 my $packageName = $this->GeneratePropertyClassName($prop,$prefix);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
217 my $tableName = $this->{$PropertyTables}->{$prop->Name}->Name;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
218 my $parentName = $this->GenerateClassName($prefix);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
219 my $text .= "package $packageName;\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
220 $text .= "use base '$baseModule';\n\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
221 $text .= "__PACKAGE__->table('`$tableName`');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
222 $text .= "__PACKAGE__->columns(Essential => qw/_id parent value/);\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
223 $text .= "__PACKAGE__->has_a( parent => '$parentName');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
224
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
225 my $typeValue;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
226 if ($prop->Type->Name->Simple eq 'Set') {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
227 $typeValue = $prop->Type->GetAttribute('TemplateInstance')->{'Parameters'}{'T'};
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
228 } else {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
229 $typeValue = $prop->Type;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
230 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
231 if ($typeValue->GetAttribute('ValueType')) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
232 if (my $reflectedClass = $this->{$Parent}->ReflectValueType($typeValue)) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
233 $text .= "__PACKAGE__->has_a( value => '$reflectedClass');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
234 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
235 } else {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
236 my $foreignName = $this->{$Parent}->GetClassMapping($prop->Type->GetAttribute('TemplateInstance')->{'Parameters'}{'T'})->GenerateClassName($prefix);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
237 $text .= "__PACKAGE__->has_a( value => '$foreignName');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
238 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
239
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
240 return $text;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
241 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
242
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
243 sub GeneratePropertyClassName {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
244 my ($this,$prop,$prefix) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
245
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
246 my $packageName = $this->{$Class}->Name->Canonical;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
247 $packageName =~ s/\W//g;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
248 return $prefix.$packageName.$prop->Name.'Ref';
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
249 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
250
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
251 sub GenerateClassName {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
252 my ($this,$prefix) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
253 my $packageName = $this->{$Class}->Name->Canonical;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
254 $packageName =~ s/\W//g;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
255 return $prefix. $packageName;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
256 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
257
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
258 sub GenerateText {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
259 my ($this,$baseModule,$prefix) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
260
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
261 return if $this->{$Class}->isTemplate or $this->{$Class}->GetAttribute('ValueType') or $this->{$Class}->Name->Simple eq 'Set';
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
262
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
263 my @PropertyModules;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
264 my $text;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
265 my $packageName = $this->GenerateClassName($prefix);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
266
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
267 my $tableName = $this->{$Table}->Name;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
268 my $listColumns = join ',', map { '\''. $_->Name . '\''} $this->{$Table}->Columns;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
269
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
270 $text .= "package $packageName;\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
271 $text .= "use base '$baseModule'". ($this->{$Class}->Name->Name eq 'Map' ? ',\'CDBI::Map\'' : '' ).";\n\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
272
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
273 $text .= "__PACKAGE__->table('`$tableName`');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
274 $text .= "__PACKAGE__->columns(Essential => $listColumns);\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
275
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
276 foreach my $prop ( grep { UNIVERSAL::isa($_,'Schema::Property') } $this->{$Class}->ListMembers ) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
277 my $propName = $prop->Name;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
278 if ($prop->Type->Name->Name eq 'Set') {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
279 # has_many
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
280 push @PropertyModules, $this->GeneratePropertyTableText($prop,$baseModule,$prefix);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
281 my $propClass = $this->GeneratePropertyClassName($prop,$prefix);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
282 $text .= <<ACCESSORS;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
283 __PACKAGE__->has_many( ${propName}_ref => '$propClass');
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
284 sub $propName {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
285 return map { \$_->value } ${propName}_ref(\@_);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
286 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
287 sub add_to_$propName {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
288 return add_to_${propName}_ref(\@_);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
289 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
290 ACCESSORS
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
291
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
292 } elsif (not $prop->Type->GetAttribute('ValueType')) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
293 # has_a
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
294 my $ForeignClass = $this->{$Parent}->GetClassMapping($prop->Type)->GenerateClassName($prefix);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
295 $text .= "__PACKAGE__->has_a( $propName => '$ForeignClass');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
296 } else {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
297 if (my $reflectedClass = $this->{$Parent}->ReflectValueType($prop->Type)) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
298 $text .= "__PACKAGE__->has_a( $propName => '$reflectedClass');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
299 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
300 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
301 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
302
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
303 #
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
304 foreach my $descedantMapping (grep {$_->{$Class}->isType($this->{$Class},1)} $this->{$Parent}->EnumClassMappings) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
305 next if $descedantMapping == $this;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
306 $text .= "__PACKAGE__->might_have('m".$descedantMapping->GenerateClassName('')."' => '".$descedantMapping->GenerateClassName($prefix)."');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
307 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
308
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
309 # ,
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
310 # : refererClassProp
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
311 foreach my $referer (grep {not $_->Class->isTemplate} $this->{$Parent}->EnumClassMappings) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
312 next if $referer == $this;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
313 foreach my $prop ( grep { $_->isa('Schema::Property') } $referer->{$Class}->ListMembers ) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
314 if($prop->Type->Equals($this->{$Class})) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
315 $text .= "__PACKAGE__->has_many('referer".$referer->GenerateClassName('').$prop->Name."' => '".$referer->GenerateClassName($prefix)."','".$prop->Name."');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
316 } elsif ($prop->Type->Name->Name eq 'Set' and $this->{$Class}->Equals($prop->Type->GetAttribute('TemplateInstance')->{'Parameters'}{'T'}) ) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
317 # $prop->Type
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
318 $text .= "__PACKAGE__->has_many('referer".$referer->GeneratePropertyClassName($prop,'')."value' => '".$referer->GeneratePropertyClassName($prop,$prefix)."','value');\n";
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
319 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
320 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
321 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
322
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
323 return (@PropertyModules,$text);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
324 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
325
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
326 1;