view Lib/IMPL/SQL/Schema/Processor.pm @ 379:a471e8b77544

sync
author cin
date Thu, 16 Jan 2014 18:10:50 +0400
parents 56364d0c4b4f
children
line wrap: on
line source

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

use IMPL::Const qw(:prop);
use IMPL::declare {
    require => {
        Exception => 'IMPL::Exception',
        ArgException => '-IMPL::InvalidArgumentException'
    },
    base => [
        'IMPL::Object' => undef
    ],
    props => [
        dbSchema => PROP_RO,
        updateBatch => PROP_RO,
        pendingOperations => PROP_RO
    ] 
};

sub CTOR {
    my ($this,$schema) = @_;
    
    $this->dbSchema($schema)
        or die ArgException->new(schema => 'A DB schema is required');
    
    $this->updateBatch([]);
    $this->pendingOperations([]);
}

sub AddUpdateBatch {
    my $this = shift;
    
    push @{$this->updateBatch}, @_;
}

sub AddPendingOperations {
    my $this = shift;
    
    push @{$this->pendingOperations}, @_;
}

sub ProcessBatch {
    my ($this,$batch) = @_;
    
    $this->pendingOperations($batch);
    my $i = 1;
    while(@{$this->pendingOperations}) {
        $batch = $this->pendingOperations;
        $this->pendingOperations([]);
        
        my $noChanges = 1;
        
        foreach my $op (@$batch) {
            if ($this->CanApplyOperation($op,$i)) {
                $noChanges = 0;
                
                $this->ApplyOperation($op,$i);
            } else {
                $this->AddPendingOperations($op);
            }
        }
        
        if ($noChanges && @{$this->pendingOperations}) {
            die Exception->new("No changes were made (iteration $i), but some operations are pending",@{$this->pendingOperations});
        }
        
        $i++;
    }
}

sub CanApplyOperation {
    my ($this,$op) = @_;
    
    return $op->CanApply($this->dbSchema);
}

sub ApplyOperation {
    my ($this,$op) = @_;
    
    $op->Apply($this->dbSchema);
    $this->AddUpdateBatch($op);
}

1;

__END__

=pod

=head1 NAME

=head1 SYNOPSIS

=head1 DESCRIPTION

Позволяет применит набор примитивных операций C<IMPL::SQL::Schema::Traits> к
схеме. 

=cut