Catalyst::Model::DBIC::Schemaでselect,insert,updateとかのメモ

※事前にTestDB::Memberに対応する
membersテーブルが作成されていること。
事前の設定などは前回の記事のModel部分を参照。
http://d.hatena.ne.jp/oggata/20110420/1303291384

キーによる検索
sub find :Local{
	my $mdata = $c->model('TestDB::Member')->find(1);
        my $name = $mdata->name;
}
カラムを条件とした検索
sub findByKey :Local{
	$c->stash->{TestTable} = $c->model('TestDB::Member')->find{'AAAA',{key=>'title'}}
}
結果をリストに表示する
=pod
<a>[%- TestTable.name|html -%]</a>
<a>[%- TestTable.price|html -%]</a>
<a>[%- TestTable.amount|html -%]</a>
<a>[%- TestTable.comment|html -%]</a>
=cut
大なり小なりを使った条件
sub where :Local{
  my $mdata = [$c->model('CatalDB::Member')->search({insert_time=>{'>'=>'2012-01-01'}})];
  my $name = $mdata->first->name;
}
複数カラムのAND条件
#and
sub where :Local{
	$c->stash->{TestTable} = [$c->model('TestDB::Member')->seaerch({title=>'AAAA',insert_time=>{'>'=>'2012-05-01'}})];
}
複数カラムのOR条件
#or
sub where :Local{
	$c->stash->{TestTable} = [$c->model('TestDB::Member')->search({title=>'AAAA'},{insert_time=>{'>'=>'2012-01-01'}})];
}
並び替え
#order by
sub orderby :Local{
	$c->stash->{list} = [$c->model('TestDB::Member')->search({},{order_by => {-desc => 'insert_time','title'}})];
}
カウントの取り方
sub count :Local{
  my($self,$c)=@_;
  my $result = $c->model('Catal::DB')->search({publish => 'aaaa'})->count;
  $c->response->body("${result}件が検索されました。");
  $c->stash->{template}='aa.tt';
}
ページャーの作り方
sub rows :LOcal{
  my($self,$c,$page)=@_;
  $page = 1 unless $page;
  $c->stash->{list}=[$c->model('Catal::DB')->search(undef,{order_by=>{-desc=>['published','price']},rows=>3,page=>$page})];
  $c->stash->{template}='aa.tt';
}
search_literalメソッドの使い方
sub search_literal :Local{
  my ($self,$c)=@_;
  $c->stash->{list} = [$c->model('Catal::Book')
	->search_literal('(title like ? or published > ?) and pubish = ?',('%Perl%','2009-01-01','AAAA'))];

}

レコードの登録、更新

レコードの登録
#レコードの登録
sub insert :Local{
  my($self,$c) = @_;
  my $row = $c->model('TestDB::Member')->create({
    id => 1,
    title => 'AAA',
    price => 1000,
    insert_date => \'NOW()'
  });
  $c->response->body('登録完了');
}
#レコードの登録2
sub insert2 :Local{
  my($self,$c) = @_;
  my $row = $c->model('TestDB::Member')->new({});
  $row->id(1);
  $row->title('AAA');
  $row->price(1000);
  $row->insert_date(\'NOW()');
  $row->insert();
}
レコードの更新
#データの更新
sub update :Local{
  my($self,$c)=@_;
  my $row = $c->model('TestDB::Member')->find('1');
  $row->title('BBB');
  $row->price(1200);
  $row->update();
  $c->response->body('更新完了');
}
レコードがなければInsert
#find_or_new
sub find_or_new :Local{
  my($self,$c)=@_;
  my $TestTable = $c->model('TestDB::Member')->find_or_new({
    id => 1,
    title => 'CCC',
    price => 1000,
    insert_date => '2012-05-01'
  });
  if($TestTable->in_storage){
  	$c->response->body('既にデータが存在します');
  }else{
  	$TestTable->insert();
  	$c->response->body('登録しました');
  }
}
レコードがあればUpdate、無ければInsert
#update_or_new
sub update_or_new :Local{
  my($self,$c)=@_;
  my $review = $c->model('TestDB::Member')->update_or_new({
    id => 1,
    title => 'aaaa',
    price => 100,
    insert_date = '2012-01-01'
  });
  if($review->in_storage){
 		$c->response->body('update完了');
  }else{
  	$review->insert();
  	$c->response->body('insert完了');
  }
}

トランザクション

トランザクションの使い方
#transaction(DBIx::ClassSchemaクラスのtxn_doメソッド)
sub transaction :Local{
	my($self,$c)=@_;
	eval{
    $c->model('TestDB')->schema->txn_do(sub{
      $c->modle('TestDB::Member')->create({
        id => 1,
        title => 'AAAA'
      });
      $c->model('TestDB::Member')->create({
      	id => 1,
      	title => 'AAAA'
      });
    });
	};
  if($@){
  	if($@ =~ /rollback failed/ ){
  		$c->response->body('ロールバック失敗');
  	}else{
      $c->response->body('ロールバック完了');
  	}
  	return;
  }
  $c->response->body('トランザクション成功');
}

ActionとModelの分離

#Actionとmodelの分離
Catalyst::ModelLLAdaptorを使用する

#アダプターの作成
_create.pl model モデル名 Adaptor モデル化するクラス名 コンストラクタ名

catal_create.pl model MemberAdaptor Adaptor Catal::Api::Member new

use Catal::Api::Member; #削除
sub adaptor :Local{
  my ($self,$c) = @_;
  my $TestTable = $c->model('MemberAdaptor');
  $c->stash->{list} = $TestTable->getInfosByPublish('テストだよ');
  $c->stash->{template}->'list.tt';
}