Newer Older
1279 lines | 42.989kb
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を生成することができないので、
update pod
Yuki Kimoto authored on 2011-01-31
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
    
update pod
Yuki Kimoto authored on 2011-01-31
102
authorだけの場合は次のSQLを実行した場合を考えましょう。
updated document
Yuki Kimoto authored on 2011-01-20
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

            
update pod
Yuki Kimoto authored on 2011-01-30
131
L<DBIx::Custom>では挿入、更新、削除、選択を行うための
132
メソッドを提供しています。
133
C<insert()>, C<update()>, C<delete()>,C<select()>などがあります。
updated document
Yuki Kimoto authored on 2011-01-20
134

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

            
update pod
Yuki Kimoto authored on 2011-01-30
138
=item 5. テーブルのためのメソッドの登録
updated document
Yuki Kimoto authored on 2011-01-20
139

            
update pod
Yuki Kimoto authored on 2011-01-30
140
テーブルのためにメソッドを登録することができます。
updated document
Yuki Kimoto authored on 2011-01-20
141

            
update pod
Yuki Kimoto authored on 2011-01-30
142
    $dbi->table('book')->method(
updated document
Yuki Kimoto authored on 2011-01-20
143
        list => sub {
144
            ...
145
        },
update pod
Yuki Kimoto authored on 2011-01-30
146
        something => sub {
147
            ...
updated document
Yuki Kimoto authored on 2011-01-20
148
        }
149
    );
150

            
update pod
Yuki Kimoto authored on 2011-01-30
151
メソッドの利用です。
updated document
Yuki Kimoto authored on 2011-01-20
152

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

            
update pod
Yuki Kimoto authored on 2011-01-30
155
多くのO/Rマッパではテーブルのためのクラスを作成する必要がありますが、
156
L<DBIx::Custom>では簡単です。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
157

            
updated document
Yuki Kimoto authored on 2011-01-20
158
=back
159

            
update pod
Yuki Kimoto authored on 2011-01-30
160
L<DBIx::Custom>はとても便利です。
161
興味をもたれた方は、続きをご覧になってみてください。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
162

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

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

            
167
    use DBIx::Custom;
168

            
update pod
Yuki Kimoto authored on 2011-01-30
169
データベースに接続するにはC<connect()>メソッドを使用します。
170
戻り値はL<DBIx::Custom>オブジェクトです。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
171

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

            
update pod
Yuki Kimoto authored on 2011-01-30
179
C<data_source>はデータベースシステムに応じたものである必要があります。
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

            
update pod
Yuki Kimoto authored on 2011-01-30
209
認証が必要な場合は、C<user>とC<password>を指定できます。
updated document
Yuki Kimoto authored on 2011-01-23
210

            
update pod
Yuki Kimoto authored on 2011-01-30
211
L<DBIx::Custom>はL<DBI>のラッパークラスです。
212
L<DBI>のデータベースハンドルは取得するにあhC<dbh()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
213

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

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

            
update pod
Yuki Kimoto authored on 2011-01-30
222
致命的なエラーが起こるとプログラムは終了します。
223
SQLが実行されると自動的にコミットされます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
224

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

            
update pod
Yuki Kimoto authored on 2011-01-31
227
下記のメソッドがあります。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
228

            
update pod
Yuki Kimoto authored on 2011-01-31
229
=head3 行の挿入 C<insert()>
added experimental expand me...
yuki-kimoto authored on 2010-10-20
230

            
update pod
Yuki Kimoto authored on 2011-01-31
231
データベースに行を挿入するにはC<insert()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
232

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

            
update pod
Yuki Kimoto authored on 2011-01-31
236
C<table>はテーブル名、C<param>は挿入する行のデータです。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
237

            
update pod
Yuki Kimoto authored on 2011-01-31
238
次のSQLが実行されます。
updated document
Yuki Kimoto authored on 2011-01-23
239

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

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

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
250
C<table>はテーブル名、C<param>は更新データ、C<where>は
251
条件です。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
252

            
update pod
Yuki Kimoto authored on 2011-01-31
253
次のSQLが実行されます。
updated document
Yuki Kimoto authored on 2011-01-23
254

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

            
update pod
Yuki Kimoto authored on 2011-01-31
257
安全のためC<where>のないupdate()を実効することはできません。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
258
もしすべての行を更新したい場合は
updated document
Yuki Kimoto authored on 2011-01-23
259
C<update_all()>を使用してください。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
260

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

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

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
271
C<table>はテーブル名、C<where>は条件です。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
272

            
update pod
Yuki Kimoto authored on 2011-01-31
273
次のSQLが実行されます。
updated document
Yuki Kimoto authored on 2011-01-23
274

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

            
update pod
Yuki Kimoto authored on 2011-01-31
277
安全のためC<where>のないC<delete()>を実効することはできません。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
278
もしすべての行を削除したい場合は
updated document
Yuki Kimoto authored on 2011-01-23
279
C<delete_all()>を使用してください。
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_all(table  => 'book');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
282

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

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
289
次のSQLが実行されます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
290

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

            
update pod
Yuki Kimoto authored on 2011-01-31
293
戻り値はL<DBIx::Custom::Result>
updated document
Yuki Kimoto authored on 2011-01-23
294
オブジェクトです。行をフェッチするにはC<fetch()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
295

            
296
    while (my $row = $result->fetch) {
297
        my $title  = $row->[0];
298
        my $author = $row->[1];
299
    }
300

            
update pod
Yuki Kimoto authored on 2011-01-31
301
L<DBIx::Custom::Result>についてはL<3. 行のフェッチ/"3. 行のフェッチ">を見てください。
updated document
Yuki Kimoto authored on 2011-01-23
302

            
update pod
Yuki Kimoto authored on 2011-01-31
303
サンプルを続けます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
304

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

            
update pod
Yuki Kimoto authored on 2011-01-31
311
C<column>は列名、C<where>は条件です。
312

            
313
次のSQLが実行されます。
updated document
Yuki Kimoto authored on 2011-01-23
314

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

            
update pod
Yuki Kimoto authored on 2011-01-31
317
次のサンプルです。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
318

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

            
update pod
Yuki Kimoto authored on 2011-01-31
325
C<relation>テーブル間の関係です。これは内部結合です。
326

            
327
次のSQLが実行されます。
328

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
334
次のサンプルです。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
335

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

            
update pod
Yuki Kimoto authored on 2011-01-31
342
C<append>はSQLの末尾に追加される文字列です。
343

            
344
次のSQLが実行されます。
updated document
Yuki Kimoto authored on 2011-01-20
345

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

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
353
SQLを実行するにはC<execute()>を使用します。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
354

            
355
    $dbi->execute("select * from book;");
356

            
update pod
Yuki Kimoto authored on 2011-01-31
357
タグを処理してSQLを実行します。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
358

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

            
update pod
Yuki Kimoto authored on 2011-01-31
364
次のSQLが実行されます。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
365

            
366
    select * from book title = ? and author = ?;
367

            
update pod
Yuki Kimoto authored on 2011-01-31
368
プレースホルダにtitleとauthorの値が埋め込まれます。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
369

            
update pod
Yuki Kimoto authored on 2011-01-31
370
タグについてはL<5. タグ/"5. タグ">を見てください。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
371

            
update pod
Yuki Kimoto authored on 2011-01-31
372
またC<execute()>のSQLの末尾にはセミコロンを置く必要はありません。
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
373

            
374
    $dbi->execute('select * from book');
375

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

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

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

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

            
386
    while (my $row = $result->fetch) {
updated document
Yuki Kimoto authored on 2011-01-23
387
        my $title  = $row->[0];
388
        my $author = $row->[1];
updated document
Yuki Kimoto authored on 2011-01-20
389
    }
390

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

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

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

            
398
    my $row = $result->fetch_first;
399

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

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

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

            
updated document
Yuki Kimoto authored on 2011-01-23
409
    while (my $rows = $result->fetch_multi(2)) {
410
        my $title0   = $rows->[0][0];
411
        my $author0  = $rows->[0][1];
412
        
413
        my $title1   = $rows->[1][0];
414
        my $author1  = $rows->[1][1];
updated document
Yuki Kimoto authored on 2011-01-20
415
    }
416

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

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

            
421
    [
422
        ['Perl', 'Ken'],
423
        ['Ruby', 'Mark']
424
    ]
425

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

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

            
431
    my $rows = $result->fetch_all;
432

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

            
435
    [
436
        ['Perl', 'Ken'],
437
        ['Ruby', 'Mark']
438
    ]
439

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

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

            
444
    while (my $row = $result->fetch_hash) {
445
        my $title  = $row->{title};
446
        my $author = $row->{author};
447
    }
448

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

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

            
454
    my $row = $result->fetch_hash_first;
455

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

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

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

            
466
    while (my $rows = $result->fetch_hash_multi(5)) {
updated document
Yuki Kimoto authored on 2011-01-23
467
        my $title0   = $rows->[0]{title};
468
        my $author0  = $rows->[0]{author};
469
        my $title1  = $rows->[1]{title};
470
        my $author1 = $rows->[1]{author};
updated document
Yuki Kimoto authored on 2011-01-20
471
    }
472

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

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

            
477
    [
478
        {title => 'Perl', author => 'Ken'},
479
        {title => 'Ruby', author => 'Mark'}
480
    ]
481

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

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

            
488
    my $rows = $result->fetch_hash_all;
489

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

            
492
    [
493
        {title => 'Perl', author => 'Ken'},
494
        {title => 'Ruby', author => 'Mark'}
495
    ]
496

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

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

            
502
    my $sth = $result->sth;
503

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

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

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

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

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

            
521
    $dbi->register_filter(
522
        # Time::Piece object to DATE format
523
        tp_to_date => sub {
524
            my $date = shift;
525

            
526
            return '0000-00-00' unless $tp;
527
            return $tp->strftime('%Y-%m-%d');
528
        },
529
        
530
        # DATE to Time::Piece object
531
        date_to_tp => sub {
532
            my $date = shift;
533

            
534
            return if $date eq '0000-00-00';
535
            return Time::Piece->strptime($date, '%Y-%m-%d');
536
        },
537
    );
538

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

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

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

            
545
    $dbi->apply_filter('book',
546
        issue_date => {out => 'tp_to_date', in => 'date_to_tp'},
547
        first_issue_date => {out => 'tp_to_date', in => 'date_to_tp'}
548
    );
549

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

            
557
    issue_date => {out => sub { ... }, in => sub { ... }}
558

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

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

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

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

            
571
    my $row = $resutl->fetch_hash_first;
572
    my $tp = $row->{issue_date};
573

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

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

            
579
    $dbi->select(
580
        table => 'book',
581
        where => {'book.title' => 'Perl', 'book.author' => 'Ken'}
582
    );
583

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

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

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

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

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

            
601
    $dbi->insert(
602
        table => 'book',
603
        param => {issue_date => $tp, first_issue_date => $tp},
604
        filter => {issue_date => 'tp_to_date', first_issue_date => 'tp_to_date'}
605
    );
606

            
607
C<execute()>の例を示します。
608

            
609
my $sql = <<"EOS";
610
select YEAR(issue_date) as issue_year
611
from book
612
where YEAR(issue_date) = {? issue_year}
613
EOS
614
   
615
    my $result = $dbi->execute(
616
        $sql,
617
        param => {issue_year => '2010'},
618
        filter => {issue_year => 'tp_to_year'}
619
    );
620

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

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

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

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

            
635
    $dbi->apply_filter('book',
636
        'issue_year' => {out => 'tp_to_year', in => 'year_to_tp'}
637
    );
638

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

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

            
646
    $result->end_filter(issue_date => sub {
647
        my $tp = shift;
648
        
649
        return '' unless $tp;
650
        return $tp->strftime('%Y/%m/%d %h:%m:%s (%a)');
651
    });
652

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

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

            
658
    $result->filter(...);
659
    $result->end_filter(...);
660
    my $row = $result->fetch_hash_first;
661

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

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

            
668
    $dbi->each_column(
669
        sub {
670
            my ($self, $table, $column, $info) = @_;
671
            
672
            my $type = $info->{TYPE_NAME};
673
            
674
            my $filter = $type eq 'DATE'     ? {out => 'tp_to_date', in => 'date_to_tp'}
675
                       : $type eq 'DATETIME' ? {out => 'tp_to_datetime', in => 'datetime_to_tp'}
676
                                             : undef;
677
            
678
            $self->apply_filter($table, $column, $filter)
679
              if $filter;
680
        }
681
    );
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
682

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
730
    $dbi->execute($sql, param => {title => 'Perl', author => '%Ken%'}
731
                  filter => {title => 'to_something');
732

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
741
=head3 タグ一覧
update pod
Yuki Kimoto authored on 2011-01-26
742

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
748
=head4 C<?>
update pod
Yuki Kimoto authored on 2011-01-26
749

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

            
752
    {? NAME}    ->   ?
753

            
update pod
Yuki Kimoto authored on 2011-01-31
754
=head4 C<=>
update pod
Yuki Kimoto authored on 2011-01-26
755

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

            
758
    {= NAME}    ->   NAME = ?
759

            
update pod
Yuki Kimoto authored on 2011-01-31
760
=head4 C<E<lt>E<gt>>
update pod
Yuki Kimoto authored on 2011-01-26
761

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

            
764
    {<> NAME}   ->   NAME <> ?
765

            
update pod
Yuki Kimoto authored on 2011-01-31
766
=head4 C<E<lt>>
update pod
Yuki Kimoto authored on 2011-01-26
767

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

            
770
    {< NAME}    ->   NAME < ?
771

            
update pod
Yuki Kimoto authored on 2011-01-31
772
=head4 C<E<gt>>
update pod
Yuki Kimoto authored on 2011-01-26
773

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

            
776
    {> NAME}    ->   NAME > ?
777

            
update pod
Yuki Kimoto authored on 2011-01-31
778
=head4 C<E<gt>=>
update pod
Yuki Kimoto authored on 2011-01-26
779

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
784
=head4 C<E<lt>=>
update pod
Yuki Kimoto authored on 2011-01-26
785

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

            
788
    {<= NAME}   ->   NAME <= ?
789

            
update pod
Yuki Kimoto authored on 2011-01-31
790
=head4 C<like>
update pod
Yuki Kimoto authored on 2011-01-26
791

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

            
794
    {like NAME}   ->   NAME like ?
795

            
update pod
Yuki Kimoto authored on 2011-01-31
796
=head4 C<in>
update pod
Yuki Kimoto authored on 2011-01-26
797

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

            
801
    {in NAME COUNT}   ->   NAME in [?, ?, ..]
802

            
update pod
Yuki Kimoto authored on 2011-01-31
803
=head4 C<insert_param>
update pod
Yuki Kimoto authored on 2011-01-26
804

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
809
=head4 C<update_param>
update pod
Yuki Kimoto authored on 2011-01-26
810

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
815
=head3 同名の列の扱い
updated document
Yuki Kimoto authored on 2011-01-20
816

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

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

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

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

            
update pod
Yuki Kimoto authored on 2011-01-31
827
=head3 タグの追加 C<register_tag()>
update pod
Yuki Kimoto authored on 2011-01-26
828

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

            
832
    $dbi->register_tag(
update pod
Yuki Kimoto authored on 2011-01-26
833
        '=' => sub {
834
            my $column = shift;
835
            
836
            return ["$column = ?", [$column]];
removed experimental txn_sco...
Yuki Kimoto authored on 2011-01-24
837
        }
838
    );
839

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

            
843
    {タグ名 引数1 引数2}
844

            
845
C<=>タグの場合は
846

            
847
    {= title}
848

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

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

            
853
    [
854
        展開後の文字列,
855
        [プレースホルダに埋め込みに利用する列名1, 列名2, ...]
856
    ]
857

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

            
860
    'title = ?'
861

            
862
を返す必要があります。
863

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

            
867
    ['title']
868

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

            
873
上記を合わせると
874

            
875
    ['title = ?', ['title']]
876
    
877
を返す必要があるということです。
878

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

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

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

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

            
890
titleの値だけで検索したい場合
891

            
892
    where {= title}
893

            
894
authorの値だけで検索したい場合
895

            
896
    where {= author}
897

            
898
titleとauthorの両方の値で検索したい場合
899

            
900
    where {= title} and {=author}
901

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

            
905
    my $where = $dbi->where;
906

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

            
909
    $where->clause(
910
        ['and', '{= title'}, '{= author}']
911
    );
912

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

            
915
    ['or' あるいは 'and', タグ1, タグ2, タグ3]
916

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

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

            
923
    ['and', 
924
      '{= title}', 
925
      ['or', '{= author}', '{like date}']
926
    ]
927

            
928
このようにC<clause>を設定した後にC<param>にパラメータを指定します。
929
    
930
    my $param => {title => 'Perl'};
931
    $where->param($param);
932

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

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

            
938
    my $where_clause = $where->to_string;
939

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

            
942
    where {= title}
943

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

            
948
    my $where_clause = "$where";
949

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

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

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

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

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

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

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

            
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
966
    my $p = {date => ['2010-11-15', '2011-11-21']};
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
    $where->clause(
972
        ['and', '{> date}', '{< date}']
973
    );
974
    $where->param($p);
975

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

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

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

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

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

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

            
989
    my $p = {date => []};
990

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

            
993
    my @date;
994
    push @date, exists $param->{start_date} ? $param->{start_date}
995
                                            : $dbi->not_exists;
996
    push @date, $param->{end_date} if exists $param->{end_date};
997
    my $p = {date => \@date};
998

            
999
=head3 C<select()>との連携
1000

            
update pod
Yuki Kimoto authored on 2011-01-26
1001
L<DBIx::Custom::Where>オブジェクトは
1002
C<select()>のC<where>に直接渡すことが
make delete() using where ob...
Yuki Kimoto authored on 2011-01-26
1003
できます。
1004
    
1005
    my $where = $dbi->where;
1006
    $where->clause(...);
1007
    $where->param($param);
1008
    my $result = $dbi->select(table => 'book', where => $where);
1009

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

            
1012
=head3 C<execute()>との連携
1013

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

            
1016

            
1017
    my $where = $dbi->where;
1018
    $where->clause(...);
1019
    $where->param($param);
1020

            
1021
    my $sql = <<"EOS"
1022
    select * from book;
1023
    $where
1024
    EOS
added experimental not_exist...
Yuki Kimoto authored on 2011-01-26
1025

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

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

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

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

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

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

            
1042
    my $table = $dbi->table('book');
1043

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

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

            
1053
    $table->insert(param => $param);
1054

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

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

            
1059
    $table->method(
1060
        register => sub {
1061
            my $self = shift;
1062
            my $table_name = $self->name;
1063
            # something
1064
        },
1065
        list => sub {
1066
            my $self = shift;
1067
            my $table_name = $self->name;
1068
            # something
1069
        }
1070
    );
1071

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

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

            
1077
    $table->register(...);
1078
    $table->list(...);
1079

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

            
1082
    $table->method(
1083
        insert => sub {
1084
            my $self = shift;
1085
            
1086
            $self->base_insert(...);
1087
            
1088
            # something
1089
        }
1090
    );
1091

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

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

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

            
1100
    $dbi->base_table->method(
1101
        count => sub {
1102
            my $self = shift;
1103
            return $self->select(column => ['count(*)']);
1104
        }
1105
    );
1106

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

            
1109
    # DBIx::Custom method
1110
    $table->execute($sql);
1111
    
1112
    # DBI method
1113
    $table->begin_work;
1114
    $table->commit;
1115

            
1116
=head2 一般的なモデルの構成
1117

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

            
1121
    package MyDBI;
1122
    
1123
    use base 'DBIx::Custom';
1124
    
1125
    sub connect {
1126
        my $self = shift->SUPER::connect(@_);
1127
        
1128
        $self->base_table->method(
1129
            ... => sub { ... }
1130
        );
1131
        
1132
        $self->table('book')->method(
1133
            insert_multi => sub { ... },
1134
            ... => sub { ... }
1135
        );
1136
        
1137
        $self->table('company')->method(
1138
            ... => sub { ... },
1139
        );
1140
    }
1141

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

            
1144
    my $dbi = MyDBI->connect(...);
1145
    $dbi->table('book')->insert_multi(...);
1146

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

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

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

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

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

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

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

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

            
1172
    {
1173
        sql     => 'insert into book (title, author) values (?, ?);',
1174
        columns => ['title', 'author'],
1175
        sth     => $sth
1176
    }
1177

            
update pod
Yuki Kimoto authored on 2011-01-26
1178
クエリオブジェクトを使って繰り返し実行するにはC<execute()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
1179
    
update pod
Yuki Kimoto authored on 2011-01-26
1180
    my $params = [
updated document
Yuki Kimoto authored on 2011-01-20
1181
        {title => 'Perl',      author => 'Ken'},
1182
        {title => 'Good days', author => 'Mike'}
1183
    ];
1184
    
update pod
Yuki Kimoto authored on 2011-01-26
1185
    foreach my $param (@$paramss) {
1186
        $dbi->execute($query, table => 'book', param => $input);
updated document
Yuki Kimoto authored on 2011-01-20
1187
    }
1188

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

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

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

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

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

            
update pod
Yuki Kimoto authored on 2011-01-26
1206
    $dbi->method(
updated document
Yuki Kimoto authored on 2011-01-20
1207
        update_or_insert => sub {
1208
            my $self = shift;
update pod
Yuki Kimoto authored on 2011-01-26
1209
            # something
updated document
Yuki Kimoto authored on 2011-01-20
1210
        },
1211
        find_or_create   => sub {
1212
            my $self = shift;
update pod
Yuki Kimoto authored on 2011-01-26
1213
            # something
updated document
Yuki Kimoto authored on 2011-01-20
1214
        }
1215
    );
1216

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

            
1220
    $dbi->update_or_insert;
1221
    $dbi->find_or_create;
1222

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

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

            
1227
    package MyResult;
1228
    use base 'DBIx::Custom::Result';
1229
    
1230
    sub some_method { ... }
updated document
Yuki Kimoto authored on 2011-01-20
1231

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1232
    1;
1233
    
1234
    package main;
1235
    
1236
    use MyResult;
1237
    
1238
    my $dbi = DBIx::Custom->connect(...);
1239
    $dbi->result_class('MyResult');
updated document
Yuki Kimoto authored on 2011-01-20
1240

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

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

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

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

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

            
removed experimental expand
Yuki Kimoto authored on 2011-01-26
1254
    $dbi->cache_method(sub {
1255
        sub {
1256
            my $self = shift;
1257
            
1258
            $self->{_cached} ||= {};
1259
            
1260
            if (@_ > 1) {
1261
                # Set
1262
                $self->{_cached}{$_[0]} = $_[1] 
1263
            }
1264
            else {
1265
                # Get
1266
                return $self->{_cached}{$_[0]}
1267
            }
1268
        }
1269
    });
1270
    
1271
第一はL<DBIx::Custom>オブジェクトです。
1272
第二引数はタグの展開される前のSQLです。
1273
第三引数はタグの展開後のSQLです。
updated document
Yuki Kimoto authored on 2011-01-20
1274

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

            
1279
=cut