M.C.P.C. (Mamesibori Creation Plus Communication)

印刷屋から五反田のWeb屋に転職したCLのブログです。

Amazon SimpleDB用アクセスモジュールをNet::Amazon::SimpleDB::SimpleからAmazon::SimpleDB::Clientに書き換え

昔(今から4年前)作ったPerlによるAmazon SimpleDBの作例サンプル、「はてな牧場」っていうのがあって、

http://labo.dtpwiki.jp/hateboku/
http://blog.dtpwiki.jp/photos/uncategorized/2009/05/18/hatebokus.jpg
作った時のエントリ
http://blog.dtpwiki.jp/dtp/2009/05/post-ca87.html

この前サーバを移転したときに、今では手に入らないモジュール「Net::Amazon::SimpleDB::Simple」を使っていたので動かなくなっていたのですけれども、がりっと「Amazon::SimpleDB::Client」(Amazonが配布している方のAmazon::SimpleDBに含まれている)に作り替えたので、メモ。

宣言

  • before:
use Net::Amazon::SimpleDB::Simple;

my $sdb = Net::Amazon::SimpleDB::Simple->new({
  AWS_ACCESS_KEY_ID     => $AWS_ACCESS_KEY_ID,
  AWS_SECRET_ACCESS_KEY => $AWS_SECRET_ACCESS_KEY,
  domain => $domain,
});
  • after:
use Amazon::SimpleDB::Client;

my $sdb = Amazon::SimpleDB::Client->new(
  $AWS_ACCESS_KEY_ID,
  $AWS_SECRET_ACCESS_KEY,
);

select

ハッシュリファレンスで設定する形になった。実行後$res->getSelectResult->getItem;をする。

  • before:
# クエリ解析
# HTMLから要求されたIDに関してAmazon SimpleDBから取得
( my $id = $q->param('id') ) =~ s/[^\d\w_]//g; # はてなIDにサニタイズ
my $output = $sdb->select(
  sprintf 'SELECT * FROM hateboku WHERE id="%s"', $id
);  
  • after:
# クエリ解析
# HTMLから要求されたIDに関してAmazon SimpleDBから取得
( my $id = $q->param('id') ) =~ s/[^\d\w_]//g; # はてなIDにサニタイズ
my $response = $sdb->select({
  SelectExpression => sprintf 'SELECT * FROM hateboku WHERE id="%s"', $id,
});
my $item_list = $response->getSelectResult->getItem;

get

出てくるデータの形が違うので、Afterの方では一度順番に取り出して分類している。

  • before:
# 取得した位置データを整理
my $positions = [];
foreach my $res ( keys %$output ) {
  for (my $i = 0; $i < scalar( $output->{$res}->{y} ); $i++ ) {
    $ctx->add($output->{$res}->{url}->[0]);
    my $item;
    ( my $x = $output->{$res}->{x}->[$i] ) =~ s/[^\d]//g;
    ( my $y = $output->{$res}->{y}->[$i] ) =~ s/[^\d]//g;
    $item->{'id_'.$ctx->hexdigest} = {
      x => $x,
      y => $y,
    };
    push @$positions, $item;
  } 
}
  • after:
# 取得した位置データを整理
my $item_list = $response->getSelectResult->getItem;
my $positions = [];
for my $item ( @$item_list ) {
  my $attribute_list = $item->getAttribute;
  my $output = {};
  for my $item2 ( @$attribute_list ) {
    push @{$output->{$item2->getName}} , $item2->getValue;
  }
  for (my $i = 0; $i < $#{$output->{y} }; $i++ ) {
    $ctx->add($output->{url}->[0]);
    my $item;
    ( my $x = $output->{x}->[$i] ) =~ s/[^\d]//g;
    ( my $y = $output->{y}->[$i] ) =~ s/[^\d]//g;
    $item->{'id_'.$ctx->hexdigest} = {
      x => $x,
      y => $y,
    };
    push @$positions, $item;
  } 
}

post

書き込みの時のハッシュリファレンスの作り方がちょっと深くなったので注意

  • before:
  # Amazon SimpleDBに書き込み
  $sdb->put_attributes( $url, {
    id  => $id,
    url => $url,
    x   => $x, 
    y   => $y, 
  });
  • after:
  my $attributes = pairs_to_attributes({
      id  => $id,
      url => $url,
      x   => $x, 
      y   => $y, 
  });

  # Amazon SimpleDBに書き込み
  my $res = $sdb->putAttributes({
    DomainName => $domain,
    ItemName   => $url,
    Attribute  => $attributes,
  }); 

sub pairs_to_attributes {
  my $hash = shift;
  my @attributes;
  foreach my $key ( keys %$hash ) {
    push @attributes, {
      Name  => $key,
      Value => $hash->{$key},
    };
  }
  return \@attributes;
}