Databaseで遊んでみた件ヒロシです。FirebaseとはGoogleが提供しているmBaasです。mBaasって?という方はググってください。Database」なるものが存在するということをお客様よりお聞きし、さっそく遊んでみました。Databaseとはなんぞや?https://firebase.google.com/「アプリデータを瞬時に保存および同期」うん、なんとなくわかった。サーバとクライアント間で同期できるNoSQLを使った仕組みで、チャットみたいなのも簡単に?作れるんだよね、きっと。技術ドキュメントあるあるワードを発見。サンプルコードもあったので見てみると、シンプルなjavascriptですね、これ簡単そう。いうことで、最近モノ忘れの激しい社内メンバーのために、リアルタイム共有TODOツールを作ってみたYO!今回作りたいものTODOを登録できるリアルタイムに共有できる完了したら削除できる至ってシンプルですが、まずはこんなところでしょうか。初期設定https://qiita.com/H_Crane/items/adf88cc01eabce2b9a5fこの辺りを参考にさせてもらって、まずは登録して、プロジェクト作って、ウェブ用のconfigをコピー(下で使ってます)、と。database.ref('todo');とりあえず、ここまでで準備は完了!まずは登録を。担当者が入力できる適当なフォームを作りました。</div></div>divdivしちゃってるのは、あとで何かスタイルつけようかと思ってるだけ。ブラウザでアクセスしてみましょう。登録アクションを作ります。内部ツールなのでタイトルだけ処理側で必須にして、弾かれてもエラーメッセージもなんもなし!そう、これを漢(をとこ)ツールと勝手に呼ぶ。postAction());そう、気づいた人もいるだろう。漢ツールはエスケープなんてものもしないのです。NOバリデーション!これぞ漢(をとこ)の浪漫!(お仕事ではちゃんとやりますので安心してくださいね)で、指定したノードにpushってやるだけで子ノードが追加できるんだと。こんな感じで、適当に入力して「ポチっ」と。Firebaseの管理画面で確認すると、、おおおお!!いけてますわー。(ちょっと感動)どんどんいきましょ、次へ。});});onの第一引数にリスナーっての指定してあげると、リスナーに対応したイベントがトリガーとなって、この部分がコールバックされて動くみたい。何言ってるかわからんって?とりあえず、公式を以下に引用しておくので各自読み解いてくださいな。パスにあるコンテンツの静的なスナップショットを、読み取りイベントのときに存在していたとおりに読み取るために使用します。データが変更されると、そのたびに再びトリガーされます。イベントのコールバックには、その場所にあるすべてのデータ(子のデータも含む)を含んでいるスナップショットが渡されます。アプリ内のすべてのブログ投稿を返しています。新しいブログ投稿が追加されるたびに、コールバック関数がすべての投稿を返します。通常、データベースからアイテムのリストを取得するために使用します。指定されたパスに新しい子が追加されると、そのたびに再びトリガーされます。コールバックには、新しい子のデータを含んでいるスナップショットが渡されます。番目の引数も渡されます。イベントがトリガーされます。この修正には、子ノードの子孫に対する修正も含まれます。組み合わせて使用されます。コールバックに渡されるスナップショットには、子の更新済みデータが含まれています。直接の子が削除されるとトリガーされます。組み合わせて使用されます。イベントのコールバックに渡されるスナップショットには、削除された子のデータが含まれています。今回はchild_addedとchild_removedを使えばよさそう。ことでまずは初期表示と登録を行うためにchild_addedをチョイス。dispTodoという実際にTODO表示を行う関数(後述)を呼び出す想定でこんな感じに。snapshotはなんぞや?という話になりますが、これは上のコールバックが呼ばれた際に受信する静的スナップショットなんだそう。なんかわからんけど、key:valueで来るのね。実際の表示処理を作ってみよう。id="${todo.id}">${todo_html}</div>`);}とりあえず、下のような空のdivを作っておいて、そこに渡されたノードの情報をどんどん出していく作戦。id="todo_list"></div>リロード。(ちょっと感動)削除する片付いたタスクは消すことができないと困りますね。いうことで、削除機能を作ります。『削除』ってのもなんかアレなんで『DONE』というボタンを作ってみました。class="done">DONE</button></div>`);}こんな感じで、しょーもないボタンを。次に削除処理も作りましょ。ボタンもどんどん動的に追加されていくので、documentのonでセレクタを指定してやる。イベントの犯人を捕まえて、その親divのid(※)を取ってきて、削除リクエストを投げる、というプレイ。id).remove();});/keyで目的のノードを操れるようだ。※登録時にkeyは指定していないが、Firebase側でユニークIDが勝手に付与される、というのはどこかで知りました。$("#"+snapshot.key).remove();});出ました、リスナー。迷わず「child_removed」でコールバックされることを期待しつつ、受け取ったkeyに対応するTODOのdivごと葬る。よし、削除してみましょ!ポチっとな!できた。(あっさり)さてさて、ほんとに同期とれてるの?同期されてなければただのしょーもないHelloWorldに毛の生えたWebシステムもどきだし。これ、複数ブラウザ開いて試してみてください。どっちかで登録すると、もう一方に出現。削除すると、もう一方からも消滅。たいしたことしてないからこその、大感動がここにあるっ!あとはちょいちょいとスタイルなんかつけちゃって、こんな感じの仕上がり♪それにしてもHTML一枚、サーバレスでこんなことできる時代になったんですね。おじさん、困っちゃう。!2016/09/19DatabasePythonエンジニアがPHPフレームワークSymfonyをざっくり紹介する普段私はPythonにDjangoで書くことが多いのですが、先日PHPのSymfonyを触る機会がありました。そこで今回は、普段Djangoを使っている目線でのSymfonyの構成などをざっくりご紹介したいと思います。Symfonyとは?Symphonyではありません。Google先生に頼っていて思うような検索結果が出ていないときは、結構な確率でタイポしていたりします。Symfonyとは、PHPのフレームワークの一つです。PHPのフレームワークというと、日本ではLaravelやCakePHPがメジャーですが、海外ではSymfonyも幅広く使われています。Controller)です。View(Django)ModelをView(Symfony)やTemplateに渡す部分ざっくり上記になっています。名前が違ったり被っていたりするので分かりにくいですが、大まかな考え方は近しい部分があります。appここに、プロジェクト全体で使用する設定ファイル(yamlなど)や、初期表示のindex.htmlを入れたりします。binコンソールで使用するコマンドなどのファイルを格納します。srcBundleごとにソースコードやHTMLファイルを格納します。開発をする際触るのはここになるかと思います。SampleBundleそもそもBundleって何?と思う方も多いかと思われます。簡潔にまとめると、Bundleとは、データベースと関連付いたエンティティや、ソースコードやテスト、画面に表示するHTMLなどのファイルをひとところにまとめた機能の塊です。Djangoで言うところのアプリケーションに近いものだと思うと、想像しやすいかもしれません。Bundle単位で機能拡張ソースコードも多く公開されているので、取捨選択することで自分でコードを書かずとも色々な機能を組み込めるようになっています。ControllerDjangoで言うところのView部分です。画面表示するデータを制御したり、URLのルーティング制御を行います。Entityデータベースのテーブルに応じたEntityを格納する場所です。setterを設定したり、更新時のシーケンスなど、データベースの接続の際の付加処理を設定します。Djangoの方がこの部分に記載する処理の幅は広くなりがちですが、各アプリのmodels.pyに記載するような、データベースに応じたオブジェクトを定義する場所です。Form画面で使用するFormを設定する部分です。ここで、各項目のバリデーションも設定するのですが、細かいバリデーション処理はまた別途記載したります。Djangoでいう各アプリのforms.pyに近い役割を担っています。Resourcesviewsディレクトリに、HTMLファイルを格納します。Bundle固有で使う設定ファイルなどある場合は、ここに置いたりも。ServiceServiceだったりhelperだったり、Bundle内の位置付けで名称は多々あるかと。Controllerでやるには複雑な処理や、細かいビジネスロジックを記載していく部分になります。Validator文字通り、バリデーションを記述する部分です。ここでバリデーションクラスを作成し、formの方でインポートして各項目へのバリデーションを設定します。varキャッシュファイルや、ログファイルを格納しておくディレクトリになります。vendorライブラリ一般を格納するディレクトリになります。webJsやcss、画像ファイルなど、画面上から見えるファイルを格納する場所です。Djangoでいうstaticのような役割です。個人的に使っていてSymfonyってここが面白い!と感じた部分を取り上げてみます。分業がしやすい画面表示はここ、バリデーションはここ、formの生成内容はここ、と細かく記述ファイルが分かれているので、多人数で分業をする際はコンフリクトを減らしやすいかと思います。Bundleごとに切り分けて開発を進める事も出来るため、開発方法の幅が広がります。テンプレート言語のTwigが使いやすいDjangoのtemplate記法と近しい、Twigが使えます。画面上でオブジェクトをループさせてテーブルに値を入れ込んだり、if分岐で表示するものを変えたり、生のHTMLでは表現しにくい処理が簡潔に行えます。検索であったりデータの登録・更新、ログインと、formを使わないシステムはほぼ無いかと思われます。Symfonyでは、Validationクラスで細かく設定してのバリデーションや、entityをまるっとフォームに入れてそれを使用してデータの更新を行う事、また画面にレンダリングする際も、細かくlabelやform本体の配置は行えます。使い方のルールがある程度定まっている事で、多人数での開発の際にソースの揺れを減らせる事もメリットだと思います。今までSymfonyの名前も知らなかったのですが、使ってみると意外と馴染んだ部分もありました。PHPのメリットでありデメリットでもある自由にコードが書ける(≒フォーマットの統一が難しい)という部分を、Symfonyの記法である程度統一規格を持たせ一貫性のあるソースに仕上げやすいという風にうまくカバーしていました。日本でのシェアが広くない事もあり、ドキュメントは少ないのでそこはお気をつけください。PHPで開発を行う事がありましたら、フレームワークの選択肢の一つに検討してみてはいかがでしょうか?2016/09/19PHPPostgreSQLで階層マスタを扱うとある案件で階層マスタを扱うことがありました。〜」という、階層問い合わせの構文があるのですが、PostgreSQLだと階層問い合わせが出来るのか知らなかったので調べてみました。データを準備する以下の様な階層構造を考えます。テーブル定義を以下の通りとします。(外部キー)DDLは以下の通りです。kamoku(id));INSERT文は以下になります。4);こうして作ったデータをSELECTすると、以下の結果になります。RECURSIVE句による階層問い合わせPostgreSQLにはWITH句というサブクエリを定義する句が使えます。ここに、RECURSIVEを付けると、再帰的なサブクエリを書くことが出来ます。具体的には、以下の様に書きます。code;結果は以下の通りです。rows)2行目のSELECT文のWHERE句の条件が、開始のidになります。開始のidを指定すれば、途中から取得することも出来ます。rows)逆順(子→親)も出来ます。今回の階層問い合わせを再帰的に行うクエリだと、1クエリで出来て速度も速いので良い方法だと思います。各階層(level)毎に取得している為、最後に並び替えをしないと、ツリー状に並ぶ結果が返ってきません。今回は簡単にするために、科目コード(code)にルールを作って並ぶようにしています。実際に使う時は、もう一工夫したいところです。