1DBIx::Class::Manual::FeUasteurreCso(n3t)ributed Perl DocDuBmIexn:t:aCtliaosns::Manual::Features(3)
2
3
4

NAME

6       DBIx::Class::Manual::Features - A boatload of DBIx::Class features with
7       links to respective documentation
8

META

10   Large Community
11       There are hundres of DBIC contributors listed in AUTHORS. That ranges
12       from documentation help, to test help, to added features, to entire
13       database support.
14
15   Active Community
16       Currently (June 9, 2010) 6 active branches (committed to in the last
17       two weeks) in git.  Last release (0.08122) had 14 new features, and 16
18       bug fixes.  Of course that ebbs and flows
19       <https://metacpan.org/changes/distribution/DBIx-Class>.)
20
21   Responsive Community
22       I needed MSSQL order-by support; the community helped me add support
23       generally very welcoming of people willing to help
24

General ORM

26       These are things that are in most other ORMs, but are still reasons to
27       use DBIC over raw SQL.
28
29   Cross DB
30       The vast majority of code should run on all databases without needing
31       tweaking
32
33   Basic CRUD
34       C - Create
35       R - Retrieve
36       U - Update
37       D - Delete
38
39   SQL: Create
40        my $sth = $dbh->prepare('
41           INSERT INTO books
42           (title, author_id)
43           values (?,?)
44        ');
45
46        $sth->execute( 'A book title', $author_id );
47
48   DBIC: Create
49        my $book = $book_rs->create({
50           title     => 'A book title',
51           author_id => $author_id,
52        });
53
54       See "create" in DBIx::Class::ResultSet
55
56       No need to pair placeholders and values
57       Automatically gets autoincremented id for you
58       Transparently uses INSERT ... RETURNING for databases that support it
59
60   SQL: Read
61        my $sth = $dbh->prepare('
62           SELECT title,
63           authors.name as author_name
64           FROM books, authors
65           WHERE books.author = authors.id
66        ');
67
68        while ( my $book = $sth->fetchrow_hashref ) {
69          say "Author of $book->{title} is $book->{author_name}";
70        }
71
72   DBIC: Read
73        my $book = $book_rs->find($book_id);
74
75       or
76
77        my $book = $book_rs->search({ title => 'A book title' }, { rows => 1 })->next;
78
79       or
80
81        my @books = $book_rs->search({ author => $author_id })->all;
82
83       or
84
85        while( my $book = $books_rs->next ) {
86          printf "Author of %s is %s\n", $book->title, $book->author->name;
87        }
88
89       See "find" in DBIx::Class::ResultSet, "search" in
90       DBIx::Class::ResultSet, "next" in DBIx::Class::ResultSet, and "all" in
91       DBIx::Class::ResultSet
92
93       TMTOWTDI!
94
95   SQL: Update
96        my $update = $dbh->prepare('
97           UPDATE books
98           SET title = ?
99           WHERE id = ?
100        ');
101
102        $update->execute( 'New title', $book_id );
103
104   DBIC: Update
105        $book->update({ title => 'New title' });
106
107       See "update" in DBIx::Class::Row
108
109       Will not update unless value changes
110
111   SQL: Delete
112        my $delete = $dbh->prepare('DELETE FROM books WHERE id = ?');
113
114        $delete->execute($book_id);
115
116   DBIC: Delete
117        $book->delete
118
119       See "delete" in DBIx::Class::Row
120
121   SQL: Search
122        my $sth = $dbh->prepare('
123          SELECT title,
124          authors.name as author_name
125          FROM books
126          WHERE books.name LIKE "%monte cristo%" AND
127          books.topic = "jailbreak"
128        ');
129
130   DBIC: Search
131        my $book = $book_rs->search({
132           'me.name'  => { -like => '%monte cristo%' },
133           'me.topic' => 'jailbreak',
134        })->next;
135
136       See SQL::Abstract::Classic, "next" in DBIx::Class::ResultSet, and
137       "search" in DBIx::Class::ResultSet
138       (kinda) introspectible
139       Prettier than SQL
140
141   OO Overridability
142       Override new if you want to do validation
143       Override delete if you want to disable deletion
144       and on and on
145
146   Convenience Methods
147       "find_or_create" in DBIx::Class::ResultSet
148       "update_or_create" in DBIx::Class::ResultSet
149
150   Non-column methods
151       Need a method to get a user's gravatar URL?  Add a "gravatar_url"
152       method to the Result class
153
154   RELATIONSHIPS
155       "belongs_to" in DBIx::Class::Relationship
156       "has_many" in DBIx::Class::Relationship
157       "might_have" in DBIx::Class::Relationship
158       "has_one" in DBIx::Class::Relationship
159       "many_to_many" in DBIx::Class::Relationship
160       SET AND FORGET
161

DBIx::Class Specific Features

163       These things may be in other ORM's, but they are very specific, so
164       doubtful
165
166   ->deploy
167       Create a database from your DBIx::Class schema.
168
169        my $schema = Frew::Schema->connect( $dsn, $user, $pass );
170
171        $schema->deploy
172
173       See "deploy" in DBIx::Class::Schema.
174
175       See also: DBIx::Class::DeploymentHandler
176
177   Schema::Loader
178       Create a DBIx::Class schema from your database.
179
180        package Frew::Schema;
181
182        use strict;
183        use warnings;
184
185        use base 'DBIx::Class::Schema::Loader';
186
187        __PACKAGE__->loader_options({
188           naming => 'v7',
189           debug  => $ENV{DBIC_TRACE},
190        });
191
192        1;
193
194        # elsewhere...
195
196        my $schema = Frew::Schema->connect( $dsn, $user, $pass );
197
198       See DBIx::Class::Schema::Loader and "CONSTRUCTOR OPTIONS" in
199       DBIx::Class::Schema::Loader::Base.
200
201   Populate
202       Made for inserting lots of rows very quickly into database
203
204        $schema->populate([ Users =>
205           [qw( username password )],
206           [qw( frew     >=4char$ )],
207           [qw(      ...          )],
208           [qw(      ...          )],
209        );
210
211       See "populate" in DBIx::Class::Schema
212
213       I use populate here <http://blog.afoolishmanifesto.com/archives/1255>
214       to export our whole (200M~) db to SQLite
215
216   Multicreate
217       Create an object and its related objects all at once
218
219        $schema->resultset('Author')->create({
220           name => 'Stephen King',
221           books => [{ title => 'The Dark Tower' }],
222           address => {
223              street => '123 Turtle Back Lane',
224              state  => { abbreviation => 'ME' },
225              city   => { name => 'Lowell'     },
226           },
227        });
228
229       See "create" in DBIx::Class::ResultSet
230
231       books is a has_many
232       address is a belongs_to which in turn belongs to state and city each
233       for this to work right state and city must mark abbreviation and name
234       as unique
235
236   Extensible
237       DBIx::Class helped pioneer fast MI in Perl 5 with Class::C3, so it is
238       made to allow extensions to nearly every part of it.
239
240   Extensibility example: DBIx::Class::Helpers
241       DBIx::Class::Helper::ResultSet::IgnoreWantarray
242       DBIx::Class::Helper::ResultSet::Random
243       DBIx::Class::Helper::ResultSet::SetOperations
244       DBIx::Class::Helper::Row::JoinTable
245       DBIx::Class::Helper::Row::NumifyGet
246       DBIx::Class::Helper::Row::SubClass
247       DBIx::Class::Helper::Row::ToJSON
248       DBIx::Class::Helper::Row::StorageValues
249       DBIx::Class::Helper::Row::OnColumnChange
250
251   Extensibility example: DBIx::Class::TimeStamp
252       See DBIx::Class::TimeStamp
253       Cross DB
254       set_on_create
255       set_on_update
256
257   Extensibility example: Kioku
258       See DBIx::Class::Schema::KiokuDB
259       Kioku is the new hotness
260       Mix RDBMS with Object DB
261
262   Result vs ResultSet
263       Result == Row
264       ResultSet == Query Plan
265        Internal Join Optimizer for all DB's (!!!)
266       (less important but...)
267       ResultSource == Queryable collection of rows (Table, View, etc)
268       Storage == Database
269       Schema == associates a set of ResultSources with a Storage
270
271   ResultSet methods
272        package MyApp::Schema::ResultSet::Book;
273
274        use strict;
275        use warnings;
276
277        use base 'DBIx::Class::ResultSet';
278
279        sub good {
280           my $self = shift;
281           $self->search({
282              $self->current_source_alias . '.rating' => { '>=' => 4 }
283           })
284        };
285
286        sub cheap {
287           my $self = shift;
288           $self->search({
289              $self->current_source_alias . '.price' => { '<=' => 5}
290           })
291        };
292
293        # ...
294
295        1;
296
297       See "Predefined searches" in DBIx::Class::Manual::Cookbook
298
299       All searches should be ResultSet methods
300       Name has obvious meaning
301       "current_source_alias" in DBIx::Class::ResultSet helps things to work
302       no matter what
303
304   ResultSet method in Action
305        $schema->resultset('Book')->good
306
307   ResultSet Chaining
308        $schema->resultset('Book')
309           ->good
310           ->cheap
311           ->recent
312
313   search_related
314        my $score = $schema->resultset('User')
315           ->search({'me.userid' => 'frew'})
316           ->related_resultset('access')
317           ->related_resultset('mgmt')
318           ->related_resultset('orders')
319           ->telephone
320           ->search_related( shops => {
321              'shops.datecompleted' => {
322                 -between => ['2009-10-01','2009-10-08']
323              }
324           })->completed
325           ->related_resultset('rpt_score')
326           ->search(undef, { rows => 1})
327           ->get_column('raw_scores')
328           ->next;
329
330       The SQL that this produces (with placeholders filled in for clarity's
331       sake) on our system (Microsoft SQL) is:
332
333        SELECT raw_scores
334          FROM (
335            SELECT raw_scores, ROW_NUMBER() OVER (
336                ORDER BY (
337                    SELECT (1)
338                  )
339              ) AS rno__row__index
340              FROM (
341                SELECT rpt_score.raw_scores
342                  FROM users me
343                  JOIN access access
344                    ON access.userid = me.userid
345                  JOIN mgmt mgmt
346                    ON mgmt.mgmtid = access.mgmtid
347                  JOIN [order] orders
348                    ON orders.mgmtid = mgmt.mgmtid
349                  JOIN shop shops
350                    ON shops.orderno = orders.orderno
351                  JOIN rpt_scores rpt_score
352                    ON rpt_score.shopno = shops.shopno
353                WHERE (
354                  datecompleted IS NOT NULL AND
355                  (
356                    (shops.datecompleted BETWEEN '2009-10-01' AND '2009-10-08')  AND
357                    (type = '1' AND me.userid = 'frew')
358                  )
359                )
360              ) rpt_score
361          ) rpt_score
362        WHERE rno__row__index BETWEEN 1 AND 1
363
364       See: "related_resultset" in DBIx::Class::ResultSet, "search_related" in
365       DBIx::Class::ResultSet, and "get_column" in DBIx::Class::ResultSet.
366
367   bonus rel methods
368        my $book = $author->create_related(
369           books => {
370              title => 'Another Discworld book',
371           }
372        );
373
374        my $book2 = $pratchett->add_to_books({
375           title => 'MOAR Discworld book',
376        });
377
378       See "create_related" in DBIx::Class::Relationship::Base and
379       "add_to_$rel" in DBIx::Class::Relationship::Base
380
381       Note that it automatically fills in foreign key for you
382
383   Excellent Transaction Support
384        $schema->txn_do(sub {
385           ...
386        });
387
388        $schema->txn_begin; # <-- low level
389        # ...
390        $schema->txn_commit;
391
392       See "txn_do" in DBIx::Class::Schema, "txn_begin" in
393       DBIx::Class::Schema, and "txn_commit" in DBIx::Class::Schema.
394
395   InflateColumn
396        package Frew::Schema::Result::Book;
397
398        use strict;
399        use warnings;
400
401        use base 'DBIx::Class::Core';
402
403        use DateTime::Format::MySQL;
404
405        # Result code here
406
407        __PACKAGE__->load_components('InflateColumn');
408
409        __PACKAGE__->inflate_column(
410           date_published => {
411              inflate => sub { DateTime::Format::MySQL->parse_date( shift ) },
412              deflate => sub { shift->ymd },
413           },
414        );
415
416       See DBIx::Class::InflateColumn, "inflate_column" in
417       DBIx::Class::InflateColumn, and DBIx::Class::InflateColumn::DateTime.
418
419   InflateColumn: deflation
420        $book->date_published(DateTime->now);
421        $book->update;
422
423   InflateColumn: inflation
424        say $book->date_published->month_abbr; # Nov
425
426   FilterColumn
427        package Frew::Schema::Result::Book;
428
429        use strict;
430        use warnings;
431
432        use base 'DBIx::Class::Core';
433
434        # Result code here
435
436        __PACKAGE__->load_components('FilterColumn');
437
438        __PACKAGE__->filter_column(
439           length => {
440              to_storage   => 'to_metric',
441              from_storage => 'to_imperial',
442           },
443        );
444
445        sub to_metric   { $_[1] * .305 }
446        sub to_imperial { $_[1] * 3.28 }
447
448       See DBIx::Class::FilterColumn and "filter_column" in
449       DBIx::Class::FilterColumn
450
451   ResultSetColumn
452        my $rsc = $schema->resultset('Book')->get_column('price');
453        $rsc->first;
454        $rsc->all;
455        $rsc->min;
456        $rsc->max;
457        $rsc->sum;
458
459       See DBIx::Class::ResultSetColumn
460
461   Aggregates
462        my @res = $rs->search(undef, {
463           select   => [
464              'price',
465              'genre',
466              { max => price },
467              { avg => price },
468           ],
469           as       => [
470              qw(price genre max_price avg_price)
471           ],
472           group_by => [qw(price genre)],
473        });
474        for (@res) {
475           say $_->price . ' ' . $_->genre;
476           say $_->get_column('max_price');
477           say $_->get_column('avg_price');
478        }
479
480       See "select" in DBIx::Class::ResultSet, "as" in DBIx::Class::ResultSet,
481       and "group_by" in DBIx::Class::ResultSet
482
483       Careful, get_column can basically mean three things
484       private in which case you should use an accessor
485       public for what there is no accessor for
486       public for get resultset column (prev example)
487
488   HRI
489        $rs->search(undef, {
490          result_class => 'DBIx::Class::ResultClass::HashRefInflator',
491        });
492
493       See "result_class" in DBIx::Class::ResultSet and
494       DBIx::Class::ResultClass::HashRefInflator.
495
496       Easy on memory
497       Mega fast
498       Great for quick debugging
499       Great for performance tuning (we went from 2m to < 3s)
500
501   Subquery Support
502        my $inner_query = $schema->resultset('Artist')
503           ->search({
504            name => [ 'Billy Joel', 'Brittany Spears' ],
505        })->get_column('id')->as_query;
506
507        my $rs = $schema->resultset('CD')->search({
508            artist_id => { -in => $inner_query },
509        });
510
511       See "Subqueries" in DBIx::Class::Manual::Cookbook
512
513   Bare SQL w/ Placeholders
514        $rs->update({
515           # !!! SQL INJECTION VECTOR
516           price => \"price + $inc", # DON'T DO THIS
517        });
518
519       Better:
520
521        $rs->update({
522           price => \['price + ?', [inc => $inc]],
523        });
524
525       See "Literal SQL with placeholders and bind values (subqueries)" in
526       SQL::Abstract::Classic
527

FURTHER QUESTIONS?

529       Check the list of additional DBIC resources.
530
532       This module is free software copyright by the DBIx::Class (DBIC)
533       authors. You can redistribute it and/or modify it under the same terms
534       as the DBIx::Class library.
535
536
537
538perl v5.36.0                      2023-01-20  DBIx::Class::Manual::Features(3)
Impressum