view Lib/CDBI/Map.pm @ 110:c13a215508ca

Refactoring, ControllerUnit
author wizard
date Mon, 17 May 2010 17:42:27 +0400
parents 16ada169ca75
children 76515373dac0
line wrap: on
line source

package CDBI::Map;
use strict;
use Common;

BEGIN {
    DeclareProperty _Cache => ACCESS_NONE;
    DeclareProperty _HoldingType => ACCESS_NONE;
}

sub _KeyValuePairClass {
    my $this = shift;
    ($this->{$_HoldingType} = ref $this ) =~ s/^((?:\w+::)*)Map(\w+)$/${1}MapItem${2}/ unless $this->{$_HoldingType};
    return $this->{$_HoldingType};
}

# при загрузке кеша нельзя грузить KeyValuePair поскольку получатся циклические ссылки:(
sub GetCache {
    my $this = shift;

    if (not $this->{$_Cache}) {
        $this->{$_Cache} = { map { $_->ItemKey, { id => $_->id, value => $_->Value} } $this->_KeyValuePairClass->search(Parent => $this) };
    }

    return $this->{$_Cache};
}

sub Keys {
    my $this = shift;
    return wantarray ? keys %{$this->GetCache} : [keys %{$this->GetCache}];
}

sub Item {
    my ($this,$key,$value,%options) = @_;

    die new Exception('A key must be specified') unless defined $key;

    if (@_ > 2) {
        # set
        if (my $pairInfo = $this->GetCache->{$key}) {
            # update
            my $pair = $this->_KeyValuePairClass->retrieve($pairInfo->{id});
            if (defined $value or $options{'keepnull'}) {
                $pair->Value($value);
                $pair->update;
                $pairInfo->{value} = $value;
            } else {
                #delete
                $pair->delete;
                delete $this->GetCache->{$key};
            }
        } else {
            if ( defined $value or $options{'keepnull'}) {
                my $pair = $this->_KeyValuePairClass->insert( {Parent => $this, ItemKey => $key, Value => $value } );
                $this->GetCache->{$key} = {id => $pair->id, value => $value };
            }
        }
        return $value;
    } else {
        # get
        if (my $pairInfo = $this->GetCache->{$key}) {
            return $pairInfo->{value};
        } else {
            return undef;
        }
    }
}

sub Delete {
    my ($this,$key) = @_;

    if (my $pair = $this->GetCache->{$key} ) {
        $pair->delete;
        delete $this->GetCache->{$key};
        return 1;
    }
    return 0;
}

sub Has {
    my ($this,$key) = @_;

    return exists $this->GetCache->{$key};
}

1;
__END__
=pod
=head1 SYNOPSIS
package App::CDBI;
use base 'Class::DBI';

#....

package App::MapString;
use base 'Class::DBI','CDBI::Map';

#....


my $Map = App::MapString->retrieve($id);
print $Map->Item('key');
$Map->Item('key','value');
$Map->Delete('key');
print "the $key is found" if $Map->Has($key);

=head1 DESCRIPTION

Provides a set of methods to manipulate with Maps;

=cut