annotate lib/IMPL/SQL/Schema.pm @ 418:3f38dabaf5cc ref20150831

sync
author cin
date Mon, 28 Dec 2015 15:11:35 +0300
parents 3ed0c58e9da3
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
407
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
1 use strict;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
2 package IMPL::SQL::Schema;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
3 use mro;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
4
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
5 use IMPL::lang qw(is);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
6 use IMPL::Const qw(:prop);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
7 use Scalar::Util qw(reftype);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
8 use IMPL::declare {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
9 require => {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
10 Table => 'IMPL::SQL::Schema::Table'
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
11 },
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
12 base => [
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
13 'IMPL::Object' => undef,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
14 'IMPL::Object::Disposable' => undef,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
15 'IMPL::Object::Clonable' => undef,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
16 ],
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
17 props => [
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
18 version => PROP_RO | PROP_DIRECT,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
19 name => PROP_RO | PROP_DIRECT,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
20 _tables => PROP_RO | PROP_DIRECT
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
21 ]
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
22 };
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
23
417
3ed0c58e9da3 working on di container, tests
cin
parents: 407
diff changeset
24 sub CTOR {
3ed0c58e9da3 working on di container, tests
cin
parents: 407
diff changeset
25 my ($this,%args) = @_;
3ed0c58e9da3 working on di container, tests
cin
parents: 407
diff changeset
26
3ed0c58e9da3 working on di container, tests
cin
parents: 407
diff changeset
27 $this->$_($args{$_}) foreach grep exists $args{$_}, qw(name version);
3ed0c58e9da3 working on di container, tests
cin
parents: 407
diff changeset
28 }
3ed0c58e9da3 working on di container, tests
cin
parents: 407
diff changeset
29
407
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
30 sub AddTable {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
31 my ($this,$table) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
32
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
33 if (is($table,Table)) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
34
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
35 $table->schema == $this or die new IMPL::InvalidOperationException('The specified table must belong to the database');
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
36 not exists $this->{$_tables}->{$table->name} or die new IMPL::InvalidOperationException('a table with the same name already exists in the database');
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
37
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
38 } elsif (reftype($table) eq 'HASH') {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
39
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
40 not exists $this->{$_tables}->{$table->{'name'}} or die new IMPL::InvalidOperationException('a table with the same name already exists in the database');
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
41 $table = { %$table };
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
42 $table->{'schema'} = $this;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
43 $table = Table->new(%{$table});
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
44 } else {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
45 die new IMPL::InvalidArgumentException('Either a table object or a hash with table parameters is required');
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
46 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
47
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
48 $this->{$_tables}{$table->name} = $table;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
49 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
50
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
51 sub RemoveTable {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
52 my ($this,$table) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
53
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
54 my $tn = is($table,Table) ? $table->name : $table;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
55
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
56 $table = delete $this->{$_tables}{$tn} or die new IMPL::InvalidArgumentException('The table doesn\'t exists',$tn);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
57
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
58 # drop foreign keys
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
59 map { $_->table->RemoveConstraint($_) } values %{$table->primaryKey->connectedFK} if $table->primaryKey;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
60
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
61 # drop table contents
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
62 $table->Dispose();
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
63
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
64 return 1;
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 sub ResolveTable {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
68 my ($this,$table) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
69
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
70 is($table,Table) ? $table : $this->{$_tables}{$table};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
71 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
72
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
73 sub GetTable {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
74 my ($this,$tableName) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
75 return $this->{$_tables}{$tableName};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
76 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
77
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
78 sub GetTables {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
79 my ($this) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
80
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
81 return wantarray ? values %{$this->{$_tables}} : [values %{$this->{$_tables}}];
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
82 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
83
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
84 sub RenameTable {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
85 my ($this,$oldName,$newName) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
86
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
87 die new IMPL::InvalidOperationException("A source table doesn't exists", $oldName) unless exists $this->{$_tables}{$oldName};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
88 die new IMPL::InvalidOperationException("A target table already exists", $newName) if exists $this->{$_tables}{$newName};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
89
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
90 my $table = delete $this->{$_tables}{$oldName};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
91 $table->_setName($newName);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
92 $this->{$_tables}{$newName} = $table;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
93 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
94
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
95 sub Dispose {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
96 my ($this) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
97
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
98 $_->Dispose foreach values %{$this->{$_tables}};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
99
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
100 delete $this->{$_tables};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
101
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
102 $this->next::method();
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
103 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
104
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
105 1;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
106
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
107 __END__
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
108 =pod
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
109
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
110 =head1 SYNOPSIS
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
111
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
112 =begin code
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
113
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
114 require IMPL::SQL::Schema;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
115 use IMPL::SQL::Types qw(Varchar Integer);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
116
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
117 my $dbSchema = new IMPL::SQL::Schema;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
118
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
119 my $tbl = $dbSchema->AddTable({name => 'Person' });
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
120 $tbl->AddColumn({
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
121 name => 'FirstName',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
122 canBeNull => 1,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
123 type => Varchar(255)
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
124 });
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
125 $tbl->AddColumn({
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
126 name => 'Age',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
127 type => Integer
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
128 });
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
129
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
130 # so on
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
131
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
132 # and finally don't forget to
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
133
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
134 $dbSchema->Dispose();
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
135
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
136 =end code
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
137
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
138 =head1 DESCRIPTION
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
139
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
140 Схема реляциоонной базы данных, орентированная на язык SQL, содержит описания таблиц
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
141 которые являются частью базы. Позволяет создавать и удалать таблицы.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
142
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
143 =head1 MEMBERS
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
144
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
145 =over
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
146
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
147 =item C<CTOR(%props)>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
148
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
149 Конструктор заполняет объект свойствами из C<props>.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
150
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
151 =item C<[get]name>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
152
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
153 Имя схемы.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
154
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
155 =item C<[get]version>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
156
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
157 Версия схемы.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
158
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
159 =item C<AddTable($table)>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
160
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
161 Доавляет таблицу в схему. C<$table> может быть либо таблице, либо хешем с набором
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
162 свойств для создания новой таблицы. Если таблица с таким именем уже существует в сехеме,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
163 то вызывается исключение.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
164
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
165 =item C<GetTable($name)>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
166
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
167 Возвращает таблицу с именем C<$name> или C<undef>.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
168
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
169 =item C<GetTables()>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
170
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
171 Возвращает список таблиц. В скалярном контексте - ссылку на массив с таблицами.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
172
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
173 =item C<ResolveTable($table)>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
174
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
175 Если параметр C<$table> - таблица, то возвращается C<$table>, если C<$table> строка, то
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
176 ищется таблица с таким именем, если таблица не найдена, возвращается C<undef>.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
177
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
178 =item C<RenameTable($oldName,$newName)>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
179
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
180 Происходит переименование таблицы. Если C<$oldName> не существует, либо если C<$newName>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
181 существует, вызывается исключение.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
182
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
183 =item C<RemoveTable($table)>
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
184
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
185 Удаляется таблица C<$table> с удалением всех связей и ограничений. Если такой таблицы нет,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
186 то вызывается исключение. C<$table> может быть либо именем таблицы, либо объектом.
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
187
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
188 =back
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
189
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
190 =cut