view Lib/IMPL/SQL/Schema.pm @ 59:0f3e369553bd

Rewritten property implementation (probably become slower but more flexible) Configuration infrastructure in progress (in the aspect of the lazy activation) Initial concept for the code generator
author wizard
date Tue, 09 Mar 2010 02:50:45 +0300
parents 16ada169ca75
children 6ce1f052b90a
line wrap: on
line source

use strict;
package IMPL::SQL::Schema;

use base qw(IMPL::Object IMPL::Object::Disposable IMPL::Object::Autofill);
use IMPL::Class::Property;
use IMPL::Class::Property::Direct;

require IMPL::SQL::Schema::Table;

__PACKAGE__->PassThroughArgs;

BEGIN {
    public _direct property Version => prop_get;
    public _direct property Name => prop_get;
    public _direct property Tables => prop_get;
}

sub AddTable {
    my ($this,$table) = @_;
    
    if (UNIVERSAL::isa($table,'IMPL::SQL::Schema::Table')) {
        $table->Schema == $this or die new IMPL::InvalidOperationException('The specified table must belong to the database');
        not exists $this->{$Tables}->{$table->Name} or die new IMPL::InvalidOperationException('a table with the same name already exists in the database');
    } elsif (UNIVERSAL::isa($table,'HASH')) {
        not exists $this->{$Tables}->{$table->{'Name'}} or die new IMPL::InvalidOperationException('a table with the same name already exists in the database');
        $table->{'Schema'} = $this;
        $table = new IMPL::SQL::Schema::Table(%{$table});
    } else {
        die new IMPL::InvalidArgumentException('Either a table object or a hash with table parameters is required');
    }
    
    $this->{$Tables}{$table->Name} = $table;
}

sub RemoveTable {
    my ($this,$table) = @_;
    
    my $tn = UNIVERSAL::isa($table,'IMPL::SQL::Schema::Table') ? $table->Name : $table;
    $table = delete $this->{$Tables}{$tn} or die new IMPL::InvalidArgumentException('The table doesn\'t exists',$tn);
    
    # drop foreign keys
    map { $_->Table->RemoveConstraint($_) } values %{$table->PrimaryKey->ConnectedFK} if $table->PrimaryKey;
    
    # drop table contents
    $table->Dispose();

    return 1;
}

sub Dispose {
    my ($this) = @_;
    
    $_->Dispose foreach values %{$this->{$Tables}};
    
    delete $this->{$Tables};
    
    $this->SUPER::Dispose;
}

1;

__END__
=pod

=head1 SINOPSYS

require IMPL::SQL::Schema;
use IMPL::SQL::Types qw(Varchar Integer);

my $dbSchema = new IMPL::SQL::Schema;

my $tbl = $dbSchema->AddTable({Name => 'Person' });
$tbl->AddColumn({
    Name => 'FirstName',
    CanBeNull => 1,
    Type => Varchar(255)
});
$tbl->AddColumn({
    Name => 'Age',
    Type => Integer
});

# so on

# and finally don't forget to

$dbSchema->Dispoce();

=head1 DESCRIPTION

Схема реляциоонной базы данных, орентированная на язык SQL, содержит описания таблиц
которые являются частью базы. Позволяет создавать и удалать таблицы.

Имея две схемы можно создавать скрипты для примениения изменений схемы данных C<<IMPL::SQL::Traits>>

=cut