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