Newer Older
1171 lines | 40.877kb
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

            
pod fix
Yuki Kimoto authored on 2011-01-21
5
DBIx::Custom::Guide::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',
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
80
        'issue_date' => {out => 'tp_to_date', in => 'date_to_tp'}
updated document
Yuki Kimoto authored on 2011-01-20
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

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

            
166
    use DBIx::Custom;
167

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

            
updated document
Yuki Kimoto authored on 2011-01-23
171
    my $dbi = DBIx::Custom->connect(
172
        data_source => "dbi:mysql:database=dbname",
173
        user => 'ken',
174
        password => '!LFKD%$&',
175
        dbi_options => {mysql_enable_utf8 => 1}
176
    );
added experimental expand me...
yuki-kimoto authored on 2010-10-20
177

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

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

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

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

            
189
    "dbi:SQLite:dbname=$database"
190
    "dbi:SQLite:dbname=:memory:"
191

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

            
194
    "dbi:Pg:dbname=$dbname"
195

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

            
198
    "dbi:Oracle:$dbname"
199
    "dbi:Oracle:host=$host;sid=$sid"
200

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

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

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

            
207
   "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
208

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

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

            
215
    my $dbh = $dbi->dbh;
216

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
updated document
Yuki Kimoto authored on 2011-01-23
272
データベースのデータを1件削除するには、C<delete()>を使用します。
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->delete(table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
275
                 where  => {author => 'Ken'});
276

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

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

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

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

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

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

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

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

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

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

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

            
303
    while (my $row = $result->fetch) {
304
        my $title  = $row->[0];
305
        my $author = $row->[1];
306
    }
307

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
357
    $dbi->execute("select * from book;");
358

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

            
361
    $dbi->execute(
362
        "select * from book {= title} and {= author};"
363
        param => {title => 'Perl', author => 'Ken'}
364
    );
365

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

            
368
    select * from book title = ? and author = ?;
369

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

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

            
378
    $dbi->execute("... \\{ ... \\} ...");
379

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

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

            
385
    $dbi->execute('select * from book');
386

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

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

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

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

            
397
    while (my $row = $result->fetch) {
updated document
Yuki Kimoto authored on 2011-01-23
398
        my $title  = $row->[0];
399
        my $author = $row->[1];
updated document
Yuki Kimoto authored on 2011-01-20
400
    }
401

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

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

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

            
409
    my $row = $result->fetch_first;
410

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

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

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

            
updated document
Yuki Kimoto authored on 2011-01-23
420
    while (my $rows = $result->fetch_multi(2)) {
421
        my $title0   = $rows->[0][0];
422
        my $author0  = $rows->[0][1];
423
        
424
        my $title1   = $rows->[1][0];
425
        my $author1  = $rows->[1][1];
updated document
Yuki Kimoto authored on 2011-01-20
426
    }
427

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

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

            
432
    [
433
        ['Perl', 'Ken'],
434
        ['Ruby', 'Mark']
435
    ]
436

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

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

            
442
    my $rows = $result->fetch_all;
443

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

            
446
    [
447
        ['Perl', 'Ken'],
448
        ['Ruby', 'Mark']
449
    ]
450

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

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

            
455
    while (my $row = $result->fetch_hash) {
456
        my $title  = $row->{title};
457
        my $author = $row->{author};
458
    }
459

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

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

            
465
    my $row = $result->fetch_hash_first;
466

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

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

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

            
477
    while (my $rows = $result->fetch_hash_multi(5)) {
updated document
Yuki Kimoto authored on 2011-01-23
478
        my $title0   = $rows->[0]{title};
479
        my $author0  = $rows->[0]{author};
480
        my $title1  = $rows->[1]{title};
481
        my $author1 = $rows->[1]{author};
updated document
Yuki Kimoto authored on 2011-01-20
482
    }
483

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

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

            
488
    [
489
        {title => 'Perl', author => 'Ken'},
490
        {title => 'Ruby', author => 'Mark'}
491
    ]
492

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

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

            
499
    my $rows = $result->fetch_hash_all;
500

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

            
503
    [
504
        {title => 'Perl', author => 'Ken'},
505
        {title => 'Ruby', author => 'Mark'}
506
    ]
507

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

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

            
513
    my $sth = $result->sth;
514

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

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

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

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

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

            
532
    $dbi->register_filter(
533
        # Time::Piece object to DATE format
534
        tp_to_date => sub {
535
            my $date = shift;
536

            
537
            return '0000-00-00' unless $tp;
538
            return $tp->strftime('%Y-%m-%d');
539
        },
540
        
541
        # DATE to Time::Piece object
542
        date_to_tp => sub {
543
            my $date = shift;
544

            
545
            return if $date eq '0000-00-00';
546
            return Time::Piece->strptime($date, '%Y-%m-%d');
547
        },
548
    );
549

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

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

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

            
556
    $dbi->apply_filter('book',
557
        issue_date => {out => 'tp_to_date', in => 'date_to_tp'},
558
        first_issue_date => {out => 'tp_to_date', in => 'date_to_tp'}
559
    );
560

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

            
568
    issue_date => {out => sub { ... }, in => sub { ... }}
569

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

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

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

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

            
582
    my $row = $resutl->fetch_hash_first;
583
    my $tp = $row->{issue_date};
584

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

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

            
590
    $dbi->select(
591
        table => 'book',
592
        where => {'book.title' => 'Perl', 'book.author' => 'Ken'}
593
    );
594

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

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

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

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

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

            
612
    $dbi->insert(
613
        table => 'book',
614
        param => {issue_date => $tp, first_issue_date => $tp},
615
        filter => {issue_date => 'tp_to_date', first_issue_date => 'tp_to_date'}
616
    );
617

            
618
C<execute()>の例を示します。
619

            
620
my $sql = <<"EOS";
621
select YEAR(issue_date) as issue_year
622
from book
623
where YEAR(issue_date) = {? issue_year}
624
EOS
625
   
626
    my $result = $dbi->execute(
627
        $sql,
628
        param => {issue_year => '2010'},
629
        filter => {issue_year => 'tp_to_year'}
630
    );
631

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

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

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

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

            
646
    $dbi->apply_filter('book',
647
        'issue_year' => {out => 'tp_to_year', in => 'year_to_tp'}
648
    );
649

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

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

            
657
    $result->end_filter(issue_date => sub {
658
        my $tp = shift;
659
        
660
        return '' unless $tp;
661
        return $tp->strftime('%Y/%m/%d %h:%m:%s (%a)');
662
    });
663

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

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

            
669
    $result->filter(...);
670
    $result->end_filter(...);
671
    my $row = $result->fetch_hash_first;
672

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
741
    $dbi->execute($sql, param => {title => 'Perl', author => '%Ken%'}
742
                  filter => {title => 'to_something');
743

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

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

            
752
=head2 タグ一覧
753

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

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

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

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

            
763
    {? NAME}    ->   ?
764

            
765
=head3 C<=>
766

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

            
769
    {= NAME}    ->   NAME = ?
770

            
771
=head3 C<E<lt>E<gt>>
772

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

            
775
    {<> NAME}   ->   NAME <> ?
776

            
777
=head3 C<E<lt>>
778

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

            
781
    {< NAME}    ->   NAME < ?
782

            
783
=head3 C<E<gt>>
784

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

            
787
    {> NAME}    ->   NAME > ?
788

            
789
=head3 C<E<gt>=>
790

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

            
793
    {>= NAME}   ->   NAME >= ?
794

            
795
=head3 C<E<lt>=>
796

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

            
799
    {<= NAME}   ->   NAME <= ?
800

            
801
=head3 C<like>
802

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

            
805
    {like NAME}   ->   NAME like ?
806

            
807
=head3 C<in>
808

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

            
812
    {in NAME COUNT}   ->   NAME in [?, ?, ..]
813

            
814
=head3 C<insert_param>
815

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

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

            
820
=head3 C<update_param>
821

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

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

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

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

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

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

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

            
838
=head2 タグの追加 C<register_tag()>
839

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

            
843
    $dbi->register_tag(
update pod
Yuki Kimoto authored on 2011-01-26
844
        '=' => sub {
845
            my $column = shift;
846
            
847
            return ["$column = ?", [$column]];
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
848
        }
849
    );
850

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

            
854
    {タグ名 引数1 引数2}
855

            
856
C<=>タグの場合は
857

            
858
    {= title}
859

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

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

            
864
    [
865
        展開後の文字列,
866
        [プレースホルダに埋め込みに利用する列名1, 列名2, ...]
867
    ]
868

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

            
871
    'title = ?'
872

            
873
を返す必要があります。
874

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

            
878
    ['title']
879

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

            
884
上記を合わせると
885

            
886
    ['title = ?', ['title']]
887
    
888
を返す必要があるということです。
889

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

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

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

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

            
901
titleの値だけで検索したい場合
902

            
903
    where {= title}
904

            
905
authorの値だけで検索したい場合
906

            
907
    where {= author}
908

            
909
titleとauthorの両方の値で検索したい場合
910

            
911
    where {= title} and {=author}
912

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

            
916
    my $where = $dbi->where;
917

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

            
920
    $where->clause(
921
        ['and', '{= title'}, '{= author}']
922
    );
923

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

            
926
    ['or' あるいは 'and', タグ1, タグ2, タグ3]
927

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

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

            
934
    ['and', 
935
      '{= title}', 
936
      ['or', '{= author}', '{like date}']
937
    ]
938

            
939
このようにC<clause>を設定した後にC<param>にパラメータを指定します。
940
    
941
    my $param => {title => 'Perl'};
942
    $where->param($param);
943

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

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

            
949
    my $where_clause = $where->to_string;
950

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

            
953
    where {= title}
954

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

            
959
    my $where_clause = "$where";
960

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

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

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

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

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

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
973
また開始日付と終了日付の片方だけや、どちらも受け取らない場合もあるかもしれません。
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
この場合は次のようなパラメータに変換することで対応することができます。
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
976

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

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
979
値が配列のリファレンスになっていることに注目してください。このようにすれば
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
    $where->clause(
983
        ['and', '{> date}', '{< date}']
984
    );
985
    $where->param($p);
986

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

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

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

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

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

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

            
1000
    my $p = {date => []};
1001

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

            
1004
    my @date;
1005
    push @date, exists $param->{start_date} ? $param->{start_date}
1006
                                            : $dbi->not_exists;
1007
    push @date, $param->{end_date} if exists $param->{end_date};
1008
    my $p = {date => \@date};
1009

            
1010
=head3 C<select()>との連携
1011

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

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

            
1023
=head3 C<execute()>との連携
1024

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

            
1027

            
1028
    my $where = $dbi->where;
1029
    $where->clause(...);
1030
    $where->param($param);
1031

            
1032
    my $sql = <<"EOS"
1033
    select * from book;
1034
    $where
1035
    EOS
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
1036

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

            
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
1039
=head2 7. パフォーマンスの改善
updated document
Yuki Kimoto authored on 2011-01-20
1040

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

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

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

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

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

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

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

            
1064
    {
1065
        sql     => 'insert into book (title, author) values (?, ?);',
1066
        columns => ['title', 'author'],
1067
        sth     => $sth
1068
    }
1069

            
update pod
Yuki Kimoto authored on 2011-01-26
1070
クエリオブジェクトを使って繰り返し実行するにはC<execute()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
1071
    
update pod
Yuki Kimoto authored on 2011-01-26
1072
    my $params = [
updated document
Yuki Kimoto authored on 2011-01-20
1073
        {title => 'Perl',      author => 'Ken'},
1074
        {title => 'Good days', author => 'Mike'}
1075
    ];
1076
    
update pod
Yuki Kimoto authored on 2011-01-26
1077
    foreach my $param (@$paramss) {
1078
        $dbi->execute($query, table => 'book', param => $input);
updated document
Yuki Kimoto authored on 2011-01-20
1079
    }
1080

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

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

            
update pod
Yuki Kimoto authored on 2011-01-26
1092
=head2 8. その他の機能
updated document
Yuki Kimoto authored on 2011-01-20
1093

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

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

            
update pod
Yuki Kimoto authored on 2011-01-26
1098
    $dbi->method(
updated document
Yuki Kimoto authored on 2011-01-20
1099
        update_or_insert => sub {
1100
            my $self = shift;
update pod
Yuki Kimoto authored on 2011-01-26
1101
            # something
updated document
Yuki Kimoto authored on 2011-01-20
1102
        },
1103
        find_or_create   => sub {
1104
            my $self = shift;
update pod
Yuki Kimoto authored on 2011-01-26
1105
            # something
updated document
Yuki Kimoto authored on 2011-01-20
1106
        }
1107
    );
1108

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

            
1112
    $dbi->update_or_insert;
1113
    $dbi->find_or_create;
1114

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

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

            
1119
    package MyResult;
1120
    use base 'DBIx::Custom::Result';
1121
    
1122
    sub some_method { ... }
updated document
Yuki Kimoto authored on 2011-01-20
1123

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1124
    1;
1125
    
1126
    package main;
1127
    
1128
    use MyResult;
1129
    
1130
    my $dbi = DBIx::Custom->connect(...);
1131
    $dbi->result_class('MyResult');
updated document
Yuki Kimoto authored on 2011-01-20
1132

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

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

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

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

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

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1146
    $dbi->cache_method(sub {
1147
        sub {
1148
            my $self = shift;
1149
            
1150
            $self->{_cached} ||= {};
1151
            
1152
            if (@_ > 1) {
1153
                # Set
1154
                $self->{_cached}{$_[0]} = $_[1] 
1155
            }
1156
            else {
1157
                # Get
1158
                return $self->{_cached}{$_[0]}
1159
            }
1160
        }
1161
    });
1162
    
1163
第一はL<DBIx::Custom>オブジェクトです。
1164
第二引数はタグの展開される前のSQLです。
1165
第三引数はタグの展開後のSQLです。
updated document
Yuki Kimoto authored on 2011-01-20
1166

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

            
1171
=cut