Newer Older
1297 lines | 44.787kb
added experimental expand me...
yuki-kimoto authored on 2010-10-20
1
=encoding utf8
2

            
updated document
yuki-kimoto authored on 2010-10-22
3
=head1 NAME
added experimental expand me...
yuki-kimoto authored on 2010-10-20
4

            
update pod
Yuki Kimoto authored on 2011-01-28
5
DBIx::Custom::Guide::Ja - DBIx::Customのガイドブック
added experimental expand me...
yuki-kimoto authored on 2010-10-20
6

            
7
=head1 ガイド
8

            
update pod
Yuki Kimoto authored on 2011-01-28
9
L<DBIx::Custom>はSQLの実行を簡単に行うためのクラスです。
10
L<DBIx::Class>やL<DBIx::Simple>と同じように
updated document
Yuki Kimoto authored on 2011-01-20
11
L<DBI>のラッパクラスになっています。L<DBIx::Class>よりも簡単に、
12
L<DBIx::Simple>よりもはるかに柔軟なことを行うことができます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
13

            
14
L<DBIx::Custom>はO/Rマッパーではありません。O/Rマッパーは
15
便利ですが、O/Rマッパのたくさんの文法を覚える必要があります。
updated document
Yuki Kimoto authored on 2011-01-20
16
また、O/Rマッパによって生成されたSQLは非効率なことがありますし、
17
複雑なSQLを生成することができないので、
18
生のSQLを発行しなければならない場合がたくさんあります。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
19

            
updated document
Yuki Kimoto authored on 2011-01-20
20
L<DBIx::Custom>はO/Rマッパとは対照的な設計が行われています。
updated document
Yuki Kimoto authored on 2011-01-20
21
L<DBIx::Custom>の主な目的は、SQLを尊重しつつ、L<DBI>だけでは
updated document
Yuki Kimoto authored on 2011-01-20
22
とてもめんどうな作業を簡単にすることです。もしSQLについて
23
多くの知識を持っているならば、L<DBIx::Custom>でそのまま
updated document
Yuki Kimoto authored on 2011-01-20
24
活用することができます。
updated document
Yuki Kimoto authored on 2011-01-20
25

            
update pod
Yuki Kimoto authored on 2011-01-28
26
L<DBIx::Custom>の仕組みを少しだけ説明しておきます。
updated document
Yuki Kimoto authored on 2011-01-20
27
L<DBIx::Custom>では、タグと呼ばれるものを
28
SQLの中に埋め込むことができます。
29

            
30
    select * from book where {= title} and {=author};
31

            
32
{}で囲まれた部分がタグです。このSQLは実際に実行されるときには
33
次のようにプレースホルダに展開されます。
34

            
updated document
Yuki Kimoto authored on 2011-01-20
35
    select * from book where title = ? and author = ?;
updated document
Yuki Kimoto authored on 2011-01-20
36

            
37
これらの展開にはどのような意味があるのでしょうかと質問
update pod
Yuki Kimoto authored on 2011-01-28
38
されるかもしれません。この簡単な仕組みの上に
39
便利な機能が実装されます。それは以下のようなものです。
updated document
Yuki Kimoto authored on 2011-01-20
40

            
updated document
Yuki Kimoto authored on 2011-01-20
41
=over 4
updated document
Yuki Kimoto authored on 2011-01-20
42

            
update pod
Yuki Kimoto authored on 2011-01-28
43
=item 1. プレースホルダにバインドする値をハッシュリファレンスで指定
updated document
Yuki Kimoto authored on 2011-01-20
44

            
update pod
Yuki Kimoto authored on 2011-01-28
45
L<DBI>を使うのであればプレースホルダにバインドする値は配列
updated document
Yuki Kimoto authored on 2011-01-20
46
で指定する必要があります。
updated document
Yuki Kimoto authored on 2011-01-20
47

            
updated document
Yuki Kimoto authored on 2011-01-20
48
    $sth->execute(@bind);
49

            
50
L<DBIx::Custom>を利用するのであればハッシュリファレンスで指定すること
51
できます。
52
    
53
    my $param = {title => 'Perl', author => 'Ken'};
54
    $dbi->execute($sql, $param);
55

            
update pod
Yuki Kimoto authored on 2011-01-28
56
=item 2. 値のフィルタリング
updated document
Yuki Kimoto authored on 2011-01-20
57

            
update pod
Yuki Kimoto authored on 2011-01-28
58
L<DBIx::Custom>はフィルタリングの機能を提供します。
updated document
Yuki Kimoto authored on 2011-01-20
59
たとえば、日付の列は、Perlで扱うときにはC<Time::Piece>などの日付オブジェクト
60
で扱い、データベースに格納するときはデータベースの日付型に変換したい
61
と思うのではないでしょうか。またデータベースから取り出すときは
62
データベースの日付型から日付オブジェクトに変換したと思うのでは
63
ないでしょうか。
64

            
65
このようなときはフィルタ機能を使うことができます。
66

            
67
まずフィルタを登録します。
68

            
69
    $dbi->register_filter(
70
        tp_to_date => sub {
71
            ...
72
        },
73
        date_to_tp => sub {
74
            ...
75
        }
76
    );
77

            
78
次にテーブルの各列にこのフィルタを適用します。
79

            
80
    $dbi->apply_filter('book',
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
81
        'issue_date' => {out => 'tp_to_date', in => 'date_to_tp'}
updated document
Yuki Kimoto authored on 2011-01-20
82
    );
83

            
84
outはPerlからデータベースに保存する方向、inはデータベースからPerlに取得する方向です。
85

            
update pod
Yuki Kimoto authored on 2011-01-28
86
多くのメソッドで自動的にこのフィルタが有効になります。
updated document
Yuki Kimoto authored on 2011-01-20
87

            
update pod
Yuki Kimoto authored on 2011-01-28
88
    $dbi->insert(table => 'book', param => {issue_date => $tp});
updated document
Yuki Kimoto authored on 2011-01-20
89

            
90
=item 3. 選択的な検索条件
91

            
update pod
Yuki Kimoto authored on 2011-01-28
92
L<DBI>では選択的に検索条件を作成することは難しいです。
updated document
Yuki Kimoto authored on 2011-01-20
93

            
94
たとえば、検索条件にtitleとauthorが指定された場合は次のSQLを
95

            
96
    select * from book where title = ? and author = ?;
97

            
98
titleだけの場合は次のSQLを
99

            
100
    select * from book where title = ?;
101
    
102
authorだけの場合は次のSQLを発行した場合を考えましょう。
103

            
104
    select * from book where author = ?;
105

            
106
これはとても大変な作業なので、通常はL<SQL::Abstract>を動的に生成してくれる
107
モジュールを利用することになります。
108

            
109
L<DBIx::Custom>はさらに簡単で便利な方法を用意しています。
110

            
update pod
Yuki Kimoto authored on 2011-01-28
111
    # Whereオブジェクト
updated document
Yuki Kimoto authored on 2011-01-20
112
    my $where = $dbi->where;
update pod
Yuki Kimoto authored on 2011-01-28
113
    
114
    # 検索条件
updated document
Yuki Kimoto authored on 2011-01-20
115
    $where->clause(
116
        ['and', '{= title}', {'= author'}]
117
    );
update pod
Yuki Kimoto authored on 2011-01-28
118
    
119
    # 必要な列を自動的に選択するための設定
120
    $where->param({title => 'Perl'});
updated document
Yuki Kimoto authored on 2011-01-20
121

            
update pod
Yuki Kimoto authored on 2011-01-28
122
    # SQLへのWhere句の埋め込み
updated document
Yuki Kimoto authored on 2011-01-20
123
    my $sql = "select * from book $where";
124

            
125
詳しい説明は後ほど行いますが、上記のように記述すれば、
126
L<DBIx::Custom>では選択的な検索条件を持つWhere句を生成することができます。
127
検索条件が入れ子になった構造やorについても対応しています。
128

            
129
=item 4. 挿入、更新、削除、選択を行うためのメソッド
130

            
131
L<DBIx::Custom>ではSQLをさらに簡単に実行するための
132
メソッドも提供しています。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
133
C<insert()>, C<update()>, C<delete()>,C<select()>などの
updated document
Yuki Kimoto authored on 2011-01-20
134
シュガーメソッドを使って、挿入、更新、削除、選択という操作を行うことが
135
できます。
136

            
137
    my $param = {title => 'Perl', author => 'Ken'};
138
    $dbi->insert(table => 'book', param => $param);
139

            
140
=item 5. テーブル単位の操作の登録
141

            
142
テーブルに対して操作を登録することができます。これによって
143
テーブル名を繰り返し指定する必要がなくなり、ソースコードの
144
見通しが良くなります。
145

            
146
    $dbi->talbe('book',
147
        list => sub {
148
            ...
149
        },
150
        list_somethin => sub {
151
            
152
        }
153
    );
154

            
155
登録したメソッドはそのまま利用することができます。
156

            
157
    $dbi->table('book')->list;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
158

            
updated document
Yuki Kimoto authored on 2011-01-20
159
通常O/Rマッパはテーブルに対応するクラスを作成しなければ
160
ならないことが多いですが、L<DBIx::Custom>ではこの作業を簡便に
161
しており、上記のように登録することができます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
162

            
updated document
Yuki Kimoto authored on 2011-01-20
163
=back
164

            
165
L<DBIx::Custom>はL<DBI>を補うとても便利なモジュールです。
166
興味をもたれた方は、この後で詳しい解説を行いますので、
167
ご覧になってみてください。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
168

            
169
=head2 1. データベースへの接続
170

            
updated document
Yuki Kimoto authored on 2011-01-23
171
まずL<DBIx::Custom>を読み込みます。
172

            
173
    use DBIx::Custom;
174

            
added experimental expand me...
yuki-kimoto authored on 2010-10-20
175
L<DBIx::Custom>オブジェクトを生成し、データベースに接続するには
176
C<connect()>メソッドを使用します。
177

            
updated document
Yuki Kimoto authored on 2011-01-23
178
    my $dbi = DBIx::Custom->connect(
179
        data_source => "dbi:mysql:database=dbname",
180
        user => 'ken',
181
        password => '!LFKD%$&',
182
        dbi_options => {mysql_enable_utf8 => 1}
183
    );
added experimental expand me...
yuki-kimoto authored on 2010-10-20
184

            
updated document
Yuki Kimoto authored on 2011-01-23
185
C<data_source>はデータベースシステムに応じたフォーマットで
186
指定する必要があります。以下にデータベースごとのフォーマット
187
方法のサンプルを掲載しておきます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
188

            
updated document
Yuki Kimoto authored on 2011-01-23
189
B<MySQL>
added experimental expand me...
yuki-kimoto authored on 2010-10-20
190

            
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
191
    "dbi:mysql:database=$database"
192
    "dbi:mysql:database=$database;host=$hostname;port=$port"
added experimental expand me...
yuki-kimoto authored on 2010-10-20
193

            
updated document
Yuki Kimoto authored on 2011-01-23
194
B<SQLite>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
195

            
196
    "dbi:SQLite:dbname=$database"
197
    "dbi:SQLite:dbname=:memory:"
198

            
updated document
Yuki Kimoto authored on 2011-01-23
199
B<PostgreSQL>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
200

            
201
    "dbi:Pg:dbname=$dbname"
202

            
updated document
Yuki Kimoto authored on 2011-01-23
203
B<Oracle>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
204

            
205
    "dbi:Oracle:$dbname"
206
    "dbi:Oracle:host=$host;sid=$sid"
207

            
updated document
Yuki Kimoto authored on 2011-01-23
208
B<ODBC(Microsoft Access)>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
209

            
210
    "dbi:ODBC:driver=Microsoft Access Driver (*.mdb);dbq=hoge.mdb"
211

            
updated document
Yuki Kimoto authored on 2011-01-23
212
B<ODBC(SQL Server)>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
213

            
214
   "dbi:ODBC:driver={SQL Server};Server=(local);database=test;Trusted_Connection=yes;AutoTranslate=No;"
added experimental expand me...
yuki-kimoto authored on 2010-10-20
215

            
updated document
Yuki Kimoto authored on 2011-01-23
216
また認証が求められる場合は、C<user>とC<password>ユーザ名と
217
パスワードを指定する必要があります。
218

            
added experimental expand me...
yuki-kimoto authored on 2010-10-20
219
L<DBIx::Custom>はL<DBI>のラッパです。
updated document
Yuki Kimoto authored on 2011-01-23
220
L<DBI>のデータベースハンドルはC<dbh>で取得することができます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
221

            
222
    my $dbh = $dbi->dbh;
223

            
updated document
Yuki Kimoto authored on 2011-01-23
224
L<DBIx::Custom>ではデータベースハンドル属性にはデフォルトで次のものが設定されます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
225
    
226
    $dbi->dbh->{RaiseError} = 1;
227
    $dbi->dbh->{PrintError} = 0;
228
    $dbi->dbh->{AutoCommit} = 1;
229

            
230
この設定を行っているので、致命的なエラーが起こると、
231
例外が発生しプログラムは終了します。
232
またクエリが発行されると自動的にコミットされます。
233

            
updated document
Yuki Kimoto authored on 2011-01-23
234
=head2 2. 挿入、更新、削除、選択のためのメソッド
added experimental expand me...
yuki-kimoto authored on 2010-10-20
235

            
236
L<DBIx::Custom>は、
237
C<insert()>、C<update()>、C<delete()>、C<select()>
updated document
Yuki Kimoto authored on 2011-01-23
238
のような挿入、更新、削除、選択を行うためのメソッドを持っています。
239
簡単なことをを行うのであれば、SQLを自分で記述する必要がありません。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
240

            
update pod
Yuki Kimoto authored on 2011-01-26
241
=head3 データの挿入 C<insert()>
added experimental expand me...
yuki-kimoto authored on 2010-10-20
242

            
updated document
Yuki Kimoto authored on 2011-01-23
243
データベースにデータを挿入するにはC<insert()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
244

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
245
    $dbi->insert(table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
246
                 param  => {title => 'Perl', author => 'Ken'});
247

            
updated document
Yuki Kimoto authored on 2011-01-23
248
C<table>にはテーブル名、C<param>には挿入したいデータを指定します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
249

            
updated document
Yuki Kimoto authored on 2011-01-23
250
次のSQLが発行されます。
251

            
252
    insert into (title, author) values (?, ?);
added experimental expand me...
yuki-kimoto authored on 2010-10-20
253

            
update pod
Yuki Kimoto authored on 2011-01-26
254
=head3 データの更新 C<update()>
added experimental expand me...
yuki-kimoto authored on 2010-10-20
255

            
updated document
Yuki Kimoto authored on 2011-01-23
256
データベースのデータを更新するには、C<update()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
257

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
258
    $dbi->update(table  => 'book', 
added experimental expand me...
yuki-kimoto authored on 2010-10-20
259
                 param  => {title => 'Perl', author => 'Ken'}, 
260
                 where  => {id => 5});
261

            
updated document
Yuki Kimoto authored on 2011-01-23
262
C<table>にはテーブル名、C<param>には挿入したいデータ、C<where>には
263
条件を指定します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
264

            
updated document
Yuki Kimoto authored on 2011-01-23
265
次のSQLが発行されます。
266

            
267
    update book set title = ?, author = ?;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
268

            
269
C<update>メソッドは安全のため
270
where句のないSQLを発行することを許可していません。
271
もしすべての行を更新したい場合は
updated document
Yuki Kimoto authored on 2011-01-23
272
C<update_all()>を使用してください。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
273

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
274
    $dbi->update_all(table  => 'book', 
added experimental expand me...
yuki-kimoto authored on 2010-10-20
275
                     param  => {title => 'Perl', author => 'Ken'});
276

            
update pod
Yuki Kimoto authored on 2011-01-26
277
=head3 データの削除 C<delete()>
added experimental expand me...
yuki-kimoto authored on 2010-10-20
278

            
updated document
Yuki Kimoto authored on 2011-01-23
279
データベースのデータを1件削除するには、C<delete()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
280

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
281
    $dbi->delete(table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
282
                 where  => {author => 'Ken'});
283

            
updated document
Yuki Kimoto authored on 2011-01-23
284
C<table>にはテーブル名、C<where>には条件を指定します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
285

            
updated document
Yuki Kimoto authored on 2011-01-23
286
次のSQLが発行されます。
287

            
288
    delete from book where id = ?;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
289

            
290
C<delete>メソッドは安全のため
291
where句のないSQLを発行することを許可していません。
292
もしすべての行を削除したい場合は
updated document
Yuki Kimoto authored on 2011-01-23
293
C<delete_all()>を使用してください。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
294

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
295
    $dbi->delete_all(table  => 'book');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
296

            
update pod
Yuki Kimoto authored on 2011-01-26
297
=head3 データの選択 C<select()>
added experimental expand me...
yuki-kimoto authored on 2010-10-20
298

            
updated document
Yuki Kimoto authored on 2011-01-23
299
行を選択するにはC<select()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
300

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
301
    my $result = $dbi->select(table => 'book');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
302

            
updated document
Yuki Kimoto authored on 2011-01-23
303
C<table>だけを指定して、他の条件を指定しない場合は次のSQLが発行されます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
304

            
updated document
Yuki Kimoto authored on 2011-01-23
305
    select * from book;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
306

            
307
C<select()>メソッドの戻り値はL<DBIx::Custom::Result>
updated document
Yuki Kimoto authored on 2011-01-23
308
オブジェクトです。行をフェッチするにはC<fetch()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
309

            
310
    while (my $row = $result->fetch) {
311
        my $title  = $row->[0];
312
        my $author = $row->[1];
313
    }
314

            
updated document
Yuki Kimoto authored on 2011-01-23
315
L<DBIx::Custom::Result>についてはこの後L<3. 行のフェッチ/"3. 行のフェッチ">で詳しく扱います。
316

            
317
さまざまなC<select()>の使い方を見ていきましょう。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
318
次のC<select>は行の名前とwhere句を指定したものです。
319

            
320
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
321
        table  => 'book',
updated document
Yuki Kimoto authored on 2011-01-23
322
        column => ['author',  'title'],
added experimental expand me...
yuki-kimoto authored on 2010-10-20
323
        where  => {author => 'Ken'}
324
    );
325

            
updated document
Yuki Kimoto authored on 2011-01-23
326
C<column>には列名を、C<where>には条件を指定することができます。
327
次のSQLが発行されます。
328

            
329
    select author, title from book where author = ?;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
330

            
updated document
Yuki Kimoto authored on 2011-01-23
331
テーブルを結合したい場合ははC<relation>にテーブルの
332
関係を記述します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
333

            
334
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
335
        table    => ['book', 'rental'],
updated document
Yuki Kimoto authored on 2011-01-23
336
        where    => {book.name => 'Perl'},
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
337
        relation => {'book.id' => 'rental.book_id'}
added experimental expand me...
yuki-kimoto authored on 2010-10-20
338
    );
339

            
updated document
Yuki Kimoto authored on 2011-01-23
340
bookテーブルのid列とrentalテーブルのbook_idが関連付けられます。
341
次のSQLが発行されます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
342

            
updated document
Yuki Kimoto authored on 2011-01-23
343
    select * from book, rental where book.name = ? and book.id = rental.book_id;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
344

            
updated document
Yuki Kimoto authored on 2011-01-23
345
SQL文の末尾に文字列を追加したい場合は<append>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
346

            
347
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
348
        table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
349
        where  => {author => 'Ken'},
updated document
Yuki Kimoto authored on 2011-01-23
350
        append => 'for update',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
351
    );
352

            
updated document
Yuki Kimoto authored on 2011-01-23
353
次のSQLが発行されます。
updated document
Yuki Kimoto authored on 2011-01-20
354

            
updated document
Yuki Kimoto authored on 2011-01-23
355
    select * book where author = ? for update;
updated document
Yuki Kimoto authored on 2011-01-20
356

            
updated document
Yuki Kimoto authored on 2011-01-23
357
またC<append>は、C<select>だけでなくC<insert()>、C<update()>、C<update_all()>
358
C<delete()>、C<delete_all()>、C<select()>で使用することもできます。
updated document
Yuki Kimoto authored on 2011-01-20
359

            
update pod
Yuki Kimoto authored on 2011-01-26
360
=head3 SQLの実行 C<execute()>
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
361

            
362
任意のSQLを実行するにはexecuteメソッドを使用します。
363

            
364
    $dbi->execute("select * from book;");
365

            
366
C<execute()>はL<DBIx::Custom>の根幹のメソッドでありタグを展開します。
367

            
368
    $dbi->execute(
369
        "select * from book {= title} and {= author};"
370
        param => {title => 'Perl', author => 'Ken'}
371
    );
372

            
373
上記のタグを含んだSQLは次のように展開されます。
374

            
375
    select * from book title = ? and author = ?;
376

            
377
SQLが実行されるときにプレースホルダ(?)に対応する位置にtitleとauthor
378
の値がが自動的に埋め込まれます。
379

            
380
タグについてはL<5. タグ/"5. タグ">で詳しく解説しますが、
381
ひとつの注意点があります。
382
タグを展開するためにC<{>とC<}>は予約語になっています。
383
もし利用したい場合は直前に\をおいてエスケープを行う必要があります。
384

            
385
    $dbi->execute("... \\{ ... \\} ...");
386

            
387
\自体がPerlのエスケープ文字ですので、二つ必要になるという点に注意してください。
388

            
389
またexecuteのキュートな機能として、SQLの最後にセミコロンをおかなくても
390
かまいません。
391

            
392
    $dbi->execute('select * from book');
393

            
updated document
Yuki Kimoto authored on 2011-01-20
394
=head2 3. 行のフェッチ
395

            
updated document
Yuki Kimoto authored on 2011-01-23
396
C<select()>メソッドの戻り値はL<DBIx::Custom::Result>オブジェクトです。
397
L<DBIx::Custom::Result>には行をフェッチするためのさまざまなメソッドが
updated document
Yuki Kimoto authored on 2011-01-20
398
用意されています。
399

            
update pod
Yuki Kimoto authored on 2011-01-26
400
=head3 1行づつフェッチ(配列) C<fetch()>
updated document
Yuki Kimoto authored on 2011-01-20
401

            
updated document
Yuki Kimoto authored on 2011-01-23
402
一行フェッチして配列のリファレンスに格納するにはC<fetch()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
403

            
404
    while (my $row = $result->fetch) {
updated document
Yuki Kimoto authored on 2011-01-23
405
        my $title  = $row->[0];
406
        my $author = $row->[1];
updated document
Yuki Kimoto authored on 2011-01-20
407
    }
408

            
updated document
Yuki Kimoto authored on 2011-01-23
409
whileループを使って、すべての行を取得することができます。
410

            
update pod
Yuki Kimoto authored on 2011-01-26
411
=head3 最初の行だけフェッチ(配列) C<fetch_first()>
updated document
Yuki Kimoto authored on 2011-01-20
412

            
updated document
Yuki Kimoto authored on 2011-01-23
413
一行だけフェッチして配列のリファレンスに格納するにはC<fetch_first()>
414
を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
415

            
416
    my $row = $result->fetch_first;
417

            
updated document
Yuki Kimoto authored on 2011-01-23
418
一行のフェッチが終わった後はそれ以上フェッチできなくなります。
419
内部的には1行のフェッチが終わった後に
420
ステートメントハンドルのC<finish()>が実行されます。
updated document
Yuki Kimoto authored on 2011-01-20
421

            
update pod
Yuki Kimoto authored on 2011-01-26
422
=head3 複数行を順にフェッチ(配列) C<fetch_multi()>
updated document
Yuki Kimoto authored on 2011-01-20
423

            
updated document
Yuki Kimoto authored on 2011-01-23
424
複数行をフェッチして配列のリファレンスを要素に持つ
425
配列のリファレンスに格納するにはC<fetch_multi()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
426

            
updated document
Yuki Kimoto authored on 2011-01-23
427
    while (my $rows = $result->fetch_multi(2)) {
428
        my $title0   = $rows->[0][0];
429
        my $author0  = $rows->[0][1];
430
        
431
        my $title1   = $rows->[1][0];
432
        my $author1  = $rows->[1][1];
updated document
Yuki Kimoto authored on 2011-01-20
433
    }
434

            
updated document
Yuki Kimoto authored on 2011-01-23
435
引数には取り出したい行数を指定します。
436

            
437
指定した行を格納した次のようなデータを取得できます。
438

            
439
    [
440
        ['Perl', 'Ken'],
441
        ['Ruby', 'Mark']
442
    ]
443

            
update pod
Yuki Kimoto authored on 2011-01-26
444
=head3 すべての行をフェッチ(配列) C<fetch_all>
updated document
Yuki Kimoto authored on 2011-01-20
445

            
updated document
Yuki Kimoto authored on 2011-01-23
446
すべての行をフェッチして配列のリファレンスを要素に持つ
447
配列のリファレンスに格納するにはC<fetch_all()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
448

            
449
    my $rows = $result->fetch_all;
450

            
updated document
Yuki Kimoto authored on 2011-01-23
451
すべての行を格納した次のようなデータを取得できます。
452

            
453
    [
454
        ['Perl', 'Ken'],
455
        ['Ruby', 'Mark']
456
    ]
457

            
update pod
Yuki Kimoto authored on 2011-01-26
458
=head3 1行づつフェッチ(ハッシュ) C<fetch_hash()>
updated document
Yuki Kimoto authored on 2011-01-20
459

            
updated document
Yuki Kimoto authored on 2011-01-23
460
一行フェッチしてハッシュのリファレンスに格納するにはC<fetch_hash()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
461

            
462
    while (my $row = $result->fetch_hash) {
463
        my $title  = $row->{title};
464
        my $author = $row->{author};
465
    }
466

            
update pod
Yuki Kimoto authored on 2011-01-26
467
=head3 最初の行だけフェッチ(ハッシュ) C<fetch_hash_first()>
updated document
Yuki Kimoto authored on 2011-01-20
468

            
updated document
Yuki Kimoto authored on 2011-01-23
469
一行だけフェッチしてハッシュのリファレンスに格納するには
470
C<fetch_hash_first()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
471

            
472
    my $row = $result->fetch_hash_first;
473

            
updated document
Yuki Kimoto authored on 2011-01-23
474
一行のフェッチが終わった後はそれ以上フェッチできなくなります。
475
内部的には1行のフェッチが終わった後に
476
ステートメントハンドルのC<finish()>が実行されます。
updated document
Yuki Kimoto authored on 2011-01-20
477

            
update pod
Yuki Kimoto authored on 2011-01-26
478
=head3 複数行を順にフェッチ(ハッシュ) C<fetch_hash_multi()>
updated document
Yuki Kimoto authored on 2011-01-20
479

            
updated document
Yuki Kimoto authored on 2011-01-23
480
複数行をフェッチしてハッシュのリファレンスを要素に持つ
481
配列のリファレンスに格納するにはC<fetch_hash_multi()>
482
を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
483

            
484
    while (my $rows = $result->fetch_hash_multi(5)) {
updated document
Yuki Kimoto authored on 2011-01-23
485
        my $title0   = $rows->[0]{title};
486
        my $author0  = $rows->[0]{author};
487
        my $title1  = $rows->[1]{title};
488
        my $author1 = $rows->[1]{author};
updated document
Yuki Kimoto authored on 2011-01-20
489
    }
490

            
updated document
Yuki Kimoto authored on 2011-01-23
491
引数には取り出したい行数を指定します。
492

            
493
指定した行を格納した次のようなデータを取得できます。
494

            
495
    [
496
        {title => 'Perl', author => 'Ken'},
497
        {title => 'Ruby', author => 'Mark'}
498
    ]
499

            
update pod
Yuki Kimoto authored on 2011-01-26
500
=head3 すべての行をフェッチ(ハッシュ) C<fetch_hash_all()>
updated document
Yuki Kimoto authored on 2011-01-20
501

            
updated document
Yuki Kimoto authored on 2011-01-23
502
すべての行をフェッチしてハッシュのリファレンスを要素に持つ
503
配列のリファレンスに格納するにはC<fetch_hash_all()>
504
を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
505

            
506
    my $rows = $result->fetch_hash_all;
507

            
updated document
Yuki Kimoto authored on 2011-01-23
508
すべての行を格納した次のようなデータを取得できます。
509

            
510
    [
511
        {title => 'Perl', author => 'Ken'},
512
        {title => 'Ruby', author => 'Mark'}
513
    ]
514

            
update pod
Yuki Kimoto authored on 2011-01-26
515
=head3 ステートメントハンドル C<sth()>
updated document
Yuki Kimoto authored on 2011-01-23
516

            
517
ステートメントハンドルに直接アクセスしたい場合は
518
<sth>で取得することができます。
updated document
Yuki Kimoto authored on 2011-01-20
519

            
520
    my $sth = $result->sth;
521

            
updated document
Yuki Kimoto authored on 2011-01-23
522
フェッチのパフォーマンスが用件を満たさないときには、
523
ステートメントハンドルから
524
利用できる速度の速いメソッドを利用することができます。
525

            
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
526
=head2 4. フィルタリング
527

            
528
データベースにデータを登録するときやデータベースからデータを取得する
529
ときに自動的に値の変換を行いたい場合が多いと思います。
530
たとえば、日付を表現する列の場合は、
531
データベースに登録する場合はL<Time::Piece>オブジェクトから
532
データベースの日付のフォーマットに、
533
データベースからデータを取得するときは、その逆を行えると便利です。
534

            
update pod
Yuki Kimoto authored on 2011-01-26
535
=head3 フィルタの登録 C<register_filter()>
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
536

            
537
フィルタを登録するにはC<register_filter()>を使用します。
538

            
539
    $dbi->register_filter(
540
        # Time::Piece object to DATE format
541
        tp_to_date => sub {
542
            my $date = shift;
543

            
544
            return '0000-00-00' unless $tp;
545
            return $tp->strftime('%Y-%m-%d');
546
        },
547
        
548
        # DATE to Time::Piece object
549
        date_to_tp => sub {
550
            my $date = shift;
551

            
552
            return if $date eq '0000-00-00';
553
            return Time::Piece->strptime($date, '%Y-%m-%d');
554
        },
555
    );
556

            
557
登録したフィルタはC<apply_filter()>などで利用することができます。
558

            
update pod
Yuki Kimoto authored on 2011-01-26
559
=head3 フィルタの適用 C<apply_filter()>
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
560

            
561
作成したフィルタを適用するには、C<apply_filter()>を使用します。
562

            
563
    $dbi->apply_filter('book',
564
        issue_date => {out => 'tp_to_date', in => 'date_to_tp'},
565
        first_issue_date => {out => 'tp_to_date', in => 'date_to_tp'}
566
    );
567

            
568
第一引数はテーブル名です。第二引数以降は、列名とフィルタルールのペアを記述します。
569
フィルタルールのoutには、データベースにデータを送信するときに適用するフィルタを、
570
フィルタルールのinには、データベースからデータを取得するときに適用するフィルタを
571
記述します。outがデータベースに送信する方向、inがデータベースから取り出す方向です。
572
フィルタには、C<register_filter>で登録したフィルタ名の他に、コードリファレンスを
573
指定することもできます。
574

            
575
    issue_date => {out => sub { ... }, in => sub { ... }}
576

            
577
適用されたフィルタはC<insert()>、C<update()>、C<update_all()>、C<delete()>、
578
C<delete_all()>、C<select()>で有効になります。
579

            
580
    my $tp = Time::Piece->strptime('2010/10/14', '%Y/%m/%d');
581
    my $result = $dbi->select(table => 'book', where => {issu_date => $tp});
582

            
583
データベースにデータが送信されるときに、L<Time::Piece>オブジェクトは
584
データベースの日付のフォーマット「2010-10-14」に変換されます。
585

            
586
また逆にデータをフェッチするときには、データベースの日付のフォーマットは
587
タイムピースオブジェクトに変換されます。
588

            
589
    my $row = $resutl->fetch_hash_first;
590
    my $tp = $row->{issue_date};
591

            
592
このような自動的に実行されるフィルタを登録できることがL<DBIx::Custom>の
593
特徴のひとつです。
594

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
595
C<apply_filter()>で適用されたフィルタはテーブル名をを含む列名に対しても有効です。
596

            
597
    $dbi->select(
598
        table => 'book',
599
        where => {'book.title' => 'Perl', 'book.author' => 'Ken'}
600
    );
601

            
602
テーブルを区別する必要があるときに便利な機能です。
603

            
update pod
Yuki Kimoto authored on 2011-01-26
604
=head3 個別のフィルタの適用 C<filter>
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
605

            
606
C<apply_filter()>を使って最初にすべてのテーブルの列について
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
607
フィルタを定義することもできますが、
608
個別にフィルタを適用することもできます。
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
609
個別のフィルタはC<apply_filter()>で適用したフィルタを上書きます。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
610
個別のフィルタはSQLのasを使って、列の別名を作成する必要がある場合に活躍します。
611

            
612
データベースに送信する場合に、個別のフィルタを適用するには、各メソッドの
613
C<filter>オプションを使用します。個別のフィルタは、C<insert()>、C<update()>、
614
C<update_all()>、C<delete()>、C<delete_all()>、C<select()>、C<execute()>
615
で使用することができます。
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
616

            
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
617
C<insert()>の例を示します。
618

            
619
    $dbi->insert(
620
        table => 'book',
621
        param => {issue_date => $tp, first_issue_date => $tp},
622
        filter => {issue_date => 'tp_to_date', first_issue_date => 'tp_to_date'}
623
    );
624

            
625
C<execute()>の例を示します。
626

            
627
my $sql = <<"EOS";
628
select YEAR(issue_date) as issue_year
629
from book
630
where YEAR(issue_date) = {? issue_year}
631
EOS
632
   
633
    my $result = $dbi->execute(
634
        $sql,
635
        param => {issue_year => '2010'},
636
        filter => {issue_year => 'tp_to_year'}
637
    );
638

            
639
これはC<filter>を使う良くある例です。issue_dateの変換についてはC<apply_filter()>
640
で登録してあるのですが、新しく作成した列であるissue_yearについては、
641
何の変換も登録されていません。ですので、個別にフィルタを設定しています。
642

            
643
また反対に行をフェッチするときにも個別のフィルタを適用することができます。
644
フィルタを適用するには、
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
645
C<DBIx::Custom::Result>クラスのC<filter>メソッドを使用します。
646

            
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
647
    $result->filter(issue_year => 'year_to_tp');
648

            
649
頻繁に利用するのであれば、個別に登録するよりもC<apply_filter()>で登録
650
しておいたほうが便利でしょう。C<apply_filter()>は存在しない列に対しても
651
フィルタを適用できるからです。
652

            
653
    $dbi->apply_filter('book',
654
        'issue_year' => {out => 'tp_to_year', in => 'year_to_tp'}
655
    );
656

            
update pod
Yuki Kimoto authored on 2011-01-26
657
=head3 最終出力のためのフィルタリング C<end_filter()>
658

            
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
659
C<DBIx::Custom::Result>ではさらに最後にもう一度、フィルタを追加で
660
登録することができます。たとえばHTMLに出力したい場合に、Time::Piece
661
オブジェクトから読みやすい記述に変換することができます。
662
最後のフィルタを登録するには、C<end_filter()>を使用します。
663

            
664
    $result->end_filter(issue_date => sub {
665
        my $tp = shift;
666
        
667
        return '' unless $tp;
668
        return $tp->strftime('%Y/%m/%d %h:%m:%s (%a)');
669
    });
670

            
671
日付を見やすい形にフォーマットすることができます。
672

            
673
フィルタはフェッチを行う前に登録しておく必要があることに
674
注意してください。
675

            
676
    $result->filter(...);
677
    $result->end_filter(...);
678
    my $row = $result->fetch_hash_first;
679

            
update pod
Yuki Kimoto authored on 2011-01-26
680
=head3 列の情報を元にフィルタを適用する C<each_column()>
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
681

            
682
日付型の列は手動で設定しなくても、自動的に設定できると便利です。
683
このためにデータベースのテーブルの列のすべての情報を
684
順番に処理するためのC<each_column()>があります。
685

            
686
    $dbi->each_column(
687
        sub {
688
            my ($self, $table, $column, $info) = @_;
689
            
690
            my $type = $info->{TYPE_NAME};
691
            
692
            my $filter = $type eq 'DATE'     ? {out => 'tp_to_date', in => 'date_to_tp'}
693
                       : $type eq 'DATETIME' ? {out => 'tp_to_datetime', in => 'datetime_to_tp'}
694
                                             : undef;
695
            
696
            $self->apply_filter($table, $column, $filter)
697
              if $filter;
698
        }
699
    );
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
700

            
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
701
each_columnはコールバックを受け取ります。コールバックの引数は
702
順番にL<DBIx::Custom>オブジェクト、テーブル名、列名、列の情報です。
703
列の型名の情報をもとに自動的に、フィルタを適用しています。
704

            
705
ひとつの注意点としてコールバックの中から、コールバックの外側
706
の変数を参照しないように注意してください。each_columnは
707
高々1回だけ実行されるだけなので、ほとんどの場合問題ありませんが、
708
循環参照によるメモリリークが発生してしまう可能性を持っているからです。
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
709

            
710
=head2 5. タグ
updated document
Yuki Kimoto authored on 2011-01-20
711

            
update pod
Yuki Kimoto authored on 2011-01-26
712
=head3 タグの機能
updated document
Yuki Kimoto authored on 2011-01-20
713

            
update pod
Yuki Kimoto authored on 2011-01-26
714
L<DBIx::Custom>はSQLの中にタグを埋め込む機能を持っています。
updated document
Yuki Kimoto authored on 2011-01-20
715

            
update pod
Yuki Kimoto authored on 2011-01-26
716
    select * from book where {= title} and {like author};
updated document
Yuki Kimoto authored on 2011-01-20
717

            
update pod
Yuki Kimoto authored on 2011-01-26
718
{= title}と{like author}の部分がタグです。タグは次のような形式
719
を持ちます。
updated document
Yuki Kimoto authored on 2011-01-20
720

            
update pod
Yuki Kimoto authored on 2011-01-26
721
    {タグ名 引数1 引数2 ...}
722
    
723
タグはC<{>で始まり、C<}>で終わります。最初のC<{>とタグ名の間
724
には空白を挿入しないよう注意してください。
updated document
Yuki Kimoto authored on 2011-01-20
725

            
update pod
Yuki Kimoto authored on 2011-01-26
726
タグの機能のためにC<{>とC<}>は予約語になっています。
727
もし利用したい場合は直前に\をおいてエスケープを行う必要があります。
updated document
Yuki Kimoto authored on 2011-01-20
728

            
update pod
Yuki Kimoto authored on 2011-01-26
729
    select from book \\{ ... \\}
730

            
731
C<\>自体がPerlのエスケープ文字ですので、
732
エスケープする場合はC<\>が二つ必要になるという点に注意してください。
733

            
734
上記のタグはSQLが実行される前に次のSQLに展開されます。
735

            
736
    select * from book where title = ? and author like ?;
updated document
Yuki Kimoto authored on 2011-01-20
737

            
update pod
Yuki Kimoto authored on 2011-01-26
738
タグを含むSQLを実行するにはC<execute()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
739

            
update pod
Yuki Kimoto authored on 2011-01-26
740
    my $sql = "select * from book where {= author} and {like title};"
741
    $dbi->execute($sql, param => {title => 'Perl', author => '%Ken%'});
updated document
Yuki Kimoto authored on 2011-01-20
742

            
update pod
Yuki Kimoto authored on 2011-01-26
743
C<param>オプションを使って、プレースホルダに埋め込みたい値を
744
ハッシュリファレンスで指定することができます。
updated document
Yuki Kimoto authored on 2011-01-20
745

            
update pod
Yuki Kimoto authored on 2011-01-26
746
他のメソッドと同様にC<execute()>においてもC<filter>を指定することができます。
747

            
748
    $dbi->execute($sql, param => {title => 'Perl', author => '%Ken%'}
749
                  filter => {title => 'to_something');
750

            
751
C<execute>のひとつの注意点としてはC<apply_filter()>で適用されたフィルタ
752
はデフォルトでは有効ではないということに注意してください。
753
C<apply_filter()>で適用されたフィルタを有効にするには、
754
C<table>を指定する必要があります。
755

            
756
    $dbi->execute($sql, param => {title => 'Perl', author => '%Ken%'}
757
                  table => ['book']);
758

            
759
=head2 タグ一覧
760

            
761
L<DBIx::Custom>では次のタグが使用可能です。
updated document
Yuki Kimoto authored on 2011-01-20
762

            
763
このようにタグを使ってSQL文を表現するのがL<DBIx::Custom>の
764
特徴です。以下のタグが利用可能です。
765

            
update pod
Yuki Kimoto authored on 2011-01-26
766
=head3 C<?>
767

            
768
C<?>タグは以下のように展開されます。
769

            
770
    {? NAME}    ->   ?
771

            
772
=head3 C<=>
773

            
774
C<=>タグは以下のように展開されます。
775

            
776
    {= NAME}    ->   NAME = ?
777

            
778
=head3 C<E<lt>E<gt>>
779

            
780
C<E<lt>E<gt>>タグは以下のように展開されます。
781

            
782
    {<> NAME}   ->   NAME <> ?
783

            
784
=head3 C<E<lt>>
785

            
786
C<E<lt>>タグは以下のように展開されます。
787

            
788
    {< NAME}    ->   NAME < ?
789

            
790
=head3 C<E<gt>>
791

            
792
C<E<gt>>タグは以下のように展開されます。
793

            
794
    {> NAME}    ->   NAME > ?
795

            
796
=head3 C<E<gt>=>
797

            
798
C<E<gt>=>タグは以下のように展開されます。
799

            
800
    {>= NAME}   ->   NAME >= ?
801

            
802
=head3 C<E<lt>=>
803

            
804
C<E<lt>=>タグは以下のように展開されます。
805

            
806
    {<= NAME}   ->   NAME <= ?
807

            
808
=head3 C<like>
809

            
810
C<like>タグは以下のように展開されます。
811

            
812
    {like NAME}   ->   NAME like ?
813

            
814
=head3 C<in>
815

            
816
C<in>タグは以下のように展開されます。プレースホルダの
817
数を引数で指定する必要があることに注意してください。
818

            
819
    {in NAME COUNT}   ->   NAME in [?, ?, ..]
820

            
821
=head3 C<insert_param>
822

            
823
C<insert_param>タグは以下のように展開されます。
824

            
updated document
Yuki Kimoto authored on 2011-01-20
825
    {insert_param NAME1 NAME2}   ->   (NAME1, NAME2) values (?, ?)
update pod
Yuki Kimoto authored on 2011-01-26
826

            
827
=head3 C<update_param>
828

            
829
C<update_param>タグは以下のように展開されます。
830

            
updated document
Yuki Kimoto authored on 2011-01-20
831
    {update_param NAME1 NAME2}   ->   set NAME1 = ?, NAME2 = ?
832

            
update pod
Yuki Kimoto authored on 2011-01-26
833
=head2 同名の列の扱い
updated document
Yuki Kimoto authored on 2011-01-20
834

            
update pod
Yuki Kimoto authored on 2011-01-26
835
同名の列を含むタグがある場合にも、SQLを実行することができます。
836
たとえば、二つの日付で比較しなければならない場合を
837
考えて見ましょう。
updated document
Yuki Kimoto authored on 2011-01-20
838

            
update pod
Yuki Kimoto authored on 2011-01-26
839
    my $sql = "select * from table where {> date} and {< date};";
updated document
Yuki Kimoto authored on 2011-01-20
840

            
update pod
Yuki Kimoto authored on 2011-01-26
841
このような場合は対応するパラメータの値を配列のリファレンスにします。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
842

            
update pod
Yuki Kimoto authored on 2011-01-26
843
    my $dbi->execute($sql, param => {date => ['2010-10-01', '2012-02-10']});
844

            
845
=head2 タグの追加 C<register_tag()>
846

            
cleanup
Yuki Kimoto authored on 2011-01-26
847
L<DBIx::Custom>ではタグを独自に追加することができます。
update pod
Yuki Kimoto authored on 2011-01-26
848
タグを追加するにはC<register_tag()>を使用します。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
849

            
850
    $dbi->register_tag(
update pod
Yuki Kimoto authored on 2011-01-26
851
        '=' => sub {
852
            my $column = shift;
853
            
854
            return ["$column = ?", [$column]];
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
855
        }
856
    );
857

            
update pod
Yuki Kimoto authored on 2011-01-26
858
ここではデフォルトのC<=>タグがどのように実装されているかを示しています。
859
タグを登録する関数の引数はタグの中に書かれた引数になります。
860

            
861
    {タグ名 引数1 引数2}
862

            
863
C<=>タグの場合は
864

            
865
    {= title}
866

            
867
という形式ですから、サブルーチンにはtitleというひとつの列名がわたってきます。
868

            
869
サブルーチンの戻り値には次の形式の配列のリファレンスを返す必要があります。
870

            
871
    [
872
        展開後の文字列,
873
        [プレースホルダに埋め込みに利用する列名1, 列名2, ...]
874
    ]
875

            
876
一つ目の要素は展開後の文字列です。この例では
877

            
878
    'title = ?'
879

            
880
を返す必要があります。
881

            
882
二つ目の要素はプレースホルダに埋め込みに利用する列名を含む配列の
883
リファレンスです。今回の例では
884

            
885
    ['title']
886

            
887
を返す必要があります。複数のプレースホルダを含む場合は、この部分が
888
複数になります。C<insert_param>タグやC<update_param>タグは
889
この部分が実際複数になっています。
890

            
891
上記を合わせると
892

            
893
    ['title = ?', ['title']]
894
    
895
を返す必要があるということです。
896

            
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
897
タグの実装の他のサンプルはL<DBIx::Custom::Tag>のソースコード
898
をご覧になってみてください。
899

            
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
900
=head2 6. Where句の動的な生成
901

            
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
902
=head3 Where句の動的な生成 where()
903

            
904
複数の検索条件を指定して、検索を行いたい場合があります。
905
次の3つのケースのwhere句を考えてみましょう。
906
下記のようなwhere句が必要になります。
907

            
908
titleの値だけで検索したい場合
909

            
910
    where {= title}
911

            
912
authorの値だけで検索したい場合
913

            
914
    where {= author}
915

            
916
titleとauthorの両方の値で検索したい場合
917

            
918
    where {= title} and {=author}
919

            
920
L<DBIx::Custom>では動的なWhere句の生成をサポートしています。
921
まずC<where()>でL<DBIx::Custom::Where>オブジェクトを生成します。
922

            
923
    my $where = $dbi->where;
924

            
925
次にC<clause()>を使用してwhere句を記述します。
926

            
927
    $where->clause(
928
        ['and', '{= title'}, '{= author}']
929
    );
930

            
931
clauseの指定方法は次のようになります。
932

            
933
    ['or' あるいは 'and', タグ1, タグ2, タグ3]
934

            
935
第一引数にはorあるいはandを指定します。第二引数以降には
936
検索条件をタグを使って記述します。
937

            
938
C<clause>の指定は入れ子にすることもでき、さらに複雑な条件
939
を記述することもできます。
940

            
941
    ['and', 
942
      '{= title}', 
943
      ['or', '{= author}', '{like date}']
944
    ]
945

            
946
このようにC<clause>を設定した後にC<param>にパラメータを指定します。
947
    
948
    my $param => {title => 'Perl'};
949
    $where->param($param);
950

            
951
この例ではtitleだけがパラメータに含まれています。
952

            
953
この後C<to_string()>を実行すると$paramに含まれるパラメータを満たす
954
where句を生成することができます。
955

            
956
    my $where_clause = $where->to_string;
957

            
958
パラメータはtitleだけですので、次のようなwhere句が生成されます。
959

            
960
    where {= title}
961

            
cleanup
Yuki Kimoto authored on 2011-01-26
962
またL<DBIx::Custom>は文字列の評価をオーバーロードして、C<to_string()>
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
963
を呼び出すようにしていますので、次のようにしてwhere句を生成することも
964
できます。
965

            
966
    my $where_clause = "$where";
967

            
968
これはSQLの中にwhere句を埋め込むときにとても役立つ機能です。
969

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
970
=head3 同一の列名を含む場合
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
971

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
972
タグの中に同一の名前を持つものが存在した場合でも動的に
973
where句を作成することができます。
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
974

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
975
たとえば、パラメータとして開始日付と終了日付を受け取ったことを
976
考えてみてください。
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
977

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
978
    my $param = {start_date => '2010-11-15', end_date => '2011-11-21'};
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
979

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
980
また開始日付と終了日付の片方だけや、どちらも受け取らない場合もあるかもしれません。
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
981

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
982
この場合は次のようなパラメータに変換することで対応することができます。
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
983

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
984
    my $p = {date => ['2010-11-15', '2011-11-21']};
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
985

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
986
値が配列のリファレンスになっていることに注目してください。このようにすれば
987
同名の列を含むタグに順番に埋め込むことができます。
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
988

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
989
    $where->clause(
990
        ['and', '{> date}', '{< date}']
991
    );
992
    $where->param($p);
993

            
994
また開始日付が存在しない場合は次のようなデータを作成します。
995

            
996
    my $p = {date => [$dbi->not_exists, '2011-11-21']};
997

            
998
L<DBIx::Custom>のC<not_exists>でDBIx::Custom::NotExistsオブジェクトを
999
取得できます。これは対応する値が存在しないことを示すためのものです。
1000

            
1001
また終了日付が存在しない場合は次のようなデータを作成します。
1002

            
1003
    my $p = {date => ['2010-11-15']};
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
1004

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
1005
どちらも存在しない場合は次のようなデータを作成します。
1006

            
1007
    my $p = {date => []};
1008

            
1009
少し難しいので一番簡単に作成できるロジックを示しておきます。
1010

            
1011
    my @date;
1012
    push @date, exists $param->{start_date} ? $param->{start_date}
1013
                                            : $dbi->not_exists;
1014
    push @date, $param->{end_date} if exists $param->{end_date};
1015
    my $p = {date => \@date};
1016

            
1017
=head3 C<select()>との連携
1018

            
update pod
Yuki Kimoto authored on 2011-01-26
1019
L<DBIx::Custom::Where>オブジェクトは
1020
C<select()>のC<where>に直接渡すことが
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
1021
できます。
1022
    
1023
    my $where = $dbi->where;
1024
    $where->clause(...);
1025
    $where->param($param);
1026
    my $result = $dbi->select(table => 'book', where => $where);
1027

            
update pod
Yuki Kimoto authored on 2011-01-26
1028
あるいはC<update()>、C<delete()>のwhereに指定することも可能です。
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
1029

            
1030
=head3 C<execute()>との連携
1031

            
1032
C<execute()>との連携です。SQLを作成するときに埋め込むことができます。
1033

            
1034

            
1035
    my $where = $dbi->where;
1036
    $where->clause(...);
1037
    $where->param($param);
1038

            
1039
    my $sql = <<"EOS"
1040
    select * from book;
1041
    $where
1042
    EOS
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
1043

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
1044
    $dbi->execute($sql, param => $param);
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
1045

            
update pod
Yuki Kimoto authored on 2011-01-28
1046
=head2 7. テーブルモデル
1047

            
1048
=head3 テーブルオブジェクトの作成 C<table()>
1049

            
1050
L<DBIx::Custom>はロジックとしてテーブルを中心にすえた
1051
モデルの作成を支援します。
1052

            
1053
アプリケーションのロジックを記述するときに、そのロジックを
1054
データベースのテーブルにすえることは、RDBMSを利用する
1055
モデルであれば、コードの重複も少なく
1056
わかりやすいものになります。
1057

            
1058
テーブルオブジェクトを生成するにはC<table()>を使用します。
1059

            
1060
    my $table = $dbi->table('book');
1061

            
1062
実際にデータベースにテーブルは存在している必要はありません。
1063
これは仮想的なテーブルオブジェクトです。これは
1064
L<DBIx::Customm::Table>オブジェクトになります。
1065

            
1066
テーブルオブジェクトからはC<insert()>、C<update()>、C<update_all()>、
1067
C<delete()>、C<delete_all()>、C<select()>などのメソッド呼び出すことができます。
1068
L<DBIx::Custom>と異なるところは、C<table>を必ずしも指定する必要が
1069
ないということです。
1070

            
1071
    $table->insert(param => $param);
1072

            
1073
C<table>の値は自動的にbookに設定されます。
1074

            
1075
またテーブルオブジェクトには独自のメソッドを追加することができます。
1076

            
1077
    $table->method(
1078
        register => sub {
1079
            my $self = shift;
1080
            my $table_name = $self->name;
1081
            # something
1082
        },
1083
        list => sub {
1084
            my $self = shift;
1085
            my $table_name = $self->name;
1086
            # something
1087
        }
1088
    );
1089

            
1090
メソッドに渡される第一引数はL<DBIx::Custom::Table>オブジェクトです。
1091
C<name()>を使用して、テーブル名を取得することができます。
1092

            
1093
このようにして登録したメソッドは直接呼び出すことができます。
1094

            
1095
    $table->register(...);
1096
    $table->list(...);
1097

            
1098
またテーブル専用のメソッドをオーバーライドして作成することもできます。
1099

            
1100
    $table->method(
1101
        insert => sub {
1102
            my $self = shift;
1103
            
1104
            $self->base_insert(...);
1105
            
1106
            # something
1107
        }
1108
    );
1109

            
1110
もともと存在していたC<insert()>を呼ぶにはC<base_$method>とします。L<DBIx::Custom::Table>
1111
のオーバーライドの機能は簡易的なものですが、とても便利です。
1112

            
1113
=head2 テーブルで共有のメソッドの登録
1114

            
1115
すべてのテーブルでメソッドを共有するにはC<table>メソッドでテーブルを作成する前に、
1116
C<base_table>にメソッドを登録しておきます。
1117

            
1118
    $dbi->base_table->method(
1119
        count => sub {
1120
            my $self = shift;
1121
            return $self->select(column => ['count(*)']);
1122
        }
1123
    );
1124

            
1125
またテーブルからはL<DBIx::Custom>とL<DBI>のすべてのメソッドを呼び出すことができます。
1126

            
1127
    # DBIx::Custom method
1128
    $table->execute($sql);
1129
    
1130
    # DBI method
1131
    $table->begin_work;
1132
    $table->commit;
1133

            
1134
=head2 一般的なモデルの構成
1135

            
1136
一般的には、L<DBIx::Custom>を継承してコンストラクタの中に、モデルを作成
1137
するのがよいでしょう。
1138

            
1139
    package MyDBI;
1140
    
1141
    use base 'DBIx::Custom';
1142
    
1143
    sub connect {
1144
        my $self = shift->SUPER::connect(@_);
1145
        
1146
        $self->base_table->method(
1147
            ... => sub { ... }
1148
        );
1149
        
1150
        $self->table('book')->method(
1151
            insert_multi => sub { ... },
1152
            ... => sub { ... }
1153
        );
1154
        
1155
        $self->table('company')->method(
1156
            ... => sub { ... },
1157
        );
1158
    }
1159

            
1160
このようにして定義しておけば、次のように利用することができます。
1161

            
1162
    my $dbi = MyDBI->connect(...);
1163
    $dbi->table('book')->insert_multi(...);
1164

            
1165
=head2 8. パフォーマンスの改善
updated document
Yuki Kimoto authored on 2011-01-20
1166

            
update pod
Yuki Kimoto authored on 2011-01-26
1167
=head3 クエリの作成
updated document
Yuki Kimoto authored on 2011-01-20
1168

            
1169
もしC<insert()>メソッドを使用してインサートを実行した場合、
1170
必要なパフォーマンスを得られない場合があるかもしれません。
1171
C<insert()>メソッドは、SQL文とステートメントハンドルを
update pod
Yuki Kimoto authored on 2011-01-26
1172
毎回作成するためです。
1173

            
1174
そのような場合は、C<query>オプションを指定することで、
1175
クエリを取得することができます。
1176

            
1177
    my $query = $dbi->insert(table => 'book', param => $param, query => 1);
1178

            
1179
またC<create_query()>メソッドを使って任意のSQLのクエリを作成
1180
することもできます。
updated document
Yuki Kimoto authored on 2011-01-20
1181

            
1182
    my $query = $dbi->create_query(
update pod
Yuki Kimoto authored on 2011-01-26
1183
        "insert into book {insert_param title author};";
updated document
Yuki Kimoto authored on 2011-01-20
1184
    );
1185

            
1186
戻り値はL<DBIx::Custom::Query>オブジェクトです。
1187
このオブジェクトはSQL文とパラメータバインド時の列名を
1188
保持しています。またステートメントハンドルも保持しています。
1189

            
1190
    {
1191
        sql     => 'insert into book (title, author) values (?, ?);',
1192
        columns => ['title', 'author'],
1193
        sth     => $sth
1194
    }
1195

            
update pod
Yuki Kimoto authored on 2011-01-26
1196
クエリオブジェクトを使って繰り返し実行するにはC<execute()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
1197
    
update pod
Yuki Kimoto authored on 2011-01-26
1198
    my $params = [
updated document
Yuki Kimoto authored on 2011-01-20
1199
        {title => 'Perl',      author => 'Ken'},
1200
        {title => 'Good days', author => 'Mike'}
1201
    ];
1202
    
update pod
Yuki Kimoto authored on 2011-01-26
1203
    foreach my $param (@$paramss) {
1204
        $dbi->execute($query, table => 'book', param => $input);
updated document
Yuki Kimoto authored on 2011-01-20
1205
    }
1206

            
1207
C<execute>メソッドの第一引数にクエリオブジェトを渡すことができます。
update pod
Yuki Kimoto authored on 2011-01-26
1208
C<insert()>メソッドよりも高速です。
updated document
Yuki Kimoto authored on 2011-01-20
1209

            
update pod
Yuki Kimoto authored on 2011-01-26
1210
注意点がいくつかあります。それはパラメータの数は必ず同じでなくてはならない
1211
ということです。最初に3つのパラメータだけを渡したのに、次の実行では
1212
二つのパラメータを渡すと予期しない結果になります。それは
1213
動的に生成されたSQLに含まれるプレースホルダの数が異なるからです。
1214
またC<execute()>によっては自動的にはフィルタが有効にならないので、
1215
C<table>を指定する必要のあることに注意してください。
1216
本当に必要な場合だけ利用してください。
updated document
Yuki Kimoto authored on 2011-01-20
1217

            
update pod
Yuki Kimoto authored on 2011-01-28
1218
=head2 9. その他の機能
updated document
Yuki Kimoto authored on 2011-01-20
1219

            
update pod
Yuki Kimoto authored on 2011-01-26
1220
=head3 メソッドの登録
updated document
Yuki Kimoto authored on 2011-01-20
1221

            
update pod
Yuki Kimoto authored on 2011-01-26
1222
メソッドを登録するにはC<method()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
1223

            
update pod
Yuki Kimoto authored on 2011-01-26
1224
    $dbi->method(
updated document
Yuki Kimoto authored on 2011-01-20
1225
        update_or_insert => sub {
1226
            my $self = shift;
update pod
Yuki Kimoto authored on 2011-01-26
1227
            # something
updated document
Yuki Kimoto authored on 2011-01-20
1228
        },
1229
        find_or_create   => sub {
1230
            my $self = shift;
update pod
Yuki Kimoto authored on 2011-01-26
1231
            # something
updated document
Yuki Kimoto authored on 2011-01-20
1232
        }
1233
    );
1234

            
update pod
Yuki Kimoto authored on 2011-01-26
1235
<method()>で登録したメソッドは
updated document
Yuki Kimoto authored on 2011-01-20
1236
L<DBIx::Custom>オブジェクトから直接呼び出すことができます。
1237

            
1238
    $dbi->update_or_insert;
1239
    $dbi->find_or_create;
1240

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1241
=head3 結果クラスの変更
1242

            
1243
必要ならば結果クラスを変更することができます。
1244

            
1245
    package MyResult;
1246
    use base 'DBIx::Custom::Result';
1247
    
1248
    sub some_method { ... }
updated document
Yuki Kimoto authored on 2011-01-20
1249

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1250
    1;
1251
    
1252
    package main;
1253
    
1254
    use MyResult;
1255
    
1256
    my $dbi = DBIx::Custom->connect(...);
1257
    $dbi->result_class('MyResult');
updated document
Yuki Kimoto authored on 2011-01-20
1258

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1259
=head3 キャッシング
updated document
Yuki Kimoto authored on 2011-01-20
1260

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1261
タグの展開後のSQLはパフォーマンスの理由のためにキャッシュされます。
1262
これはC<chace>で設定でき、デフォルトではキャッシュを行う設定です。
updated document
Yuki Kimoto authored on 2011-01-20
1263

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1264
    $dbi->cache(1);
updated document
Yuki Kimoto authored on 2011-01-20
1265

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1266
キャッシュ方法はC<cache_method>にメソッドを指定することで
1267
変更することができます。
1268
データの保存と取得のためのメソッドを定義します。
updated document
Yuki Kimoto authored on 2011-01-20
1269

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1270
デフォルトでは次のようにメモリ上にキャッシュを行うものになっています。
updated document
Yuki Kimoto authored on 2011-01-20
1271

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1272
    $dbi->cache_method(sub {
1273
        sub {
1274
            my $self = shift;
1275
            
1276
            $self->{_cached} ||= {};
1277
            
1278
            if (@_ > 1) {
1279
                # Set
1280
                $self->{_cached}{$_[0]} = $_[1] 
1281
            }
1282
            else {
1283
                # Get
1284
                return $self->{_cached}{$_[0]}
1285
            }
1286
        }
1287
    });
1288
    
1289
第一はL<DBIx::Custom>オブジェクトです。
1290
第二引数はタグの展開される前のSQLです。
1291
第三引数はタグの展開後のSQLです。
updated document
Yuki Kimoto authored on 2011-01-20
1292

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1293
自分で作成する場合は第三引数が存在した場合はキャッシュを設定し、
1294
存在しなかった場合はキャッシュを取得する実装に
1295
してください。
updated document
Yuki Kimoto authored on 2011-01-20
1296

            
1297
=cut