Amazon-DynamoDB-Simple
view release on metacpan or search on metacpan
# returns a hash representing the whole table as key value pairs
$table->items();
# returns all the keys in the table
$table->keys();
# delete $old_key, create $new_key
$table->rename($old_key, $new_key);
# sync data between AWS regions using the 'last_updated' field to select
# the newest data. This method will permanently delete any items marked as
# 'deleted'.
$table->sync_regions();
# This sets the value of the hosts attribute. The value shown is the
# default value. You must use exactly two hosts for stuff to work atm.
# Sorry.
$table->hosts([qw/
dynamodb.us-east-1.amazonaws.com
dynamodb.us-west-1.amazonaws.com
lib/Amazon/DynamoDB/Simple.pm view on Meta::CPAN
# returns a hash representing the whole table as key value pairs
$table->items();
# returns all the keys in the table
$table->keys();
# delete $old_key, create $new_key
$table->rename($old_key, $new_key);
# sync data between AWS regions using the 'last_updated' field to select
# the newest data. This method will permanently delete any items marked as
# 'deleted'.
$table->sync_regions();
# This sets the value of the hosts attribute. The value shown is the
# default value. You must use exactly two hosts for stuff to work atm.
# Sorry.
$table->hosts([qw/
dynamodb.us-east-1.amazonaws.com
dynamodb.us-west-1.amazonaws.com
lib/Amazon/DynamoDB/Simple.pm view on Meta::CPAN
);
}
return \@dynamodbs;
}
sub put {
my ($self, %item) = @_;
# timestamp this transaction
$item{last_updated} = DateTime->now . ""; # stringify datetime
$item{deleted} ||= 0;
%item = $self->deflate(%item);
my $dynamodbs = $self->dynamodbs();
my $success = 0;
for my $dynamodb (@$dynamodbs) {
try {
$dynamodb->put_item(
TableName => $self->table,
lib/Amazon/DynamoDB/Simple.pm view on Meta::CPAN
}
confess "unable to connect and get item from any dynamodb" unless $success;
my $most_recent;
for my $item (@items) {
next unless $item;
$most_recent = $item
if !$most_recent ||
$most_recent->{last_updated} le $item->{last_updated};
}
return if $most_recent->{deleted};
return $self->inflate(%$most_recent);
}
sub scan {
my ($self) = @_;
lib/Amazon/DynamoDB/Simple.pm view on Meta::CPAN
sub _sync_items {
my ($self, $from_ddb, $to_ddb, $from_items, $to_items) = @_;
my $primary_key_name = $self->primary_key;
for my $from_key (keys %$from_items) {
my $from_value = $from_items->{$from_key};
my $to_value = $to_items->{$from_key};
if (!$to_value) {
$to_value = {last_updated => '1900-01-01T00:00:00'};
$to_items->{$from_key} = $to_value;
}
my $updated0 = $from_value->{last_updated};
my $updated1 = $to_value->{last_updated};
# don't need to sync if the items are the same age and not deleted
next if $updated0 eq $updated1 && !$to_value->{deleted};
# find the newest item
my $newest = $updated0 gt $updated1
? $from_value
: $to_value;
# sync newest item to the other region
if ($newest->{deleted}) {
$self->permanent_delete( $newest->{$primary_key_name} );
}
else {
# TODO: this could be more efficient by syncing to just the ddb
# that needs it
$self->put(%$newest);
}
# Lets say we are syncing from $dynamodb0 -> $dynamodb1. This prevents
# us from re syncing this item when we sync in the other direction from
# $dynamodb1 -> $dynamodb0
$to_value->{last_updated} = $from_value->{last_updated};
}
}
sub items {
my ($self) = @_;
my $human_items = {};
my $items = $self->scan->{Items};
my $primary_key_name = $self->primary_key;
xt/amazon/dynamodb/simple.t view on Meta::CPAN
region => 'highlyavailable',
zone => 'highlyavailable',
hashthing => [{
a => 'firstthing',
b => 2000,
c => 200,
}],
};
my $expected_item = {
%$server_definition,
last_updated => re(qr/^\d{4}-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}/),
deleted => bool(),
};
subtest 'put' => sub {
$dynamodb->put(%$server_definition);
my $ddbs = $dynamodb->dynamodbs();
for my $ddb (@$ddbs) {
xt/amazon/dynamodb/simple.t view on Meta::CPAN
my %item = $dynamodb->get($node);
cmp_deeply \%item, $expected_item, 'got item';
# update item in one region
my $ddb = $dynamodb->dynamodbs->[1];
%item = $dynamodb->deflate(
%$server_definition,
flavor => 'highlyavailable2',
deleted => 0,
last_updated => DateTime->now . ""
);
$ddb->put_item(
TableName => 'server_definitions',
Item => \%item,
);
%item = $dynamodb->get($node);
is $item{flavor}, 'highlyavailable2', 'got most recent item';
};
xt/amazon/dynamodb/sync.t view on Meta::CPAN
$table->put(%item);
sleep 1;
# update one dynamodb
$table->dynamodbs->[0]->put_item(
TableName => 'server_definitions',
Item => {
%item,
zone => 'z',
deleted => 0,
last_updated => DateTime->now() . "",
},
);
# sync
$table->sync_regions;
# check that sync worked
my $saved_items = {};
for my $i (0, 1) {
$saved_items->{$i} = $table->dynamodbs->[$i]->get_item(
sub { shift },
TableName => 'server_definitions',
Key => { node => $node },
)->get();
cmp_deeply $saved_items->{$i}, {
%item,
zone => 'z',
deleted => 0,
last_updated => re(qr/^\d{4}-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}/),
}, "saved server definition to dynamodb $i";
}
# cleanup: permanently delete item from all dynamodbs
$table->permanent_delete($node);
};
subtest 'sync: create new records' => sub {
my %item = (
node => $node,
xt/amazon/dynamodb/sync.t view on Meta::CPAN
region => $cfg->{region},
zone => $cfg->{zone},
);
# create item on one dynamodb
$table->dynamodbs->[0]->put_item(
TableName => 'server_definitions',
Item => {
%item,
deleted => 0,
last_updated => DateTime->now() . "",
},
);
# sync
$table->sync_regions;
# check that sync worked
my $saved_items = {};
for my $i (0, 1) {
$saved_items->{$i} = $table->dynamodbs->[$i]->get_item(
sub { shift },
TableName => 'server_definitions',
Key => { node => $node },
)->get();
cmp_deeply $saved_items->{$i}, {
%item,
deleted => 0,
last_updated => re(qr/^\d{4}-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}/),
}, "saved server definition to dynamodb $i";
}
# cleanup: permanently delete item from all dynamodbs
$table->permanent_delete($node);
};
done_testing;
( run in 0.373 second using v1.01-cache-2.11-cpan-05444aca049 )