| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Net::Amazon::DynamoDB::Table; | 
| 2 | 2 |  |  | 2 |  | 23285 | use Net::Amazon::DynamoDB::Lite; | 
|  | 2 |  |  |  |  | 193368 |  | 
|  | 2 |  |  |  |  | 72 |  | 
| 3 | 2 |  |  | 2 |  | 14 | use Carp qw/cluck confess carp croak/; | 
|  | 2 |  |  |  |  | 3 |  | 
|  | 2 |  |  |  |  | 97 |  | 
| 4 | 2 |  |  | 2 |  | 8 | use Moo; | 
|  | 2 |  |  |  |  | 8 |  | 
|  | 2 |  |  |  |  | 7 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | our $VERSION="0.05"; | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | has table       => (is => 'rw', required => 1); | 
| 9 |  |  |  |  |  |  | has hash_key    => (is => 'rw', required => 1); | 
| 10 |  |  |  |  |  |  | has range_key   => (is => 'rw', required => 0); | 
| 11 |  |  |  |  |  |  | has dynamodb    => (is => 'lazy'); | 
| 12 |  |  |  |  |  |  | has region      => (is => 'rw', required => 1); | 
| 13 |  |  |  |  |  |  | has access_key  => (is => 'rw', lazy => 1, builder => 1); | 
| 14 |  |  |  |  |  |  | has secret_key  => (is => 'rw', lazy => 1, builder => 1); | 
| 15 |  |  |  |  |  |  | has timeout     => (is => 'rw', default => 5); | 
| 16 |  |  |  |  |  |  |  | 
| 17 | 0 |  |  | 0 |  | 0 | sub _build_access_key { $ENV{AWS_ACCESS_KEY} } | 
| 18 | 0 |  |  | 0 |  | 0 | sub _build_secret_key { $ENV{AWS_SECRET_KEY} } | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | sub _build_dynamodb { | 
| 21 | 0 |  |  | 0 |  | 0 | my $self = shift; | 
| 22 | 0 |  |  |  |  | 0 | Net::Amazon::DynamoDB::Lite->new( | 
| 23 |  |  |  |  |  |  | region             => $self->region, | 
| 24 |  |  |  |  |  |  | access_key         => $self->access_key, | 
| 25 |  |  |  |  |  |  | secret_key         => $self->secret_key, | 
| 26 |  |  |  |  |  |  | connection_timeout => $self->timeout, | 
| 27 |  |  |  |  |  |  | ); | 
| 28 |  |  |  |  |  |  | } | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | sub get { | 
| 31 | 0 |  |  | 0 | 1 | 0 | my ($self, %args) = @_; | 
| 32 | 0 |  |  |  |  | 0 | my $hash_key      = $self->hash_key; | 
| 33 | 0 |  |  |  |  | 0 | my $range_key     = $self->range_key; | 
| 34 | 0 |  |  |  |  | 0 | my $primary_key   = {}; | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 0 | 0 | 0 |  |  | 0 | die "Key or $hash_key param required" unless $args{Key} || $args{$hash_key}; | 
| 37 |  |  |  |  |  |  |  | 
| 38 | 0 | 0 |  |  |  | 0 | if ($args{$hash_key}) { | 
| 39 | 0 |  |  |  |  | 0 | my $value = delete $args{$hash_key}; | 
| 40 | 0 |  |  |  |  | 0 | $primary_key->{$hash_key} = $self->inflate_attribute_value($value); | 
| 41 |  |  |  |  |  |  | } | 
| 42 | 0 | 0 | 0 |  |  | 0 | if ($range_key && $args{$range_key} ) { | 
| 43 | 0 |  |  |  |  | 0 | my $value = delete $args{$range_key}; | 
| 44 | 0 |  |  |  |  | 0 | $primary_key->{$range_key} = $self->inflate_attribute_value($value); | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 0 |  | 0 |  |  | 0 | $args{Key}       ||= $primary_key; | 
| 48 | 0 |  | 0 |  |  | 0 | $args{TableName} ||= $self->table; | 
| 49 |  |  |  |  |  |  |  | 
| 50 | 0 |  |  |  |  | 0 | return $self->dynamodb->get_item(\%args); | 
| 51 |  |  |  |  |  |  | } | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | sub put { | 
| 54 | 0 |  |  | 0 | 1 | 0 | my ($self, %args)  = @_; | 
| 55 |  |  |  |  |  |  |  | 
| 56 | 0 | 0 |  |  |  | 0 | die "Item param required" unless $args{Item}; | 
| 57 |  |  |  |  |  |  |  | 
| 58 | 0 |  | 0 |  |  | 0 | $args{TableName} ||= $self->table; | 
| 59 | 0 |  |  |  |  | 0 | $args{Item}        = $self->inflate_item($args{Item}); | 
| 60 |  |  |  |  |  |  |  | 
| 61 | 0 |  |  |  |  | 0 | return $self->dynamodb->put_item(\%args); | 
| 62 |  |  |  |  |  |  | } | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | sub delete { | 
| 65 | 0 |  |  | 0 | 1 | 0 | my ($self, %args) = @_; | 
| 66 | 0 |  |  |  |  | 0 | my $hash_key      = $self->hash_key; | 
| 67 | 0 |  |  |  |  | 0 | my $range_key     = $self->range_key; | 
| 68 | 0 |  |  |  |  | 0 | my $primary_key   = {}; | 
| 69 |  |  |  |  |  |  |  | 
| 70 | 0 | 0 | 0 |  |  | 0 | die "Key or $hash_key param required" unless $args{Key} || $args{$hash_key}; | 
| 71 |  |  |  |  |  |  |  | 
| 72 | 0 | 0 |  |  |  | 0 | if ($args{$hash_key}) { | 
| 73 | 0 |  |  |  |  | 0 | my $value = delete $args{$hash_key}; | 
| 74 | 0 |  |  |  |  | 0 | $primary_key->{$hash_key} = $self->inflate_attribute_value($value); | 
| 75 |  |  |  |  |  |  | } | 
| 76 | 0 | 0 | 0 |  |  | 0 | if ($range_key && $args{$range_key} ) { | 
| 77 | 0 |  |  |  |  | 0 | my $value = delete $args{$range_key}; | 
| 78 | 0 |  |  |  |  | 0 | $primary_key->{$range_key} = $self->inflate_attribute_value($value); | 
| 79 |  |  |  |  |  |  | } | 
| 80 |  |  |  |  |  |  |  | 
| 81 | 0 |  | 0 |  |  | 0 | $args{Key}       ||= $primary_key; | 
| 82 | 0 |  | 0 |  |  | 0 | $args{TableName} ||= $self->table; | 
| 83 |  |  |  |  |  |  |  | 
| 84 | 0 |  |  |  |  | 0 | return $self->dynamodb->delete_item(\%args); | 
| 85 |  |  |  |  |  |  | } | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | sub inflate_item { | 
| 88 | 1 |  |  | 1 | 0 | 1120 | my ($self, $item) = @_; | 
| 89 | 1 |  |  |  |  | 1 | my %new; | 
| 90 |  |  |  |  |  |  |  | 
| 91 | 1 |  |  |  |  | 4 | for my $attr (keys %$item) { | 
| 92 | 9 |  |  |  |  | 10 | my $val = $item->{$attr}; | 
| 93 | 9 |  | 100 |  |  | 12 | $new{$attr} = $self->inflate_attribute_value($val) || next; | 
| 94 |  |  |  |  |  |  | } | 
| 95 |  |  |  |  |  |  |  | 
| 96 | 1 |  |  |  |  | 3 | return \%new; | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | sub inflate_hash_key { | 
| 100 | 0 |  |  | 0 | 0 | 0 | my ($self, $thing) = @_; | 
| 101 | 0 |  |  |  |  | 0 | my %new; | 
| 102 |  |  |  |  |  |  |  | 
| 103 | 0 | 0 |  |  |  | 0 | if (ref($thing) eq 'HASH') { | 
| 104 | 0 |  |  |  |  | 0 | my %new; | 
| 105 | 0 |  |  |  |  | 0 | for my $key (keys %$thing) { | 
| 106 | 0 |  |  |  |  | 0 | $new{$key} = $self->inflate_attribute_value($thing->{$key}); | 
| 107 |  |  |  |  |  |  | } | 
| 108 | 0 |  |  |  |  | 0 | return \%new; | 
| 109 |  |  |  |  |  |  | } | 
| 110 |  |  |  |  |  |  | else { | 
| 111 | 0 |  |  |  |  | 0 | return $self->inflate_attribute_value($thing); | 
| 112 |  |  |  |  |  |  | } | 
| 113 |  |  |  |  |  |  | } | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | sub inflate_attribute_value { | 
| 116 | 14 |  |  | 14 | 0 | 13 | my ($self, $thing) = @_; | 
| 117 |  |  |  |  |  |  |  | 
| 118 | 14 | 100 |  |  |  | 31 | if (ref($thing) eq 'HASH') { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 119 | 3 |  |  |  |  | 2 | my %vals; | 
| 120 | 3 |  |  |  |  | 6 | for my $key (keys %$thing) { | 
| 121 | 3 |  | 100 |  |  | 5 | $vals{$key} = $self->inflate_attribute_value($thing->{$key}) || next; | 
| 122 |  |  |  |  |  |  | } | 
| 123 | 3 | 100 |  |  |  | 8 | return unless keys %vals; | 
| 124 | 1 |  |  |  |  | 3 | return { M => \%vals }; | 
| 125 |  |  |  |  |  |  | } | 
| 126 |  |  |  |  |  |  | elsif (ref($thing) eq 'ARRAY') { | 
| 127 | 2 |  |  |  |  | 2 | my @vals; | 
| 128 | 2 |  |  |  |  | 3 | for my $t (@$thing) { | 
| 129 | 2 |  | 50 |  |  | 5 | push @vals, $self->inflate_attribute_value($t) || next; | 
| 130 |  |  |  |  |  |  | } | 
| 131 | 2 | 100 |  |  |  | 7 | return unless scalar @vals; | 
| 132 | 1 |  |  |  |  | 8 | return { L => [@vals] }; | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  | elsif (ref($thing) eq 'SCALAR') { | 
| 135 | 0 | 0 |  |  |  | 0 | return unless $$thing; | 
| 136 | 0 |  |  |  |  | 0 | return { B => MIME::Base64::encode_base64($$thing, '') }; | 
| 137 |  |  |  |  |  |  | } | 
| 138 |  |  |  |  |  |  | elsif ($self->isa_number($thing)) { | 
| 139 | 4 |  |  |  |  | 22 | return { N => "$thing" }; | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  | else { | 
| 142 | 5 | 100 |  |  |  | 10 | return unless $thing; | 
| 143 | 4 |  |  |  |  | 13 | return { S => $thing }; | 
| 144 |  |  |  |  |  |  | } | 
| 145 |  |  |  |  |  |  | } | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | sub isa_number { | 
| 148 | 9 |  |  | 9 | 0 | 7 | my ($self, $thing) = @_; | 
| 149 | 9 | 50 | 66 |  |  | 103 | return 1 if B::svref_2object(\$thing)->FLAGS & (B::SVp_IOK | B::SVp_NOK) | 
|  |  |  | 66 |  |  |  |  | 
| 150 |  |  |  |  |  |  | && 0 + $thing eq $thing | 
| 151 |  |  |  |  |  |  | && $thing * 0 == 0; | 
| 152 | 5 |  |  |  |  | 12 | return 0; | 
| 153 |  |  |  |  |  |  | } | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  | sub scan { | 
| 156 | 0 |  |  | 0 | 1 |  | my ($self, %args) = @_; | 
| 157 | 0 |  | 0 |  |  |  | $args{TableName} ||= $self->table; | 
| 158 | 0 |  |  |  |  |  | return $self->dynamodb->scan(\%args); | 
| 159 |  |  |  |  |  |  | } | 
| 160 |  |  |  |  |  |  |  | 
| 161 |  |  |  |  |  |  | sub scan_as_hashref { | 
| 162 | 0 |  |  | 0 | 1 |  | my ($self, %args)  = @_; | 
| 163 | 0 |  | 0 |  |  |  | $args{TableName} ||= $self->table; | 
| 164 | 0 |  |  |  |  |  | my $items_hashref  = {}; | 
| 165 | 0 |  |  |  |  |  | my $items_arrayref = $self->scan(%args); | 
| 166 | 0 |  |  |  |  |  | my $hash_key_name  = $self->hash_key; | 
| 167 |  |  |  |  |  |  |  | 
| 168 | 0 |  |  |  |  |  | for my $item (@$items_arrayref) { | 
| 169 | 0 |  |  |  |  |  | my $hash_key_value = delete $item->{$hash_key_name}; | 
| 170 | 0 |  |  |  |  |  | $items_hashref->{$hash_key_value} = $item; | 
| 171 |  |  |  |  |  |  | } | 
| 172 |  |  |  |  |  |  |  | 
| 173 | 0 |  |  |  |  |  | return $items_hashref; | 
| 174 |  |  |  |  |  |  | } | 
| 175 |  |  |  |  |  |  |  | 
| 176 |  |  |  |  |  |  | 1; | 
| 177 |  |  |  |  |  |  | __END__ |