3 DBIx::Class::Manual::Example - Simple CD database example
7 This tutorial will guide you through the process of setting up and
8 testing a very basic CD database using SQLite, with DBIx::Class::Schema
9 as the database frontend.
11 The database consists of the following:
13 table 'artist' with columns: artistid, name
14 table 'cd' with columns: cdid, artist, title
15 table 'track' with columns: trackid, cd, title
18 And these rules exists:
20 one artist can have many cds
21 one cd belongs to one artist
22 one cd can have many tracks
23 one track belongs to one cd
28 Install DBIx::Class via CPAN should be sufficient.
30 =head3 Create the database/tables.
32 First make and change the directory:
39 This example uses SQLite which is a dependency of DBIx::Class, so you
40 shouldn't have to install extra software.
42 Save the following into a example.sql in the directory db
45 artistid INTEGER PRIMARY KEY,
50 cdid INTEGER PRIMARY KEY,
51 artist INTEGER NOT NULL REFERENCES artist(artistid),
56 trackid INTEGER PRIMARY KEY,
57 cd INTEGER NOT NULL REFERENCES cd(cdid),
61 and create the sqlite database file:
63 sqlite3 example.db < example.sql
65 =head3 Set up DBIx::Class::Schema
67 Change directory back from db to the directory app:
71 Now create some more directories:
75 mkdir MyDatabase/Main/Result
76 mkdir MyDatabase/Main/ResultSet
78 Then, create the following DBIx::Class::Schema classes:
82 package MyDatabase::Main;
83 use base qw/DBIx::Class::Schema/;
84 __PACKAGE__->load_namespaces;
89 MyDatabase/Main/Result/Artist.pm:
91 package MyDatabase::Main::Result::Artist;
92 use base qw/DBIx::Class/;
93 __PACKAGE__->load_components(qw/PK::Auto Core/);
94 __PACKAGE__->table('artist');
95 __PACKAGE__->add_columns(qw/ artistid name /);
96 __PACKAGE__->set_primary_key('artistid');
97 __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Result::Cd');
102 MyDatabase/Main/Result/Cd.pm:
104 package MyDatabase::Main::Result::Cd;
105 use base qw/DBIx::Class/;
106 __PACKAGE__->load_components(qw/PK::Auto Core/);
107 __PACKAGE__->table('cd');
108 __PACKAGE__->add_columns(qw/ cdid artist title/);
109 __PACKAGE__->set_primary_key('cdid');
110 __PACKAGE__->belongs_to('artist' => 'MyDatabase::Main::Result::Artist');
111 __PACKAGE__->has_many('tracks' => 'MyDatabase::Main::Result::Track');
116 MyDatabase/Main/Result/Track.pm:
118 package MyDatabase::Main::Result::Track;
119 use base qw/DBIx::Class/;
120 __PACKAGE__->load_components(qw/PK::Auto Core/);
121 __PACKAGE__->table('track');
122 __PACKAGE__->add_columns(qw/ trackid cd title/);
123 __PACKAGE__->set_primary_key('trackid');
124 __PACKAGE__->belongs_to('cd' => 'MyDatabase::Main::Result::Cd');
129 =head3 Write a script to insert some records.
135 use MyDatabase::Main;
138 my $schema = MyDatabase::Main->connect('dbi:SQLite:db/example.db');
140 # here's some of the sql that is going to be generated by the schema
141 # INSERT INTO artist VALUES (NULL,'Michael Jackson');
142 # INSERT INTO artist VALUES (NULL,'Eminem');
144 my @artists = (['Michael Jackson'], ['Eminem']);
145 $schema->populate('Artist', [
151 'Thriller' => 'Michael Jackson',
152 'Bad' => 'Michael Jackson',
153 'The Marshall Mathers LP' => 'Eminem',
157 foreach my $lp (keys %albums) {
158 my $artist = $schema->resultset('Artist')->search({
161 push @cds, [$lp, $artist->first];
164 $schema->populate('Cd', [
171 'Beat It' => 'Thriller',
172 'Billie Jean' => 'Thriller',
173 'Dirty Diana' => 'Bad',
174 'Smooth Criminal' => 'Bad',
175 'Leave Me Alone' => 'Bad',
176 'Stan' => 'The Marshall Mathers LP',
177 'The Way I Am' => 'The Marshall Mathers LP',
181 foreach my $track (keys %tracks) {
182 my $cdname = $schema->resultset('Cd')->search({
183 title => $tracks{$track},
185 push @tracks, [$cdname->first, $track];
188 $schema->populate('Track',[
193 =head3 Create and run the test scripts
199 use MyDatabase::Main;
202 my $schema = MyDatabase::Main->connect('dbi:SQLite:db/example.db');
203 # for other DSNs, e.g. MySql, see the perldoc for the relevant dbd
204 # driver, e.g perldoc L<DBD::mysql>.
206 get_tracks_by_cd('Bad');
207 get_tracks_by_artist('Michael Jackson');
209 get_cd_by_track('Stan');
210 get_cds_by_artist('Michael Jackson');
212 get_artist_by_track('Dirty Diana');
213 get_artist_by_cd('The Marshall Mathers LP');
216 sub get_tracks_by_cd {
218 print "get_tracks_by_cd($cdtitle):\n";
219 my $rs = $schema->resultset('Track')->search(
221 'cd.title' => $cdtitle
227 while (my $track = $rs->next) {
228 print $track->title . "\n";
233 sub get_tracks_by_artist {
234 my $artistname = shift;
235 print "get_tracks_by_artist($artistname):\n";
236 my $rs = $schema->resultset('Track')->search(
238 'artist.name' => $artistname
246 while (my $track = $rs->next) {
247 print $track->title . "\n";
253 sub get_cd_by_track {
254 my $tracktitle = shift;
255 print "get_cd_by_track($tracktitle):\n";
256 my $rs = $schema->resultset('Cd')->search(
258 'tracks.title' => $tracktitle
261 join => [qw/ tracks /],
265 print $cd->title . "\n\n";
268 sub get_cds_by_artist {
269 my $artistname = shift;
270 print "get_cds_by_artist($artistname):\n";
271 my $rs = $schema->resultset('Cd')->search(
273 'artist.name' => $artistname
276 join => [qw/ artist /],
279 while (my $cd = $rs->next) {
280 print $cd->title . "\n";
287 sub get_artist_by_track {
288 my $tracktitle = shift;
289 print "get_artist_by_track($tracktitle):\n";
290 my $rs = $schema->resultset('Artist')->search(
292 'tracks.title' => $tracktitle
300 my $artist = $rs->first;
301 print $artist->name . "\n\n";
304 sub get_artist_by_cd {
306 print "get_artist_by_cd($cdtitle):\n";
307 my $rs = $schema->resultset('Artist')->search(
309 'cds.title' => $cdtitle
315 my $artist = $rs->first;
316 print $artist->name . "\n\n";
323 get_tracks_by_cd(Bad):
328 get_tracks_by_artist(Michael Jackson):
335 get_cd_by_track(Stan):
336 The Marshall Mathers LP
338 get_cds_by_artist(Michael Jackson):
342 get_artist_by_track(Dirty Diana):
345 get_artist_by_cd(The Marshall Mathers LP):
350 A reference implentation of the database and scripts in this example
351 are available in the main distribution for DBIx::Class under the
352 directory t/examples/Schema
354 With these scripts we're relying on @INC looking in the current
355 working directory. You may want to add the MyDatabase namespaces to
356 @INC in a different way when it comes to deployment.
358 The testdb.pl script is an excellent start for testing your database
361 This example uses load_namespaces to load in the appropriate Row classes
362 from the MyDatabase::Main::Result namespace, and any required resultset
363 classes from the MyDatabase::Main::ResultSet namespace (although we
364 created the directory in the directions above we did not add, or need to
365 add, any resultset classes).
371 sc_ from irc.perl.org#dbix-class
372 Kieren Diment <kd@totaldatasolution.com>
373 Nigel Metheringham <nigelm@cpan.org>