Data-Model

 view release on metacpan or  search on metacpan

lib/Data/Model/Driver/Memcached.pm  view on Meta::CPAN

# storaged to memcache protocol (not for cache)
package Data::Model::Driver::Memcached;
use strict;
use warnings;
use base 'Data::Model::Driver';

use Carp ();
$Carp::Internal{(__PACKAGE__)}++;

sub memcached { shift->{memcached} }

sub update_direct { Carp::croak("update_direct is NOT IMPLEMENTED") }

sub init {
    my $self = shift;
    if (my $serializer = $self->{serializer}) {
        $serializer = 'Data::Model::Driver::Memcached::Serializer::' . $serializer
            unless $serializer =~ s/^\+//;
        unless ($serializer eq 'Data::Model::Driver::Memcached::Serializer::Default') {
            eval "use $serializer"; ## no critic
            Carp::croak $@;
        }
        $self->{serializer} = $serializer;
    }
}

sub lookup {
    my($self, $schema, $key) = @_;
    my $cache_key = $self->cache_key($schema, $key);
    my $ret = $self->{memcached}->get( $cache_key );
    return unless $ret;
    $ret = $self->{serializer}->deserialize($self, $ret) if $self->{serializer};
    my $map = $schema->options->{column_name_rename};
    $ret = $self->column_name_rename($map, $ret, 1)      if $map;
    $ret = $self->revert_undefvalue($schema, $ret)       if $self->{ignore_undef_value};
    $ret = $self->revert_keyvalue($schema, $key, $ret)   if $self->{strip_keys};
    return $ret;
}

sub lookup_multi {
    my($self, $schema, $keys) = @_;
    my $keys_map = {};
    my @cache_keys = map { my $k = $self->cache_key($schema, $_); $keys_map->{$k} = $_ ; $k } @{ $keys };
    my $ret = $self->{memcached}->get_multi( @cache_keys );
    return unless $ret;

    my %resultlist;
    while (my($id, $data) = each %{ $ret }) {
        $data = $self->{serializer}->deserialize($self, $data)           if $self->{serializer};
        my $map = $schema->options->{column_name_rename};
        $data = $self->column_name_rename($map, $data, 1)                if $map;
        $data = $self->revert_undefvalue($schema, $data)                 if $self->{ignore_undef_value};
        $data = $self->revert_keyvalue($schema, $keys_map->{$id}, $data) if $self->{strip_keys};
        my $key = $schema->get_key_array_by_hash($data);
        $resultlist{join "\0", @{ $key }} = +{ %{ $data } };
    }
    return \%resultlist;
}

sub get {
    my($self, $schema, $key, $columns, %args) = @_;

    my $cache_key = $self->cache_key($schema, $key);
    my $ret = $self->{memcached}->get( $cache_key );
    return unless $ret;
    $ret = $self->{serializer}->deserialize($self, $ret) if $self->{serializer};
    my $map = $schema->options->{column_name_rename};
    $ret = $self->column_name_rename($map, $ret, 1)      if $map;
    $ret = $self->revert_undefvalue($schema, $ret)       if $self->{ignore_undef_value};
    $ret = $self->revert_keyvalue($schema, $key, $ret)   if $self->{strip_keys};
    return $self->_generate_result_iterator([ $ret ]), +{};
}

sub set {
    my($self, $schema, $key, $columns, %args) = @_;

    my $cache_key = $self->cache_key($schema, $key);
    my $data = $columns;
    $data = $self->strip_keyvalue($schema, $key, $data)  if $self->{strip_keys};
    $data = $self->strip_undefvalue($schema, $data)      if $self->{ignore_undef_value};
    my $map = $schema->options->{column_name_rename};
    $data = $self->column_name_rename($map, $data)       if $map;
    $data = $self->{serializer}->serialize($self, $data) if $self->{serializer};
    my $ret = $self->{always_overwrite} ?
        $self->{memcached}->set( $cache_key, $data ) :
            $self->{memcached}->add( $cache_key, $data );
    return unless $ret;

    $columns;
}

sub replace {
    my($self, $schema, $key, $columns, %args) = @_;

    my $cache_key = $self->cache_key($schema, $key);
    my $data = $columns;
    $data = $self->strip_keyvalue($schema, $key, $data)  if $self->{strip_keys};
    $data = $self->strip_undefvalue($schema, $data)      if $self->{ignore_undef_value};
    my $map = $schema->options->{column_name_rename};
    $data = $self->column_name_rename($map, $data)       if $map;
    $data = $self->{serializer}->serialize($self, $data) if $self->{serializer};
    my $ret = $self->{memcached}->set( $cache_key, $data );
    return unless $ret;

    $columns;
}

sub update {
    my($self, $schema, $old_key, $key, $old_columns, $columns, $changed_columns, %args) = @_;

    my $old_cache_key = $self->cache_key($schema, $old_key);
    my $new_cache_key = $self->cache_key($schema, $key);
    unless ($old_cache_key eq $new_cache_key) {
        my $ret = $self->delete($schema, $old_key);
        return unless $ret;
    }

    my $data = $columns;
    $data = $self->strip_keyvalue($schema, $key, $data)  if $self->{strip_keys};
    $data = $self->strip_undefvalue($schema, $data)      if $self->{ignore_undef_value};
    my $map = $schema->options->{column_name_rename};
    $data = $self->column_name_rename($map, $data)       if $map;
    $data = $self->{serializer}->serialize($self, $data) if $self->{serializer};
    my $ret = $self->{memcached}->set( $new_cache_key, $data );
    return unless $ret;

    $columns;
}

sub delete {
    my($self, $schema, $key, $columns, %args) = @_;
    my $cache_key = $self->cache_key($schema, $key);
    my $data = $self->{memcached}->get( $cache_key );
    return unless $data;
    my $ret = $self->{memcached}->delete( $cache_key );
    return unless $ret;
    $data;
}

sub strip_keyvalue {
    my($self, $schema, $keys, $columns) = @_;
    my $data = { %{ $columns } };
    for my $key (@{ $schema->key }) {
        delete $data->{$key};
    }
    $data;
}

sub revert_keyvalue {
    my($self, $schema, $keys, $columns) = @_;
    my $i = 0;
    my $data = { %{ $columns } };
    for my $key (@{ $schema->key }) {
        $data->{$key} = $keys->[$i++].''; # copy
    }
    $data;
}

sub strip_undefvalue {
    my($self, $schema, $columns) = @_;
    my $data = { %{ $columns } };
    for my $key (@{ $schema->columns }) {
        delete $data->{$key} unless exists $data->{$key} && defined $data->{$key};
    }
    $data;
}

sub revert_undefvalue {



( run in 1.325 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )