tag:blogger.com,1999:blog-50971830659710962712024-03-14T15:57:44.835+09:00tkg84's devlogtkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.comBlogger26125tag:blogger.com,1999:blog-5097183065971096271.post-73703704768463438862013-02-20T17:51:00.000+09:002013-02-20T19:17:53.367+09:00Azure Virtual MachineでVisual Studio & JenkinsなCI環境を構築する(2) ~ Githubプライベートリポジトリからのソース取得<p>「Azure Virtual MachineでVisual Studio & JenkinsなCI環境を構築する(1) ~ インストール編」でAzure Virtual Machineを使ったJenkinsサーバの構築を行いました。今回はそれに続いてJenkinsからgithubのプライベートリポジトリからソースコードを取得してビルドする方法を紹介します。</p><a href="http://tkg84.blogspot.com/2013/02/azure-virtual-machinevisual-studio.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-15633800216517300042013-02-19T18:48:00.000+09:002013-02-19T18:48:00.572+09:00Azure Virtual MachineでVisual Studio & JenkinsなCI環境を構築する(1) ~ Jenkinsのインストール<p>Azure Virtual Machine上にVisual StudioとJenkinsサーバを使ったCI環境を構築してみました。今回はそのVS&JenkinsなCI環境の構築手順を紹介します。</p> <a href="http://tkg84.blogspot.com/2013/02/azure-virtual-machinevisual-studio_19.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-60194622049488532592013-02-18T19:00:00.000+09:002013-02-18T19:00:10.348+09:00Windows Azure Tableの検索パフォーマンス<p><font color="#333333">大分昔(2011年の年末あたり)にAzure Tableへのクエリパターン別の検索パフォーマンスを測って記事を書いていたのですが、公開してませんでした(忘れてた。。。)。</font></p> <p><font color="#333333">その後いわゆるGen 2のストレージが現れたりしているので、絶対値的には参考にならないと思います。ただ、クエリエンジンがより最適化されるようになったとかっていう話は聞かないので、各クエリ別の相対的な評価としては通用するかと思います。</font></p> <p><font color="#333333">このまま公開しないのももったいないので、以下最初に書いた時のままですが公開したいと思います。</font></p> <hr> <p>Windows Azure Tableを使うにあたって、どんなクエリだとどの程度のパフォーマンスが出るのかは気になるところだと思います。昨年末あたりにパフォーマンス計測だけして放っていたので、そろそろ書きます。</p> <p>ここでは単一パーティションでのクエリ性能を調べるため、単一パーティション内における「RowKeyによる検索とプロパティによる検索」と、「レンジ検索とOR検索」でそれぞれパフォーマンス差がどの程度あるかという点をベンチマークします。そこでベンチマーク対象のクエリは以下の6種類です。</p> <ol> <li>RowKeyの完全一致 </li> <li>RowKeyのレンジ検索 </li> <li>RowKeyのOR検索 </li> <li>プロパティの完全一致 </li> <li>プロパティのレンジ検索 </li> <li>プロパティのOR検索 </li> </ol> <a href="http://tkg84.blogspot.com/2013/02/windows-azure-table.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-5485059735802571312013-02-15T18:34:00.000+09:002013-02-18T16:10:36.597+09:00デブサミ2013メモ 【14-D-6】Yahoo! JAPANの新しいクラウドストレージサービス ~Yahoo! JAPANがRiakを選んだ理由とは?~<table cellspacing="0" cellpadding="0" width="100%" style="padding-bottom:20px;padding-top:10px;"><tr> <td style="line-height:1;text-align:left;padding-bottom:0px;"> <h3 style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#262626;font-weight:bold;font-size:11px;"><a href="http://evernote.com/" style="color:#3697b3;font-weight:bold;text-decoration:none;">From Evernote:</a></h3></td> </tr>
<tr> <td style="line-height:1.3;text-align:left;padding-top:0px;padding-bottom:7px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#b5b5b5;font-size:11px;"> <h1 style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-bottom:0;padding-right:0;padding-left:0;color:#262626;font-weight:bold;padding-top:5px;font-size:18px;">【14-D-6】Yahoo! JAPANの新しいクラウドストレージサービス ~Yahoo! JAPANがRiakを選んだ理由とは?~</h1>Clipped from: <a href="http://event.shoeisha.jp/detail/1/session/26/" style="color:#3697b3;font-weight:bold;text-decoration:none;">http://event.shoeisha.jp/detail/1/session/26/</a> </td> </tr>
</table><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="ennote"><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifEz0Sh6v-P5WCpiwoGU0NTofaqis5-69oVOCuHD-Q1L6m4qDhn3AAurfDMzDLBH-ZsTYlJePvxnb87KlBu16A9O4teREMxd4tZGkToZWSuShzdMO5QrGG3VjpeqWzW5_lOE5DPfx9sxi4/s1600/290f60715c3e7268bba87244a2686e82-754471.jpeg"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifEz0Sh6v-P5WCpiwoGU0NTofaqis5-69oVOCuHD-Q1L6m4qDhn3AAurfDMzDLBH-ZsTYlJePvxnb87KlBu16A9O4teREMxd4tZGkToZWSuShzdMO5QrGG3VjpeqWzW5_lOE5DPfx9sxi4/s320/290f60715c3e7268bba87244a2686e82-754471.jpeg" border="0" alt="" id="BLOGGER_PHOTO_ID_5845083073613052786" /></a></div><div><strong>阪田浩隆 </strong>ヤフー株式会社 マーケティングソリューションカンパニー 新規事業本部</div><div>2004年ヤフー株式会社入社。</div><div>認証システム、社内ツールの開発経験を経て、基盤システム開発リーダーに就任。</div><div>主に大規模分散コアシステムの開発・保守・運用に従事。</div><div>2009年7月よりオブジェクトストレージ開発を開始し、2011年10月Yahoo!ボックスをリリース。</div><div>2012年6月よりクラウド基盤・ビックデータインフラ開発のチーフアーキテクトを担当。</div><div><br />
</div><div><br />
</div><div>===メモ===<br />
Yahooを支える技術<br />
<br />
96年から分散kvsに取り組んできた(独自開発)<br />
認証、課金、広告、cdn すべての基盤となるコアテクノロジになっている<br />
<br />
データレプリケーションにも対応<br />
フロントがdcをまたがる構成とか<br />
<br />
独自開発のオブジェクトストレージがある<br />
利用実績<br />
Yahooボックス 数TB/dayでデータ増加<br />
天気災害<br />
ブックストア<br />
ロコプレイス<br />
など<br />
<br />
<br />
Riakの紹介</div><div><br />
Riak kvsエンジン<br />
Riak eds レプリケーションとか<br />
Riak cs オブジェクトストレージ、データはriak,riak edsに保存<br />
<br />
ノードをリング状に並べる<br />
Consistent hashing<br />
CAP定理に従う、1ノード壊れても可用性は失わない<br />
<br />
Riak eds インストール<br />
Yumでインストール可<br />
設定変更<br />
自分自身のipを設定<br />
Restで受け付けるipの設定<br />
Earlangの設定<br />
じぶんのip<br />
それからクラスターにjoin<br />
<br />
利用する場面<br />
高速なデータアクセスが必要な場合<br />
将来的にデータ件数が増える場合<br />
<br />
Riak csインストール<br />
Yumでインストール<br />
同時にstanchonコンポーネントをインストール<br />
<br />
Bucketを作ってそこにファイルをいれる感じ s3cmdコマンドを使って操作<br />
<br />
オブジェクトストレージ自体をマウントできる<br />
<br />
事例<br />
Lohaco アスクル<br />
画像ファイルの配信<br />
450req/s<br />
<br />
Riak csを利用したyahooストレージ<br />
2013/4 本番<br />
<br />
<br />
なぜriakをえらんだか?<br />
<br />
S3のapiで使えるものが必要だった<br />
運用コスト削減<br />
既存ノウハウを活かしやすいアーキテクチャ<br />
<br />
Riak meetup 3/11<br />
</div></div>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-79592665724315858552013-02-15T18:33:00.000+09:002013-02-18T16:10:42.659+09:00デブサミ2013メモ 【14-C-5】O2Oのデザイン<table cellpadding="0" cellspacing="0" style="padding-bottom: 20px; padding-top: 10px; width: 100%px;"><tbody>
<tr> <td style="line-height: 1; padding-bottom: 0px; text-align: left;"><h3 style="color: #262626; font-size: 11px; font-weight: bold; margin-bottom: 0; margin-left: 0; margin-right: 0; margin-top: 0; padding-bottom: 0; padding-left: 0; padding-right: 0; padding-top: 0;"><a href="http://evernote.com/" style="color: #3697b3; font-weight: bold; text-decoration: none;">From Evernote:</a></h3></td> </tr>
<tr> <td style="border-bottom-color: #b5b5b5; border-bottom-style: solid; border-bottom-width: 1px; font-size: 11px; line-height: 1.3; padding-bottom: 7px; padding-top: 0px; text-align: left;"><h1 style="color: #262626; font-size: 18px; font-weight: bold; margin-bottom: 0; margin-left: 0; margin-right: 0; margin-top: 0; padding-bottom: 0; padding-left: 0; padding-right: 0; padding-top: 5px;">【14-C-5】O2Oのデザイン</h1>Clipped from: <a href="http://event.shoeisha.jp/detail/1/session/18/" style="color: #3697b3; font-weight: bold; text-decoration: none;">http://event.shoeisha.jp/detail/1/session/18/</a> </td> </tr>
</tbody></table><div class="ennote" style="-webkit-line-break: after-white-space; -webkit-nbsp-mode: space; word-wrap: break-word;"><div><strong>河村奨 </strong>Librize</div><div><br />
</div><div><br />
</div><div>===メモ===<br />
Online to offlineの例<br />
クーポン<br />
ソーシャルで伝えたくなる何か<br />
口コミ<br />
在庫の事前確認<br />
など<br />
<br />
Offline to onlineの例<br />
qrコード<br />
シェアしたくなるもの<br />
チェックイン<br />
<br />
オンラインとオフラインは不可分に<br />
拡張現実の世界へ<br />
<br />
リアルなものにオンラインから付加価値を与えることが重要<br />
<br />
バーコードUI<br />
バーコードリーダだけでUIを操作する<br />
<br />
<br />
Tips<br />
バーコードリーダ ー>キーボードとして認識される</div></div>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-5480523593804426972013-02-15T18:32:00.000+09:002013-02-18T16:10:48.891+09:00デブサミ2013メモ 【14-A-4】グリーにおけるスマホアプリ開発~ネイティブ編<table cellspacing="0" cellpadding="0" width="100%" style="padding-bottom:20px;padding-top:10px;"><tr> <td style="line-height:1;text-align:left;padding-bottom:0px;"> <h3 style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#262626;font-weight:bold;font-size:11px;"><a href="http://evernote.com/" style="color:#3697b3;font-weight:bold;text-decoration:none;">From Evernote:</a></h3></td> </tr>
<tr> <td style="line-height:1.3;text-align:left;padding-top:0px;padding-bottom:7px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#b5b5b5;font-size:11px;"> <h1 style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-bottom:0;padding-right:0;padding-left:0;color:#262626;font-weight:bold;padding-top:5px;font-size:18px;">【14-A-4】グリーにおけるスマホアプリ開発~ネイティブ編</h1>Clipped from: <a href="http://event.shoeisha.jp/detail/1/session/4/" style="color:#3697b3;font-weight:bold;text-decoration:none;">http://event.shoeisha.jp/detail/1/session/4/</a> </td> </tr>
</table><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="ennote"><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCiI7VaZmEu-JH9gP4NJYyXOBpM61S49itH6oEXcb_ar4OcBEAptBa_V7P2Zazp_yUOJd9EdTDVHL8hcxoLg2a87ZGMAfpcHivNb-Dlae3-GJD8CHFFlfvxYBFlDlCp6lIBEzcIfbzcwm4/s1600/182b8c5d3e3243a7bb50ee92e6105948-735617.jpeg"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCiI7VaZmEu-JH9gP4NJYyXOBpM61S49itH6oEXcb_ar4OcBEAptBa_V7P2Zazp_yUOJd9EdTDVHL8hcxoLg2a87ZGMAfpcHivNb-Dlae3-GJD8CHFFlfvxYBFlDlCp6lIBEzcIfbzcwm4/s320/182b8c5d3e3243a7bb50ee92e6105948-735617.jpeg" border="0" alt="" id="BLOGGER_PHOTO_ID_5845083421742792818" /></a></div><div><strong>堀田敏史 </strong>グリー株式会社 開発本部 Japan Studio統括部 第1プロダクション部</div><div><br />
</div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqVjz7csn8DBZtffw6gVXs9YP-2cRWQCz4lp0eYAOMWhLEAYyeY7KuHYJf-dZtOgdk8K4KTqAkhEMvD59jahr3f2k8oSCY9aFoCZHbSDLF_gLElCpApSeiRPpTwbw7bvTsZMaqAw0OFxJa/s1600/fa9856a297877f887673fc2173410fd8-736898.jpeg"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqVjz7csn8DBZtffw6gVXs9YP-2cRWQCz4lp0eYAOMWhLEAYyeY7KuHYJf-dZtOgdk8K4KTqAkhEMvD59jahr3f2k8oSCY9aFoCZHbSDLF_gLElCpApSeiRPpTwbw7bvTsZMaqAw0OFxJa/s320/fa9856a297877f887673fc2173410fd8-736898.jpeg" border="0" alt="" id="BLOGGER_PHOTO_ID_5845083426045063458" /></a></div><div><span style="font-weight: bold;">白倉悠祐 </span>グリー株式会社 開発本部 Japan Studio統括部 第1プロダクション部<br />
<br />
<br />
===メモ===<br />
サーバサイド<br />
Webアプリとネイティブの違い<br />
<br />
通信タイミング</div><div> ウェブは画面ベース</div><div> ネイティブはフローベース、必要なタイミングで行われる<br />
表示データ(アセット)のありか</div><div> ネイティブだとローカルにキャッシュできる<br />
<br />
通信タイミングを考える<br />
都度通信<br />
非同期通信<br />
更新タイミングで適宜通信<br />
<br />
通信していない時のログ<br />
クライアントで集めて、適宜サーバへ送信する必要あり<br />
<br />
データ管理<br />
更新頻度が低い</div><div> キャッシュ<br />
更新頻度が高い</div><div> 適宜通信<br />
<br />
マスタデータの同期<br />
最初に全部<br />
更新分はテーブル単位でハッシュ値比較して、更新分だけ同期<br />
<br />
</div><div>アセットの同期<br />
最初は全部(容量はコントロールすべき、全部やったら大きすぎるなど<br />
更新分はアセットひとつ単位で同期<br />
アセット管理のテーブルをマスタ上に持ってる雰囲気<br />
<br />
APIの構成<br />
JSONフォーマットでデータをやり取り<br />
クライアントとの擦り合わせが重要<br />
Webと同じ技術</div><div> Php,MySQL,flare,memcached<br />
<br />
通信タイミングの設計が重要<br />
<br />
<br />
<br />
クライアントサイド<br />
<br />
通信と表示で役割分担して開発<br />
<br />
使ってる技術<br />
Unity<br />
Gree unity platform<br />
Lightweight swf<br />
<br />
<br />
ちょっとした工夫<br />
<br />
遷移図からコードを自動生成<br />
<br />
考えたこと<br />
共通項は何か?<br />
どこまで自動生成するか?<br />
どれくらいなら使いやすいか?<br />
<br />
Yamlで遷移を記述<br />
Graphvizで図式化<br />
rubyのコンバータ(独自)でC#のコード生成<br />
<br />
良かったこと</div><div>遷移図が整備されているため、新しく入った人にも説明しやすい</div><div> これ見といて、で済む</div><div>全体のコードに統一感ができて、読みやすい</div></div>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-28986511353260773152013-02-15T18:31:00.000+09:002013-02-18T16:10:57.457+09:00デブサミ2013メモ 【14-B-3】自動改札機の運賃計算プログラムのデバッグ手法 ~10の40乗のパターンをいかにテストするか~<table cellspacing="0" cellpadding="0" width="100%" style="padding-bottom:20px;padding-top:10px;"><tr> <td style="line-height:1;text-align:left;padding-bottom:0px;"> <h3 style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#262626;font-weight:bold;font-size:11px;"><a href="http://evernote.com/" style="color:#3697b3;font-weight:bold;text-decoration:none;">From Evernote:</a></h3></td> </tr>
<tr> <td style="line-height:1.3;text-align:left;padding-top:0px;padding-bottom:7px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#b5b5b5;font-size:11px;"> <h1 style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-bottom:0;padding-right:0;padding-left:0;color:#262626;font-weight:bold;padding-top:5px;font-size:18px;">【14-B-3】自動改札機の運賃計算プログラムのデバッグ手法 ~10の40乗のパターンをいかにテストするか~</h1>Clipped from: <a href="http://event.shoeisha.jp/detail/1/session/9/" style="color:#3697b3;font-weight:bold;text-decoration:none;">http://event.shoeisha.jp/detail/1/session/9/</a> </td> </tr>
</table><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="ennote"><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKUfS6IpTDGzgtO4olxbFWSpNqRU8xBZkrPUURDQewO9ALyjcEgIq4OzdnGCnrRwvLbOsV7yMx2CGFTIW7k6H5Bvyzueqb_RCX16j_dK4auPdeRgFksXvkd7dcpZ0KvAYvK35vAU1Gw6y8/s1600/c0c2dc9877fdd8347c3b40a93676c876-748669.jpeg"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKUfS6IpTDGzgtO4olxbFWSpNqRU8xBZkrPUURDQewO9ALyjcEgIq4OzdnGCnrRwvLbOsV7yMx2CGFTIW7k6H5Bvyzueqb_RCX16j_dK4auPdeRgFksXvkd7dcpZ0KvAYvK35vAU1Gw6y8/s320/c0c2dc9877fdd8347c3b40a93676c876-748669.jpeg" border="0" alt="" id="BLOGGER_PHOTO_ID_5845083478553026466" /></a></div><div><strong>幡山五郎 </strong>オムロンソーシアルソリューションズ</div><div>社内で運賃計算ソフトウェアの開発部署でプログラムのデバッグを担当していました。現在は、社内開発現場への形式手法導入プロジェクトの主担当をしています。</div><div><br />
</div><div><br />
</div><div>===メモ===</div><div>運賃計算の膨大なテストケース</div><div>乗換</div><div>特別料金</div><div>割引</div><div>など、色々なルールがあって、テストケースがあまりにも複雑</div><div>西船橋とか鬼門</div><div><br />
</div><div>過去</div><div>積み上げ式で属人性が高い</div><div><br />
</div><div>今(運賃検証システムという名前)</div><div>まず全体を定義</div><div>電車の乗り降りをパターン化(8種類</div><div>すべての駅をあてはめると10^40</div><div>それから3段階の絞り込みを行って10^8ぐらいまで減らす</div><div><br />
</div><div>利点</div><div>積み上げでは見つからないパターンがみつかる</div><div>絞り込みに理由があるので、なぜそのテストを行っていないのかに答えやすい</div><div><br />
</div><div>テストの実施</div><div>一回流すのに3週間ぐらいかかる</div><div>検証用のソフトウェアを独立で開発して答えを突き合わせる</div><div>両方間違っているけど、たまたま一致するケースがある</div><div> 別のチーム、別の言語、別のプログラムでやって、同じバグが起きにくいようにする</div><div><br />
</div><div>実機と検証用で制約が違う</div><div>処理時間50ms</div><div>メモリ20MBなど</div><div>検証用は制約が緩いため、原則通りのアルゴリズムで計算できる</div><div> 駅の増加などでも変更不要</div><div> 実機用アルゴリズムでは対応してないパターンにも対応可</div><div><br />
</div><div>最終的に仕様書の問題が残った</div><div>VDM++で仕様を記述</div><div> 仕様書の暗黙知が列挙できた</div></div>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-60824256313379947782013-02-15T18:30:00.000+09:002013-02-18T16:11:04.419+09:00デブサミ2013メモ 【14-C-2】決済だけではないペイパル(ペイパルアクセス活用事例)<table cellspacing="0" cellpadding="0" width="100%" style="padding-bottom:20px;padding-top:10px;"><tr> <td style="line-height:1;text-align:left;padding-bottom:0px;"> <h3 style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#262626;font-weight:bold;font-size:11px;"><a href="http://evernote.com/" style="color:#3697b3;font-weight:bold;text-decoration:none;">From Evernote:</a></h3></td> </tr>
<tr> <td style="line-height:1.3;text-align:left;padding-top:0px;padding-bottom:7px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#b5b5b5;font-size:11px;"> <h1 style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-bottom:0;padding-right:0;padding-left:0;color:#262626;font-weight:bold;padding-top:5px;font-size:18px;">【14-C-2】決済だけではないペイパル(ペイパルアクセス活用事例)</h1>Clipped from: <a href="http://event.shoeisha.jp/detail/1/session/15/" style="color:#3697b3;font-weight:bold;text-decoration:none;">http://event.shoeisha.jp/detail/1/session/15/</a> </td> </tr>
</table><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="ennote"><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCTVXzIowaxtbTAPyv7DVUpUmrfvnC-0hz5GKCjq8o6u32cimARKXegTjWnc24RsOxC0nKosWHUDFnIZKZMH3_4ilFWZddThiHpbvdrBxQNTYGsneskGJLJvaO4dWFq76EpWHmADpMJ-nL/s1600/b1600cfb2c24fed30d286ee04d4d61b2-727907.jpeg"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCTVXzIowaxtbTAPyv7DVUpUmrfvnC-0hz5GKCjq8o6u32cimARKXegTjWnc24RsOxC0nKosWHUDFnIZKZMH3_4ilFWZddThiHpbvdrBxQNTYGsneskGJLJvaO4dWFq76EpWHmADpMJ-nL/s320/b1600cfb2c24fed30d286ee04d4d61b2-727907.jpeg" border="0" alt="" id="BLOGGER_PHOTO_ID_5845083388076067666" /></a></div><div><strong>植野稔之 </strong>PayPal Pte. Ltd, インテグレーションマネージャー</div><div>1985年に富士通に入社し、ワークステーション向けアプリケーション及びマルチメディアアプリケーションの開発に従事。</div><div>その後1997年よりシリコンバレーのベンチャー企業数社にてシステム運用やバックエンドシステム開発を経験後、2001年に独立。</div><div>独立後は決済システムやWebサーバシステムのコンサルティング、開発を行う。</div><div>2010年からはペイパルジャパンのインテグレーションマネージャとして、ペイパルの日本での導入・普及活動中です。</div><div><br />
</div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1BAcC1nqxuSeo54CDYwgUfYV01eOZ2tL2hhU3cog0juDmG49cZgzrhX5LWzQogaCmOGg6TrTl-ph-0RPXszFBmNR3sFgA7dpH9U65eTRcSXf7ClM31bBGdPjSuHEcbFmRuPDSykq6uNUA/s1600/180290efb34ae4d8bf02914710697745-730829.jpeg"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1BAcC1nqxuSeo54CDYwgUfYV01eOZ2tL2hhU3cog0juDmG49cZgzrhX5LWzQogaCmOGg6TrTl-ph-0RPXszFBmNR3sFgA7dpH9U65eTRcSXf7ClM31bBGdPjSuHEcbFmRuPDSykq6uNUA/s320/180290efb34ae4d8bf02914710697745-730829.jpeg" border="0" alt="" id="BLOGGER_PHOTO_ID_5845083399041292962" /></a></div><div><span style="font-weight: bold;">志水信也 </span>PayPal Pte. Ltd, インテグレーションマネージャー</div><div>日系電機メーカ米国支社において、ウェブデータベース開発等に携わる。</div><div>その後、決済関連ベンチャーにてシステム運用、インフラ構築や新規サービスの企画・開発を行う。</div><div>外資系EC関連オンラインサービス会社を経て、2012年よりインテグレーションマネージャとしてペイパルの導入支援を担当。</div><div><br />
</div><div><br />
</div><div>===メモ===</div><div>決済総額1450億ドル/年</div><div>activeaccount1.23億</div><div>Ebayの決済は全体の32%</div><div><br />
</div><div>Paypal access</div><div>Openidの一種(Oauth 2.0 / opened connect standard 1.0準拠</div><div>登録されている住所、電話番号データの信頼性が高い</div><div>クレジットカード情報は提供されない</div><div>x.com デベロッパーポータル</div><div>github.com/paypal/paypal-access</div><div><br />
</div><div>PayPal accessと決済の連携</div><div>現状</div><div> Paypalaccessとcheckoutの両方でログインが必要</div><div>近い将来(数ヶ月後?</div><div> Checkoutでのログインをスキップ</div><div><br />
</div><div>PayPal here</div><div>ユースケースの動画(コーヒーの移動販売</div><div>1 クレジットカード払い</div><div>2 事前チェックイン&paypalアカウント決済</div><div><br />
</div><div>Api(2種類)で利用可能</div><div><br />
</div><div>Paypal Here mobile apps API</div><div>自前のレジアプリケーション内にPayPal hereのカード決済を組み込める</div><div>アプリ間連携を利用</div><div>Paypalのモバイルアプリに決済する商品情報を渡す(json形式</div><div>まだドキュメント等は公開されてない</div><div><br />
</div><div>Paypal Here API</div><div>商品情報の登録とかができるみたい</div><div>mobile apps APIよりももっと低レベルなAPIな雰囲気</div></div>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-62560966845451903442012-11-07T11:17:00.001+09:002012-11-07T11:17:55.760+09:00ブランチの作成&追跡ブランチ化の方法<p>久しぶりの更新です。今回のgitの使い方のお話です。</p><p>本来gitは分散型で、中央集権型のサーバを持たない使い方が想定されていると思いますが(実際オープンソースの開発だと特に)、仕事でgitを使うような場合はやはりSubversionに慣れているのもあり、共有サーバを一台用意し、それに対して開発メンバがPushしていくという使い方が多いかと思います。</p><p>そのような使い方の場合は、リモートにあるブランチを追跡する追跡ブランチをローカルに持っておくのが便利ですが、今までは「ローカルブランチ作成」→「追跡ブランチ化のコンフィグ設定」→「リモートへ作成したブランチをPush」という手順で追跡ブランチを作成していました。</p><p>ちょっとgitの使い方を調べていた所、もっと賢い方法があったので紹介します。(自分への備忘録としても。。。)</p><script src="https://gist.github.com/4029179.js?file=gistfile1.txt"></script> <p>これで、追跡ブランチとして新しいブランチを作成できます。</p>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-67463195925179588172011-11-28T15:54:00.001+09:002011-11-29T10:39:54.573+09:00Azure Tableによるデータ検索 - エンティティの結合(Join)<p>Windows Azure Tableに対するLINQクエリおよびREST APIでは、Joinによるエンティティの結合をサポートしていません。もちろんAzure Tableを使う時には、関連するエンティティのプロパティをコピーさせるなどしてJoinする必要がないようにデータモデルの設計を行います。</p><p>ただそれでも、仕様変更や機能追加によって当初想定していなかったデータの結合が必要になる場合もあります。そして、どうしてもデータモデルを変更したくないような場合には、Join処理が必要になってくると思います。</p><p>今までシステムを実装してきた中で行ったJoinの実装パターンを紹介します。</p><a href="http://tkg84.blogspot.com/2011/11/azure-table-join.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-62453308122079660752011-11-28T13:17:00.001+09:002011-11-28T13:21:21.796+09:00Azure Tableによるデータ検索処理<p>Windows AzureのTableストレージにおけるデータ検索では、基本的にはStorage Client LibraryのLinq to Azure Tableを使って開発するものの、AzureのLinqでは一部のLinq式しかサポートしておらず大部分のLinq式がサポート外になっています。<a href="http://msdn.microsoft.com/en-us/library/windowsazure/dd135725.aspx">http://msdn.microsoft.com/en-us/library/windowsazure/dd135725.aspx</a></p><p>そのため、Azure Tableにおいてデータ検索を行う際は、Linq to Objectを並行して利用する必要が出てきます。この使い分けについての基本的な考え方は表示対象エンティティをLinq to Azure Tableで取得し、その後のデータ加工処理をLinq to Objectで行うといった雰囲気です。ただしこの2つのLinqの使い分けでは、Linq to Azure Tableにおける取得可能なエンティティ数に制限がある(1000件未満、クエリ実行時間5秒以下 参考:<a href="http://msdn.microsoft.com/en-us/library/windowsazure/dd179421.aspx">http://msdn.microsoft.com/en-us/library/windowsazure/dd179421.aspx</a>)ので、この制限にかからないよう十分にLinq to Azure Tableで絞込みを行う必要です。</p><a href="http://tkg84.blogspot.com/2011/11/azure-table.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-29641529135535469022011-06-17T13:36:00.001+09:002011-06-17T13:36:30.624+09:00Windows AzureでLog4Net RollingFileAppenderを使う<p>Windows Azure上で、Log4NetのRollingFileAppenderによりBlobストレージ上にログファイルを書きだすようにしてみたので、その方法についてまとめです。</p> <p>やり方自体は単純で、RollingFileAppenderのログファイルの出力先を Windows Azureの Local Storageに設定し(これが意外と面倒)、出力先のLocal Storageの内容をDiagnostics Monitorで転送させてるだけです。またlog4netの設定ファイルlog4net.configはBlobストレージ上に置かれたものを使うようにしました。</p> <a href="http://tkg84.blogspot.com/2011/06/windows-azurelog4net.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-37617347036339269072011-05-30T13:51:00.003+09:002011-06-09T13:11:55.496+09:00CygwinでGit/GitHubを使うための環境構築<p>最近Gitを使い始めたんですが、コミットメッセージが文字化けるとか色々悩まされたんで、その結論的なものをまとめます。とりあえず、これでCygwinだけを使っている分には文字化けに悩まされずに済みそうです(やってることは文字コードをUTF-8で統一するように設定してるだけですが)</p> <p>以下セットアップ手順です(既にGitHub上にアカウントを持ってる前提です)。</p> <a href="http://tkg84.blogspot.com/2011/05/cygwingitgithub.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-32659069542852363302011-05-16T17:39:00.001+09:002011-05-16T17:39:29.386+09:00Azure Table Storageに非サポート型のプロパティを保存する<p>標準のAzure Table Storageにおいては以下の型のみが保存可能な型としてサポートされており、これ以外のプロパティとして持つエンティティを保存しようとするとエラーになってしまいます。</p> <table><tbody> <tr> <td>EDM型</td> <td width="110">CLR型</td> <td width="381">詳細</td> </tr> <tr> <td width="117">Edm.Binary</td> <td width="110">byte[]</td> <td width="381">バイトの配列 (サイズは最大 64 KB)</td> </tr> <tr> <td width="117">Edm.Boolean</td> <td width="110">bool</td> <td width="381">ブール値</td> </tr> <tr> <td width="117">Edm.DateTime</td> <td width="110">DateTime</td> <td width="381">UTC 時刻として表現された 64 ビット値 (サポートされている値の範囲は 1/1/1601 ~ 12/31/9999)</td> </tr> <tr> <td width="117">Edm.Double</td> <td width="110">double</td> <td width="381">64 ビットの浮動小数点値</td> </tr> <tr> <td width="117">Edm.Guid</td> <td width="110">Guid</td> <td width="381">128 ビットのグローバル一意識別子</td> </tr> <tr> <td width="117">Edm.Int32</td> <td width="110">Int32 or int</td> <td width="381">32 ビットの整数</td> </tr> <tr> <td width="117">Edm.Int64</td> <td width="110">Int64 or long</td> <td width="381">64 ビットの整数</td> </tr> <tr> <td width="117">Edm.String</td> <td width="110">String</td> <td width="381">UTF-16 でエンコードされた値 (サイズは最大 64 KB)</td> </tr> </tbody></table> <p>ただ、この制限に従って実際にシステムを作ろうとすると、ビジネスロジック層がドメインモデルとして設計されている場合に、ドメインオブジェクト群をストレージへ保存する際、そのオブジェクト構造をフラットに展開してからデータを保存しなければなりません。また、そのデータを読み込む時もフラットな構造から元のドメインオブジェクトに戻す処理が必要です。</p> <p>データを読み書きするためにいちいちこんなことはやってられないので、今回はStorage Client APIをカスタマイズして、オブジェクト構造をそのままTable Storageへ保存できるようにします。</p> <a href="http://tkg84.blogspot.com/2011/05/azure-table-storage.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-77094268138046292322011-04-06T12:00:00.001+09:002011-04-06T12:00:20.499+09:00TableストレージにおけるExpect100ContinueとUseNagleAlgorithmの効果(2)~EGTを用いたエンティティ追加の場合<p><a href="http://tkg84.blogspot.com/2011/04/tableexpect100continueusenaglealgorithm.html">前回の記事</a>に引き続き、Expect100ContinueおよびUseNagleAlgorithmの無効化が与えるパフォーマンスへの影響をエンティティグループトランザクション(以下、EGT)を用いた場合について測定してみた。</p> <a href="http://tkg84.blogspot.com/2011/04/tableexpect100continueusenaglealgorithm_06.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-58595159313164743102011-04-04T18:29:00.001+09:002011-04-04T18:29:07.422+09:00TableストレージにおけるExpect100ContinueとUseNagleAlgorithmの効果(1)~1件のエンティティ追加の場合<p>Windows AzureのTableストレージに関するホワイトペーパー「Windows Azure Table – テーブルストレージのプログラミング」(<a href="http://www.microsoft.com/japan/windowsazure/whitepapers/">http://www.microsoft.com/japan/windowsazure/whitepapers/</a>)では、ストレージのパフォーマンス向上のために、Expect100ContinueおよびUseNagleAlgorithmをfalseにすることが推奨されている(p67-68あたり)。</p> <p>ただ実際のところ、この設定がどの程度パフォーマンスに影響を及ぼすか不明だったため、試してみた。</p> <a href="http://tkg84.blogspot.com/2011/04/tableexpect100continueusenaglealgorithm.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-191903086599426142011-04-04T11:07:00.001+09:002011-04-04T11:09:39.561+09:00Windows AzureでZeroMQを使ってみた<p>Windows Azureのインスタンス間通信にzeromq(<a href="http://www.zeromq.org/">http://www.zeromq.org/</a>)をWindows Azure上で使う機会があったので、使うまでの手順とか注意点を記す。またWindows Azureプロジェクトからzeromqを利用するために、clrzmq2(<a href="http://www.zeromq.org/bindings:clr">http://www.zeromq.org/bindings:clr</a>)というzeromqのC#バインディングを用いる。</p> <a href="http://tkg84.blogspot.com/2011/04/windows-azurezeromq.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-18649487241016219952011-03-31T20:04:00.002+09:002011-04-01T11:33:54.818+09:00Visual StudioにDLLをコピペする際の注意点<p>64bit版Windows 7において、Visual Studio上にSystem32のDLLをコピペすると32bit版のDLLがペーストされる問題があった。わかってから考えると当然かとは思うものの結構ハマったのでメモ。</p>
<a href="http://tkg84.blogspot.com/2011/03/visual-studiodll.html#more">続きを読む »</a>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-3384178666399088592011-03-10T09:47:00.007+09:002011-03-31T19:19:06.563+09:00Azure SDK 1.4がリリースされました今日、2010年3月9日にWindows Azure SDK 1.4がリリースされました。今回のアップデートでは、Windows Azure ConnectおよびWindows Azure CDN周りが強化されたようです。<a href="http://blogs.msdn.com/b/windowsazure/archive/2011/03/09/now-available-updated-windows-azure-sdk-and-windows-azure-management-portal.aspx">http://blogs.msdn.com/b/windowsazure/archive/2011/03/09/now-available-updated-windows-azure-sdk-and-windows-azure-management-portal.aspx</a> <br />
今回のアップデート内容は以下。(訳が間違っていたら教えてください、修正します) <br />
<ul>
<li>Windows Azure Connect: <ul>
<li>管理UIでの複数管理者サポート </li>
<li>クライアントUIの更新(ステータス通知やDiagnostic周りの機能向上) </li>
<li>非英語版WindowsでConnect Clientがインストールできるようになった </li>
</ul>
</li>
<li>Windows Azure CDN: <ul>
<li>Windows Azure CDN for Hosted Services: WebRoleやVMRoleのコンテンツをWindows Azure CDN経由で配信出来るようになった。静的なコンテンツは<span style="background-color: white;">自動的</span>にエッジサーバ(United States, Europe, Asia, Australia, South America)でキャッシュされ最大の帯域幅と低レイテンシでユーザにコンテンツが届けられる。 </li>
<li>Serve secure content from the Windows Azure CDN: Azure管理ポータル上のオプション設定を有効にすると、https経由でAzure CDN上のコンテンツをセキュアに配信できる </li>
</ul>
</li>
</ul>
<strong>追記</strong>:このアップデートでSDK 1.3のIIS LogがAzure Storageに転送できない問題が解決したようです。<a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=7a1089b6-4050-4307-86c4-9dadaa5ed018&displaylang=en#Overview">ココを見ると</a>他にもいくつかのバグが修正されたらしい。tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-38526850878102294632011-03-04T17:49:00.002+09:002011-03-31T19:19:51.120+09:00ODataObjCを使ったiOSアプリを作ってみた(4)~ソースコード公開しました3回にわたって書いてきたアプリ「Cloud BookShelf」ですが、先ほどソースコードを公開しました。<br />↓からダウンロードできます。<br />
<a href="http://cloudbookshelf.codeplex.com/">http://cloudbookshelf.codeplex.com/</a><br />
Apache License 2.0で配布してますので、ご自由に使ってください。<br />
ODataObjC(OData Client for Objective-C)に関する情報がもっともっと増えていけばいいなと思います。tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-36046239521716396992011-03-04T11:52:00.004+09:002011-03-31T19:22:05.887+09:00ODataObjCを使ったiOSアプリを作ってみた(3)~ODataObjCによるCRUD<a href="http://tkg84.blogspot.com/2011/03/odataobjciosodataobjc.html">前回</a>で、Azure Tableに対してODataObjCライブラリを使う準備ができました。いよいよ本番ということで、ODataObjCを用いたAzure Tableに対するCRUD処理について書いていきます。<br />
記事中で使用しているソースコードは、作成したiOSアプリ「Cloud BookShelf」のものです。記事内ではソースコードを切りだしているため分かりにくい部分もあると思いますが、後ほどソース全部を公開しますのでそっちも合わせて参考にしてください。<br />
<h1>エンティティの定義</h1>
まず最初に、Azure Tableに保存するエンティティを表すクラスとして、Bookクラスを作成します。<br />
Book.h<br />
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #cc6633;">#import</span> <Foundation/Foundation.h></pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: #cc6633;">#import</span> <span style="color: #006080;">"Azure/TableEntry.h"</span></pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum3" style="color: #606060;"> 3:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum4" style="color: #606060;"> 4:</span> @interface Book : TableEntry {</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum5" style="color: #606060;"> 5:</span> NSString *title;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum6" style="color: #606060;"> 6:</span> NSString *author;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum7" style="color: #606060;"> 7:</span> NSString *rate;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum8" style="color: #606060;"> 8:</span> }</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum9" style="color: #606060;"> 9:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum10" style="color: #606060;"> 10:</span> @property (nonatomic, retain) NSString *title;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum11" style="color: #606060;"> 11:</span> @property (nonatomic, retain) NSString *author;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum12" style="color: #606060;"> 12:</span> @property (nonatomic, retain) NSString *rate;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum13" style="color: #606060;"> 13:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum14" style="color: #606060;"> 14:</span> @end</pre>
</div>
</div>
<div>
</div>
このように、エンティティが保持する情報をプロパティとして定義します。(Book.mはそれぞれ定義したpropertyをsynthesizeするだけ)<br />
<h1>エンティティの追加</h1>
そして定義したエンティティをAzure Table上に追加します。<br />
このメソッドが定義されたクラスでは、tableContextプロパティとしてObjectContextを保持していて、そのObjectContextを使ってエンティティを保存しています。(学習用のアプリなので強制的にParitionKey・RowKeyを再設定していますが、既存のエンティティをパラメータにしても新規追加されてしまうため、ちゃんと使いたいときはその辺りも考えないといけない)<br />
<div>
<div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> - (Book *) insert:(Book *)aBook {</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> NSLog(<span style="color: #006080;">@"Insert"</span>);</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum3" style="color: #606060;"> 3:</span> [aBook setPartitionKey:[[UIDevice currentDevice] uniqueIdentifier]]; <span style="color: green;">//PartitionKeyとしてiPhoneのUDIDを使う</span></pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum4" style="color: #606060;"> 4:</span> [aBook setRowKey:[ODataGUID GetNewGuid]]; <span style="color: green;">//RowKeyはGUIDにしておく</span></pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum5" style="color: #606060;"> 5:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum6" style="color: #606060;"> 6:</span> [self.tableContext addObject:@BOOK_ENTITY_NAME object:aBook];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum7" style="color: #606060;"> 7:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum8" style="color: #606060;"> 8:</span> <span style="color: blue;">if</span> ( !self.enabledBatch ){</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum9" style="color: #606060;"> 9:</span> <span style="color: green;">//バッチモードでない場合だけSaveChangesする</span></pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum10" style="color: #606060;"> 10:</span> [self commit];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum11" style="color: #606060;"> 11:</span> }</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum12" style="color: #606060;"> 12:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum13" style="color: #606060;"> 13:</span> <span style="color: blue;">return</span> aBook;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum14" style="color: #606060;"> 14:</span> }</pre>
</div>
</div>
<div>
</div>
<h1>エンティティの検索</h1>
次にAzure Table上に保存されたエンティティの検索です。以前<a href="http://tkg84.blogspot.com/2011/03/odataobjc_4372.html">この記事</a>で書いたとおりオリジナルのODataObjCでは日本語をパラメータに使えません。(まぁ、自力でURLエンコードさせればいいんですが。。。)<br />
そこで、その記事中に載せた簡易クエリビルダを利用します。<br />
<div>
<div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> - (NSArray *) find:(NSString *)aQuery {</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> NSString *deviceId = [[UIDevice currentDevice] uniqueIdentifier];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum3" style="color: #606060;"> 3:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum4" style="color: #606060;"> 4:</span> <span style="color: green;">//デフォルトでPartitionKeyによる絞り込みを入れておく</span></pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum5" style="color: #606060;"> 5:</span> NSString *q = [NSString stringWithFormat:<span style="color: #006080;">@"PartitionKey eq '%@'%@%@"</span>, deviceId, ( aQuery != <span style="color: #006080;">@""</span> ? <span style="color: #006080;">@" and "</span> : <span style="color: #006080;">@""</span> ), aQuery];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum6" style="color: #606060;"> 6:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum7" style="color: #606060;"> 7:</span> DataServiceQuery *query = [[DataServiceQuery alloc] initWithUri:@BOOK_ENTITY_NAME objectContext:self.tableContext];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum8" style="color: #606060;"> 8:</span> [query filter:q];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum9" style="color: #606060;"> 9:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum10" style="color: #606060;"> 10:</span> QueryOperationResponse *response = [query execute];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum11" style="color: #606060;"> 11:</span> NSArray *result = [response getResult];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum12" style="color: #606060;"> 12:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum13" style="color: #606060;"> 13:</span> NSLog(<span style="color: #006080;">@"Query Result"</span>);</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum14" style="color: #606060;"> 14:</span> <span style="color: blue;">for</span>(Book *r in result){</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum15" style="color: #606060;"> 15:</span> NSLog(<span style="color: #006080;">@"Book(title=%@, author=%@, rate=%@) PK:%@ RK:%@ Timestamp:%@"</span>, r.title, r.author, r.rate, r.PartitionKey, r.RowKey, r.Timestamp);</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum16" style="color: #606060;"> 16:</span> }</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum17" style="color: #606060;"> 17:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum18" style="color: #606060;"> 18:</span> <span style="color: blue;">return</span> result;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum19" style="color: #606060;"> 19:</span> }</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum20" style="color: #606060;"> 20:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum21" style="color: #606060;"> 21:</span> - (NSArray *) findByQueries:(Queries *)aQueries {</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum22" style="color: #606060;"> 22:</span> <span style="color: blue;">return</span> [self find:aQueries.filterString];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum23" style="color: #606060;"> 23:</span> }</pre>
</div>
</div>
呼び出し側はこんな感じ。
<div>
<div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> Queries *aQueries = [Queries with:<span style="color: #006080;">@"title"</span> eq:text];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> self.books = [bookService findByQueries:aQueries];</pre>
</div>
</div>
<h1>エンティティの更新</h1>
次のエンティティの更新はエンティティを追加とほぼ同じ。PartitionKeyとRowKeyは既に付いているためセットしないのと追加するときはaddObjectだったのをupdateObjectにするだけ。<br />
ただし要注意は、<strong>updateObjectの引数にしているエンティティはそのObjectContextで追跡されていなければならない</strong>こと。具体的には、<strong>同じObjectContextで追加したものや検索して取得したものしか更新はできない</strong>。<br />
ソースコードはこんな感じ。<br />
<div>
<div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> - (Book *) update:(Book *)aBook {</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> [self.tableContext updateObject:aBook];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum3" style="color: #606060;"> 3:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum4" style="color: #606060;"> 4:</span> <span style="color: blue;">if</span> ( !self.enabledBatch ){</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: green;">//バッチモードでない場合だけSaveChangesする</span></pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum6" style="color: #606060;"> 6:</span> [self commit];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum7" style="color: #606060;"> 7:</span> }</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum8" style="color: #606060;"> 8:</span> </pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum9" style="color: #606060;"> 9:</span> <span style="color: blue;">return</span> aBook;</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum10" style="color: #606060;"> 10:</span> }</pre>
</div>
</div>
<h1>エンティティの削除</h1>
最後にエンティティの削除ですが、これも追加や更新と同じようなコーディングでOKです。addObjectやupdateObjectをdeleteObjectに書き換えるだけ。<br />
ただし、更新と同様に<strong>ObjectContextで追跡済みのエンティティしか削除出来ません</strong>。<br />
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum1" style="color: #606060;"> 1:</span> - (<span style="color: blue;">void</span>) remove:(Book *)aBook {</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum2" style="color: #606060;"> 2:</span> [self.tableContext deleteObject:aBook];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: blue;">if</span> ( !self.enabledBatch ){</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum4" style="color: #606060;"> 4:</span> [self commit];</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum5" style="color: #606060;"> 5:</span> }</pre>
<pre style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span id="lnum6" style="color: #606060;"> 6:</span> }</pre>
</div>
</div>
こんな感じで削除できます。tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-74251779280628676572011-03-03T19:06:00.002+09:002011-03-31T19:24:27.142+09:00ODataObjCを使ったiOSアプリを作ってみた(2)~ODataObjCの使い方<a href="http://tkg84.blogspot.com/2011/03/odataobjcios.html">ODataObjCを使ったiOSアプリを作ってみた(1)</a>で紹介した「Cloud BookShelf」を作った際に、ODataObjCの使い方に関して色々ハマったところがあったのでメモ書き。<br />
まず、ODataObjC付属のドキュメントに記載されたコードを見つつ、とりあえず必要そうな処理だけコピってやってみたところ、うまく動かなかった。Fiddler使ってHTTPリクエストの内容とかを見ていたところ、Azure REST APIで必要な署名が付与されておらず、認証エラーになっていた。<br />
以下は付属ドキュメント上でエンティティをAzure Tableに保存するサンプルですが、<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: #cc6633;">#import</span> “Context/ObjectContext.h”
<span style="color: #cc6633;">#define</span> AZURE_SERVICE_URL “http:<span style="color: green;">//<Account>.table.core.windows.net”</span>
<span style="color: #cc6633;">#define</span> AZURE_ACCOUNT_NAME “specify your account name here”
<span style="color: #cc6633;">#define</span> AZURE_ACCOUNT_KEY “specify your account key here”
@interface Person :TableEntry
{
NSString *m_Name;
NSString *m_Age;
}
@property(nonatomic,retain,getter=getName, setter = setName)NSString *m_Name;
@property(nonatomic,retain,getter=getAge, setter = setAge)NSString *m_Age;
-(id) initWithUri:(NSString *)aUri;
@end
@implementation Person
@synthesize m_Name,m_Age;
-(id) initWithUri:(NSString *)aUri
{
self=[super initWithUri:aUri];
<span style="color: blue;">return</span> self;
}
@end
@<span style="color: blue;">try</span>
{
AzureTableCredential *cred=[[AzureTableCredential alloc]
initWithAccountName:AZURE_ACCOUNT_NAME accountKey:AZURE_ACCOUNT_KEY userPathStyleUrl:YES];
ObjectContext *proxy=[[ObjectContext alloc]
initWithUri:AZURE_SERVICE_URL credentials:cred dataServiceVersion:<span style="color: #006080;">@"1.0"</span>];
[proxy setODataDelegate:self];
Person *tableEntry=[[Person alloc]initWithUri:<span style="color: #006080;">@""</span>];
[tableEntry setPartitionKey:<span style="color: #006080;">@"Partition1"</span>];
[tableEntry setRowKey:<span style="color: #006080;">@"Row1"</span>];
[tableEntry setName:<span style="color: #006080;">@"TableEntry1"</span>];
[tableEntry setAge:<span style="color: #006080;">@"37"</span>];
[proxy addObject:<span style="color: #006080;">@"Person"</span> object:tableEntry];<span style="color: green;">//Person is the table name</span>
[proxy saveChanges];
}
@<span style="color: blue;">catch</span>(NSException *e)
{
NSLog(<span style="color: #006080;">@"Exception:%@:%@"</span>,[e name],[e reason]);
}</pre></div>
このうち、必要ないと思って削っていた
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;">[proxy setODataDelegate:self];</pre>
</div>
の部分が原因で、このライブラリではODataDelegateのonBeforeSendメソッド内で署名を付与するような設計になっているようです。まぁ必要ないと思って削ってしまった自分が悪いんですが。。。<br />
しかしここで気になるのは、Azure Table用の署名の生成処理自体はユーティリティ(AzureTableUtil)として提供されているものの、このODataDelegateのonBeforeSendメソッドは自分で実装する必要があるという点。<br />
<strong>こんな定型処理、なぜ自分で実装しないといけないんだ~</strong><br />
ということで、とりあえずこのObjectContextの生成と同時にAzure Table向けの署名を付けるようなクラスを作成する使い方がベストだと思います(多分ライブラリの作者もこんな使い方を想定してるはず)。<br />
こんな感じ。<br />
<div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; cursor: text; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 20px 0px 10px; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; text-align: left; width: 97.5%;">
<pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none; color: black; direction: ltr; font-family: 'Courier New', courier, monospace; font-size: 8pt; line-height: 12pt; margin: 0em; overflow: visible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 100%;"><span style="color: #cc6633;">#import</span> <span style="color: #006080;">"Context/ObjectContext.h"</span>
<span style="color: #cc6633;">#import</span> <span style="color: #006080;">"Context/DataServiceQuery.h"</span>
<span style="color: #cc6633;">#import</span> <span style="color: #006080;">"Common/AzureTableUtil.h"</span>
<span style="color: #cc6633;">#import</span> <span style="color: #006080;">"Credential/AzureTableCredential.h"</span>
<span style="color: #cc6633;">#define</span> TABLE_URL_FORMAT <span style="color: #006080;">"http://%@.table.core.windows.net"</span>
@interface StorageClient : NSObject<ODataDelegate, BlobContextDelegate> {
NSString *tableServiceURL;
NSString *accountName;
NSString *accountKey;
}
@property(retain, nonatomic) NSString *tableServiceURL;
@property(retain, nonatomic) NSString *accountName;
@property(retain, nonatomic) NSString *accountKey;
- (id) initWithAccountName:(NSString *)aName andKey:(NSString *)aKey;
- (ObjectContext *) createTableContext;
@end
@implementation StorageClient
@synthesize tableServiceURL, accountName, accountKey, dateFormatter;
- (id) initWithAccountName:(NSString *)aName andKey:(NSString *)aKey {
self.tableServiceURL = [NSString stringWithFormat:@TABLE_URL_FORMAT, aName];
self.accountName = aName;
self.accountKey = aKey;
<span style="color: blue;">return</span> self;
}
- (ObjectContext *) createTableContext {
AzureTableCredential *cred = [[AzureTableCredential alloc] initWithAccountName:self.accountName accountKey:self.accountKey userPathStyleUrl:YES];
ObjectContext *ctx = [[ObjectContext alloc] initWithUri:self.tableServiceURL credentials:cred dataServiceVersion:<span style="color: #006080;">@"1.0"</span>];
[ctx setODataDelegate:self];
<span style="color: blue;">return</span> ctx;
}
- (<span style="color: blue;">void</span>) onBeforeSend:(HttpRequest*)request{
AzureTableUtil *util=[[AzureTableUtil alloc] initWithAccountName:self.accountName accountKey:self.accountKey usePathStyleUri:NO];
[[request getHeaders] CopyFrom:[util getSignedHeaders:[request getUri]]];
}
@end</pre></div>tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-23725327792651913862011-03-03T17:54:00.001+09:002011-03-03T17:54:46.986+09:00ODataObjCを使ったiOSアプリを作ってみた(1)<p>ODataObjCを使ってみる練習としてiOSアプリを作ってみました。</p> <p>書籍管理っぽいことを行うようなアプリで、本の登録/検索/更新/削除が行えます。ついでにAzure Blob上に本の表紙画像をアップロードする機能をつけてみました。(iOSアプリをちゃんと作るのはこれが初めてだったので、ODataObjCの使い方よりもObjective-Cに悩まされましたが。。。)</p> <p>まずは簡単にアプリ紹介です。 <br />ちなみにアプリ名は、Azure上に本棚を用意するってことでCloud BookShelfと付けてみました(安直だなー。。。)。</p> <p>まず起動直後の画面ですが、こんな感じで登録された本の一覧が表示されます。また、本にはそれぞれタイトル、著者、レートといった情報(これはAzure Table上に保存)と表紙画像一枚(こっちはAzure Blob上に保存)が付いてます。</p> <p><a href="http://lh4.ggpht.com/_4qDWaubH2tM/TW9W7sIuxzI/AAAAAAAAABg/X9HTzobvvt0/s1600-h/IMG_01735.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="IMG_0173" border="0" alt="IMG_0173" src="http://lh5.ggpht.com/_4qDWaubH2tM/TW9W8YIoTUI/AAAAAAAAABk/zFcmEOm7c9s/IMG_0173_thumb1.png?imgmax=800" width="164" height="244" /></a></p> <p>本をタップすると、本の情報を編集する画面になります。</p> <p><a href="http://lh3.ggpht.com/_4qDWaubH2tM/TW9XSwyY0VI/AAAAAAAAABo/n8gL06MLOeI/s1600-h/IMG_01752.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="IMG_0175" border="0" alt="IMG_0175" src="http://lh6.ggpht.com/_4qDWaubH2tM/TW9XTpnY9MI/AAAAAAAAABs/gDdZQpFtY-I/IMG_0175_thumb.png?imgmax=800" width="164" height="244" /></a></p> <p>この画面で好きにタイトルとか著者、レートを書き換え、右上の保存ボタンをタップすると更新された内容でAzure Table上にデータを保存します。</p> <p>一番下の[表紙を見る/変更する]をタップすると</p> <p><a href="http://lh6.ggpht.com/_4qDWaubH2tM/TW9XU5HrtII/AAAAAAAAABw/L9SPMr7kw0k/s1600-h/IMG_01762.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="IMG_0176" border="0" alt="IMG_0176" src="http://lh4.ggpht.com/_4qDWaubH2tM/TW9XVYEPplI/AAAAAAAAAB0/hRFzPVAPLXg/IMG_0176_thumb.png?imgmax=800" width="164" height="244" /></a></p> <p>表紙として登録された画像が表示されます。で、右上の表紙を変更をタップするとiPhoneのカメラが起動し、撮影した画像で表紙が置き換えらるって感じです。</p> <p>簡単なアプリケーションですが、iOSプログラミングの癖とかODataObjCの使い方、Azure BlobのREST APIとかいろんなことがわかりました。これを機会にiOSアプリを作ってみようかな~と。</p> tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-43836017103937167862011-03-03T17:50:00.001+09:002011-03-03T17:50:11.116+09:00ODataObjCで日本語パラメータを使う方法<p>OData Client for Objective-C(<a title="http://odataobjc.codeplex.com/" href="http://odataobjc.codeplex.com/">http://odataobjc.codeplex.com/</a>)を触っていて気づいたことが、Azure Tableストレージを対象に日本語をパラメータとして検索するフィルタクエリを実行すると、Cocoaのライブラリ側で不正なURLという例外が発生してしまう。</p> <p>なぜそんなことになっているかソースコードを見ていたら、ライブラリ内部ではフィルタクエリのURLエンコードを行っていないことがわかった。また、そのソースの近くにURLエンコードを試みたらしくコメントアウトされたコードがあるものの、それを外しても動かない。</p> <p>原因をよくよく考えてみると、Azure Tableストレージに対するエンティティのクエリ構文では、全体をURLエンコードするのではなく個々のフィルタパラメータをURLエンコードしなくてはならないことがわかった。</p> <p>例えば、</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.46%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; height: 32px; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">$filter=(PartitionKey eq 'あいうえお')</pre>
<br /></div>
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>こんなクエリを投げたいときは</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.49%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; height: 34px; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">$filter=(PartitionKey%20eq%20%27%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A%27)</pre>
<br /></div>
<p>ではなく、</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.49%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; height: 33px; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">$filter=(PartitionKey%20eq%20'%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A')</pre>
<br /></div>
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>のようにしなければならない(%20は+でもOK)。</p>
<p>しかし、このODataObjCではこの$filter=の後の文字列を直接メソッドのパラメータとして受け取るように作られているため、ライブラリ内部で対応するのは難しい感じです。(だから諦めたのかな。。。)</p>
<p>しかしこのままじゃ使えないため、$filter=の後の文字列を生成する簡単なクエリビルダを作成し、その中でURLエンコードするようにして対処してみました。というわけで作成したクエリビルダのソースを置いておきます。(URLエンコードの処理はODataObjCライブラリのUtilityクラスを利用してます)</p>
<p>Queries.h</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #cc6633">#import</span> <Foundation/Foundation.h><br /><span style="color: #cc6633">#import</span> <span style="color: #006080">"Utility.h"</span><br /><br /><br />@interface Queries : NSObject {<br />@<span style="color: #0000ff">private</span><br /> NSString *filterString;<br />}<br /><br />@property (nonatomic, retain) NSString *filterString;<br /><br />- (id) initWithString:(NSString *)aFilterString;<br /><br />+ (Queries *) withEmpty;<br />+ (Queries *) with:(NSString *)name eq:(NSString *)value;<br />+ (Queries *) with:(NSString *)name gt:(NSString *)value;<br />+ (Queries *) with:(NSString *)name ge:(NSString *)value;<br />+ (Queries *) with:(NSString *)name lt:(NSString *)value;<br />+ (Queries *) with:(NSString *)name le:(NSString *)value;<br />+ (Queries *) with:(NSString *)name ne:(NSString *)value;<br /><br />- (Queries *) and:(Queries *)aQueries;<br />- (Queries *) or:(Queries *)aQueries;<br />- (Queries *) not;<br /><br />@end</pre>
<br /></div>
<p> </p>
<p>Queries.m</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #cc6633">#import</span> <span style="color: #006080">"Queries.h"</span><br /><br /><br />@implementation Queries<br /><br />@synthesize filterString;<br /><br />- (id) initWithString:(NSString *)aFilterString {<br /> self.filterString = aFilterString;<br /> <br /> <span style="color: #0000ff">return</span> self;<br />}<br /><br />+ (Queries *) withEmpty {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:<span style="color: #006080">@""</span>] autorelease];<br />}<br /><br />+ (Queries *) with:(NSString *)name eq:(NSString *)value {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(%@ eq '%@')"</span>, name, [Utility URLEncode:value]]] autorelease];<br />}<br /><br />+ (Queries *) with:(NSString *)name gt:(NSString *)value {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(%@ gt '%@')"</span>, name, [Utility URLEncode:value]]] autorelease];<br />}<br /><br />+ (Queries *) with:(NSString *)name ge:(NSString *)value {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(%@ ge '%@')"</span>, name, [Utility URLEncode:value]]] autorelease];<br />}<br /><br />+ (Queries *) with:(NSString *)name lt:(NSString *)value {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(%@ lt '%@')"</span>, name, [Utility URLEncode:value]]] autorelease];<br />}<br /><br />+ (Queries *) with:(NSString *)name le:(NSString *)value {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(%@ le '%@')"</span>, name, [Utility URLEncode:value]]] autorelease];<br />}<br /><br />+ (Queries *) with:(NSString *)name ne:(NSString *)value {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(%@ ne '%@')"</span>, name, [Utility URLEncode:value]]] autorelease];<br />}<br /><br />- (Queries *) and:(Queries *)aQueries {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(%@ and %@)"</span>, self.filterString, aQueries.filterString]] autorelease];<br />}<br /><br />- (Queries *) or:(Queries *)aQueries {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(%@ or %@)"</span>, self.filterString, aQueries.filterString]] autorelease];<br />}<br /><br />- (Queries *) not {<br /> <span style="color: #0000ff">return</span> [[[Queries alloc] initWithString:[NSString stringWithFormat:<span style="color: #006080">@"(not %@)"</span>, self.filterString]] autorelease]; <br />}<br /><br />- (<span style="color: #0000ff">void</span>) dealloc {<br /> [self.filterString release];<br /> <br /> [super dealloc];<br />}<br /><br />@end</pre>
<br /></div>
<style type="text/css">
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p> </p>
<p>このクエリビルダを使うと上記のクエリは、</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.47%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; height: 30px; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">[Queries with:<span style="color: #006080">@"PartitionKey"</span> eq:<span style="color: #006080">@"あいうえお"</span>].filterString;</pre>
<br /></div>
<p>と書ける。</p> tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0tag:blogger.com,1999:blog-5097183065971096271.post-2306733331589653272011-03-03T17:37:00.001+09:002011-03-03T17:45:04.826+09:00OData Client for Objective-CのAPIリファレンス<p>OData Client for Objective-C(<a title="http://odataobjc.codeplex.com/" href="http://odataobjc.codeplex.com/">http://odataobjc.codeplex.com/</a>)であるが、配布しているものをダウンロードしてみると、ライブラリのバイナリ&ソースコードとサンプルアプリ、ユーザガイドが入っている。</p> <p>このユーザガイドを見ればなんとなくの使い方はわかるものの、ユーザガイドに書いてあることとちょっとでも違うことをやろうとすると、なんと「<strong>APIリファレンスが無い</strong>」ことに気付く。</p> <p>ライブラリとして配布しているのに、APIリファレンスがないとはなんということだと思うものの、ちょっと冷静になってソースコードを見ていると。。。</p> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #008000">/**</span><br /><span style="color: #008000"> * To add a filter query option.</span><br /><span style="color: #008000"> *</span><br /><span style="color: #008000"> * @param <string> expression</span><br /><span style="color: #008000"> * @return <DataServiceQuery> Self reference that includes the requested</span><br /><span style="color: #008000"> * filter option</span><br /><span style="color: #008000"> * @throws DataServiceRequestException</span><br /><span style="color: #008000"> */</span><br />- (DataServiceQuery*) filter:(NSString*)anExpression<br />{<br /> <span style="color: #0000ff">return</span> [self addQueryOption:<span style="color: #006080">@"$filter"</span> query:anExpression];<br />}</pre>
<br /></div>
<p>なんと、ソースコードの中にはちゃんとAPIリファレンスが書かれていました!しかも、この記述形式がDoxygenのものっぽいなと思い、試しにDoxygenでドキュメントを吐き出させてみると、しっかりAPIリファレンスが出力されます。</p>
<p>まぁ、全てのメソッドにリファレンスが付いているわけではないものの、このライブラリを使う際にコード上で触る範囲のものにはだいたい書かれている感じです。</p>
<p>ということで、作成したAPIリファレンスを置いておきます。</p>
<p><a href="http://public.blu.livefilestore.com/y1pX_dQe9xJhyhIJCtGl8NSBW1LG76WLyay4tTPpd-IJdlTBFeOZXuCWSC6C_pKAYg1rjSLiqOGCXZKC8N-R2YiNA/odataobjc-apidoc.zip?download&psid=1">odataobjc-v1.1-apidoc.zip</a></p> tkg84http://www.blogger.com/profile/09194224343238620119noreply@blogger.com0