DBIx-Class-0.07006 > 0.08127 との差分

DBIx::Class::Manual::Cookbook 0.08127 と 0.07006 の差分

1=encoding utf8
21
2=encoding euc-jp
3
34=head1 名前
45
56DBIx::Class::Manual::Cookbook - レシピいろいろ
67
7=head1 検索
8=head1 レシピ
89
9=head2 ページ処理された結果
10=head2 検索
1011
11=begin original
12=head3 ページ処理された結果セット
1213
1314When you expect a large number of results, you can ask L<DBIx::Class> for a
14paged resultset, which will fetch only a defined number of records at a time:
15paged resultset, which will fetch only a small number of records at a time:
1516
16=end original
17
1817結果セットが膨大になりそうなら、ページ処理された結果をL<DBIx::Class>で取得できます。
19一回に、決まった数のレコードしかとってきません:
18一回に、少しのレコードしかとってきません:
2019
2120 my $rs = $schema->resultset('Artist')->search(
2221 undef,
2322 {
2423 page => 1, # page to return (defaults to 1)
2524 rows => 10, # number of results per page
2625 },
2726 );
2827
2928 return $rs->all(); # all records for page 1
3029
31 return $rs->page(2); # records for page 2
30The C<page> attribute does not have to be specified in your search:
3231
33=begin original
32C<page>属性は検索に指定する必要はありません:
3433
35You can get a L<Data::Page> object for the resultset (suitable for use
34 my $rs = $schema->resultset('Artist')->search(
36in e.g. a template) using the C<pager> method:
35 undef,
36 {
37 rows => 10,
38 }
39 );
3740
38=end original
41 return $rs->page(1); # DBIx::Class::ResultSet containing first 10 records
3942
43In either of the above cases, you can return a L<Data::Page> object for the
44resultset (suitable for use in e.g. a template) using the C<pager> method:
45
4046上のケースのいずれでも、結果セットに、L<Data::Page>オブジェクト(テンプレートに使うのに適した)
4147を得ることができます。C<pager>メソッドを使って:
4248
4349 return $rs->pager();
4450
45=head2 複雑な WHERE節
51=head3 複雑な WHERE節
4652
47=begin original
48
4953Sometimes you need to formulate a query using specific operators:
5054
51=end original
52
5355特定の演算子を使ったクエリを定式化する必要がある時もあるでしょう:
5456
5557 my @albums = $schema->resultset('Album')->search({
5658 artist => { 'like', '%Lamb%' },
5759 title => { 'like', '%Fear of Fours%' },
5860 });
5961
60=begin original
61
6262This results in something like the following C<WHERE> clause:
6363
64=end original
65
6664結果は下記のC<WHERE>節のようなものになります:
6765
68 WHERE artist LIKE ? AND title LIKE ?
66 WHERE artist LIKE '%Lamb%' AND title LIKE '%Fear of Fours%'
6967
70=begin original
71
72And the following bind values for the placeholders: C<'%Lamb%'>, C<'%Fear of
73Fours%'>.
74
75=end original
76
77そして、プレースフォルダーのために、バインドする値を続けます: C<%Lamb%>, C<'%Fear of
78Fours%'>.
79
80=begin original
81
8268Other queries might require slightly more complex logic:
8369
84=end original
85
8670もうちょっと複雑なロジックが必要な他のクエリもあるでしょう:
8771
8872 my @albums = $schema->resultset('Album')->search({
8973 -or => [
9074 -and => [
9175 artist => { 'like', '%Smashing Pumpkins%' },
9276 title => 'Siamese Dream',
9377 ],
9478 artist => 'Starchildren',
9579 ],
9680 });
9781
98=begin original
99
10082This results in the following C<WHERE> clause:
10183
102=end original
103
10484結果は下記のC<WHERE>節になります:
10585
10686 WHERE ( artist LIKE '%Smashing Pumpkins%' AND title = 'Siamese Dream' )
10787 OR artist = 'Starchildren'
10888
109=begin original
110
11189For more information on generating complex queries, see
11290L<SQL::Abstract/WHERE CLAUSES>.
11391
114=end original
115
11692複雑なクエリをつくるためのより詳しい説明は、L<SQL::Abstract/WHERE CLAUSES>を見てください。
11793
118=head2 Retrieve one and only one row from a resultset
94=head3 特定のカラムを使う
11995
120Sometimes you need only the first "top" row of a resultset. While this
121can be easily done with L<< $rs->first|DBIx::Class::ResultSet/first
122>>, it is suboptimal, as a full blown cursor for the resultset will be
123created and then immediately destroyed after fetching the first row
124object. L<< $rs->single|DBIx::Class::ResultSet/single >> is designed
125specifically for this case - it will grab the first returned result
126without even instantiating a cursor.
127
128Before replacing all your calls to C<first()> with C<single()> please observe the
129following CAVEATS:
130
131=over
132
133=item *
134
135While single() takes a search condition just like search() does, it does
136_not_ accept search attributes. However one can always chain a single() to
137a search():
138
139 my $top_cd = $cd_rs->search({}, { order_by => 'rating' })->single;
140
141
142=item *
143
144Since single() is the engine behind find(), it is designed to fetch a
145single row per database query. Thus a warning will be issued when the
146underlying SELECT returns more than one row. Sometimes however this usage
147is valid: i.e. we have an arbitrary number of cd's but only one of them is
148at the top of the charts at any given time. If you know what you are doing,
149you can silence the warning by explicitly limiting the resultset size:
150
151 my $top_cd = $cd_rs->search ({}, { order_by => 'rating', rows => 1 })->single;
152
153=back
154
155=head2 Arbitrary SQL through a custom ResultSource
156
157Sometimes you have to run arbitrary SQL because your query is too complex
158(e.g. it contains Unions, Sub-Selects, Stored Procedures, etc.) or has to
159be optimized for your database in a special way, but you still want to
160get the results as a L<DBIx::Class::ResultSet>.
161
162This is accomplished by defining a
163L<ResultSource::View|DBIx::Class::ResultSource::View> for your query,
164almost like you would define a regular ResultSource.
165
166 package My::Schema::Result::UserFriendsComplex;
167 use strict;
168 use warnings;
169 use base qw/DBIx::Class::Core/;
170
171 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
172
173 # ->table, ->add_columns, etc.
174
175 # do not attempt to deploy() this view
176 __PACKAGE__->result_source_instance->is_virtual(1);
177
178 __PACKAGE__->result_source_instance->view_definition(q[
179 SELECT u.* FROM user u
180 INNER JOIN user_friends f ON u.id = f.user_id
181 WHERE f.friend_user_id = ?
182 UNION
183 SELECT u.* FROM user u
184 INNER JOIN user_friends f ON u.id = f.friend_user_id
185 WHERE f.user_id = ?
186 ]);
187
188Next, you can execute your complex query using bind parameters like this:
189
190 my $friends = $schema->resultset( 'UserFriendsComplex' )->search( {},
191 {
192 bind => [ 12345, 12345 ]
193 }
194 );
195
196... and you'll get back a perfect L<DBIx::Class::ResultSet> (except, of course,
197that you cannot modify the rows it contains, e.g. cannot call L</update>,
198L</delete>, ... on it).
199
200Note that you cannot have bind parameters unless is_virtual is set to true.
201
202=over
203
204=item * NOTE
205
206If you're using the old deprecated C<< $rsrc_instance->name(\'( SELECT ...') >>
207method for custom SQL execution, you are highly encouraged to update your code
208to use a virtual view as above. If you do not want to change your code, and just
209want to suppress the deprecation warning when you call
210L<DBIx::Class::Schema/deploy>, add this line to your source definition, so that
211C<deploy> will exclude this "table":
212
213 sub sqlt_deploy_hook { $_[1]->schema->drop_table ($_[1]) }
214
215=back
216
217=head2 特定のカラムを使う
218
219=begin original
220
22196When you only want specific columns from a table, you can use
22297C<columns> to specify which ones you need. This is useful to avoid
22398loading columns with large amounts of data that you aren't about to
22499use anyway:
225100
226=end original
227
228101テーブルから特定のカラムが欲しいだけのときには、C<columns>を使って、
229102必要なものを指定できます。何にも使わない大量のデータを取り込むのを
230103避けることができます。
231104
232105 my $rs = $schema->resultset('Artist')->search(
233106 undef,
234107 {
235108 columns => [qw/ name /]
236109 }
237110 );
238111
239112 # Equivalent SQL:
240113 # SELECT artist.name FROM artist
241114
242=begin original
243
244115This is a shortcut for C<select> and C<as>, see below. C<columns>
245116cannot be used together with C<select> and C<as>.
246117
247=end original
248
249118後でも見ますが、これは、C<select>とC<as>のショートカットです。
250119C<columns>はC<select>とC<as>と一緒には使えません。
251120
252=head2 データベースの関数やストアドプロシージャを使う
121=head3 データベースの関数やストアドプロシージャを使う
253122
254=begin original
255
256123The combination of C<select> and C<as> can be used to return the result of a
257124database function or stored procedure as a column value. You use C<select> to
258125specify the source for your column value (e.g. a column name, function, or
259126stored procedure name). You then use C<as> to set the column name you will use
260127to access the returned value:
261128
262=end original
263
264129C<select>とC<as>の組み合わせで、カラムの値としてデータベース関数やストアド
265130プロシージャの結果を返すのに使うことが出来ます。C<select>を使って、カラムの
266131値のためのソースを指定できます(例えば、カラム名、関数、ストアドプロシージャ名)。
267132それから、C<as>を、返された値にアクセスするのに使うカラム名をセットするのに
268133使えます:
269134
270135 my $rs = $schema->resultset('Artist')->search(
271136 {},
272137 {
273138 select => [ 'name', { LENGTH => 'name' } ],
274139 as => [qw/ name name_length /],
275140 }
276141 );
277142
278143 # Equivalent SQL:
279144 # SELECT name name, LENGTH( name )
280145 # FROM artist
281146
282Note that the C<as> attribute B<has absolutely nothing to do> with the SQL
147Note that the C< as > attribute has absolutely nothing to with the sql
283148syntax C< SELECT foo AS bar > (see the documentation in
284L<DBIx::Class::ResultSet/ATTRIBUTES>). You can control the C<AS> part of the
149L<DBIx::Class::ResultSet/ATTRIBUTES>). If your alias exists as a
285generated SQL via the C<-as> field attribute as follows:
150column in your base class (i.e. it was added with C<add_columns>), you
151just access it as normal. Our C<Artist> class has a C<name> column, so
152we just use the C<name> accessor:
286153
287 my $rs = $schema->resultset('Artist')->search(
288 {},
289 {
290 join => 'cds',
291 distinct => 1,
292 '+select' => [ { count => 'cds.cdid', -as => 'amount_of_cds' } ],
293 '+as' => [qw/num_cds/],
294 order_by => { -desc => 'amount_of_cds' },
295 }
296 );
297
298 # Equivalent SQL
299 # SELECT me.artistid, me.name, me.rank, me.charfield, COUNT( cds.cdid ) AS amount_of_cds
300 # FROM artist me LEFT JOIN cd cds ON cds.artist = me.artistid
301 # GROUP BY me.artistid, me.name, me.rank, me.charfield
302 # ORDER BY amount_of_cds DESC
303
304=begin original
305
306If your alias exists as a column in your base class (i.e. it was added with
307L<add_columns|DBIx::Class::ResultSource/add_columns>), you just access it as
308normal. Our C<Artist> class has a C<name> column, so we just use the C<name>
309accessor:
310
311=end original
312
313154C< as >属性は、SQLのシンタックスC< SELECT foo AS bar>とまったく関係ないことに
314155気をつけてください(L<DBIx::Class::ResultSet/ATTRIBUTES>のドキュメントを見てください)。
315156ベースクラスにカラムとしてエイリアスがある(すなわち、C<add_columns>で追加されている)のなら、
316157普通にそれにアクセスできます。この例で言えば、C<Artist>クラスには、
317158C<name>カラムがあるので、C<name>アクセサを使えます:
318159
319160 my $artist = $rs->first();
320161 my $name = $artist->name();
321162
322=begin original
323
324163If on the other hand the alias does not correspond to an existing column, you
325164have to fetch the value using the C<get_column> accessor:
326165
327=end original
328
329166一方で、エイリアスが既存のカラムに一致しないなら、C<get_column>アクセサを使って、
330167値を取得する必要があります:
331168
332169 my $name_length = $artist->get_column('name_length');
333170
334=begin original
335
336171If you don't like using C<get_column>, you can always create an accessor for
337172any of your aliases using either of these:
338173
339=end original
340
341174C<get_column>が気に入らなければ、いつでも、下記のいずれかを使ってどんな
342175エイリアスにもアクセサを作れます:
343176
344177 # Define accessor manually:
345178 sub name_length { shift->get_column('name_length'); }
179
347180 # Or use DBIx::Class::AccessorGroup:
348181 __PACKAGE__->mk_group_accessors('column' => 'name_length');
349182
350See also L</Using SQL functions on the left hand side of a comparison>.
183=head3 SELECT DISTINCT with multiple columns
351184
352=head2 SELECT DISTINCT with multiple columns
185 my $rs = $schema->resultset('Foo')->search(
353
354 my $rs = $schema->resultset('Artist')->search(
355186 {},
356187 {
357 columns => [ qw/artist_id name rank/ ],
188 select => [
358 distinct => 1
189 { distinct => [ $source->columns ] }
190 ],
191 as => [ $source->columns ] # remember 'as' is not the same as SQL AS :-)
359192 }
360193 );
361194
362 my $rs = $schema->resultset('Artist')->search(
195 my $count = $rs->next->get_column('count');
363 {},
364 {
365 columns => [ qw/artist_id name rank/ ],
366 group_by => [ qw/artist_id name rank/ ],
367 }
368 );
369196
370 # Equivalent SQL:
197=head3 SELECT COUNT(DISTINCT colname)
371 # SELECT me.artist_id, me.name, me.rank
372 # FROM artist me
373 # GROUP BY artist_id, name, rank
374198
375=head2 SELECT COUNT(DISTINCT colname)
199 my $rs = $schema->resultset('Foo')->search(
376
377 my $rs = $schema->resultset('Artist')->search(
378200 {},
379201 {
380 columns => [ qw/name/ ],
202 select => [
381 distinct => 1
203 { count => { distinct => 'colname' } }
204 ],
205 as => [ 'count' ]
382206 }
383207 );
384208
385 my $rs = $schema->resultset('Artist')->search(
209=head3 結果のグルーピング
386 {},
387 {
388 columns => [ qw/name/ ],
389 group_by => [ qw/name/ ],
390 }
391 );
392210
393 my $count = $rs->count;
394
395 # Equivalent SQL:
396 # SELECT COUNT( * ) FROM (SELECT me.name FROM artist me GROUP BY me.name) me:
397
398=head2 結果のグルーピング
399
400211L<DBIx::Class> supports C<GROUP BY> as follows:
401212
402213L<DBIx::Class>はC<GROUP BY>をサポートします:
403214
404215 my $rs = $schema->resultset('Artist')->search(
405216 {},
406217 {
407218 join => [qw/ cds /],
408 select => [ 'name', { count => 'cds.id' } ],
219 select => [ 'name', { count => 'cds.cdid' } ],
409220 as => [qw/ name cd_count /],
410221 group_by => [qw/ name /]
411222 }
412223 );
413224
414225 # Equivalent SQL:
415 # SELECT name, COUNT( cd.id ) FROM artist
226 # SELECT name, COUNT( cds.cdid ) FROM artist me
416 # LEFT JOIN cd ON artist.id = cd.artist
227 # LEFT JOIN cd cds ON ( cds.artist = me.artistid )
417228 # GROUP BY name
418229
419=begin original
420
421230Please see L<DBIx::Class::ResultSet/ATTRIBUTES> documentation if you
422231are in any way unsure about the use of the attributes above (C< join
423232>, C< select >, C< as > and C< group_by >).
424233
425=end original
426
427234上記の(C< join >、 C< select >、 C< as >、 C< group_by>)属性の使い方がわからなければ、
428235L<DBIx::Class::ResultSet/ATTRIBUTES>ドキュメントをみてください。
429236
430=head2 Subqueries
237=head3 定義済み検索
431238
432You can write subqueries relatively easily in DBIC.
239You can write your own L<DBIx::Class::ResultSet> class by inheriting from it
240and define often used searches as methods:
433241
434 my $inside_rs = $schema->resultset('Artist')->search({
435 name => [ 'Billy Joel', 'Brittany Spears' ],
436 });
437
438 my $rs = $schema->resultset('CD')->search({
439 artist_id => { 'IN' => $inside_rs->get_column('id')->as_query },
440 });
441
442The usual operators ( =, !=, IN, NOT IN, etc.) are supported.
443
444B<NOTE>: You have to explicitly use '=' when doing an equality comparison.
445The following will B<not> work:
446
447 my $rs = $schema->resultset('CD')->search({
448 artist_id => $inside_rs->get_column('id')->as_query, # does NOT work
449 });
450
451=head3 Support
452
453Subqueries are supported in the where clause (first hashref), and in the
454from, select, and +select attributes.
455
456=head3 Correlated subqueries
457
458 my $cdrs = $schema->resultset('CD');
459 my $rs = $cdrs->search({
460 year => {
461 '=' => $cdrs->search(
462 { artist_id => { '=' => { -ident => 'me.artist_id' } } },
463 { alias => 'inner' }
464 )->get_column('year')->max_rs->as_query,
465 },
466 });
467
468That creates the following SQL:
469
470 SELECT me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
471 FROM cd me
472 WHERE year = (
473 SELECT MAX(inner.year)
474 FROM cd inner
475 WHERE artist_id = me.artist_id
476 )
477
478=head2 定義済み検索
479
480=begin original
481
482You can define frequently used searches as methods by subclassing
483L<DBIx::Class::ResultSet>:
484
485=end original
486
487242L<DBIx::Class::ResultSet>クラスを継承して、自分自身のクラスを書き、よく使う
488243検索をメソッドとして定義できます:
489244
490245 package My::DBIC::ResultSet::CD;
491246 use strict;
492247 use warnings;
493248 use base 'DBIx::Class::ResultSet';
494249
495250 sub search_cds_ordered {
496251 my ($self) = @_;
497252
498253 return $self->search(
499254 {},
500255 { order_by => 'name DESC' },
501256 );
502257 }
503258
504259 1;
505260
506If you're using L<DBIx::Class::Schema/load_namespaces>, simply place the file
261To use your resultset, first tell DBIx::Class to create an instance of it
507into the C<ResultSet> directory next to your C<Result> directory, and it will
262for you, in your My::DBIC::Schema::CD class:
508be automatically loaded.
509263
510=begin original
511
512If however you are still using L<DBIx::Class::Schema/load_classes>, first tell
513DBIx::Class to create an instance of the ResultSet class for you, in your
514My::DBIC::Schema::CD class:
515
516=end original
517
518264自分の結果セット使うには、最初に、自分のMy::DBIC::Schema::CDクラスの中で、
519265DBIx::Classにそのインスタンスを作るように教えます。
520266
521 # class definition as normal
522 use base 'DBIx::Class::Core';
523 __PACKAGE__->table('cd');
524
525 # tell DBIC to use the custom ResultSet class
526267 __PACKAGE__->resultset_class('My::DBIC::ResultSet::CD');
527268
528Note that C<resultset_class> must be called after C<load_components> and C<table>, or you will get errors about missing methods.
529
530=begin original
531
532269Then call your new method in your code:
533270
534=end original
535
536271それから、コードの中で、新しいメソッドを呼びます:
537272
538273 my $ordered_cds = $schema->resultset('CD')->search_cds_ordered();
539274
540=head2 Using SQL functions on the left hand side of a comparison
541275
542Using SQL functions on the left hand side of a comparison is generally not a
276=head3 ResultSetクラスを書かかない、先に定義された検索
543good idea since it requires a scan of the entire table. (Unless your RDBMS
544supports indexes on expressions - including return values of functions - and
545you create an index on the return value of the function in question.) However,
546it can be accomplished with C<DBIx::Class> when necessary by resorting to
547literal SQL:
548277
549 $rs->search(\[ 'YEAR(date_of_birth) = ?', [ plain_value => 1979 ] ]);
278Alternatively you can automatically generate a DBIx::Class::ResultSet
279class by using the ResultSetManager component and tagging your method
280as ResultSet:
550281
551 # Equivalent SQL:
282別のやりかたとして、ResultSetManagerコンポーネントを使い、ResultSetとして
552 # SELECT * FROM employee WHERE YEAR(date_of_birth) = ?
283自分のメソッドをタギングすることで、DBIx::Class::ResultSetクラスを自動的に作れます。
553284
554 $rs->search({ -and => [
285 __PACKAGE__->load_components(qw/ ResultSetManager Core /);
555 name => 'Bob',
556 \[ 'YEAR(date_of_birth) = ?', [ plain_value => 1979 ] ],
557 ]});
558286
559 # Equivalent SQL:
287 sub search_cds_ordered : ResultSet {
560 # SELECT * FROM employee WHERE name = ? AND YEAR(date_of_birth) = ?
288 my ($self) = @_;
289 return $self->search(
290 {},
291 { order_by => 'name DESC' },
292 );
293 }
561294
562Note: the C<plain_value> string in the C<< [ plain_value => 1979 ] >> part
295Then call your method in the same way from your code:
563should be either the same as the name of the column (do this if the type of the
564return value of the function is the same as the type of the column) or in the
565case of a function it's currently treated as a dummy string (it is a good idea
566to use C<plain_value> or something similar to convey intent). The value is
567currently only significant when handling special column types (BLOBs, arrays,
568etc.), but this may change in the future.
569296
570See also L<SQL::Abstract/Literal SQL with placeholders and bind values
297これで、コードから同じ方法で呼べます:
571(subqueries)>.
572298
299 my $ordered_cds = $schema->resultset('CD')->search_cds_ordered();
573300
574=head1 JOINS AND PREFETCHING
575
576301=head2 joins と prefetch を使う
577302
578=begin original
579
580303You can use the C<join> attribute to allow searching on, or sorting your
581results by, one or more columns in a related table.
304results by, one or more columns in a related table. To return all CDs matching
305a particular artist name:
582306
583=end original
584
585307C<join>属性を使って、関連するテーブルの1つ以上のカラムを使って、
586検索や、結果のソートができます。
308検索や、結果のソートができます。特定のアーティスト名の全てのCDを
309返すためには:
587310
588This requires that you have defined the L<DBIx::Class::Relationship>. For example :
589
590L<DBIx::Class::Relationship>を定義する必要があります。例えば:
591
592 My::Schema::CD->has_many( artists => 'My::Schema::Artist', 'artist_id');
593
594=begin original
595
596To return all CDs matching a particular artist name, you specify the name of the relationship ('artists'):
597
598=end original
599
600特定のアーティスト名の全てのCDを返すためには:
601
602
603311 my $rs = $schema->resultset('CD')->search(
604312 {
605 'artists.name' => 'Bob Marley'
313 'artist.name' => 'Bob Marley'
606314 },
607315 {
608 join => 'artists', # join the artist table
316 join => [qw/artist/], # join the artist table
609317 }
610318 );
611319
612320 # Equivalent SQL:
613321 # SELECT cd.* FROM cd
614322 # JOIN artist ON cd.artist = artist.id
615323 # WHERE artist.name = 'Bob Marley'
616324
617In that example both the join, and the condition use the relationship name rather than the table name
618(see L<DBIx::Class::Manual::Joining> for more details on aliasing ).
619
620=begin original
621
622325If required, you can now sort on any column in the related tables by including
623it in your C<order_by> attribute, (again using the aliased relation name rather than table name) :
326it in your C<order_by> attribute:
624327
625=end original
626
627328必要なら、C<order_by>属性にそれを含めて、関連するテーブルのいずれかのカラムで
628ソートすることも出来ます(テーブル名ではなくエイリアスのリレーション名を再度使って):
329ソートすることも出来ます
629330
630331 my $rs = $schema->resultset('CD')->search(
631332 {
632 'artists.name' => 'Bob Marley'
333 'artist.name' => 'Bob Marley'
633334 },
634335 {
635 join => 'artists',
336 join => [qw/ artist /],
636 order_by => [qw/ artists.name /]
337 order_by => [qw/ artist.name /]
637338 }
638 );
339 };
639340
640341 # Equivalent SQL:
641342 # SELECT cd.* FROM cd
642343 # JOIN artist ON cd.artist = artist.id
643344 # WHERE artist.name = 'Bob Marley'
644345 # ORDER BY artist.name
645346
646=begin original
647
648347Note that the C<join> attribute should only be used when you need to search or
649348sort using columns in a related table. Joining related tables when you only
650349need columns from the main table will make performance worse!
651350
652=end original
653
654351C<join>属性は関連するテーブルのカラムを使って検索やソートをする必要があるときにのみ
655352使われるべきだということに注意してください。
656353メインのテーブルからカラムが必要なときに、関連するテーブルを結合するのは、
657354パフォーマンスが悪いです!
658355
659=begin original
660
661356Now let's say you want to display a list of CDs, each with the name of the
662357artist. The following will work fine:
663358
664=end original
665
666359で、、CDのリストを、それぞれのアーティストの名前と一緒に表示したいとしましょう。
667360下記のやりかたでうまくいきます:
668361
669362 while (my $cd = $rs->next) {
670363 print "CD: " . $cd->title . ", Artist: " . $cd->artist->name;
671364 }
672365
673=begin original
674
675366There is a problem however. We have searched both the C<cd> and C<artist> tables
676367in our main query, but we have only returned data from the C<cd> table. To get
677368the artist name for any of the CD objects returned, L<DBIx::Class> will go back
678369to the database:
679370
680=end original
681
682371ですが、一つ問題があります。このメインクエリで、C<cd>とC<artist>テーブルの両方を
683372検索していますが、C<cd>からのみデータが返されています。返されたCDオブジェクトの一部で、
684373アーティスト名を得るために、L<DBIx::Class>は、データベースに戻ります:
685374
686375 SELECT artist.* FROM artist WHERE artist.id = ?
687376
688=begin original
689
690377A statement like the one above will run for each and every CD returned by our
691378main query. Five CDs, five extra queries. A hundred CDs, one hundred extra
692379queries!
693380
694=end original
695
696381上記のようなステートメントが、メインクエリによって返された、それぞれの、全ての
697382CDで走ります。5つのCDであれば、5つの別のクエリです。100のCDであれば、100の別の
698383クエリ!
699384
700=begin original
701
702385Thankfully, L<DBIx::Class> has a C<prefetch> attribute to solve this problem.
703386This allows you to fetch results from related tables in advance:
704387
705=end original
706
707388ありがたいことに、L<DBIx::Class>は、C<prefetch>属性があり、この問題を解決できます。
708389この属性を使うと、先に関連するテーブルから結果をとってこれます:
709390
710391
711392 my $rs = $schema->resultset('CD')->search(
712393 {
713 'artists.name' => 'Bob Marley'
394 'artist.name' => 'Bob Marley'
714395 },
715396 {
716 join => 'artists',
397 join => [qw/ artist /],
717 order_by => [qw/ artists.name /],
398 order_by => [qw/ artist.name /],
718 prefetch => 'artists' # return artist data too!
399 prefetch => [qw/ artist /] # return artist data too!
719400 }
720401 );
721402
722403 # Equivalent SQL (note SELECT from both "cd" and "artist"):
723404 # SELECT cd.*, artist.* FROM cd
724405 # JOIN artist ON cd.artist = artist.id
725406 # WHERE artist.name = 'Bob Marley'
726407 # ORDER BY artist.name
727408
728=begin original
729
730409The code to print the CD list remains the same:
731410
732=end original
733
734411CDのリストを表示するコードは同じ物が使えます:
735412
736413 while (my $cd = $rs->next) {
737414 print "CD: " . $cd->title . ", Artist: " . $cd->artist->name;
738415 }
739416
740=begin original
741
742417L<DBIx::Class> has now prefetched all matching data from the C<artist> table,
743418so no additional SQL statements are executed. You now have a much more
744419efficient query.
745420
746=end original
747
748421L<DBIx::Class>はC<artist>テーブルからすべてのマッチするデータを先にとってきています。
749422そのため、余分なSQLステートメントは実行されません。より効率的なクエリになりました。
750423
751=begin original
424Note that as of L<DBIx::Class> 0.05999_01, C<prefetch> I<can> be used with
425C<has_many> relationships.
752426
427L<DBIx::Class> 0.05999_01の時点で、 C<has_many>のリレーションシップで、
428C<prefetch>をI<使え>たのに注意してください。
429
753430Also note that C<prefetch> should only be used when you know you will
754431definitely use data from a related table. Pre-fetching related tables when you
755432only need columns from the main table will make performance worse!
756433
757=end original
758434
759435また、C<prefetch>は、関連するテーブルからデータを必ず使うとわかっているときのみに、
760436使うべきです。メインテーブルからのカラムしか必要としないなら、
761437関連するテーブルから先に取得するのは、パフォーマンスを悪くします!
762438
763=head2 複数の結合(join)
439=head3 マルチステップの結合(join)
764440
765In the examples above, the C<join> attribute was a scalar. If you
766pass an array reference instead, you can join to multiple tables. In
767this example, we want to limit the search further, using
768C<LinerNotes>:
769
770 # Relationships defined elsewhere:
771 # CD->belongs_to('artist' => 'Artist');
772 # CD->has_one('liner_notes' => 'LinerNotes', 'cd');
773 my $rs = $schema->resultset('CD')->search(
774 {
775 'artist.name' => 'Bob Marley'
776 'liner_notes.notes' => { 'like', '%some text%' },
777 },
778 {
779 join => [qw/ artist liner_notes /],
780 order_by => [qw/ artist.name /],
781 }
782 );
783
784 # Equivalent SQL:
785 # SELECT cd.*, artist.*, liner_notes.* FROM cd
786 # JOIN artist ON cd.artist = artist.id
787 # JOIN liner_notes ON cd.id = liner_notes.cd
788 # WHERE artist.name = 'Bob Marley'
789 # ORDER BY artist.name
790
791=head2 マルチステップの結合(join)
792
793=begin original
794
795441Sometimes you want to join more than one relationship deep. In this example,
796442we want to find all C<Artist> objects who have C<CD>s whose C<LinerNotes>
797443contain a specific string:
798444
799=end original
800
8014452つ以上の深いリレーションシップでjoinしたいときもあるでしょう。
802446この例では、C<LinerNotes>に特定の文字が含まれるC<CD>を持っている、
803447C<Artist>オブジェクトを探したいとします:
804448
805449 # Relationships defined elsewhere:
806450 # Artist->has_many('cds' => 'CD', 'artist');
807451 # CD->has_one('liner_notes' => 'LinerNotes', 'cd');
808452
809453 my $rs = $schema->resultset('Artist')->search(
810454 {
811455 'liner_notes.notes' => { 'like', '%some text%' },
812456 },
813457 {
814458 join => {
815459 'cds' => 'liner_notes'
816460 }
817461 }
818462 );
819463
820464 # Equivalent SQL:
821465 # SELECT artist.* FROM artist
822 # LEFT JOIN cd ON artist.id = cd.artist
466 # JOIN ( cd ON artist.id = cd.artist )
823 # LEFT JOIN liner_notes ON cd.id = liner_notes.cd
467 # JOIN ( liner_notes ON cd.id = liner_notes.cd )
824468 # WHERE liner_notes.notes LIKE '%some text%'
825469
826=begin original
827
828470Joins can be nested to an arbitrary level. So if we decide later that we
829471want to reduce the number of Artists returned based on who wrote the liner
830472notes:
831473
832=end original
833
834474結合は任意のレベルでネストできます。ですので、後から、ライナーノーツを
835475誰が書いたかを元に、返されるアーティストの数を減らしたいと決めたとしたら:
836476
837477 # Relationship defined elsewhere:
838478 # LinerNotes->belongs_to('author' => 'Person');
839479
840480 my $rs = $schema->resultset('Artist')->search(
841481 {
842482 'liner_notes.notes' => { 'like', '%some text%' },
843483 'author.name' => 'A. Writer'
844484 },
845485 {
846486 join => {
847487 'cds' => {
848488 'liner_notes' => 'author'
849489 }
850490 }
851491 }
852492 );
853493
854494 # Equivalent SQL:
855495 # SELECT artist.* FROM artist
856 # LEFT JOIN cd ON artist.id = cd.artist
496 # JOIN ( cd ON artist.id = cd.artist )
857 # LEFT JOIN liner_notes ON cd.id = liner_notes.cd
497 # JOIN ( liner_notes ON cd.id = liner_notes.cd )
858 # LEFT JOIN author ON author.id = liner_notes.author
498 # JOIN ( author ON author.id = liner_notes.author )
859499 # WHERE liner_notes.notes LIKE '%some text%'
860500 # AND author.name = 'A. Writer'
861501
862=head2 マルチステップで複数結合
502=head2 マルチステップのprefetch
863503
864With various combinations of array and hash references, you can join
504From 0.04999_05 onwards, C<prefetch> can be nested more than one relationship
865tables in any combination you desire. For example, to join Artist to
866CD and Concert, and join CD to LinerNotes:
867
868 # Relationships defined elsewhere:
869 # Artist->has_many('concerts' => 'Concert', 'artist');
870
871 my $rs = $schema->resultset('Artist')->search(
872 { },
873 {
874 join => [
875 {
876 cds => 'liner_notes'
877 },
878 'concerts'
879 ],
880 }
881 );
882
883 # Equivalent SQL:
884 # SELECT artist.* FROM artist
885 # LEFT JOIN cd ON artist.id = cd.artist
886 # LEFT JOIN liner_notes ON cd.id = liner_notes.cd
887 # LEFT JOIN concert ON artist.id = concert.artist
888
889=head2 Multi-step prefetch
890
891=begin original
892
893C<prefetch> can be nested more than one relationship
894505deep using the same syntax as a multi-step join:
895506
896=end original
5070.04999_05から、C<prefetch>は、マルチステップの結合と同じシンタックスで、
897
898C<prefetch>は、マルチステップの結合と同じシンタックスで、
8995082つ以上の深いリレーションシップでネストできました:
900509
901510 my $rs = $schema->resultset('Tag')->search(
902511 {},
903512 {
904513 prefetch => {
905514 cd => 'artist'
906515 }
907516 }
908517 );
909518
910519 # Equivalent SQL:
911520 # SELECT tag.*, cd.*, artist.* FROM tag
912 # JOIN cd ON tag.cd = cd.id
521 # JOIN cd ON tag.cd = cd.cdid
913 # JOIN artist ON cd.artist = artist.id
522 # JOIN artist ON cd.artist = artist.artistid
914523
915=begin original
916
917524Now accessing our C<cd> and C<artist> relationships does not need additional
918525SQL statements:
919526
920=end original
921527
922
923528これで、C<cd>とC<artist>のリレーションシップにアクセスするのに、
924529追加のSQLステートメントは必要ありません:
925530
926531 my $tag = $rs->first;
927532 print $tag->cd->artist->name;
928533
929=head1 ROW-LEVEL OPERATIONS
534=head2 Columns of data
930535
931=head2 列オブジェクトのスキーマを得る
932
933=begin original
934
935It is possible to get a Schema object from a row object like so:
936
937=end original
938
939次のようにして、列のオブジェクトからスキーマを得ることができます:
940
941 my $schema = $cd->result_source->schema;
942 # use the schema as normal:
943 my $artist_rs = $schema->resultset('Artist');
944
945=begin original
946
947This can be useful when you don't want to pass around a Schema object to every
948method.
949
950=end original
951
952全てのメソッドで、スキーマオブジェクトを順に回したくなければ、便利でしょう。
953
954=head2 最後にデータベースにインサートしたプライマリキーの値を取りたい
955
956=begin original
957
958AKA getting last_insert_id
959
960=end original
961
962last_insert_id を取るともいいます。
963
964=begin original
965
966Thanks to the core component PK::Auto, this is straightforward:
967
968=end original
969
970コアコンポーネントのPK::Autoに感謝して、直接:
971
972 my $foo = $rs->create(\%blah);
973 # do more stuff
974 my $id = $foo->id; # foo->my_primary_key_field will also work.
975
976=begin original
977
978If you are not using autoincrementing primary keys, this will probably
979not work, but then you already know the value of the last primary key anyway.
980
981=end original
982
983オートインクリメントのプライマリキーを使っていないのなら、おそらく動きません。
984ですが、その場合は、すでに、プライマリキーの値を知っていることでしょう。
985
986=head2 Stringification
987
988=begin original
989
990Employ the standard stringification technique by using the L<overload>
991module.
992
993=end original
994
995C<overload> モジュールで標準的な文字列化のテクニックを使えます。
996
997=begin original
998
999To make an object stringify itself as a single column, use something
1000like this (replace C<name> with the column/method of your choice):
1001
1002=end original
1003
1004ひとつのカラムについて、オブジェクト自身を文字列化するには、
1005次のようにします。(カラム/メソッドでC<name>を置き換えてください)
1006
1007 use overload '""' => sub { shift->name}, fallback => 1;
1008
1009=begin original
1010
1011For more complex stringification, you can use an anonymous subroutine:
1012
1013=end original
1014
1015より複雑な文字列化では、無名サブルーチンを使えます:
1016
1017 use overload '""' => sub { $_[0]->name . ", " .
1018 $_[0]->address }, fallback => 1;
1019
1020=head3 文字列化の例
1021
1022=begin original
1023
1024Suppose we have two tables: C<Product> and C<Category>. The table
1025specifications are:
1026
1027=end original
1028
1029二つのテーブルがあるとします:C<Product>とC<Cateogry>。
1030テーブルの定義は次の通り:
1031
1032 Product(id, Description, category)
1033 Category(id, Description)
1034
1035=begin original
1036
1037C<category> is a foreign key into the Category table.
1038
1039=end original
1040
1041C<category>はCategoryテーブルの外部キーです。
1042
1043=begin original
1044
1045If you have a Product object C<$obj> and write something like
1046
1047=end original
1048
1049ProductオブジェクトC<$obj>があり、次のように書いたとすると、
1050
1051 print $obj->category
1052
1053=begin original
1054
1055things will not work as expected.
1056
1057=end original
1058
1059期待どおりには動きません。
1060
1061=begin original
1062
1063To obtain, for example, the category description, you should add this
1064method to the class defining the Category table:
1065
1066=end original
1067
1068カテゴリの内容を得たいなら、例えば、Categoryテーブルのクラス定義に次の
1069メソッドを追加すべきです:
1070
1071 use overload "" => sub {
1072 my $self = shift;
1073
1074 return $self->Description;
1075 }, fallback => 1;
1076
1077=head2 find_or_create が見付けたのか、列を作ったのかを知りたい?
1078
1079=begin original
1080
1081Just use C<find_or_new> instead, then check C<in_storage>:
1082
1083=end original
1084
1085C<find_or_new>を代わりに使ってください。それから、C<in_storage>をチェックします:
1086
1087 my $obj = $rs->find_or_new({ blah => 'blarg' });
1088 unless ($obj->in_storage) {
1089 $obj->insert;
1090 # do whatever else you wanted if it was a new row
1091 }
1092
1093=head2 Static sub-classing DBIx::Class result classes
1094
1095AKA adding additional relationships/methods/etc. to a model for a
1096specific usage of the (shared) model.
1097
1098B<Schema definition>
1099
1100 package My::App::Schema;
1101
1102 use base 'DBIx::Class::Schema';
1103
1104 # load subclassed classes from My::App::Schema::Result/ResultSet
1105 __PACKAGE__->load_namespaces;
1106
1107 # load classes from shared model
1108 load_classes({
1109 'My::Shared::Model::Result' => [qw/
1110 Foo
1111 Bar
1112 /]});
1113
1114 1;
1115
1116B<Result-Subclass definition>
1117
1118 package My::App::Schema::Result::Baz;
1119
1120 use strict;
1121 use warnings;
1122 use base 'My::Shared::Model::Result::Baz';
1123
1124 # WARNING: Make sure you call table() again in your subclass,
1125 # otherwise DBIx::Class::ResultSourceProxy::Table will not be called
1126 # and the class name is not correctly registered as a source
1127 __PACKAGE__->table('baz');
1128
1129 sub additional_method {
1130 return "I'm an additional method only needed by this app";
1131 }
1132
1133 1;
1134
1135=head2 DBIx::Classのプロキシクラスを動的にサブクラス化する
1136
1137=begin original
1138
1139AKA multi-class object inflation from one table
1140
1141=end original
1142
1143AKA 1つのテーブルからマルチクラスのオブジェクトに展開する
1144
1145=begin original
1146
1147L<DBIx::Class> classes are proxy classes, therefore some different
1148techniques need to be employed for more than basic subclassing. In
1149this example we have a single user table that carries a boolean bit
1150for admin. We would like like to give the admin users
1151objects (L<DBIx::Class::Row>) the same methods as a regular user but
1152also special admin only methods. It doesn't make sense to create two
1153separate proxy-class files for this. We would be copying all the user
1154methods into the Admin class. There is a cleaner way to accomplish
1155this.
1156
1157=end original
1158
1159L<DBIx::Class>クラスはプロキシクラスです。そのため、基本的なサブクラス化以上に、
1160いくつかの違ったテクニックが必要とされます。
1161この例では、管理者用に真偽値を持っているユーザーテーブルがあります。
1162管理者ユーザーには、オブジェクト(L<DBIx::Class::Row>)のメソッドを、
1163普通のユーザーと同じようにあたえますが、管理者のみの特別なメソッドも、
1164あたえたいとします。このために2つのプロキシクラスファイルに分割するのは
1165理にかないません。Adminクラスに全てのユーザークラスのメソッドをコピー
1166することになります。これをするために、よりすっきりした方法があります。
1167
1168=begin original
1169
1170Overriding the C<inflate_result> method within the User proxy-class
1171gives us the effect we want. This method is called by
1172L<DBIx::Class::ResultSet> when inflating a result from storage. So we
1173grab the object being returned, inspect the values we are looking for,
1174bless it if it's an admin object, and then return it. See the example
1175below:
1176
1177=end original
1178
1179ユーザーのプロキシクラス内でC<inflate_result>メソッドをオーバーライドすることで、
1180望んでいる効果が得られます。このメソッドは、ストレージから結果が展開されるときに、
1181L<DBIx::Class::ResultSet>によって呼ばれます。
1182返されたオブジェクトを掴んだら、探している値を調べ、管理者オブジェクトであれば、
1183それをblessして返します。下の例を見てください:
1184
1185B<Schema Definition>
1186
1187 package My::Schema;
1188
1189 use base qw/DBIx::Class::Schema/;
1190
1191 __PACKAGE__->load_namespaces;
1192
1193 1;
1194
1195
1196B<Proxy-Class definitions>
1197
1198 package My::Schema::Result::User;
1199
1200 use strict;
1201 use warnings;
1202 use base qw/DBIx::Class::Core/;
1203
1204 ### Define what our admin class is, for ensure_class_loaded()
1205 my $admin_class = __PACKAGE__ . '::Admin';
1206
1207 __PACKAGE__->table('users');
1208
1209 __PACKAGE__->add_columns(qw/user_id email password
1210 firstname lastname active
1211 admin/);
1212
1213 __PACKAGE__->set_primary_key('user_id');
1214
1215 sub inflate_result {
1216 my $self = shift;
1217 my $ret = $self->next::method(@_);
1218 if( $ret->admin ) {### If this is an admin, rebless for extra functions
1219 $self->ensure_class_loaded( $admin_class );
1220 bless $ret, $admin_class;
1221 }
1222 return $ret;
1223 }
1224
1225 sub hello {
1226 print "I am a regular user.\n";
1227 return ;
1228 }
1229
1230 1;
1231
1232
1233 package My::Schema::Result::User::Admin;
1234
1235 use strict;
1236 use warnings;
1237 use base qw/My::Schema::Result::User/;
1238
1239 # This line is important
1240 __PACKAGE__->table('users');
1241
1242 sub hello
1243 {
1244 print "I am an admin.\n";
1245 return;
1246 }
1247
1248 sub do_admin_stuff
1249 {
1250 print "I am doing admin stuff\n";
1251 return ;
1252 }
1253
1254 1;
1255
1256B<Test File> test.pl
1257
1258 use warnings;
1259 use strict;
1260 use My::Schema;
1261
1262 my $user_data = { email => 'someguy@place.com',
1263 password => 'pass1',
1264 admin => 0 };
1265
1266 my $admin_data = { email => 'someadmin@adminplace.com',
1267 password => 'pass2',
1268 admin => 1 };
1269
1270 my $schema = My::Schema->connection('dbi:Pg:dbname=test');
1271
1272 $schema->resultset('User')->create( $user_data );
1273 $schema->resultset('User')->create( $admin_data );
1274
1275 ### Now we search for them
1276 my $user = $schema->resultset('User')->single( $user_data );
1277 my $admin = $schema->resultset('User')->single( $admin_data );
1278
1279 print ref $user, "\n";
1280 print ref $admin, "\n";
1281
1282 print $user->password , "\n"; # pass1
1283 print $admin->password , "\n";# pass2; inherited from User
1284 print $user->hello , "\n";# I am a regular user.
1285 print $admin->hello, "\n";# I am an admin.
1286
1287 ### The statement below will NOT print
1288 print "I can do admin stuff\n" if $user->can('do_admin_stuff');
1289 ### The statement below will print
1290 print "I can do admin stuff\n" if $admin->can('do_admin_stuff');
1291
1292Alternatively you can use L<DBIx::Class::DynamicSubclass> that implements
1293exactly the above functionality.
1294
1295=head2 高速に結果を得るために、オブジェクトの作成をスキップしたい
1296
1297=begin original
1298
1299DBIx::Class is not built for speed, it's built for convenience and
1300ease of use, but sometimes you just need to get the data, and skip the
1301fancy objects.
1302
1303=end original
1304
1305DBIx::Class はスピードのためには作られておらず、DBIx::Classは、
1306利便性と使い易さのために作られました。ですが、時には、データをただ
1307取得しなければいけないだけの時があり、素敵なオブジェクトはスキップ
1308したい場合もあるでしょう。
1309
1310To do this simply use L<DBIx::Class::ResultClass::HashRefInflator>.
1311
1312この用途には、L<DBIx::Class::ResultClass::HashRefInflator>が、簡単に使えます。
1313
1314 my $rs = $schema->resultset('CD');
1315
1316 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
1317
1318 my $hash_ref = $rs->find(1);
1319
1320Wasn't that easy?
1321
1322Beware, changing the Result class using
1323L<DBIx::Class::ResultSet/result_class> will replace any existing class
1324completely including any special components loaded using
1325load_components, eg L<DBIx::Class::InflateColumn::DateTime>.
1326
1327=head2 Get raw data for blindingly fast results
1328
1329If the L<HashRefInflator|DBIx::Class::ResultClass::HashRefInflator> solution
1330above is not fast enough for you, you can use a DBIx::Class to return values
1331exactly as they come out of the database with none of the convenience methods
1332wrapped round them.
1333
1334This is used like so:
1335
1336 my $cursor = $rs->cursor
1337 while (my @vals = $cursor->next) {
1338 # use $val[0..n] here
1339 }
1340
1341You will need to map the array offsets to particular columns (you can
1342use the L<DBIx::Class::ResultSet/select> attribute of L<DBIx::Class::ResultSet/search> to force ordering).
1343
1344=head1 RESULTSET OPERATIONS
1345
1346=head2 Getting Schema from a ResultSet
1347
1348To get the L<DBIx::Class::Schema> object from a ResultSet, do the following:
1349
1350 $rs->result_source->schema
1351
1352=head2 Getting Columns Of Data
1353
1354AKA Aggregating Data
1355
1356=begin original
1357
1358536If you want to find the sum of a particular column there are several
1359537ways, the obvious one is to use search:
1360538
1361=end original
1362
1363539特定のカラムの合計を探したければ、いくつもの方法があります。自明のものとしては、
1364540searchを使うものです:
1365541
1366542 my $rs = $schema->resultset('Items')->search(
1367543 {},
1368 {
544 {
1369545 select => [ { sum => 'Cost' } ],
1370546 as => [ 'total_cost' ], # remember this 'as' is for DBIx::Class::ResultSet not SQL
1371547 }
1372548 );
1373549 my $tc = $rs->first->get_column('total_cost');
1374550
1375=begin original
1376
1377551Or, you can use the L<DBIx::Class::ResultSetColumn>, which gets
1378552returned when you ask the C<ResultSet> for a column using
1379553C<get_column>:
1380554
1381=end original
1382
1383555もしくは、L<DBIx::Class::ResultSetColumn>を使うことも出来ます。
1384556これは、C<ResultSet>でC<get_column>を使ってカラムを取るときに
1385557返されるものが取れます。
1386558
1387559 my $cost = $schema->resultset('Items')->get_column('Cost');
1388560 my $tc = $cost->sum;
1389561
1390=begin original
1391
1392562With this you can also do:
1393563
1394=end original
1395
1396564これを、次のようにできます:
1397565
1398566 my $minvalue = $cost->min;
1399567 my $maxvalue = $cost->max;
1400568
1401=begin original
1402
1403569Or just iterate through the values of this column only:
1404570
1405=end original
1406
1407571または、このカラムの値のみを通してイテレートします:
1408572
1409573 while ( my $c = $cost->next ) {
1410574 print $c;
1411575 }
1412576
1413577 foreach my $c ($cost->all) {
1414578 print $c;
1415579 }
1416580
1417=begin original
581C<ResultSetColumn> only has a limited number of built-in functions, if
1418
1419C<ResultSetColumn> only has a limited number of built-in functions. If
1420582you need one that it doesn't have, then you can use the C<func> method
1421583instead:
1422584
1423=end original
1424
1425585C<ResultSetColumn>は少しだけビルトインの関数があります。
1426586これにないものが必要なら、C<func>メソッドを代わりに使うことができます:
1427587
1428588 my $avg = $cost->func('AVERAGE');
1429589
1430=begin original
1431
1432590This will cause the following SQL statement to be run:
1433591
1434=end original
1435
1436592こうすると、下記のSQLステートメントが走ります:
1437593
1438594 SELECT AVERAGE(Cost) FROM Items me
1439595
1440=begin original
1441
1442596Which will of course only work if your database supports this function.
1443597See L<DBIx::Class::ResultSetColumn> for more documentation.
1444598
1445=end original
1446
1447599もちろん、使っているデータベースがこの関数をサポートしていなければいけません。
1448600より詳しくは、L<DBIx::Class::ResultSetColumn>をみてください。
1449601
1450=head2 Creating a result set from a set of rows
602=head2 リレーションシップを使う
1451603
1452Sometimes you have a (set of) row objects that you want to put into a
604=head3 関連するテーブルに新しい列を作る
1453resultset without the need to hit the DB again. You can do that by using the
1454L<set_cache|DBIx::Class::Resultset/set_cache> method:
1455605
1456 my @uploadable_groups;
606 my $book->create_related('author', { name => 'Fred'});
1457 while (my $group = $groups->next) {
1458 if ($group->can_upload($self)) {
1459 push @uploadable_groups, $group;
1460 }
1461 }
1462 my $new_rs = $self->result_source->resultset;
1463 $new_rs->set_cache(\@uploadable_groups);
1464 return $new_rs;
1465607
1466=head1 リレションシップ使う
608=head3 関連するテブル検索する
1467609
1468=head2 関連するテーブルに新しい列を作る
1469
1470 my $author = $book->create_related('author', { name => 'Fred'});
1471
1472=head2 関連するテーブルを検索する
1473
1474=begin original
1475
1476610Only searches for books named 'Titanic' by the author in $author.
1477611
1478=end original
1479
1480612$autorの著者で、'Titanic'という名前の本だけを検索したい。
1481613
1482 my $books_rs = $author->search_related('books', { name => 'Titanic' });
614 my $author->search_related('books', { name => 'Titanic' });
1483615
1484=head2 関連するテーブルのデータを削除する
616=head3 関連するテーブルのデータを削除する
1485617
1486=begin original
1487
1488618Deletes only the book named Titanic by the author in $author.
1489619
1490=end original
1491
1492620$autorの著者で、Titanicという名前の本だけを削除したい。
1493621
1494 $author->delete_related('books', { name => 'Titanic' });
622 my $author->delete_related('books', { name => 'Titanic' });
1495623
1496=head2 関係する結果セットの順序付け
624=head3 関係する結果セットの順序付け
1497625
1498=begin original
626If you always want a relation to be ordered, you can specify this when you
1499
1500If you always want a relation to be ordered, you can specify this when you
1501627create the relationship.
1502628
1503=end original
1504
1505629順序付けられた関係が常にほしいなら、リレーションシップを作るときに、次の指定をできます。
1506630
1507=begin original
631To order C<< $book->pages >> by descending page_number.
1508632
1509To order C<< $book->pages >> by descending page_number, create the relation
633page_numberを降順で、C<< $book->pages >>を並び変えたいなら。
1510as follows:
1511634
1512=end original
635 Book->has_many('pages' => 'Page', 'book', { order_by => \'page_number DESC'} );
1513636
1514page_numberを降順で、C<< $book->pages >>を並び変えたいなら。次のように
637=head2 トランザクション
1515リレーションを作ります:
1516638
1517
1518 __PACKAGE__->has_many('pages' => 'Page', 'book', { order_by => { -desc => 'page_number'} } );
1519
1520=head2 Filtering a relationship result set
1521
1522If you want to get a filtered result set, you can just add add to $attr as follows:
1523
1524 __PACKAGE__->has_many('pages' => 'Page', 'book', { where => { scrap => 0 } } );
1525
1526=head2 Many-to-many のリレーションシップ
1527
1528=begin original
1529
1530This is straightforward using L<ManyToMany|DBIx::Class::Relationship/many_to_many>:
1531
1532=end original
1533
1534これは、単純にL<ManyToMany|DBIx::Class::Relationship/many_to_many>を使います:
1535
1536 package My::User;
1537 use base 'DBIx::Class::Core';
1538 __PACKAGE__->table('user');
1539 __PACKAGE__->add_columns(qw/id name/);
1540 __PACKAGE__->set_primary_key('id');
1541 __PACKAGE__->has_many('user_address' => 'My::UserAddress', 'user');
1542 __PACKAGE__->many_to_many('addresses' => 'user_address', 'address');
1543
1544 package My::UserAddress;
1545 use base 'DBIx::Class::Core';
1546 __PACKAGE__->table('user_address');
1547 __PACKAGE__->add_columns(qw/user address/);
1548 __PACKAGE__->set_primary_key(qw/user address/);
1549 __PACKAGE__->belongs_to('user' => 'My::User');
1550 __PACKAGE__->belongs_to('address' => 'My::Address');
1551
1552 package My::Address;
1553 use base 'DBIx::Class::Core';
1554 __PACKAGE__->table('address');
1555 __PACKAGE__->add_columns(qw/id street town area_code country/);
1556 __PACKAGE__->set_primary_key('id');
1557 __PACKAGE__->has_many('user_address' => 'My::UserAddress', 'address');
1558 __PACKAGE__->many_to_many('users' => 'user_address', 'user');
1559
1560 $rs = $user->addresses(); # get all addresses for a user
1561 $rs = $address->users(); # get all users for an address
1562
1563 my $address = $user->add_to_addresses( # returns a My::Address instance,
1564 # NOT a My::UserAddress instance!
1565 {
1566 country => 'United Kingdom',
1567 area_code => 'XYZ',
1568 town => 'London',
1569 street => 'Sesame',
1570 }
1571 );
1572
1573=head2 Relationships across DB schemas
1574
1575Mapping relationships across L<DB schemas|DBIx::Class::Manual::Glossary/DB schema>
1576is easy as long as the schemas themselves are all accessible via the same DBI
1577connection. In most cases, this means that they are on the same database host
1578as each other and your connecting database user has the proper permissions to them.
1579
1580To accomplish this one only needs to specify the DB schema name in the table
1581declaration, like so...
1582
1583 package MyDatabase::Main::Artist;
1584 use base qw/DBIx::Class::Core/;
1585
1586 __PACKAGE__->table('database1.artist'); # will use "database1.artist" in FROM clause
1587
1588 __PACKAGE__->add_columns(qw/ artist_id name /);
1589 __PACKAGE__->set_primary_key('artist_id');
1590 __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Cd');
1591
1592 1;
1593
1594Whatever string you specify there will be used to build the "FROM" clause in SQL
1595queries.
1596
1597The big drawback to this is you now have DB schema names hardcoded in your
1598class files. This becomes especially troublesome if you have multiple instances
1599of your application to support a change lifecycle (e.g. DEV, TEST, PROD) and
1600the DB schemas are named based on the environment (e.g. database1_dev).
1601
1602However, one can dynamically "map" to the proper DB schema by overriding the
1603L<connection|DBIx::Class::Schama/connection> method in your Schema class and
1604building a renaming facility, like so:
1605
1606 package MyDatabase::Schema;
1607 use Moose;
1608
1609 extends 'DBIx::Class::Schema';
1610
1611 around connection => sub {
1612 my ( $inner, $self, $dsn, $username, $pass, $attr ) = ( shift, @_ );
1613
1614 my $postfix = delete $attr->{schema_name_postfix};
1615
1616 $inner->(@_);
1617
1618 if ( $postfix ) {
1619 $self->append_db_name($postfix);
1620 }
1621 };
1622
1623 sub append_db_name {
1624 my ( $self, $postfix ) = @_;
1625
1626 my @sources_with_db
1627 = grep
1628 { $_->name =~ /^\w+\./mx }
1629 map
1630 { $self->source($_) }
1631 $self->sources;
1632
1633 foreach my $source (@sources_with_db) {
1634 my $name = $source->name;
1635 $name =~ s{^(\w+)\.}{${1}${postfix}\.}mx;
1636
1637 $source->name($name);
1638 }
1639 }
1640
1641 1;
1642
1643By overridding the L<connection|DBIx::Class::Schama/connection>
1644method and extracting a custom option from the provided \%attr hashref one can
1645then simply iterate over all the Schema's ResultSources, renaming them as
1646needed.
1647
1648To use this facility, simply add or modify the \%attr hashref that is passed to
1649L<connection|DBIx::Class::Schama/connect>, as follows:
1650
1651 my $schema
1652 = MyDatabase::Schema->connect(
1653 $dsn,
1654 $user,
1655 $pass,
1656 {
1657 schema_name_postfix => '_dev'
1658 # ... Other options as desired ...
1659 })
1660
1661Obviously, one could accomplish even more advanced mapping via a hash map or a
1662callback routine.
1663
1664=head1 txn_do でのトランザクション
1665
1666639As of version 0.04001, there is improved transaction support in
1667L<DBIx::Class::Storage> and L<DBIx::Class::Schema>. Here is an
640L<DBIx::Class::Storage::DBI> and L<DBIx::Class::Schema>. Here is an
1668641example of the recommended way to use it:
1669642
16706430.04001以降に、 L<DBIx::Class::Storage::DBI>とL<DBIx::Class::Schema>に、改良された
1671644トランザクションサポートがあります。これを使う推奨される方法の一例です:
1672645
1673646 my $genus = $schema->resultset('Genus')->find(12);
1674647
1675648 my $coderef2 = sub {
1676649 $genus->extinct(1);
1677650 $genus->update;
1678651 };
1679652
1680653 my $coderef1 = sub {
1681654 $genus->add_to_species({ name => 'troglodyte' });
1682655 $genus->wings(2);
1683656 $genus->update;
1684 $schema->txn_do($coderef2); # Can have a nested transaction. Only the outer will actualy commit
657 $schema->txn_do($coderef2); # Can have a nested transaction
1685658 return $genus->species;
1686659 };
1687660
1688 use Try::Tiny;
1689661 my $rs;
1690 try {
662 eval {
1691663 $rs = $schema->txn_do($coderef1);
1692 } catch {
664 };
1693 # Transaction failed
666 if ($@) { # Transaction failed
1694667 die "the sky is falling!" #
1695 if ($_ =~ /Rollback failed/); # Rollback failed
668 if ($@ =~ /Rollback failed/); # Rollback failed
1696669
1697670 deal_with_failed_transaction();
1698 };
671 }
1699672
1700Note: by default C<txn_do> will re-run the coderef one more time if an
1701error occurs due to client disconnection (e.g. the server is bounced).
1702You need to make sure that your coderef can be invoked multiple times
1703without terrible side effects.
1704
1705=begin original
1706
1707673Nested transactions will work as expected. That is, only the outermost
1708674transaction will actually issue a commit to the $dbh, and a rollback
1709675at any level of any transaction will cause the entire nested
1710transaction to fail.
676transaction to fail. Support for savepoints and for true nested
677transactions (for databases that support them) will hopefully be added
678in the future.
1711679
1712=end original
1713
1714680ネストされたトランザクションは期待どおりに動きます。
1715681一番外側のトランザクションだけが実際に$dbhにコミットを発行します。
1716682どのレベルのどのトランザクションでも、ロールバックしたら、
1717683ネストされたトランザクション全てが失敗します。
684セーブポイントと、本当にネストされたトランザクション
685(それをサポートしているデータベース用に)は、将来、うまくいけば、追加されるでしょう。
1718686
1719=head2 Nested transactions and auto-savepoints
687=head2 Many-to-many のリレーションシップ
1720688
1721If savepoints are supported by your RDBMS, it is possible to achieve true
689This is straightforward using L<ManyToMany|DBIx::Class::Relationship/many_to_many>:
1722nested transactions with minimal effort. To enable auto-savepoints via nested
690これは、単純にL<ManyToMany|DBIx::Class::Relationship/many_to_many>を使います:
1723transactions, supply the C<< auto_savepoint = 1 >> connection attribute.
1724691
1725Here is an example of true nested transactions. In the example, we start a big
692 package My::DB;
1726task which will create several rows. Generation of data for each row is a
693 # ... set up connection ...
1727fragile operation and might fail. If we fail creating something, depending on
1728the type of failure, we want to abort the whole task, or only skip the failed
1729row.
1730694
1731 my $schema = MySchema->connect("dbi:Pg:dbname=my_db");
695 package My::User;
696 use base 'My::DB';
697 __PACKAGE__->table('user');
698 __PACKAGE__->add_columns(qw/id name/);
699 __PACKAGE__->set_primary_key('id');
700 __PACKAGE__->has_many('user_address' => 'My::UserAddress', 'user');
701 __PACKAGE__->many_to_many('addresses' => 'user_address', 'address');
1732702
1733 # Start a transaction. Every database change from here on will only be
703 package My::UserAddress;
1734 # committed into the database if the try block succeeds.
704 use base 'My::DB';
1735 use Try::Tiny;
705 __PACKAGE__->table('user_address');
1736 my $exception;
706 __PACKAGE__->add_columns(qw/user address/);
1737 try {
707 __PACKAGE__->set_primary_key(qw/user address/);
1738 $schema->txn_do(sub {
708 __PACKAGE__->belongs_to('user' => 'My::User');
1739 # SQL: BEGIN WORK;
709 __PACKAGE__->belongs_to('address' => 'My::Address');
1740710
1741 my $job = $schema->resultset('Job')->create({ name=> 'big job' });
711 package My::Address;
1742 # SQL: INSERT INTO job ( name) VALUES ( 'big job' );
712 use base 'My::DB';
713 __PACKAGE__->table('address');
714 __PACKAGE__->add_columns(qw/id street town area_code country/);
715 __PACKAGE__->set_primary_key('id');
716 __PACKAGE__->has_many('user_address' => 'My::UserAddress', 'address');
717 __PACKAGE__->many_to_many('users' => 'user_address', 'user');
1743718
1744 for (1..10) {
719 $rs = $user->addresses(); # get all addresses for a user
720 $rs = $address->users(); # get all users for an address
1745721
1746 # Start a nested transaction, which in fact sets a savepoint.
722=head2 列のデフォルトの値を用意する
1747 try {
1748 $schema->txn_do(sub {
1749 # SQL: SAVEPOINT savepoint_0;
1750723
1751 my $thing = $schema->resultset('Thing')->create({ job=>$job->id });
724It's as simple as overriding the C<new> method. Note the use of
1752 # SQL: INSERT INTO thing ( job) VALUES ( 1 );
725C<next::method>.
1753726
1754 if (rand > 0.8) {
727単純に、C<new>メソッドをオーバーライドします。
1755 # This will generate an error, thus setting $@
728C<next::method>の使いかたに注意してください。
1756729
1757 $thing->update({force_fail=>'foo'});
730 sub new {
1758 # SQL: UPDATE thing SET force_fail = 'foo'
731 my ( $self, $attrs ) = @_;
1759 # WHERE ( id = 42 );
1760 }
1761 });
1762 } catch {
1763 # SQL: ROLLBACK TO SAVEPOINT savepoint_0;
1764732
1765 # There was an error while creating a $thing. Depending on the error
733 $attrs->{foo} = 'bar' unless defined $attrs->{foo};
1766 # we want to abort the whole transaction, or only rollback the
1767 # changes related to the creation of this $thing
1768734
1769 # Abort the whole job
735 $self->next::method($attrs);
1770 if ($_ =~ /horrible_problem/) {
1771 print "something horrible happend, aborting job!";
1772 die $_; # rethrow error
1773 }
1774736
1775 # Ignore this $thing, report the error, and continue with the
737 return $self;
1776 # next $thing
1777 print "Cannot create thing: $_";
1778 }
1779 # There was no error, so save all changes since the last
1780 # savepoint.
1781
1782 # SQL: RELEASE SAVEPOINT savepoint_0;
1783 }
1784 });
1785 } catch {
1786 $exception = $_;
1787738 }
1788739
1789 if ($caught) {
740For more information about C<next::method>, look in the L<Class::C3>
1790 # There was an error while handling the $job. Rollback all changes
741documentation. See also L<DBIx::Class::Manual::Component> for more
1791 # since the transaction started, including the already committed
742ways to write your own base classes to do this.
1792 # ('released') savepoints. There will be neither a new $job nor any
1793 # $thing entry in the database.
1794743
1795 # SQL: ROLLBACK;
744C<next::method>についてより詳しくは、L<Class::C3>のドキュメントを参照してください。
745これをするための、自分自身のベースクラスを書くための、より多くの方法については、
746L<DBIx::CLass::Manual::Component>を見てください。
1796747
1797 print "ERROR: $exception\n";
748People looking for ways to do "triggers" with DBIx::Class are probably
1798 }
749just looking for this.
1799 else {
1800 # There was no error while handling the $job. Commit all changes.
1801 # Only now other connections can see the newly created $job and
1802 # @things.
1803750
1804 # SQL: COMMIT;
751DBIx::Classで"triggers"をする方法を探している人も、これを探しているでしょう。
1805752
1806 print "Ok\n";
753=head2 Stringification
1807 }
1808754
1809In this example it might be hard to see where the rollbacks, releases and
755Employ the standard stringification technique by using the C<overload>
1810commits are happening, but it works just the same as for plain L<<txn_do>>: If
756module.
1811the C<try>-block around C<txn_do> fails, a rollback is issued. If the C<try>
1812succeeds, the transaction is committed (or the savepoint released).
1813757
1814While you can get more fine-grained control using C<svp_begin>, C<svp_release>
758C<overload> モジュールで標準的な文字列化のテクニックを使えます。
1815and C<svp_rollback>, it is strongly recommended to use C<txn_do> with coderefs.
1816759
1817=head2 Simple Transactions with DBIx::Class::Storage::TxnScopeGuard
760To make an object stringify itself as a single column, use something
761like this (replace C<foo> with the column/method of your choice):
1818762
1819An easy way to use transactions is with
763ひとつのカラムについて、オブジェクト自身を文字列化するには、
1820L<DBIx::Class::Storage::TxnScopeGuard>. See L</Automatically creating
764次のようにします。(カラム/メソッドでC<foo>を置き換えてください)
1821related objects> for an example.
1822765
1823Note that unlike txn_do, TxnScopeGuard will only make sure the connection is
766 use overload '""' => sub { shift->name}, fallback => 1;
1824alive when issuing the C<BEGIN> statement. It will not (and really can not)
1825retry if the server goes away mid-operations, unlike C<txn_do>.
1826767
1827=head1 SQL
768For more complex stringification, you can use an anonymous subroutine:
1828769
1829=head2 Creating Schemas From An Existing Database
770より複雑な文字列化では、無名サブルーチンを使えます:
1830771
1831L<DBIx::Class::Schema::Loader> will connect to a database and create a
772 use overload '""' => sub { $_[0]->name . ", " .
1832L<DBIx::Class::Schema> and associated sources by examining the database.
773 $_[0]->address }, fallback => 1;
1833774
1834The recommend way of achieving this is to use the
775=head3 文字列化の例
1835L<make_schema_at|DBIx::Class::Schema::Loader/make_schema_at> method:
1836776
1837 perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib \
777Suppose we have two tables: C<Product> and C<Category>. The table
1838 -e 'make_schema_at("My::Schema", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])'
778specifications are:
1839779
1840This will create a tree of files rooted at C<./lib/My/Schema/> containing
780二つのテーブルがあるとします:C<Product>とC<Cateogry>。
1841source definitions for all the tables found in the C<foo> database.
781テーブルの定義は次の通り:
1842782
1843=head2 Creating DDL SQL
783 Product(id, Description, category)
784 Category(id, Description)
1844785
1845The following functionality requires you to have L<SQL::Translator>
786C<category> is a foreign key into the Category table.
1846(also known as "SQL Fairy") installed.
1847787
1848To create a set of database-specific .sql files for the above schema:
788C<category>はCategoryテーブルの外部キーです。
1849789
1850 my $schema = My::Schema->connect($dsn);
790If you have a Product object C<$obj> and write something like
1851 $schema->create_ddl_dir(['MySQL', 'SQLite', 'PostgreSQL'],
1852 '0.1',
1853 './dbscriptdir/'
1854 );
1855791
1856By default this will create schema files in the current directory, for
792ProductオブジェクトC<$obj>があり、次のように書いたとすると、
1857MySQL, SQLite and PostgreSQL, using the $VERSION from your Schema.pm.
1858793
1859To create a new database using the schema:
794 print $obj->category
1860795
1861 my $schema = My::Schema->connect($dsn);
796things will not work as expected.
1862 $schema->deploy({ add_drop_table => 1});
1863797
1864To import created .sql files using the mysql client:
798期待どおりには動きません。
1865799
1866 mysql -h "host" -D "database" -u "user" -p < My_Schema_1.0_MySQL.sql
800To obtain, for example, the category description, you should add this
801method to the class defining the Category table:
1867802
1868To create C<ALTER TABLE> conversion scripts to update a database to a
803カテゴリの内容を得たいなら、例えば、Categoryテーブルのクラス定義に次の
1869newer version of your schema at a later point, first set a new
804メソッドを追加すべきです:
1870C<$VERSION> in your Schema file, then:
1871805
1872 my $schema = My::Schema->connect($dsn);
806 use overload "" => sub {
1873 $schema->create_ddl_dir(['MySQL', 'SQLite', 'PostgreSQL'],
807 my $self = shift;
1874 '0.2',
1875 '/dbscriptdir/',
1876 '0.1'
1877 );
1878808
1879This will produce new database-specific .sql files for the new version
809 return $self->Description;
1880of the schema, plus scripts to convert from version 0.1 to 0.2. This
810 }, fallback => 1;
1881requires that the files for 0.1 as created above are available in the
1882given directory to diff against.
1883811
1884=head2 Select from dual
812=head2 きれいに切断
1885813
1886Dummy tables are needed by some databases to allow calling functions
814If you find yourself quitting an app with Control-C a lot during
1887or expressions that aren't based on table content, for examples of how
815development, you might like to put the following signal handler in
1888this applies to various database types, see:
816your main database class to make sure it disconnects cleanly:
1889L<http://troels.arvin.dk/db/rdbms/#other-dummy_table>.
1890817
1891Note: If you're using Oracles dual table don't B<ever> do anything
818開発中に、Cotrol-Cを多用して、アプリケーションを終了させることが
1892other than a select, if you CRUD on your dual table you *will* break
819多いなら、下記のようなシグナルハンドラーをデータベースクラスに置いて、
1893your database.
820確実にきれいに切断したいかもしれません:
1894821
1895Make a table class as you would for any other table
822 $SIG{INT} = sub {
823 __PACKAGE__->storage->disconnect;
824 };
1896825
1897 package MyAppDB::Dual;
826=head2 スキーマのインポート/エクスポート
1898 use strict;
1899 use warnings;
1900 use base 'DBIx::Class::Core';
1901 __PACKAGE__->table("Dual");
1902 __PACKAGE__->add_columns(
1903 "dummy",
1904 { data_type => "VARCHAR2", is_nullable => 0, size => 1 },
1905 );
1906827
1907Once you've loaded your table class select from it using C<select>
828This functionality requires you to have L<SQL::Translator> (also known as
1908and C<as> instead of C<columns>
829"SQL Fairy") installed.
1909830
1910 my $rs = $schema->resultset('Dual')->search(undef,
831この機能を使うには、L<SQL::Translator>("SQL Fairy"とも知られる)を
1911 { select => [ 'sydate' ],
832インストールする必要があります。
1912 as => [ 'now' ]
1913 },
1914 );
1915833
1916All you have to do now is be careful how you access your resultset, the below
834To create a DBIx::Class schema from an existing database:
1917will not work because there is no column called 'now' in the Dual table class
1918835
1919 while (my $dual = $rs->next) {
836DBIx::Classスキーマを既存のデータベースから作ります:
1920 print $dual->now."\n";
1921 }
1922 # Can't locate object method "now" via package "MyAppDB::Dual" at headshot.pl line 23.
1923837
1924You could of course use 'dummy' in C<as> instead of 'now', or C<add_columns> to
838 sqlt --from DBI
1925your Dual class for whatever you wanted to select from dual, but that's just
839 --to DBIx::Class::File
1926silly, instead use C<get_column>
840 --prefix "MySchema" > MySchema.pm
1927841
1928 while (my $dual = $rs->next) {
842To create a MySQL database from an existing L<DBIx::Class> schema, convert the
1929 print $dual->get_column('now')."\n";
843schema to MySQL's dialect of SQL:
1930 }
1931844
1932Or use C<cursor>
845MySQLデータベースを既存のL<DBIx::Class>スキーマから作ります。
846スキーマをMySQLのSQL方言に変換します:
1933847
1934 my $cursor = $rs->cursor;
848 sqlt --from SQL::Translator::Parser::DBIx::Class
1935 while (my @vals = $cursor->next) {
849 --to MySQL
1936 print $vals[0]."\n";
850 --DBIx::Class "MySchema.pm" > Schema1.sql
1937 }
851
852And import using the mysql client:
1938853
1939In case you're going to use this "trick" together with L<DBIx::Class::Schema/deploy> or
854mysqlクライアントでimportします:
1940L<DBIx::Class::Schema/create_ddl_dir> a table called "dual" will be created in your
1941current schema. This would overlap "sys.dual" and you could not fetch "sysdate" or
1942"sequence.nextval" anymore from dual. To avoid this problem, just tell
1943L<SQL::Translator> to not create table dual:
1944855
1945 my $sqlt_args = {
856 mysql -h "host" -D "database" -u "user" -p < Schema1.sql
1946 add_drop_table => 1,
1947 parser_args => { sources => [ grep $_ ne 'Dual', schema->sources ] },
1948 };
1949 $schema->create_ddl_dir( [qw/Oracle/], undef, './sql', undef, $sqlt_args );
1950857
1951Or use L<DBIx::Class::ResultClass::HashRefInflator>
858=head2 クラスベースからスキーマベースセットアップへの簡単な移行
1952859
1953 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
860You want to start using the schema-based approach to L<DBIx::Class>
1954 while ( my $dual = $rs->next ) {
861(see L<SchemaIntro.pod>), but have an established class-based setup with lots
1955 print $dual->{now}."\n";
862of existing classes that you don't want to move by hand. Try this nifty script
1956 }
863instead:
1957864
1958Here are some example C<select> conditions to illustrate the different syntax
865L<DBIx::Class>へのスキーマベースのアプローチを使いたい(L<SchemaIntro.pod>をみてください)、
1959you could use for doing stuff like
866でも、既存の大量のクラスで、従来のクラスベースのセットアップがあり、
1960C<oracles.heavily(nested(functions_can('take', 'lots'), OF), 'args')>
867手でそれらを動かしたくはないとします。手で動かす変わりに、下記の気の利いたスクリプトを
868試してみて下さい:
1961869
1962 # get a sequence value
1963 select => [ 'A_SEQ.nextval' ],
1964870
1965 # get create table sql
871 use MyDB;
1966 select => [ { 'dbms_metadata.get_ddl' => [ "'TABLE'", "'ARTIST'" ]} ],
872 use SQL::Translator;
873
874 my $schema = MyDB->schema_instance;
875
876 my $translator = SQL::Translator->new(
877 debug => $debug || 0,
878 trace => $trace || 0,
879 no_comments => $no_comments || 0,
880 show_warnings => $show_warnings || 0,
881 add_drop_table => $add_drop_table || 0,
882 validate => $validate || 0,
883 parser_args => {
884 'DBIx::Schema' => $schema,
885 },
886 producer_args => {
887 'prefix' => 'My::Schema',
888 },
889 );
890
891 $translator->parser('SQL::Translator::Parser::DBIx::Class');
892 $translator->producer('SQL::Translator::Producer::DBIx::Class::File');
893
894 my $output = $translator->translate(@args) or die
895 "Error: " . $translator->error;
896
897 print $output;
1967898
1968 # get a random num between 0 and 100
899You could use L<Module::Find> to search for all subclasses in the MyDB::*
1969 select => [ { "trunc" => [ { "dbms_random.value" => [0,100] } ]} ],
900namespace, which is currently left as an exercise for the reader.
1970901
1971 # what year is it?
902L<Module::Find>を使って、MyDB::*名前空間にある全てのサブクラスを探すことが出来ますが、
1972 select => [ { 'extract' => [ \'year from sysdate' ] } ],
903これは、今のところ、読者への課題としておきます。
1973904
1974 # do some math
1975 select => [ {'round' => [{'cos' => [ \'180 * 3.14159265359/180' ]}]}],
1976905
1977 # which day of the week were you born on?
1978 select => [{'to_char' => [{'to_date' => [ "'25-DEC-1980'", "'dd-mon-yyyy'" ]}, "'day'"]}],
1979
1980 # select 16 rows from dual
1981 select => [ "'hello'" ],
1982 as => [ 'world' ],
1983 group_by => [ 'cube( 1, 2, 3, 4 )' ],
1984
1985
1986
1987=head2 Adding Indexes And Functions To Your SQL
1988
1989Often you will want indexes on columns on your table to speed up searching. To
1990do this, create a method called C<sqlt_deploy_hook> in the relevant source
1991class (refer to the advanced
1992L<callback system|DBIx::Class::ResultSource/sqlt_deploy_callback> if you wish
1993to share a hook between multiple sources):
1994
1995 package My::Schema::Result::Artist;
1996
1997 __PACKAGE__->table('artist');
1998 __PACKAGE__->add_columns(id => { ... }, name => { ... })
1999
2000 sub sqlt_deploy_hook {
2001 my ($self, $sqlt_table) = @_;
2002
2003 $sqlt_table->add_index(name => 'idx_name', fields => ['name']);
2004 }
2005
2006 1;
2007
2008Sometimes you might want to change the index depending on the type of the
2009database for which SQL is being generated:
2010
2011 my ($db_type = $sqlt_table->schema->translator->producer_type)
2012 =~ s/^SQL::Translator::Producer:://;
2013
2014You can also add hooks to the schema level to stop certain tables being
2015created:
2016
2017 package My::Schema;
2018
2019 ...
2020
2021 sub sqlt_deploy_hook {
2022 my ($self, $sqlt_schema) = @_;
2023
2024 $sqlt_schema->drop_table('table_name');
2025 }
2026
2027You could also add views, procedures or triggers to the output using
2028L<SQL::Translator::Schema/add_view>,
2029L<SQL::Translator::Schema/add_procedure> or
2030L<SQL::Translator::Schema/add_trigger>.
2031
2032
2033906=head2 スキーマのバージョニング
2034907
2035=begin original
2036
2037908The following example shows simplistically how you might use DBIx::Class to
2038909deploy versioned schemas to your customers. The basic process is as follows:
2039910
2040=end original
2041
2042911下記の例では、DBIx::Classを使って、顧客向けにバージョン付きのスキーマをどうやって
2043912デプロイするかをお見せします。基本的なプロセスは下記のようになります:
2044913
2045914=over 4
2046915
2047916=item 1.
2048917
2049=begin original
2050
2051918Create a DBIx::Class schema
2052919
2053=end original
2054
2055920DBIx::Classスキーマを作ります
2056921
2057922=item 2.
2058923
2059=begin original
2060
2061924Save the schema
2062925
2063=end original
2064
2065926スキーマを保存します
2066927
2067928=item 3.
2068929
2069=begin original
2070
2071930Deploy to customers
2072931
2073=end original
2074
2075932顧客にデプロイします
2076933
2077934=item 4.
2078935
2079=begin original
2080
2081936Modify schema to change functionality
2082937
2083=end original
2084
2085938スキーマを変更して、 functionality を変更します
2086939
2087940=item 5.
2088941
2089=begin original
2090
2091942Deploy update to customers
2092943
2093=end original
2094
2095944顧客に更新をデプロイします
2096945
2097946=back
2098947
2099=begin original
948=head3 DBIx::Calssスキーマを作る
2100949
2101B<Create a DBIx::Class schema>
2102
2103=end original
2104
2105B<DBIx::Calssスキーマを作る>
2106
2107=begin original
2108
2109950This can either be done manually, or generated from an existing database as
2110described under L</Creating Schemas From An Existing Database>
951described under C<Schema import/export>.
2111952
2112=end original
953これは、手で行うことも、C<Schema import/export>で説明しますが、
2113
2114これは、手で行うことも、C<既存のデータベースからスキーマを作る>で説明しますが、
2115954既存のデータベースから生成することもできます。
2116955
2117=begin original
956=head3 スキーマを保存する
2118957
2119B<Save the schema>
958Use C<sqlt> to transform your schema into an SQL script suitable for your
959customer's database. E.g. for MySQL:
2120960
2121=end original
961C<sqlt>を使って、スキーマを変換して、顧客のデータベース(例えば、MySQL)に合った、
962SQLスクリプトにします。
2122963
2123B<スキーマを保存する>
964 sqlt --from SQL::Translator::Parser::DBIx::Class
965 --to MySQL
966 --DBIx::Class "MySchema.pm" > Schema1.mysql.sql
2124967
2125Call L<DBIx::Class::Schema/create_ddl_dir> as above under L</Creating DDL SQL>.
968If you need to target databases from multiple vendors, just generate an SQL
969script suitable for each. To support PostgreSQL too:
2126970
2127=begin original
971複数のベンダからデーベースをターゲットにしなければならないなら、
972それぞれに合ったSQLスクリプトを生成するだけです。PostgreSQLもサポートしています:
2128973
2129B<Deploy to customers>
974 sqlt --from SQL::Translator::DBIx::Class
975 --to PostgreSQL
976 --DBIx::Class "MySchema.pm" > Schema1.pgsql.sql
2130977
2131=end original
978=head3 顧客にデプロイする
2132979
2133B<顧客にデプロイする>
2134
2135=begin original
2136
2137980There are several ways you could deploy your schema. These are probably
2138981beyond the scope of this recipe, but might include:
2139982
2140=end original
2141
2142983スキーマをデプロイするのには複数の方法があります。
2143984このレシピの範疇を越えそうですが、含めておきます:
2144985
2145986=over 4
2146987
2147988=item 1.
2148989
2149=begin original
2150
2151990Require customer to apply manually using their RDBMS.
2152991
2153=end original
2154
2155992顧客にRDBMSを使って、手で適用するように求める
2156993
2157994=item 2.
2158995
2159=begin original
2160
2161996Package along with your app, making database dump/schema update/tests
2162997all part of your install.
2163998
2164=end original
2165
2166999アプリケーションと一緒に、データベースのダンプ、スキーマのアップデート、
21671000インストールの全パートのテストを作るように、パッケージする
21681001
21691002=back
21701003
2171=begin original
1004=head3 機能性を変更するために、スキーマを変更する
21721005
2173B<Modify the schema to change functionality>
1006As your application evolves, it may be necessary to modify your schema to
1007change functionality. Once the changes are made to your schema in DBIx::Class,
1008export the modified schema as before, taking care not to overwrite the original:
21741009
2175=end original
1010アプリケーションが進化するにつれ、機能性を変更するために、スキーマを修正する必要があるでしょう。
1011DBIx::Classでスキーマを変更したら、以前のように修正されたスキーマをエクスポートします。
1012オリジナルのスキーマを上書きしないように気を付けましょう:
21761013
2177B<機能性を変更するために、スキーマを変更する>
1014 sqlt --from SQL::Translator::DBIx::Class
1015 --to MySQL
1016 --DBIx::Class "Anything.pm" > Schema2.mysql.sql
21781017
2179=begin original
1018Next, use sqlt-diff to create an SQL script that will update the customer's
1019database schema:
21801020
2181As your application evolves, it may be necessary to modify your schema
1021次に、sqlt-diffを使って、顧客のデータベーススキーマを更新するSQLスクリプトを作ります:
2182to change functionality. Once the changes are made to your schema in
2183DBIx::Class, export the modified schema and the conversion scripts as
2184in L</Creating DDL SQL>.
21851022
2186=end original
1023 sqlt-diff --to MySQL Schema1=MySQL Schema2=MySQL > SchemaUpdate.mysql.sql
21871024
2188アプリケーションが進化するつれ、機能性を変するために、スキーマ修正する必要があるでょう。
1025=head3 顧客に更デプロイます
2189DBIx::Classでスキーマを変更したら、以前のように修正されたスキーマをエクスポートし、
2190L</Creating DDL SQL>にあるような変換スクリプトを使います
21911026
2192B<Deploy update to customers>
1027The schema update can be deployed to customers using the same method as before.
21931028
2194B<顧客に更新をデプロイます>
1029スキーマの更新は以前と同じようにして、顧客にデプロイされます
21951030
2196Add the L<DBIx::Class::Schema::Versioned> schema component to your
1031=head2 SQL::Abstract::Limit のために、リミットの方言を設定する
2197Schema class. This will add a new table to your database called
2198C<dbix_class_schema_vesion> which will keep track of which version is installed
2199and warn if the user tries to run a newer schema version than the
2200database thinks it has.
22011032
2202Alternatively, you can send the conversion SQL scripts to your
1033In some cases, SQL::Abstract::Limit cannot determine the dialect of
2203customers as above.
1034the remote SQL server by looking at the database handle. This is a
1035common problem when using the DBD::JDBC, since the DBD-driver only
1036know that in has a Java-driver available, not which JDBC driver the
1037Java component has loaded. This specifically sets the limit_dialect
1038to Microsoft SQL-server (See more names in SQL::Abstract::Limit
1039-documentation.
22041040
2205=head2 生成されたSQLをクォトす
1041時には、SQL::Abstract::Limit はデタベースハンドルで見ていことで、
1042リモートのSQLサーバの方言を決めれられない場合があります。
1043これは、DBD::JDBCを使っているときの、よく知られた問題です。
1044DBD-driver は Java-driver が利用できることを知っているだけで、
1045どのJDBCドライバをJavaコンポーネントがロードしているかを知らないからです。
1046具体的に、Microsoft SQL-server のlimitの方言をセットします
1047(SQL::Abstract::Limitのドキュメントには、より多くの名前があります)。
22061048
2207=begin original
1049 __PACKAGE__->storage->sql_maker->limit_dialect('mssql');
22081050
1051The JDBC bridge is one way of getting access to a MSSQL server from a platform
1052that Microsoft doesn't deliver native client libraries for. (e.g. Linux)
1053
1054JDBCブリッジはMicrosoftがネイティブのクライアントライブラリを配布していない
1055プラットフォーム(例えば、Linux)からMSSQLサーバへアクセスする1つの方法です。
1056
1057=head2 生成されたSQLをクォートする
1058
22091059If the database contains column names with spaces and/or reserved words, they
22101060need to be quoted in the SQL queries. This is done using:
22111061
2212=end original
2213
22141062データベースにスペースおよび/または予約語のついたカラム名がある場合、
22151063SQLクエリ内で、クォートされる必要があります。次のようにします:
22161064
2217 $schema->storage->sql_maker->quote_char([ qw/[ ]/] );
1065 __PACKAGE__->storage->sql_maker->quote_char([ qw/[ ]/] );
2218 $schema->storage->sql_maker->name_sep('.');
1066 __PACKAGE__->storage->sql_maker->name_sep('.');
22191067
2220=begin original
2221
22221068The first sets the quote characters. Either a pair of matching
22231069brackets, or a C<"> or C<'>:
22241070
2225=end original
2226
222710711行目は、クォート文字をセットしています。ブラケットのペアか、C<">, C<'>です。
22281072
2229 $schema->storage->sql_maker->quote_char('"');
1073 __PACKAGE__->storage->sql_maker->quote_char('"');
22301074
2231=begin original
2232
22331075Check the documentation of your database for the correct quote
22341076characters to use. C<name_sep> needs to be set to allow the SQL
2235generator to put the quotes the correct place, and defaults to
1077generator to put the quotes the correct place.
2236C<.> if not supplied.
22371078
2238=end original
2239
22401079正しいクォート文字を使うために、データベースのドキュメントをチェックしてください。
22411080C<name_sep>は、SQLジェネレーターが正しい場所にクォートを置くために、
2242セットしなければいけません。デフォルトではC<.>になります。
1081セットしなければいけません。
22431082
2244In most cases you should set these as part of the arguments passed to
1083=head2 メソッドのオーバーロード
2245L<DBIx::Class::Schema/connect>:
22461084
2247 my $schema = My::Schema->connect(
1085L<DBIx::Class> uses the L<Class::C3> package, which provides for redispatch of
2248 'dbi:mysql:my_db',
1086method calls. You have to use calls to C<next::method> to overload methods.
2249 'db_user',
1087More information on using L<Class::C3> with L<DBIx::Class> can be found in
2250 'db_password',
2251 {
2252 quote_char => '"',
2253 name_sep => '.'
2254 }
2255 )
2256
2257In some cases, quoting will be required for all users of a schema. To enforce
2258this, you can also overload the C<connection> method for your schema class:
2259
2260 sub connection {
2261 my $self = shift;
2262 my $rv = $self->next::method( @_ );
2263 $rv->storage->sql_maker->quote_char([ qw/[ ]/ ]);
2264 $rv->storage->sql_maker->name_sep('.');
2265 return $rv;
2266 }
2267
2268=head2 Working with PostgreSQL array types
2269
2270You can also assign values to PostgreSQL array columns by passing array
2271references in the C<\%columns> (C<\%vals>) hashref of the
2272L<DBIx::Class::ResultSet/create> and L<DBIx::Class::Row/update> family of
2273methods:
2274
2275 $resultset->create({
2276 numbers => [1, 2, 3]
2277 });
2278
2279 $row->update(
2280 {
2281 numbers => [1, 2, 3]
2282 },
2283 {
2284 day => '2008-11-24'
2285 }
2286 );
2287
2288In conditions (e.g. C<\%cond> in the L<DBIx::Class::ResultSet/search> family of
2289methods) you cannot directly use array references (since this is interpreted as
2290a list of values to be C<OR>ed), but you can use the following syntax to force
2291passing them as bind values:
2292
2293 $resultset->search(
2294 {
2295 numbers => \[ '= ?', [numbers => [1, 2, 3]] ]
2296 }
2297 );
2298
2299See L<SQL::Abstract/array_datatypes> and L<SQL::Abstract/Literal SQL with
2300placeholders and bind values (subqueries)> for more explanation. Note that
2301L<DBIx::Class> sets L<SQL::Abstract/bindtype> to C<columns>, so you must pass
2302the bind values (the C<[1, 2, 3]> arrayref in the above example) wrapped in
2303arrayrefs together with the column name, like this:
2304C<< [column_name => value] >>.
2305
2306=head2 Formatting DateTime objects in queries
2307
2308To ensure C<WHERE> conditions containing L<DateTime> arguments are properly
2309formatted to be understood by your RDBMS, you must use the C<DateTime>
2310formatter returned by L<DBIx::Class::Storage::DBI/datetime_parser> to format
2311any L<DateTime> objects you pass to L<search|DBIx::Class::ResultSet/search>
2312conditions. Any L<Storage|DBIx::Class::Storage> object attached to your
2313L<Schema|DBIx::Class::Schema> provides a correct C<DateTime> formatter, so
2314all you have to do is:
2315
2316 my $dtf = $schema->storage->datetime_parser;
2317 my $rs = $schema->resultset('users')->search(
2318 {
2319 signup_date => {
2320 -between => [
2321 $dtf->format_datetime($dt_start),
2322 $dtf->format_datetime($dt_end),
2323 ],
2324 }
2325 },
2326 );
2327
2328Without doing this the query will contain the simple stringification of the
2329C<DateTime> object, which almost never matches the RDBMS expectations.
2330
2331This kludge is necessary only for conditions passed to
2332L<DBIx::Class::ResultSet/search>, whereas
2333L<create|DBIx::Class::ResultSet/create>,
2334L<find|DBIx::Class::ResultSet/find>,
2335L<DBIx::Class::Row/update> (but not L<DBIx::Class::ResultSet/update>) are all
2336L<DBIx::Class::InflateColumn>-aware and will do the right thing when supplied
2337an inflated C<DateTime> object.
2338
2339=head2 Using Unicode
2340
2341When using unicode character data there are two alternatives -
2342either your database supports unicode characters (including setting
2343the utf8 flag on the returned string), or you need to encode/decode
2344data appropriately each time a string field is inserted into or
2345retrieved from the database. It is better to avoid
2346encoding/decoding data and to use your database's own unicode
2347capabilities if at all possible.
2348
2349The L<DBIx::Class::UTF8Columns> component handles storing selected
2350unicode columns in a database that does not directly support
2351unicode. If used with a database that does correctly handle unicode
2352then strange and unexpected data corrupt B<will> occur.
2353
2354The Catalyst Wiki Unicode page at
2355L<http://wiki.catalystframework.org/wiki/tutorialsandhowtos/using_unicode>
2356has additional information on the use of Unicode with Catalyst and
2357DBIx::Class.
2358
2359The following databases do correctly handle unicode data:-
2360
2361=head3 MySQL
2362
2363MySQL supports unicode, and will correctly flag utf8 data from the
2364database if the C<mysql_enable_utf8> is set in the connect options.
2365
2366 my $schema = My::Schema->connection('dbi:mysql:dbname=test',
2367 $user, $pass,
2368 { mysql_enable_utf8 => 1} );
2369
2370
2371When set, a data retrieved from a textual column type (char,
2372varchar, etc) will have the UTF-8 flag turned on if necessary. This
2373enables character semantics on that string. You will also need to
2374ensure that your database / table / column is configured to use
2375UTF8. See Chapter 10 of the mysql manual for details.
2376
2377See L<DBD::mysql> for further details.
2378
2379=head3 Oracle
2380
2381Information about Oracle support for unicode can be found in
2382L<DBD::Oracle/Unicode>.
2383
2384=head3 PostgreSQL
2385
2386PostgreSQL supports unicode if the character set is correctly set
2387at database creation time. Additionally the C<pg_enable_utf8>
2388should be set to ensure unicode data is correctly marked.
2389
2390 my $schema = My::Schema->connection('dbi:Pg:dbname=test',
2391 $user, $pass,
2392 { pg_enable_utf8 => 1} );
2393
2394Further information can be found in L<DBD::Pg>.
2395
2396=head3 SQLite
2397
2398SQLite version 3 and above natively use unicode internally. To
2399correctly mark unicode strings taken from the database, the
2400C<sqlite_unicode> flag should be set at connect time (in versions
2401of L<DBD::SQLite> prior to 1.27 this attribute was named
2402C<unicode>).
2403
2404 my $schema = My::Schema->connection('dbi:SQLite:/tmp/test.db',
2405 '', '',
2406 { sqlite_unicode => 1} );
2407
2408=head1 BOOTSTRAPPING/MIGRATING
2409
2410=head2 クラスベースからスキーマベースセットアップへの簡単な移行
2411
2412=begin original
2413
2414You want to start using the schema-based approach to L<DBIx::Class>
2415(see L<DBIx::Class::Manual::Intro/Setting it up manually>), but have an
2416established class-based setup with lots of existing classes that you don't
2417want to move by hand. Try this nifty script instead:
2418
2419=end original
2420
2421L<DBIx::Class>へのスキーマベースのアプローチを使いたい(L<SchemaIntro.pod>をみてください)、
2422でも、既存の大量のクラスで、従来のクラスベースのセットアップがあり、
2423手でそれらを動かしたくはないとします。手で動かす変わりに、下記の気の利いたスクリプトを
2424試してみて下さい:
2425
2426 use MyDB;
2427 use SQL::Translator;
2428
2429 my $schema = MyDB->schema_instance;
2430
2431 my $translator = SQL::Translator->new(
2432 debug => $debug || 0,
2433 trace => $trace || 0,
2434 no_comments => $no_comments || 0,
2435 show_warnings => $show_warnings || 0,
2436 add_drop_table => $add_drop_table || 0,
2437 validate => $validate || 0,
2438 parser_args => {
2439 'DBIx::Schema' => $schema,
2440 },
2441 producer_args => {
2442 'prefix' => 'My::Schema',
2443 },
2444 );
2445
2446 $translator->parser('SQL::Translator::Parser::DBIx::Class');
2447 $translator->producer('SQL::Translator::Producer::DBIx::Class::File');
2448
2449 my $output = $translator->translate(@args) or die
2450 "Error: " . $translator->error;
2451
2452 print $output;
2453
2454=begin original
2455
2456You could use L<Module::Find> to search for all subclasses in the MyDB::*
2457namespace, which is currently left as an exercise for the reader.
2458
2459=end original
2460
2461L<Module::Find>を使って、MyDB::*名前空間にある全てのサブクラスを探すことが出来ますが、
2462これは、今のところ、読者への課題としておきます。
2463
2464=head1 メソッドのオーバーロード
2465
2466=begin original
2467
2468L<DBIx::Class> uses the L<Class::C3> package, which provides for redispatch of
2469method calls, useful for things like default values and triggers. You have to
2470use calls to C<next::method> to overload methods. More information on using
2471L<Class::C3> with L<DBIx::Class> can be found in
24721088L<DBIx::Class::Manual::Component>.
24731089
2474=end original
2475
24761090L<DBIx::Class>はL<Class::C3>パッケージを使っています。L<Class::C3>はメソッドコールを
24771091再分岐させるために使われています。メソッドをオーバーロードするために、
24781092C<next::method>の呼び出しを使わなければいけません。
24791093L<DBIx::Class>とL<Class::C3>の利用に関する詳しい情報は、
24801094L<DBIx::Class::Manual::Component>を見てください。
24811095
2482=head2 列のデフォルトの値を用意する
2483
2484=begin original
2485
2486It's as simple as overriding the C<new> method. Note the use of
2487C<next::method>.
2488
2489=end original
2490
2491単純に、C<new>メソッドをオーバーライドします。
2492C<next::method>の使いかたに注意してください。
2493
2494 sub new {
2495 my ( $class, $attrs ) = @_;
2496
2497 $attrs->{foo} = 'bar' unless defined $attrs->{foo};
2498
2499 my $new = $class->next::method($attrs);
2500
2501 return $new;
2502 }
2503
2504=begin original
2505
2506For more information about C<next::method>, look in the L<Class::C3>
2507documentation. See also L<DBIx::Class::Manual::Component> for more
2508ways to write your own base classes to do this.
2509
2510=end original
2511
2512C<next::method>についてより詳しくは、L<Class::C3>のドキュメントを参照してください。
2513これをするための、自分自身のベースクラスを書くための、より多くの方法については、
2514L<DBIx::CLass::Manual::Component>を見てください。
2515
2516=begin original
2517
2518People looking for ways to do "triggers" with DBIx::Class are probably
2519just looking for this.
2520
2521=end original
2522
2523DBIx::Classで"triggers"をする方法を探している人も、これを探しているでしょう。
2524
25251096=head3 他が変更されたらいつでもあるフィールドを変更する
25261097
2527=begin original
1098For example, say that you have three columns, C<id>, C<number>, and
2528
2529For example, say that you have three columns, C<id>, C<number>, and
25301099C<squared>. You would like to make changes to C<number> and have
25311100C<squared> be automagically set to the value of C<number> squared.
2532You can accomplish this by wrapping the C<number> accessor with
1101You can accomplish this by overriding C<store_column>:
2533L<Class::Method::Modifiers>:
25341102
2535=end original
2536
25371103例えば、3つのカラムがあったとします。C<id>、C<number>、C<squared>。
25381104C<number>に変更を加え、C<squared>は自動的に、C<number>の二乗の値を
2539セットしたいとします。C<number>アクセサをL<Class::Method::Modifiers>で
1105セットしたいとします。C<store_column>をオーバーロードすること
2540ラップすることで、これができます:
1106これができます:
25411107
2542 around number => sub {
1108 sub store_column {
2543 my ($orig, $self) = (shift, shift);
1109 my ( $self, $name, $value ) = @_;
1110 if ($name eq 'number') {
2545 if (@_) {
1111 $self->squared($value * $value);
2546 my $value = $_[0];
2547 $self->squared( $value * $value );
25481112 }
1113 $self->next::method($name, $value);
2550 $self->next::method(@_);
25511114 }
25521115
2553=begin original
2554
25551116Note that the hard work is done by the call to C<next::method>, which
25561117redispatches your call to store_column in the superclass(es).
25571118
2558=end original
2559
25601119C<next::method>を呼び出すことで、大変な仕事がされていることに注意しましょう。
25611120呼び出しが、(複数の)スーパークラスのstore_columnに再分岐されてます:
25621121
2563Generally, if this is a calculation your database can easily do, try
1122=head3 関連するオブジェクトを自動的に作る
2564and avoid storing the calculated value, it is safer to calculate when
2565needed, than rely on the data being in sync.
25661123
2567=head2 関連するオブジェクトを自動的に作る
1124You might have a class C<Artist> which has many C<CD>s. Further, if you
2568
2569=begin original
2570
2571You might have a class C<Artist> which has many C<CD>s. Further, you
25721125want to create a C<CD> object every time you insert an C<Artist> object.
25731126You can accomplish this by overriding C<insert> on your objects:
25741127
2575=end original
2576
25771128多くのC<CD>を持ったC<Artist>クラスがあるとします。
25781129さらに、C<Artist>オブジェクトをインサートする度毎にC<CD>オブジェクトを
25791130作りたいとします。これは、オブジェクトのC<insert>をオーバロードすればできます:
25801131
25811132 sub insert {
25821133 my ( $self, @args ) = @_;
25831134 $self->next::method(@args);
2584 $self->create_related ('cds', \%initial_cd_data );
1135 $self->cds->new({})->fill_from_artist($self)->insert;
25851136 return $self;
25861137 }
25871138
2588If you want to wrap the two inserts in a transaction (for consistency,
1139where C<fill_from_artist> is a method you specify in C<CD> which sets
2589an excellent idea), you can use the awesome
1140values in C<CD> based on the data in the C<Artist> object you pass in.
2590L<DBIx::Class::Storage::TxnScopeGuard>:
25911141
2592 sub insert {
1142C<fill_from_artist>はC<CD>で指定しているメソッドで、
2593 my ( $self, @args ) = @_;
1143渡したC<Artist>オブジェクトのデータに基づいた値をCDにセットします。
25941144
2595 my $guard = $self->result_source->schema->txn_scope_guard;
1145=head2 Data::Dumperを使って、DBIx::Classをデバッグする
25961146
2597 $self->next::method(@args);
2598 $self->create_related ('cds', \%initial_cd_data );
2599
2600 $guard->commit;
2601
2602 return $self
2603 }
2604
2605=head2 カラムのアクセサをラッピング/オーバーロードする
2606
2607B<Problem:>
2608
2609B<問題:>
2610
2611=begin original
2612
2613Say you have a table "Camera" and want to associate a description
2614with each camera. For most cameras, you'll be able to generate the description from
2615the other columns. However, in a few special cases you may want to associate a
2616custom description with a camera.
2617
2618=end original
2619
2620 "Camera"テーブルがあったとして、それぞれのカメラについて、
2621説明を関連付けたいとします。ほとんどのカメラでは、他のカラムから説明を生成できるでしょう。
2622しかし、特別な数ケースでは、カメラのカスタムの説明を関連付けたいとします。
2623
2624B<Solution:>
2625
2626B<解:>
2627
2628=begin original
2629
2630In your database schema, define a description field in the "Camera" table that
2631can contain text and null values.
2632
2633=end original
2634
2635データベーススキーマで、"Camera"にdescriptionフィールドが定義し、
2636textとnullの値を含むことをできるようにします。
2637
2638=begin original
2639
2640In DBIC, we'll overload the column accessor to provide a sane default if no
2641custom description is defined. The accessor will either return or generate the
2642description, depending on whether the field is null or not.
2643
2644=end original
2645
2646DBICは、カスタムの description が定義されていなければ、
2647提供されているまともなデフォルトのカラムアクセサをオーバーロードできます。
2648フィールドがnullかnullでないかに依存して、アクセサはdescriptionを返すか生成します。
2649
2650=begin original
2651
2652First, in your "Camera" schema class, define the description field as follows:
2653
2654=end original
2655
2656まず、"Camera"スキーマクラスで、下記のようにdescriptionフィールドを定義します:
2657
2658 __PACKAGE__->add_columns(description => { accessor => '_description' });
2659
2660=begin original
2661
2662Next, we'll define the accessor-wrapper subroutine:
2663
2664=end original
2665
2666次に、アクセサラッパーサブルーチンを定義します:
2667
2668 sub description {
2669 my $self = shift;
2670
2671 # If there is an update to the column, we'll let the original accessor
2672 # deal with it.
2673 return $self->_description(@_) if @_;
2674
2675 # Fetch the column value.
2676 my $description = $self->_description;
2677
2678 # If there's something in the description field, then just return that.
2679 return $description if defined $description && length $descripton;
2680
2681 # Otherwise, generate a description.
2682 return $self->generate_description;
2683 }
2684
2685=head1 デバッギングとプロファイリング
2686
2687=head2 Data::Dumperと、DBIx::Classオブジェクト
2688
2689=begin original
2690
26911147L<Data::Dumper> can be a very useful tool for debugging, but sometimes it can
26921148be hard to find the pertinent data in all the data it can generate.
26931149Specifically, if one naively tries to use it like so,
26941150
2695=end original
2696
26971151L<Data::Dumper> はデバッグにとても便利なツールです。ですが、
26981152生成された全てのデータの中の、該当のデータを見付けるのが難しい時があります。
2699特に、次のように単純に使おうとしたら、
1153次のように単純に使おうとしたら、
27001154
27011155 use Data::Dumper;
27021156
27031157 my $cd = $schema->resultset('CD')->find(1);
27041158 print Dumper($cd);
27051159
2706=begin original
2707
27081160several pages worth of data from the CD object's schema and result source will
27091161be dumped to the screen. Since usually one is only interested in a few column
27101162values of the object, this is not very helpful.
27111163
2712=end original
2713
27141164複数ページにわたり、CDオブジェクトのスキーマと結果のソースが、複数
27151165ページにわたるデータとなってスクリーンにダンプされます。ですが、
27161166普通はオブジェクトの数カラムの値の1つのみに興味があるので、これでは、
27171167あまり便利ではありません。
27181168
2719=begin original
2720
27211169Luckily, it is possible to modify the data before L<Data::Dumper> outputs
27221170it. Simply define a hook that L<Data::Dumper> will call on the object before
27231171dumping it. For example,
27241172
2725=end original
2726
27271173幸運にも、L<Data::Dumper>が出力する前にデータを加工することが出来ます。
27281174簡単にフックを定義すると、L<Data::Dumper>がダンプする前に、オブジェクトで
27291175それを呼び出します。
27301176
27311177 package My::DB::CD;
27321178
27331179 sub _dumper_hook {
27341180 $_[0] = bless {
27351181 %{ $_[0] },
27361182 result_source => undef,
27371183 }, ref($_[0]);
27381184 }
27391185
27401186 [...]
27411187
27421188 use Data::Dumper;
27431189
27441190 local $Data::Dumper::Freezer = '_dumper_hook';
27451191
27461192 my $cd = $schema->resultset('CD')->find(1);
27471193 print Dumper($cd);
27481194 # dumps $cd without its ResultSource
27491195
2750=begin original
2751
27521196If the structure of your schema is such that there is a common base class for
27531197all your table classes, simply put a method similar to C<_dumper_hook> in the
27541198base class and set C<$Data::Dumper::Freezer> to its name and L<Data::Dumper>
27551199will automagically clean up your data before printing it. See
27561200L<Data::Dumper/EXAMPLES> for more information.
27571201
2758=end original
2759
27601202スキーマの構造が、全てのテーブルクラスのための共通のベースクラスがあるような
27611203ものであれば、単純に、ベースクラスに、C<_dumper_hook>と同じようなメソッドを作り、
27621204C<$Data::Dumper::Freezer>にその名前をセットします。
27631205L<Data::Dumper>は、自動的に、データを出力する前に、きれいにします。
27641206L<Data::Dumper/EXAMPLES>により詳しい情報ががあります。
27651207
2766=head2 プロファイリング
1208=head2 列オブジェクトのスキーマを得る
27671209
2768=begin original
1210It is possible to get a Schema object from a row object like so:
27691211
2770When you enable L<DBIx::Class::Storage>'s debugging it prints the SQL
1212次のようにして、列のオブジェクトからスキーマを得ることができます:
1213
1214 my $schema = $cd->result_source->schema;
1215 # use the schema as normal:
1216 my $artist_rs = $schema->resultset('Artist');
1217
1218This can be useful when you don't want to pass around a Schema object to every
1219method.
1220
1221全てのメソッドで、スキーマオブジェクトを順に回したくなければ、便利でしょう。
1222
1223=head2 プロファイリング
1224
1225When you enable L<DBIx::Class::Storage::DBI>'s debugging it prints the SQL
27711226executed as well as notifications of query completion and transaction
27721227begin/commit. If you'd like to profile the SQL you can subclass the
27731228L<DBIx::Class::Storage::Statistics> class and write your own profiling
27741229mechanism:
27751230
2776=end original
1231L<DBIx::Class::Storage::DBI>のデバッギングを有効にすれば、
2777
2778L<DBIx::Class::Storage>のデバッギングを有効にすれば、
27791232実行されたSQLだけでなく、クエリの完了や、トランザクションの開始/コミット
27801233も、出力します。SQLを分析したければ、 L<DBIx::Class::Storage::Statistics>
27811234クラスのサブクラスを作り、自分自身のプロファイリングメカニズムを書けます:
27821235
27831236 package My::Profiler;
27841237 use strict;
27851238
27861239 use base 'DBIx::Class::Storage::Statistics';
27871240
27881241 use Time::HiRes qw(time);
27891242
27901243 my $start;
27911244
27921245 sub query_start {
27931246 my $self = shift();
27941247 my $sql = shift();
2795 my @params = @_;
1248 my $params = @_;
27961249
2797 $self->print("Executing $sql: ".join(', ', @params)."\n");
1250 print "Executing $sql: ".join(', ', @params)."\n";
27981251 $start = time();
27991252 }
28001253
28011254 sub query_end {
28021255 my $self = shift();
28031256 my $sql = shift();
28041257 my @params = @_;
28051258
2806 my $elapsed = sprintf("%0.4f", time() - $start);
1259 printf("Execution took %0.4f seconds.\n", time() - $start);
2807 $self->print("Execution took $elapsed seconds.\n");
28081260 $start = undef;
28091261 }
28101262
28111263 1;
28121264
28131265You can then install that class as the debugging object:
28141266
2815それから、このクラスを、デバッギングオブジェクトにインストールできます:
1267それから、このクラスを、デバッギングオブジェクトにインストールます:
28161268
2817 __PACKAGE__->storage->debugobj(new My::Profiler());
1269 __PACKAGE__->storage()->debugobj(new My::Profiler());
2818 __PACKAGE__->storage->debug(1);
1270 __PACKAGE__->storage()->debug(1);
28191271
28201272A more complicated example might involve storing each execution of SQL in an
28211273array:
28221274
28231275より複雑な例としては、配列に実行する各SQLを貯めておくようなものを含むでしょう:
28241276
28251277 sub query_end {
28261278 my $self = shift();
28271279 my $sql = shift();
28281280 my @params = @_;
28291281
28301282 my $elapsed = time() - $start;
28311283 push(@{ $calls{$sql} }, {
28321284 params => \@params,
28331285 elapsed => $elapsed
28341286 });
28351287 }
28361288
2837=begin original
2838
28391289You could then create average, high and low execution times for an SQL
28401290statement and dig down to see if certain parameters cause aberrant behavior.
2841You might want to check out L<DBIx::Class::QueryLog> as well.
28421291
2843=end original
2844
28451292それから、SQLステートメントの平均、最長、最短実行時間を取れますし、ある
28461293パラメータが異常な振る舞いを引き起こしていれば、掘り下げることも出来るでしょう。
2847L<DBIx::Class::QueryLog>もチェックしたいいかもしれません。
28481294
2849=head1 IMPROVING PERFORMANCE
1295=head2 最後にデータベースにインサートしたプライマリキーの値を取りたい
28501296
2851=over
1297last_insert_id を取るともいいます。
28521298
2853=item *
1299If you are using PK::Auto, this is straightforward:
28541300
2855Install L<Class::XSAccessor> to speed up L<Class::Accessor::Grouped>.
1301PK::Autoを使っているのなら、直接:
28561302
2857=item *
1303 my $foo = $rs->create(\%blah);
1304 # do more stuff
1305 my $id = $foo->id; # foo->my_primary_key_field will also work.
28581306
2859On Perl 5.8 install L<Class::C3::XS>.
1307If you are not using autoincrementing primary keys, this will probably
1308not work, but then you already know the value of the last primary key anyway.
28601309
2861=item *
1310オートインクリメントのプライマリキーを使っていないのなら、おそらく動きません。
1311ですが、すでに、プライマリキーの値を知っていることでしょう。
28621312
2863L<prefetch|DBIx::Class::ResultSet/prefetch> relationships, where possible. See
1313=head2 DBIx::Classのプロキシクラスを動的にサブクラス化する
2864L</Using joins and prefetch>.
1314(AKA multi-class object inflation from one table)
28651315
2866=item *
1316(AKA 1つのテーブルからマルチクラスのオブジェクトに展開する)
1317
1318L<DBIx::Class> classes are proxy classes, therefore some different
1319techniques need to be employed for more than basic subclassing. In
1320this example we have a single user table that carries a boolean bit
1321for admin. We would like like to give the admin users
1322objects(L<DBIx::Class::Row>) the same methods as a regular user but
1323also special admin only methods. It doesn't make sense to create two
1324seperate proxy-class files for this. We would be copying all the user
1325methods into the Admin class. There is a cleaner way to accomplish
1326this.
28671327
2868Use L<populate|DBIx::Class::ResultSet/populate> in void context to insert data
1328L<DBIx::Class>クラスはプロキシクラスです。そのため、基本的なサブクラス化以上に、
2869when you don't need the resulting L<DBIx::Class::Row> objects, if possible, but
1329いくつかの違ったテクニックが必要とされます。
2870see the caveats.
1330この例では、管理者用に真偽値を持っているユーザーテーブルがあります。
1331管理者ユーザーには、オブジェクト(L<DBIx::Class::Row>)のメソッドを、
1332普通のユーザーと同じようにあたえますが、管理者のみの特別なメソッドも、
1333あたえたいとします。このために2つのプロキシクラスファイルに分割するのは
1334理にかないません。Adminクラスに全てのユーザークラスのメソッドをコピー
1335することになります。これをするために、よりすっきりした方法があります。
28711336
2872When inserting many rows, for best results, populate a large number of rows at a
1337Overriding the C<inflate_result> method within the User proxy-class
2873time, but not so large that the table is locked for an unacceptably long time.
1338gives us the effect we want. This method is called by
1339L<DBIx::Class::ResultSet> when inflating a result from storage. So we
1340grab the object being returned, inspect the values we are looking for,
1341bless it if it's an admin object, and then return it. See the example
1342below:
28741343
2875If using L<create|DBIx::Class::ResultSet/create> instead, use a transaction and
1344ユーザーのプロキシクラス内でC<inflate_result>メソッドをオーバーライドすることで、
2876commit every C<X> rows; where C<X> gives you the best performance without
1345望んでいる効果が得られます。このメソッドは、ストレージから結果が展開されるときに、
2877locking the table for too long.
1346L<DBIx::Class::ResultSet>によって呼ばれます。
1347返されたオブジェクトを掴んだら、探している値を調べ、管理者オブジェクトであれば、
1348それをblessします。下の例を見てください:
28781349
2879=item *
1350B<Schema Definition>
28801351
2881When selecting many rows, if you don't need full-blown L<DBIx::Class::Row>
1352 package DB::Schema;
2882objects, consider using L<DBIx::Class::ResultClass::HashRefInflator>.
1353
1354 use base qw/DBIx::Class::Schema/;
1355
1356 __PACKAGE__->load_classes(qw/User/);
1357
1358
1359B<Proxy-Class definitions>
28831360
2884=item *
1361 package DB::Schema::User;
1362
1363 use strict;
1364 use warnings;
1365 use base qw/DBIx::Class/;
1366
1367 ### Defined what our admin class is for ensure_class_loaded
1368 my $admin_class = __PACKAGE__ . '::Admin';
1369
1370 __PACKAGE__->load_components(qw/Core/);
1371
1372 __PACKAGE__->table('users');
1373
1374 __PACKAGE__->add_columns(qw/user_id email password
1375 firstname lastname active
1376 admin/);
1377
1378 __PACKAGE__->set_primary_key('user_id');
1379
1380 sub inflate_result {
1381 my $self = shift;
1382 my $ret = $self->next::method(@_);
1383 if( $ret->admin ) {### If this is an admin rebless for extra functions
1384 $self->ensure_class_loaded( $admin_class );
1385 bless $ret, $admin_class;
1386 }
1387 return $ret;
1388 }
1389
1390 sub hello {
1391 print "I am a regular user.\n";
1392 return ;
1393 }
1394
1395
1396 package DB::Schema::User::Admin;
1397
1398 use strict;
1399 use warnings;
1400 use base qw/DB::Schema::User/;
1401
1402 sub hello
1403 {
1404 print "I am an admin.\n";
1405 return;
1406 }
1407
1408 sub do_admin_stuff
1409 {
1410 print "I am doing admin stuff\n";
1411 return ;
1412 }
1413
1414B<Test File> test.pl
28851415
2886See also L</STARTUP SPEED> and L</MEMORY USAGE> in this document.
1416 use warnings;
1417 use strict;
1418 use DB::Schema;
1419
1420 my $user_data = { email => 'someguy@place.com',
1421 password => 'pass1',
1422 admin => 0 };
1423
1424 my $admin_data = { email => 'someadmin@adminplace.com',
1425 password => 'pass2',
1426 admin => 1 };
1427
1428 my $schema = DB::Schema->connection('dbi:Pg:dbname=test');
1429
1430 $schema->resultset('User')->create( $user_data );
1431 $schema->resultset('User')->create( $admin_data );
1432
1433 ### Now we search for them
1434 my $user = $schema->resultset('User')->single( $user_data );
1435 my $admin = $schema->resultset('User')->single( $admin_data );
1436
1437 print ref $user, "\n";
1438 print ref $admin, "\n";
1439
1440 print $user->password , "\n"; # pass1
1441 print $admin->password , "\n";# pass2; inherited from User
1442 print $user->hello , "\n";# I am a regular user.
1443 print $admin->hello, "\n";# I am an admin.
1444
1445 ### The statement below will NOT print
1446 print "I can do admin stuff\n" if $user->can('do_admin_stuff');
1447 ### The statement below will print
1448 print "I can do admin stuff\n" if $admin->can('do_admin_stuff');
28871449
2888=back
1450=head2 高速に結果を得るために、オブジェクトの作成をスキップしたい
28891451
2890=head1 STARTUP SPEED
1452DBIx::Class is not built for speed, it's built for convenience and
1453ease of use, but sometimes you just need to get the data, and skip the
1454fancy objects. Luckily this is also fairly easy using
1455C<inflate_result>:
28911456
2892L<DBIx::Class|DBIx::Class> programs can have a significant startup delay
1457DBIx::Class はスピードのためには作られておらず、DBIx::Classは、
2893as the ORM loads all the relevant classes. This section examines
1458利便性と使い易さのために作られました。ですが、時には、データをただ
2894techniques for reducing the startup delay.
1459取得しなければいけないだけの時があり、素敵なオブジェクトはスキップ
1460したい場合もあるでしょう。幸運なことに、この用途には、C<inflate_result>
1461が、実に簡単に使えます。
28951462
2896These tips are are listed in order of decreasing effectiveness - so the
1463 # Define a class which just returns the results as a hashref:
2897first tip, if applicable, should have the greatest effect on your
1464 package My::HashRefInflator;
2898application.
28991465
2900=head2 Statically Define Your Schema
1466 ## $me is the hashref of cols/data from the immediate resultsource
1467 ## $prefetch is a deep hashref of all the data from the prefetched
1468 ## related sources.
29011469
2902If you are using
1470 sub mk_hash {
2903L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> to build the
1471 my ($me, $rest) = @_;
2904classes dynamically based on the database schema then there will be a
2905significant startup delay.
29061472
2907For production use a statically defined schema (which can be generated
1473 return { %$me,
2908using L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> to dump
1474 map { ($_ => mk_hash(@{$rest->{$_}})) } keys %$rest
2909the database schema once - see
1475 };
2910L<make_schema_at|DBIx::Class::Schema::Loader/make_schema_at> and
1476 }
2911L<dump_directory|DBIx::Class::Schema::Loader/dump_directory> for more
2912details on creating static schemas from a database).
29131477
2914=head2 Move Common Startup into a Base Class
1478 sub inflate_result {
1479 my ($self, $source, $me, $prefetch) = @_;
1480 return mk_hash($me, $prefetch);
1481 }
29151482
2916Typically L<DBIx::Class> result classes start off with
1483 # Change the object inflation to a hashref for just this resultset:
1484 $rs->result_class('My::HashRefInflator');
29171485
2918 use base qw/DBIx::Class::Core/;
1486 my $datahashref = $rs->next;
2919 __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
1487 foreach my $col (keys %$datahashref) {
1488 if(!ref($datahashref->{$col})) {
1489 # It's a plain value
1490 }
1491 elsif(ref($datahashref->{$col} eq 'HASH')) {
1492 # It's a related value in a hashref
1493 }
1494 }
29201495
2921If this preamble is moved into a common base class:-
1496=head2 find_or_create が見付けたのか、列を作ったのかを知りたい?
29221497
2923 package MyDBICbase;
1498Just use C<find_or_new> instead, then check C<in_storage>:
29241499
2925 use base qw/DBIx::Class::Core/;
1500C<find_or_new>を代わりに使ってください。それから、C<in_storage>をチェックします:
2926 __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
2927 1;
29281501
2929and each result class then uses this as a base:-
1502 my $obj = $rs->find_or_new({ blah => 'blarg' });
1503 unless ($obj->in_storage) {
1504 $obj->insert;
1505 # do whatever else you wanted if it was a new row
1506 }
29301507
2931 use base qw/MyDBICbase/;
1508=head3 カラムのアクセサをラッピング/オーバーロードする
29321509
2933then the load_components is only performed once, which can result in a
1510Problem: Say you have a table "Camera" and want to associate a description
2934considerable startup speedup for schemas with many classes.
1511with each camera. For most cameras, you'll be able to generate the description from
1512the other columns. However, in a few special cases you may want to associate a
1513custom description with a camera.
29351514
2936=head2 Explicitly List Schema Result Classes
1515問題: "Camera"テーブルがあったとして、それぞれのカメラについて、
1516説明を関連付けたいとします。ほとんどのカメラでは、他のカラムから説明を生成できるでしょう。
1517しかし、特別な数ケースでは、カメラのカスタムの説明を関連付けたいとします。
29371518
2938The schema class will normally contain
1519Solution:
29391520
2940 __PACKAGE__->load_classes();
1521解:
29411522
2942to load the result classes. This will use L<Module::Find|Module::Find>
1523In your database schema, define a description field in the "Camera" table that
2943to find and load the appropriate modules. Explicitly defining the
1524can contain text and null values.
2944classes you wish to load will remove the overhead of
2945L<Module::Find|Module::Find> and the related directory operations:
29461525
2947 __PACKAGE__->load_classes(qw/ CD Artist Track /);
1526データベーススキーマで、"Camera"にdescriptionフィールドが定義し、
1527textとnullの値を含むことをできるようにします。
29481528
2949If you are instead using the L<load_namespaces|DBIx::Class::Schema/load_namespaces>
1529In DBIC, we'll overload the column accessor to provide a sane default if no
2950syntax to load the appropriate classes there is not a direct alternative
1530custom description is defined. The accessor will either return or generate the
2951avoiding L<Module::Find|Module::Find>.
1531description, depending on whether the field is null or not.
29521532
2953=head1 MEMORY USAGE
1533DBICは、カスタムの description が定義されていなければ、
1534提供されているまともなデフォルトのカラムアクセサをオーバーロードできます。
1535フィールドがnullかnullでないかに依存して、アクセサはdescriptionを返すか生成します。
29541536
2955=head2 Cached statements
1537First, in your "Camera" schema class, define the description field as follows:
29561538
2957L<DBIx::Class> normally caches all statements with L<< prepare_cached()|DBI/prepare_cached >>.
1539まず、"Camera"スキーマクラスで、下記のようにdescriptionフィールドを定義します:
2958This is normally a good idea, but if too many statements are cached, the database may use too much
2959memory and may eventually run out and fail entirely. If you suspect this may be the case, you may want
2960to examine DBI's L<< CachedKids|DBI/CachedKidsCachedKids_(hash_ref) >> hash:
29611540
2962 # print all currently cached prepared statements
1541 __PACKAGE__->add_columns(description => { accessor => '_description' });
2963 print for keys %{$schema->storage->dbh->{CachedKids}};
2964 # get a count of currently cached prepared statements
2965 my $count = scalar keys %{$schema->storage->dbh->{CachedKids}};
29661542
2967If it's appropriate, you can simply clear these statements, automatically deallocating them in the
1543Next, we'll define the accessor-wrapper subroutine:
2968database:
29691544
2970 my $kids = $schema->storage->dbh->{CachedKids};
1545次に、アクセサラッパーサブルーチンを定義します:
2971 delete @{$kids}{keys %$kids} if scalar keys %$kids > 100;
29721546
2973But what you probably want is to expire unused statements and not those that are used frequently.
1547 sub description {
2974You can accomplish this with L<Tie::Cache> or L<Tie::Cache::LRU>:
1548 my $self = shift;
29751549
2976 use Tie::Cache;
1550 # If there is an update to the column, we'll let the original accessor
2977 use DB::Main;
1551 # deal with it.
2978 my $schema = DB::Main->connect($dbi_dsn, $user, $pass, {
1552 return $self->_description(@_) if @_;
2979 on_connect_do => sub { tie %{shift->_dbh->{CachedKids}}, 'Tie::Cache', 100 },
2980 });
1554 # Fetch the column value.
1555 my $description = $self->_description;
1556
1557 # If there's something in the description field, then just return that.
1558 return $description if defined $description && length $descripton;
1559
1560 # Otherwise, generate a description.
1561 return $self->generate_description;
1562 }
29811563
29821564=head1 翻訳について
29831565
29841566翻訳者:加藤敦 (ktat.is at gmail.com)
29851567
29861568Perlドキュメント日本語訳 Project にて、
29871569Perlモジュール、ドキュメントの翻訳を行っております。
29881570
29891571 http://perldocjp.sourceforge.jp/
29901572 http://sourceforge.jp/projects/perldocjp/
29911573 http://www.freeml.com/perldocjp/
29921574 http://www.perldoc.jp
29931575
29941576=cut