annotate Lib/Schema/DataSource.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 package Configuration;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
2 our $DataDir;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
3 package Schema::DataSource;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
4 use Common;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
5 use strict;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
6 use base qw(Object);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
7
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
8 use BNFCompiler;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
9 use Schema::DB;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
10 use Schema;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
11 use URI::file;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
12
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
13 BEGIN {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
14 DeclareProperty ProcessedSchemas => ACCESS_NONE; #{ uri => schema }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
15 DeclareProperty Types => ACCESS_READ; # Schema
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
16 DeclareProperty DataSourceBuilder => ACCESS_READ;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
17 DeclareProperty Compiler => ACCESS_NONE;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
18 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
19
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
20 sub CTOR {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
21 my ($this,%args) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
22
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
23 $this->{$DataSourceBuilder} = $args{'DataSourceBuilder'} or die new Exception('A data source builder is required');
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
24 $this->{$Types} = new Schema;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
25 $this->{$Compiler} = new BNFCompiler(SchemaCache => "${DataDir}Cache/",Transform => sub { BNFCompiler::DOM::TransformDOMToHash(@_,{skip_spaces => 1})} );
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
26 $this->{$Compiler}->LoadBNFSchema(file => 'Schema/schema.def');
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
27 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
28
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
29 sub as_list {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
30 return( map { UNIVERSAL::isa($_,'ARRAY') ? @{$_} : defined $_ ? $_ : () } @_ );
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
31 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
32
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
33 sub ProcessSchema {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
34 my ($this,$uriFile) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
35
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
36 return 1 if $this->{$ProcessedSchemas}{$uriFile->as_string};
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
37
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
38 my $uriDir = URI::file->new('./')->abs($uriFile);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
39 $this->{$ProcessedSchemas}->{$uriFile->as_string} = 1;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
40
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
41 my $Schema = $this->ParseSchema($uriFile);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
42
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
43 foreach my $item (as_list($Schema->{'header'}{'include_item'})) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
44 my $uriItem = URI::file->new($item->{'file_name'})->abs($uriDir);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
45 $this->ProcessSchema($uriItem);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
46 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
47
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
48 $this->ConstructTypes($Schema);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
49
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
50 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
51
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
52 sub ParseSchema {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
53 my ($this,$fileUri) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
54
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
55 my $fileName = $fileUri->file;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
56 open my $hfile,"$fileName" or die new Exception('Failed to read the file',$fileName,$!);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
57 local $/ = undef;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
58 my $Schema = $this->{$Compiler}->Parse(<$hfile>);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
59
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
60 return $Schema;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
61 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
62
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
63 sub ConstructTypes {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
64 my ($this,$schema) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
65 return if not $schema->{'class'};
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
66
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
67 foreach my $class (as_list($schema->{'class'})){
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
68 #
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
69 my $type;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
70 my $builder;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
71 if ($class->{'type_definition'}{'args_list'}) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
72 $type = $this->{$Types}->CreateTemplate($class->{'type_definition'}{'name'},as_list($class->{'type_definition'}{'args_list'}{'name'}));
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
73 } else {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
74 $type = $this->{$Types}->CreateType($class->{'type_definition'}{'name'});
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
75 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
76
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
77 $type->SetAttributes(ValueType => 1) if $class->{'value_type'};
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
78
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
79 my $mappingTip = $this->{$DataSourceBuilder}->GetClassMapping($type);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
80
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
81
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
82 #
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
83
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
84 if ($class->{'base_types'}) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
85 foreach my $typename (as_list($class->{'base_types'}{'type'})) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
86 $type->AddBase(MakeTypeName($typename));
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
87 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
88 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
89
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
90 #
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
91 if ($class->{'property_list'}) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
92 foreach my $property (as_list($class->{'property_list'}{'property'})) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
93 $type->InsertProperty($property->{'name'},MakeTypeName($property->{'type'}));
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
94 if (my $mapping = $property->{'mapping'}) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
95 $mappingTip->PropertyMapping($property->{'name'},Column => $mapping->{'column_name'},DBType => $mapping->{'db_type'});
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
96 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
97 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
98 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
99 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
100 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
101
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
102 sub MakeTypeName {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
103 my ($typename) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
104
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
105 return new Schema::TypeName(
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
106 $typename->{'name'},
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
107 (
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
108 $typename->{'template_list'} ?
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
109 map { MakeTypeName($_) } as_list($typename->{'template_list'}{'type'})
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
110 :
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
111 ()
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
112 )
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
113 );
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
114 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
115
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
116 sub BuildSchema {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
117 my ($this,$fileName) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
118
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
119 my $uriFile = URI::file->new_abs($fileName);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
120
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
121 $this->ProcessSchema($uriFile);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
122
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
123 $this->{$Types}->Close();
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
124
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
125 foreach my $type ($this->{$Types}->EnumTypes(skip_templates => 1)) {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
126 $this->{$DataSourceBuilder}->AddType($type);
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
127 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
128 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
129
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
130 sub DESTROY {
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
131 my ($this) = @_;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
132
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
133 $this->{$Compiler}->Dispose;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
134 $this->{$DataSourceBuilder}->Dispose;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
135 $this->{$Types}->Dispose;
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
136 }
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
137
03e58a454b20 Создан репозитарий
Sergey
parents:
diff changeset
138 1;