Newer Older
769 lines | 25.035kb
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

            
updated document
yuki-kimoto authored on 2010-10-22
5
DBIx::Custom::Guides::Ja - DBIx::Customの日本語ガイド
added experimental expand me...
yuki-kimoto authored on 2010-10-20
6

            
7
=head1 ガイド
8

            
9
L<DBIx::Custom>はデータベースへのクエリの発行を簡単に行うための
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

            
26
L<DBIx::Custom>の仕組みを簡単に説明しておきましょう。
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
これらの展開にはどのような意味があるのでしょうかと質問
updated document
Yuki Kimoto authored on 2011-01-20
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

            
updated document
Yuki Kimoto authored on 2011-01-20
43
=item 1. プレースホルダのパラメータをハッシュリファレンスで指定
updated document
Yuki Kimoto authored on 2011-01-20
44

            
updated document
Yuki Kimoto authored on 2011-01-20
45
L<DBI>をそのまま使うのであればプレースホルダのパラメータは配列
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

            
56
=item 2. パラメータのフィルタリング
57

            
58
たとえば、日付の列は、Perlで扱うときにはC<Time::Piece>などの日付オブジェクト
59
で扱い、データベースに格納するときはデータベースの日付型に変換したい
60
と思うのではないでしょうか。またデータベースから取り出すときは
61
データベースの日付型から日付オブジェクトに変換したと思うのでは
62
ないでしょうか。
63

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

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

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

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

            
79
    $dbi->apply_filter('book',
80
        'publish_date' => {out => 'tp_to_date', in => 'date_to_tp'}
81
    );
82

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

            
85
SQLを発行するときにテーブルの指定を行えば、自動的にこのフィルタが適用されます。
86

            
87
    $dbi->execute($sql, $param, table => 'book');
88

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

            
91
生のDBIを利用しているとき一番たいへんなのは選択的な検索条件を作成したいときです。
92

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

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

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

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

            
103
    select * from book where author = ?;
104

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

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

            
110
    my $where = $dbi->where;
111
    $where->param({title => 'Perl'});
112
    $where->clause(
113
        ['and', '{= title}', {'= author'}]
114
    );
115

            
116
    my $sql = "select * from book $where";
117

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

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

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

            
130
    my $param = {title => 'Perl', author => 'Ken'};
131
    $dbi->insert(table => 'book', param => $param);
132

            
133
=item 5. テーブル単位の操作の登録
134

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

            
139
    $dbi->talbe('book',
140
        list => sub {
141
            ...
142
        },
143
        list_somethin => sub {
144
            
145
        }
146
    );
147

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

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

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

            
updated document
Yuki Kimoto authored on 2011-01-20
156
=back
157

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

            
162
=head2 1. データベースへの接続
163

            
164
L<DBIx::Custom>オブジェクトを生成し、データベースに接続するには
165
C<connect()>メソッドを使用します。
166

            
167
    use DBIx::Custom;
168
    my $dbi = DBIx::Custom->connect(data_source => "dbi:mysql:database=dbname",
169
                                    user => 'ken', password => '!LFKD%$&');
170

            
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
171
B<Data sourceのサンプル:>
added experimental expand me...
yuki-kimoto authored on 2010-10-20
172

            
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
173
MySQL
added experimental expand me...
yuki-kimoto authored on 2010-10-20
174

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

            
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
178
SQLite
179

            
180
    "dbi:SQLite:dbname=$database"
181
    "dbi:SQLite:dbname=:memory:"
182

            
183
PostgreSQL
184

            
185
    "dbi:Pg:dbname=$dbname"
186

            
187
Oracle
188

            
189
    "dbi:Oracle:$dbname"
190
    "dbi:Oracle:host=$host;sid=$sid"
191

            
192
ODBC(Microsoft Access)
193

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

            
196
ODBC(SQL Server)
197

            
198
   "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
199

            
200
L<DBIx::Custom>はL<DBI>のラッパです。
201
L<DBI>オブジェクトはC<dbh>で取得することができます。
202

            
203
    my $dbh = $dbi->dbh;
204

            
205
データベースハンドル属性にはデフォルトで次のものが設定されます。
206
    
207
    $dbi->dbh->{RaiseError} = 1;
208
    $dbi->dbh->{PrintError} = 0;
209
    $dbi->dbh->{AutoCommit} = 1;
210

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

            
215
=head2 2. シュガーメソッド
216

            
217
L<DBIx::Custom>は、
218
C<insert()>、C<update()>、C<delete()>、C<select()>
219
のようなシュガーメソッドを持っています。
220
小さなことを行うのであれば、SQL文を
221
作成する必要はありません。
222

            
223
=head3 C<insert()>
224

            
225
C<insert>メソッドです。データベースにデータを挿入します。
226

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

            
230
これは次のL<DBI>の操作と同じです。
231

            
232
    my $sth = $dbh->prepare('insert into (title, author) values (?, ?);');
233
    $sth->execute('Perl', 'Ken');
234

            
235
=head3 C<update()>
236

            
237
C<update>メソッドです。データベースのデータを更新します。
238

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

            
243
これは次のL<DBI>の操作と同じです。
244

            
245
    my $sth = $dbh->prepare(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
246
        'update book set title = ?, author = ? where id = ?;');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
247
    $sth->execute('Perl', 'Ken', 5);
248

            
249
C<update>メソッドは安全のため
250
where句のないSQLを発行することを許可していません。
251
もしすべての行を更新したい場合は
252
C<update_all()>メソッドを使用してください。
253

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

            
257
=head3 C<delete()>
258

            
259
C<delete>メソッドです。データベースのデータを削除します。
260

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

            
264
これは次のL<DBI>の操作と同じです。
265

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
266
    my $sth = $dbh->prepare('delete from book where id = ?;');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
267
    $sth->execute('Ken');
268

            
269
C<delete>メソッドは安全のため
270
where句のないSQLを発行することを許可していません。
271
もしすべての行を削除したい場合は
272
C<delete_all()>メソッドを使用してください。
273

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

            
276
=head3 C<select()>
277

            
278
C<select>メソッドです。テーブル名だけを指定しています。
279

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

            
282
これは次のL<DBI>の操作と同じです。
283

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
284
    my $sth = $dbh->prepare('select * from book;);
added experimental expand me...
yuki-kimoto authored on 2010-10-20
285
    $sth->execute;
286

            
287
C<select()>メソッドの戻り値はL<DBIx::Custom::Result>
288
オブジェクトです。C<fetch>メソッドを使用して
289
行をフェッチすることができます。
290

            
291
    while (my $row = $result->fetch) {
292
        my $title  = $row->[0];
293
        my $author = $row->[1];
294
    }
295

            
296
次のC<select>は行の名前とwhere句を指定したものです。
297

            
298
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
299
        table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
300
        column => [qw/author title/],
301
        where  => {author => 'Ken'}
302
    );
303

            
304
次のL<DBI>の操作と同じです。
305
    
306
    my $sth = $dbh->prepare(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
307
        'select author, title from book where author = ?;');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
308
    $sht->execute('Ken');
309

            
310
テーブルをjoinしたい場合はC<relation>を使用します。
311

            
312
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
313
        table    => ['book', 'rental'],
314
        column   => ['book.name as book_name']
315
        relation => {'book.id' => 'rental.book_id'}
added experimental expand me...
yuki-kimoto authored on 2010-10-20
316
    );
317

            
318
次のL<DBI>の操作と同じです。
319

            
320
    my $sth = $dbh->prepare(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
321
        'select book.name as book_name from book, rental' .
322
        'where book.id = rental.book_id;');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
323
    $sth->execute;
324

            
325
SQL文の末尾に文字列を追加したい場合は<append>オプションを使用します。
326

            
327
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
328
        table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
329
        where  => {author => 'Ken'},
330
        append => 'order by price limit 5',
331
    );
332

            
333
次のL<DBI>の操作と同じです。
334

            
335
    my $sth = $dbh->prepare(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
336
        'select * book where author = ? order by price limit 5;');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
337
    $sth->execute;
338

            
339
C<append>オプションは、C<insert()>、C<update()>、C<update_all()>
340
C<delete()>、C<select>メソッドで使用することが
341
できます。
342

            
343
この後のフィルタリングの解説で詳しく扱いますが、値をフィルタリングしたい
344
場合はC<filter>オプションを使用することができます。
345

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
346
    $dbi->insert(table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
347
                 param  => {title => 'Perl', author => 'Ken'});
348
                 filter => {title  => 'encode_utf8',
updated document
Yuki Kimoto authored on 2011-01-20
349
                            author => 'encode_utf8'});
350

            
351
C<filter>オプションは、C<insert()>、C<update()>、C<update_all()>
352
C<delete()>、C<select>メソッドで使用することが
353
できます。
354

            
355
C<select()>メソッドのC<where>オプションではハッシュの代わりに
356
タグを利用することもできます。これによって柔軟な
357
条件を指定することができます。
358

            
359
    # Select, more flexible where
360
    my $result = $dbi->select(
361
        table  => 'book',
362
        where  => ['{= author} and {like title}', 
363
                   {author => 'Ken', title => '%Perl%'}]
364
    );
365

            
366
タグについては以降で解説します。
367

            
368
=head2 3. 行のフェッチ
369

            
370
C<select()>メソッドの戻り値であるL<DBIx::Custom::Result>
371
には行をフェッチするためのさまざまなメソッドが
372
用意されています。
373
(このセクションの解説では「配列」は「配列のリファレンス」を
374
「ハッシュ」は「ハッシュのリファレンス」を意味しますので
375
注意してください。)
376

            
377
=head3 C<fetch>
378

            
379
一行フェッチして配列に格納します。
380

            
381
    while (my $row = $result->fetch) {
382
        my $author = $row->[0];
383
        my $title  = $row->[1];
384
    }
385

            
386
=head3 C<fetch_first>
387

            
388
一行だけフェッチして配列に格納します。
389

            
390
    my $row = $result->fetch_first;
391

            
392
フェッチが終わった後は、ステートメントハンドルからC<finish()>
393
メソッドが呼び出されてそれ以上フェッチできなくなります。
394

            
395
=head3 C<fetch_multi>
396

            
397
複数行をフェッチして配列の配列に格納します。
398

            
399
    while (my $rows = $result->fetch_multi(5)) {
400
        my $first_author  = $rows->[0][0];
401
        my $first_title   = $rows->[0][1];
402
        my $second_author = $rows->[1][0];
403
        my $second_value  = $rows->[1][1];
404
    }
405

            
406
=head3 C<fetch_all>
407

            
408
すべての行をフェッチして配列の配列に格納します。
409

            
410
    my $rows = $result->fetch_all;
411

            
412
=head3 C<fetch_hash>
413

            
414
一行フェッチしてハッシュに格納します。
415

            
416
    while (my $row = $result->fetch_hash) {
417
        my $title  = $row->{title};
418
        my $author = $row->{author};
419
    }
420

            
421
=head3 C<fetch_hash_first>
422

            
423
一行だけフェッチしてハッシュに格納します。
424

            
425
    my $row = $result->fetch_hash_first;
426

            
427
フェッチが終わった後は、ステートメントハンドルからC<finish()>
428
メソッドが呼び出されてそれ以上フェッチできなくなります。
429

            
430
=head3 C<fetch_hash_multi>
431

            
432
複数行をフェッチしてハッシュの配列に格納します。
433

            
434
    while (my $rows = $result->fetch_hash_multi(5)) {
435
        my $first_title   = $rows->[0]{title};
436
        my $first_author  = $rows->[0]{author};
437
        my $second_title  = $rows->[1]{title};
438
        my $second_author = $rows->[1]{author};
439
    }
440

            
441
=head3 C<fetch_all>
442

            
443
すべての行をフェッチしてハッシュの配列に格納します。
444

            
445
    my $rows = $result->fetch_hash_all;
446

            
447
L<DBI>のステートメントハンドルに直接アクセスしたい場合は
448
<sth>を使用します。
449

            
450
    my $sth = $result->sth;
451

            
452
=head2 4. ハッシュパラメタバインド
453

            
454
L<DBIx::Custom>はハッシュパラメタバインドを提供します。
455

            
456
まず最初にL<DBI>による通常のパラメタバインドをご覧ください。
457

            
458
    use DBI;
459
    my $dbh = DBI->connect(...);
460
    my $sth = $dbh->prepare(
461
        "select * from book where author = ? and title like ?;"
462
    );
463
    $sth->execute('Ken', '%Perl%');
464

            
465
これはデータベースシステムがSQLをキャッシュすることができ、
466
パラメータは自動的にクォートされるので、
467
パフォーマンス面でも、セキュリティ面でも
468
とても良い方法です。
469

            
470

            
471
L<DBIx::Custom>はこれを改善して、ハッシュで
472
パラメタを指定できるようにしました。
473

            
474
    my $result = $dbi->execute(
475
        "select * from book where {= author} and {like title};"
476
        param => {author => 'Ken', title => '%Perl%'}
477
    );
478

            
479
C<{= author}>とC<{like title}>はタグと呼ばれます。
480
タグは内部ではプレースホルダを含む文字列に置き換えられます。
481

            
482
    select * from book where {= author} and {like title}
483

            
484
という文は以下のSQLに置き換えられます。
485

            
486
    select * from book where author = ? and title like ?;
487

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

            
491
    [TAG]                       [REPLACED]
492
    {? NAME}               ->   ?
493
    {= NAME}               ->   NAME = ?
494
    {<> NAME}              ->   NAME <> ?
495
    
496
    {< NAME}               ->   NAME < ?
497
    {> NAME}               ->   NAME > ?
498
    {>= NAME}              ->   NAME >= ?
499
    {<= NAME}              ->   NAME <= ?
500
    
501
    {like NAME}            ->   NAME like ?
502
    {in NAME COUNT}        ->   NAME in [?, ?, ..]
503
    
504
    {insert_param NAME1 NAME2}   ->   (NAME1, NAME2) values (?, ?)
505
    {update_param NAME1 NAME2}   ->   set NAME1 = ?, NAME2 = ?
506

            
507
これらの変換はL<DBIx::Custom::QueryBuilder>によって行われます。
508

            
509
C<{>とC<}>は予約語です。これらの文字を使いたい場合は
510
「\」を使ってエスケープする必要があります。
511
'\'はPerlのエスケープ文字なので、
512
エスケープするためには'\\'と書く必要があることに注意
513
してください。
514

            
515
    'select * from book \\{ something statement \\}'
516

            
517
=head2 5. フィルタリング
518

            
519
=head3 パラメタバインド時のフィルタリング
520

            
521
データベースに登録するデータをフィルタリングしたい場合
522
があります。たとえば、内部文字列で文字列を保持している場合は
523
データベースにデータを登録する前に、バイト文字列に変換する
524
必要があります。L<DBIx::Custom>のフィルタリングシステムは
525
あるデータを他のデータに変換するのを手助けしてくれます。
526

            
527
フィルタリングを利用するにはまず、
528
C<register_filter()>メソッドを使用して
529
フィルタを登録しておく必要があります。
530

            
531
    $dbi->register_filter(
532
        to_upper_case => sub {
533
            my $value = shift;
534
            return uc $value;
535
        }
536
    );
537

            
538
デフォルトのフィルタとしてC<encode_utf8>とC<decode_utf8>
539
が登録されています。
540

            
541
登録されているフィルタはC<execute()>メソッドのC<filter>オプション
542
で指定することができます。
543

            
544
    my $result = $dbi->execute(
545
        "select * from book where {= author} and {like title};"
546
        param  => {author => 'Ken', title => '%Perl%'},
547
        filter => {author => 'to_upper_case, title => 'encode_utf8'}
548
    );
549

            
550
この例ではC<author>の値はバインドされるときに大文字に変換され、
551
C<title>の値はバイト文字列に変換されます。
552

            
553
C<filter>オプションは
554
C<insert()>、C<update()>、 C<update_all()>,
555
C<delete()>、C<select()>
556
メソッドにおいても使用することができます。
557

            
558
    # insert() with filter option
559
    $dbi->insert(table  => 'book',
560
                 param  => {title => 'Perl', author => 'Ken'},
561
                 filter => {title => 'encode_utf8'});
562
    
563
    # select() with filter option
564
    my $result = $dbi->select(
565
        table  => 'book',
566
        column => [qw/author title/],
567
        where  => {author => 'Ken'},
568
        append => 'order by id limit 1',
569
        filter => {title => 'encode_utf8'}
570
    );
571

            
572
B<フィルタのサンプル>
573

            
574
MySQL
575

            
576
    # Time::Piece object to DATETIME format
577
    tp_to_datetime => sub {
578
        return shift->strftime('%Y-%m-%d %H:%M:%S');
579
    }
580
    
581
    # Time::Piece object to DATE format
582
    tp_to_date => sub {
583
        return shift->strftime('%Y-%m-%d');
584
    }
585
    
586
    # DATETIME to Time::Piece object
587
    datetime_to_tp => sub {
588
        return Time::Piece->strptime(shift, '%Y-%m-%d %H:%M:%S');
589
    }
590
    
591
    # DATE to Time::Piece object
592
    date_to_tp => sub {
593
        return Time::Piece->strptime(shift, '%Y-%m-%d');
594
    }
595

            
596
SQLite
597
    
598
    # Time::Piece object to DATETIME format
599
    tp_to_datetime => sub {
600
        return shift->strftime('%Y-%m-%d %H:%M:%S');
601
    }
602
    
603
    # Time::Piece object to DATE format
604
    tp_to_date => sub {
605
        return shift->strftime('%Y-%m-%d');
606
    }
607
    
608
    # DATETIME to Time::Piece object
609
    datetime_to_tp => sub {
610
        return Time::Piece->strptime(shift, '%Y-%m-%d %H:%M:%S');
611
    }
612
    
613
    # DATE to Time::Piece object
614
    date_to_tp => sub {
615
        return Time::Piece->strptime(shift, '%Y-%m-%d');
616
    }
617

            
618
=head3 行のフェッチ時のフィルタリング
619

            
620
行をフェッチするときのフィルタも設定することができます。
621
これはL<DBIx::Custom::Result>クラスのC<filter>メソッドを使って
622
行います。
623

            
624
    my $result = $dbi->select(table => 'book');
625
    $result->filter({title => 'decode_utf8', author => 'to_upper_case'});
626

            
627
フェッチのためのフィルタにおいて、
628
たとえ、列名が大文字を含む場合であっても
629
列名は小文字であることに注意してください。
630
これはデータベースシステムに依存させないための要件です。
631

            
632
=head2 6. パフォーマンスの改善
633

            
634
=head3 シュガーメソッドを使わない
635

            
636
もしC<insert()>メソッドを使用してインサートを実行した場合、
637
必要なパフォーマンスを得られない場合があるかもしれません。
638
C<insert()>メソッドは、SQL文とステートメントハンドルを
639
毎回作成するためすこし遅いです。
640

            
641
そのような場合は、C<create_query()>メソッドによって
642
クエリを用意しておくことができます。
643
    
644
    my $query = $dbi->create_query(
645
        "insert into book {insert_param title author};"
646
    );
647

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

            
652
    {
653
        sql     => 'insert into book (title, author) values (?, ?);',
654
        columns => ['title', 'author'],
655
        sth     => $sth
656
    }
657

            
658
クエリオブジェクトを使って繰り返し実行するには次のようにします。
659
    
660
    my $inputs = [
661
        {title => 'Perl',      author => 'Ken'},
662
        {title => 'Good days', author => 'Mike'}
663
    ];
664
    
665
    foreach my $input (@$inputs) {
666
        $dbi->execute($query, $input);
667
    }
668

            
669
C<execute>メソッドの第一引数にクエリオブジェトを渡すことができます。
670
これはC<insert()>メソッドよりも高速です。
671

            
672
=head2 7. その他の機能
673

            
674
=head3 トランザクション
675

            
676
トランザクションを便利に利用するために、
677
C<begin_work()>、C<commit()>、C<rollback()>
678
という三つのメソッドが容易されています。
679
これはL<DBI>の同名のメソッドと同じ機能を持ちます。
680

            
681
    $dbi->begin_work;
682
    
683
    eval {
684
        $dbi->update(...);
685
        $dbi->update(...);
686
    };
687
    
688
    if ($@) {
689
        $dbi->rollback;
690
    }
691
    else {
692
        $dbi->commit;
693
    }
694

            
695
=head3 selectメソッドの結果クラスの変更
696

            
697
必要ならばC<select()>メソッドの結果クラスを変更することができます。
698

            
699
    package Your::Result;
700
    use base 'DBIx::Custom::Result';
701
    
702
    sub some_method { ... }
703

            
704
    1;
705
    
706
    package main;
707
    
708
    use Your::Result;
709
    
710
    my $dbi = DBIx::Custom->connect(...);
711
    $dbi->result_class('Your::Result');
712

            
713
=head3 L<DBIx::Custom::QueryBuilder>の機能の拡張
714

            
715
新しいタグが欲しい場合はL<DBIx::Custom::QueryBuilder>の機能を拡張
716
することができます。
717

            
718
    my $dbi = DBIx::Custom->connect(...);
719
    $dbi->query_builder->register_tag_processor(
720
        name => sub {
721
           ...
722
        }
723
    );
724

            
725
=head3 ヘルパーメソッドの登録
726

            
727
ヘルパーメソッドを登録することができます。
728

            
729
    $dbi->helper(
730
        update_or_insert => sub {
731
            my $self = shift;
732
            # do something
733
        },
734
        find_or_create   => sub {
735
            my $self = shift;
736
            # do something
737
        }
738
    );
739

            
740
<helper()>メソッドで登録したメソッドは
741
L<DBIx::Custom>オブジェクトから直接呼び出すことができます。
742

            
743
    $dbi->update_or_insert;
744
    $dbi->find_or_create;
745

            
746
=head3 ユーティリティメソッド(実験的)
747

            
748
C<expand>メソッドを使用すると次のようなハッシュに含まれる
749
テーブル名と列名を結合することができます。
750

            
751
    my %expanded = $dbi->expand(\%source);
752

            
753
以下のハッシュ
754

            
755
    {book => {title => 'Perl', author => 'Ken'}}
756

            
757
は次のように展開されます。
758

            
759
    ('book.title' => 'Perl', 'book.author' => 'Ken')
760

            
761
これはテーブル名を含むselect文で利用すると便利です。
762

            
763
    my $param = {title => 'Perl', author => '%Ken%'};
764
    $dbi->execute(
765
        'select * from book where {= book.title} && {like book.author};',
766
        param => {$dbi->expand({book => $param})}
767
    );
768

            
769
=cut