Mercurial > pub > Impl
view Lib/IMPL/SQL/Schema/Traits.pm @ 250:129e48bb5afb
DOM refactoring
ObjectToDOM methods are virtual
QueryToDOM uses inflators
Fixed transform for the complex values in the ObjectToDOM
QueryToDOM doesn't allow to use complex values (HASHes) as values for nodes (overpost problem)
author | sergey |
---|---|
date | Wed, 07 Nov 2012 04:17:53 +0400 |
parents | 4d0e1962161c |
children | dacfe7c0311a |
line wrap: on
line source
package IMPL::SQL::Schema::Traits; use strict; use IMPL::_core::version; use IMPL::Exception(); use parent qw(IMPL::Object); # required for use with typeof operator use IMPL::SQL::Schema::Constraint::PrimaryKey(); use IMPL::SQL::Schema::Constraint::Index(); use IMPL::SQL::Schema::Constraint::Unique(); use IMPL::SQL::Schema::Constraint::ForeignKey(); ################################################### package IMPL::SQL::Schema::Traits::Table; use base qw(IMPL::Object::Fields); use fields qw( name columns constraints options ); sub CTOR { my ($this,$table,$columns,$constraints,$options) = @_; $this->{name} = $table or die new IMPL::InvalidArgumentException(table => "A table name is required"); $this->{columns} = $columns if defined $columns; $this->{constraints} = $constraints if defined $constraints; $this->{options} = $options if defined $options; } ################################################### package IMPL::SQL::Schema::Traits::Column; use base qw(IMPL::Object::Fields); use fields qw( name type isNullable defaultValue tag ); sub CTOR { my ($this, $name, $type, %args) = @_; $this->{name} = $name or die new IMPL::InvalidArgumentException("name"); $this->{type} = $type or die new IMPL::InvalidArgumentException("type"); $this->{isNullable} = $args{isNullable} if exists $args{isNullable}; $this->{defaultValue} = $args{defaultValue} if exists $args{defaultValue}; $this->{tag} = $args{tag} if exists $args{tag}; } ################################################## package IMPL::SQL::Schema::Traits::Constraint; use base qw(IMPL::Object::Fields); use fields qw( name columns ); sub CTOR { my ($this, $name, $columns) = @_; $this->{name} = $name; $this->{columns} = $columns; # list of columnNames } sub constraintClass { die new IMPL::NotImplementedException(); } ################################################## package IMPL::SQL::Schema::Traits::PrimaryKey; use base qw(IMPL::SQL::Schema::Traits::Constraint); __PACKAGE__->PassThroughArgs; use constant { constraintClass => typeof IMPL::SQL::Schema::Constraint::PrimaryKey }; ################################################## package IMPL::SQL::Schema::Traits::Index; use base qw(IMPL::SQL::Schema::Traits::Constraint); __PACKAGE__->PassThroughArgs; use constant { constraintClass => typeof IMPL::SQL::Schema::Constraint::Index }; ################################################## package IMPL::SQL::Schema::Traits::Unique; use base qw(IMPL::SQL::Schema::Traits::Constraint); __PACKAGE__->PassThroughArgs; use constant { constraintClass => typeof IMPL::SQL::Schema::Constraint::Unique }; ################################################## package IMPL::SQL::Schema::Traits::ForeignKey; use base qw(IMPL::SQL::Schema::Traits::Constraint); use fields qw( foreignTable foreignColumns ); use constant { constraintClass => typeof IMPL::SQL::Schema::Constraint::ForeignKey }; our %CTOR = ( 'IMPL::SQL::Schema::Traits::Constraint' => sub { @_[0..1] } ); sub CTOR { my ($this,$foreignTable,$foreignColumns) = @_[0,3,4]; $this->{foreignTable} = $foreignTable; $this->{foreignColunms} = $foreignColumns; } ################################################## package IMPL::SQL::Schema::Traits::CreateTable; use parent qw(-norequire IMPL::SQL::Schema::Traits); use IMPL::Class::Property; use IMPL::lang; BEGIN { public property table => prop_get | owner_set; } sub CTOR { my ($this,$table) = @_; die new IMPL::InvalidArgumentException("table", "An object of IMPL::SQL::Schema::Traits::Table type is required") unless is $table, typeof IMPL::SQL::Schema::Traits::Table; $this->table($table); } sub apply { my ($this,$schema) = @_; return 0 if ( $schema->GetTable( $this->table->{name} ) ); $schema->AddTable($this->table); return 1; } ################################################## package IMPL::SQL::Schema::Traits::DropTable; use parent qw(-norequire IMPL::SQL::Schema::Traits); use IMPL::Class::Property; BEGIN { public property tableName => prop_get | owner_set; } sub CTOR { my ($this,$tableName) = @_; $this->tableName($tableName) or die new IMPL::InvalidArgumentException("tableName is required"); } sub apply { my ($this,$schema) = @_; return 0 if $schema->GetTable( $this->tableName ); $schema->RemoveTable($this->tableName); return 1; } ################################################## package IMPL::SQL::Schema::Traits::RenameTable; use parent qw(-norequire IMPL::SQL::Schema::Traits); use IMPL::Class::Property; BEGIN { public property tableName => prop_get | owner_set; public property tableNewName => prop_get | owner_set; } sub CTOR { my ($this, $oldName, $newName) = @_; $this->tableName($oldName) or die new IMPL::InvalidArgumentException("A table name is required"); $this->tableNewName($newName) or die new IMPL::InvalidArgumentException("A new table name is required"); } sub apply { my ($this,$schema) = @_; return 0 if not $schema->GetTable($this->tableName) or $schema->GetTable($this->tableNewName); $this->RenameTable($this->tableName, $this->tableNewName); return 1; } ################################################# package IMPL::SQL::Schema::Traits::AlterTableAddColumn; use parent qw(-norequire IMPL::SQL::Schema::Traits); use IMPL::Class::Property; use IMPL::lang; BEGIN { public property tableName => prop_get | owner_set; public property column => prop_get | owner_set; } sub CTOR { my ($this,$tableName,$column) = @_; $this->tableName($tableName) or die new IMPL::InvalidArgumentException("A table name is required"); die new IMPL::InvalidArgumentException("A column should be a IMPL::SQL::Schema::Traits::Column object") unless is $column, typeof IMPL::SQL::Schema::Traits::Column; $this->column($column); } sub apply { my ($this,$schema) = @_; my $table = $schema->GetTable($this->tableName) or return 0; return 0 if $table->GetColumn( $this->column->{name} ); $table->AddColumn($this->column); return 1; } ################################################# package IMPL::SQL::Schema::Traits::AlterTableDropColumn; use parent qw(-norequire IMPL::SQL::Schema::Traits); use IMPL::Class::Property; BEGIN { public property tableName => prop_get | owner_set; public property columnName => prop_get | owner_set; } sub CTOR { my ($this,$table,$column) = @_; $this->tableName($table) or die new IMPL::InvalidArgumentException(tableName => "A table name should be specified"); $this->columnName($column) or die new IMPL::InvalidArgumentException(columnName => "A column name should be specified"); } sub apply { my ($this,$schema) = @_; local $@; return eval { $schema->GetTable($this->tableName)->RemoveColumn($this->columnName); return 1; } || 0; } ################################################# package IMPL::SQL::Schema::Traits::AlterTableChangeColumn; use parent qw(-norequire IMPL::SQL::Schema::Traits); use IMPL::Class::Property; BEGIN { public property tableName => prop_get | owner_set; public property columnName => prop_get | owner_set; public property columnType => prop_all; public property defaultValue => prop_all; public property isNullable => prop_all; public property options => prop_all; # hash diff format, (keys have a prefix '+' - add or update value, '-' remove value) } sub CTOR { my ($this, $table,$column,%args) = @_; $this->tableName($table) or die new IMPL::InvalidArgumentException(tableName => "A table name is required"); $this->columnName($column) or die new IMPL::InvalidArgumentException(columnName => "A column name is required"); $this->$_($args{$_}) for (grep exists $args{$_}, qw(columnType defaultValue isNullable options)); } sub apply { my ($this,$schema) = @_; local $@; return eval { my $column = $schema->GetTable($this->tableName)->GetColumn($this->columnName); $column->SetType($this->columnType) if defined $this->columnType; $column->SetNullable($this->isNullable) if defined $this->isNullable; $column->SetDefaultValue($this->defaultValue) if defined $this->defaultValue; $column->SetOptions($this->options) if defined $this->options; return 1; } || 0; } ################################################# package IMPL::SQL::Schema::Traits::AlterTableAddConstraint; use parent qw(-norequire IMPL::SQL::Schema::Traits); use IMPL::Class::Property; use IMPL::lang; BEGIN { public property tableName => prop_get | owner_set; public property constraint => prop_get | owner_set; } sub CTOR { my ($this,$table,$constraint) = @_; $this->tableName($table) or die new IMPL::InvalidArgumentException( tableName => "A table name is required"); die new IMPL::InvalidArgumentException(constaraint => "A valid IMPL::SQL::Schema::Traits::Constarint is required") unless is $constraint, typeof IMPL::SQL::Schema::Traits::Constraint; $this->constraint($constraint); } sub apply { my ($this,$schema) = @_; local $@; return eval { $schema->GetTable($this->tableName)->AddConstraint($this->constraint->constraintClass, $this->constraint); return 1; } || 0; } ################################################# package IMPL::SQL::Schema::Traits::AlterTableDropConstraint; use parent qw(-norequire IMPL::SQL::Schema::Traits); use IMPL::Class::Property; BEGIN { public property tableName => prop_get | owner_set; public property constraintName => prop_get | owner_set; } sub CTOR { my ($this,$table,$constraint) = @_; die new IMPL::InvalidArgumentException( tableName => "A table name is required" ) unless $table; die new IMPL::InvalidArgumentException( constraintName => "A constraint name is required" ) unless $constraint; $this->tableName($table); $this->constraintName($constraint); } sub apply { my ($this,$schema) = @_; my $table = $schema->GetTable($this->tableName) or return 0; return 0 unless $table->GetConstraint($this->constraintName); $table->RemoveConstraint($this->constraintName); return 1; } 1; __END__ =pod =head1 NAME C<IMPL::SQL::Traits> - Операции над объектками SQL схемы. =head1 DESCRIPTION Изменения схемы могу быть представлены в виде последовательности примитивных операций. Правила выполнения последовательности примитывных действий могут варьироваться в зависимости от процессора, который их выполняет. Например C<IMPL::SQL::Schema::Traits::Processor>. Данные, которые содержаться в примитивных операциях не могут существовать независимо от схемы. =head1 OPEARATIONS =head2 General Методы обще для всех примитивных операций. =over =item C<apply($schema)> Пытается приминить операцию к указанной схеме. Возвращаемое значение: =over =item C<true> Операция успешно применена к схеме. =item C<false> Операция не может быть применена к схеме. =back =back =head2 Primitive operations =over =item C<IMPL::SQL::Schema::Traits::CreateTable> Создает таблицу =over =item C<CTOR($table)> =item C<[get]table> C<IMPL::SQL::Schema::Traits::Table> - описание создаваемой таблицы =back =item C<IMPL::SQL::Schema::Traits::DropTable> Удалает таблицу по имени =over =item C<CTOR($tableName)> =item C<[get]tableName> Имя удаляемой таблицы =back =item C<IMPL::SQL::Schema::Traits::RenameTable> =over =item C<CTOR($tableName,$tableNewName)> =item C<[get]tableName> Имя таблицы, которую требуется переименовать =item C<[get]tableNewName> Новое имя таблицы =back =item C<IMPL::SQL::Schema::Traits::AlterTableAddColumn> Добавляет столбец в таблицу =over =item C<CTOR($tableName,$column)> =item C<[get]tableName> Имя таблицы в которую нужно добавить столбец =item C<[get]column> C<IMPL::SQL::Schema::Traits::Column> - описание столбца который нужно добавить =back =item C<IMPL::SQL::Schema::Traits::AlterTableDropColumn> Удаляет столбец из таблицы =over =item C<CTOR($tableName,$columnName)> =item C<[get]tableName> Имя таблицы в которой нужно удалить столбец =item C<[get]columnName> Имя столбца для удаления =back =item C<IMPL::SQL::Schema::Traits::AlterTableChangeColumn> Меняет описание столбца =over =item C<CTOR($tableName,$columnName,%args)> C<%args> - хеш, ключами которого являются оставшиеся свойства создаваемого объекта. =item C<[get]tableName> Имя таблицы в которой находится столбец. =item C<[get]columnName> Имя столбца для изменения =item C<[get]columnType> Новый тип столбца. Не задан, если тип не меняется =item C<[get]defaultValue> Значение по умолчанию. Не задано, если не меняется =item C<[get]isNullable> Может ли столбец содержать C<NULL>. Не задано, если не меняется. =item C<[get]options> Хеш опций, не задан, если опции не меняются =back =item C<IMPL::SQL::Schema::Traits::AlterTableAddConstraint> Базовый класс для операций по добавлению ограничений =over =item C<CTOR($tableName,$constraint)> =item C<[get]tableName> Имя таблицы в которую добавляется ограничение. =item C<[get]constraint> C<IMPL::SQL::Schema::Traits::Constraint> - описние ограничения, которое нужно добавить. =back =item C<IMPL::SQL::Schema::Traits::AlterTableDropConstraint> Удаляет ограничение на таблицу =over =item C<CTOR($tableName,$constraintName)> =item C<[get]tableName> Имя таблицы в которой требуется удалить ограничение. =item C<[get]constraintName> Имя ограничения для удаления. =back =back =cut