annotate Lib/Schema/DataSource/CDBIBuilder.pm @ 31:d59526f6310e

Small fixes to Test framework (correct handlinf of the compilation errors in the test units) Imported and refactored SQL DB schema from the old project
author Sergey
date Mon, 09 Nov 2009 01:39:16 +0300
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;