Perl入門ゼミスマートフォン用の表示で見るPerl入門ゼミこの広告は、90日以上更新していないブログに表示しています。2011-09-26DBIx::Customで「フィルタリング」を利用するPerl›モジュール›データベース›DBIx::Custom›hereDBIx::Customで「フィルタリング」を利用する方法を解説します。列名によるフィルタリングDBIx::Customでは列名を指定して値をフィルタリングすることができます。データベースにデータを送信するときにも、データベースからデータを取り出すときにもフィルタリングをかけることができます。フィルタの登録フィルタを実際に利用する前に、フィルタを登録しておくと便利です。フィルタの登録をしておけば、フィルタ名でフィルタを指定することができます。ここでは画像を印字可能な文字列に変換するBase64という変換を行うフィルタを作成してみましょう。});encode_base64というフィルタはデータベースにデータを挿入するときはバイナリのデータをBase64形式のフォーマットに変換するために利用します。decode_base64というフィルタはデータをデータベースから取り出すときはBase64形式からバイナリにデータを変換するために利用します。register_filterに登録しただけではフィルタは有効にはなりません。register_filterはフィルタを名前で呼び出すための便利な仕組みを提供するだけです。filterオプションデータベースにデータを送信するときのフィルタを指定してみましょう。bookというテーブルにidとimageという列があるとします。imageは本来はバイナリの画像のデータですが、Base64形式で保存します。次のようにfilterオプションを利用すると、簡単にこの変換を記述することができます。'encode_base64'});これでデータベースにはBase64形式で画像が保存されます。executeメソッドで利用することができます。filterオプションにはフィルタ名のほかに、変換のためのサブルーチンを直接指定することもできます。}}また複数の列名に同一のフィルタが必要な場合は、次のようにハッシュのリファレンスの変わりに配列のリファレンスを使うことができます。外側も配列のリファレンスで、列名の部分も配列のリファレンスになっていることに注意してください。'encode_base64'}]内部的にはこれをハッシュのリファレンスに変換しますので、必要がない場合はハッシュのリファレンスを利用するのがよいでしょう。idオプションとfilterオプションを併用する場合の注意点idオプションを利用する場合は、ほとんどが単なる数値や文字列であって、フィルタリングの必要はないと思いますが、仕様の上での注意点を書いておきます。insertメソッドでidオプションを使用する場合はprimary_keyオプションで指定した列名をフィルタリングに利用することができます。selectメソッドでidオプションを利用する場合は少し注意が必要です。これらのメソッドでは、列名を完全に区別するために、テーブル名がつけられた列名が内部的に利用されます。フィルタを設定するときも、primary_keyで指定した列名にテーブル名を修飾した名前を使う必要があります。}});データベースからデータを取得するときのフィルタリングselectを実行したときに戻り値はDBIx::Custom::Resultオブジェクトが返ってきますが、このオブジェクトはfilter属性を持っています。filter属性にフィルタを設定すれば、フェッチしたときにフィルタリングが行われます。$result->all;ここではallメソッドを使っていますが、fetchなどのフェッチを行うすべてのメソッドでフィルタリングが行われます。filterオプションと同じように、フィルタとして直接サブルーチンを指定したり、配列のリファレンスを指定することもできます。'decode_base64']);型によるフィルタリングDBIx::Customでは型を指定してフィルタリングを行うことができます。日付型のフィールドであれば、自動的に日付オブジェクトから、データベースの日付に変換するということが可能です。RDBMSとDBIの実装の制約から、型によるフィルタリングの実現はそれほど簡単ではありませんが、少しの制約を受け入れると実用的に利用することができると思います。フィルタの登録フィルタを実際に利用する前に、フィルタを登録しておくと便利です。フィルタの登録をしておけば、フィルタ名でフィルタを指定することができます。ここではデータベースに日付を送信するときはTime::Pieceオブジェクトからデータベースの日付に変換して、反対に取り出すときは、データベースの日付をTime::Pieceオブジェクトに変換するということを行ってみましょう。});tp_to_datetimeというフィルタはTime::Pieceオブジェクトをデータベースの日付・時刻のフォーマットに変換するものです。処理内容としては、undefが渡された場合は空文字列に変換、Time::Pieceオブジェクトではない文字列を渡された場合は変換しない、Time::Pieceオブジェクトの場合は、データベースの日付・時刻のフォーマットに変換という処理を行っています。datetime_to_tpというフィルタはデータベースの日付・時刻のフォーマットをTime::Pieceオブジェクトに変換するものです。処理内容としては、データがなければundefを、存在すればTime::Pieceオブジェクトに変換(ローカル時刻)にして返すという処理を行っています。type_rule型によるフィルタの設定を行うにはtype_ruleメソッドを使用します。});into1とinto2はデータベースにデータを送信するときに実行されるフィルタを指定します。二つまでフィルタを指定することができます。into2」の順番です。into2」の順番に実行されます。from1とfrom2はデータベースからデータを取り出すときに実行されるフィルタを指定します。二つまでフィルタを指定することができます。from2」の順番です。filter属性」の順に実行されます。into1とinto2に指定するタイプ名タイプ名とデータタイプという用語を区別していることに注意してください。into1とinto2ではタイプ名を指定する必要があります。タイプ名とは一般的には、データベースのテーブル定義をするときに指定した名前です。タイプ名は小文字で指定する必要があります。実際に各列のタイプ名を知るためには、show_typenameメソッドを使用します。$dbi->show_typename('book');そこで表示されたタイプ名を利用してください。from1とfrom2に指定するデータタイプfrom1とfrom2にはデータタイプを指定する必要があります。データタイプとは、データベースの内部的なデータの型のことであって一般的には数値になります。一般的には数値ですが、文字列であった場合には、指定するときはデータタイプは小文字で指定する必要があります。実際にデータタイプを知るためには、show_datatypeメソッドを使用します。$dbi->show_datatype('book');型によるフィルタリングのサンプルではSQLiteを使った型によるフィルタリングのサンプルを書いてみたいと思います。$issue_datetime;このサンプルを見ると、insertを行うときは、Time::Pieceオブジェクトがデータベースの日付のフォーマットに変換されて、行をフェッチして取得するときにデータベースの日付のフォーマットからTime::Pieceオブジェクトに変換されていることが確認できます。type_ruleを無効にするinto1のフィルタはtype_rule1_offオプションで、into2のフィルタはtype_rule2_offオプションで無効にすることができます。両方を無効にするには、type_rule_offオプションを利用します。1insertメソッドでは次のように記述できます。'book');from1のフィルタはDBIx::Custom::Resultオブジェクトのtype_rule1_offメソッドで、from2のフィルタはtype_rule2_offメソッドで無効にできます。両方を無効にするには、type_rule_offメソッドを使用します。type_rule_onメソッドを使用してください。type_ruleの実装についてinto1とinto2の実装type_ruleの実装は次のようになっています。into1とinto2によるフィルタは、データベースにデータを送信するときに指定できるフィルタです。実際はパラメータがバインドされる前にフィルタリングが実行されますが、毎回列名がどのようなタイプ名を持つのかを調べたりはしません。それはおそらくとても重い処理になりますし、テーブル名が省略された場合にはうまく機能しないでしょう。type_ruleメソッドが実行された時に、データベースにあるテーブルの列がどのようなタイプ名を持っているかをまず調べて、その情報が保存されます。executeメソッドの実行時にどのフィルタを適用するかを決定します。insertなどのメソッドは内部的にはexecuteを呼び出しています。どのような場合にフィルタリングがかかるかinsertとexecuteの例で説明します。次のinsertを見てください。'book'});type_ruleメソッドが呼ばれた時点で、bookテーブルのissue_datetimeはDATETIME型であるということをDBIx::Customは覚えます。上記のinsertではテーブル名としてbook、列名としてissue_datetimeが指定されていますので、フィルタリングが実行されることになります。次はexecuteメソッドです。次のような場合はフィルタリングがかかりません。11:34:56'});なぜならテーブル名が指定されていないので、どのテーブルのissue_datetimeという列なのかを知ることができないからです。テーブル名を先頭に付加するか、tableオプションでテーブル名を指定するとフィルタリングが行われるようになります。'book');from1とfrom2の実装from1とfrom2は難しいことを考える必要はありません。フェッチしたときにデータタイプを簡単に知ることができるので、その情報を元にフィルタリングを行います。columnオプションで、columnを指定するときに難しいことを考える必要はありません。register_filterフィルタ関数を登録するにはregister_filterメソッドを使用します。});ここで登録したフィルタは、executeメソッドなどのfilterオプションで利用することができます。ユーザー環境にPerlをインストールする月別アーカイブはてなブログをはじめよう!perlcodesampleさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。