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::Core/;
93 __PACKAGE__->table('artist');
94 __PACKAGE__->add_columns(qw/ artistid name /);
95 __PACKAGE__->set_primary_key('artistid');
96 __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Result::Cd');
101 MyDatabase/Main/Result/Cd.pm:
103 package MyDatabase::Main::Result::Cd;
104 use base qw/DBIx::Class::Core/;
105 __PACKAGE__->load_components(qw/InflateColumn::DateTime/);
106 __PACKAGE__->table('cd');
107 __PACKAGE__->add_columns(qw/ cdid artist title/);
108 __PACKAGE__->set_primary_key('cdid');
109 __PACKAGE__->belongs_to('artist' => 'MyDatabase::Main::Result::Artist');
110 __PACKAGE__->has_many('tracks' => 'MyDatabase::Main::Result::Track');
115 MyDatabase/Main/Result/Track.pm:
117 package MyDatabase::Main::Result::Track;
118 use base qw/DBIx::Class::Core/;
119 __PACKAGE__->table('track');
120 __PACKAGE__->add_columns(qw/ trackid cd title /);
121 __PACKAGE__->set_primary_key('trackid');
122 __PACKAGE__->belongs_to('cd' => 'MyDatabase::Main::Result::Cd');
127 =head3 Write a script to insert some records
136 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')->find({
161 push @cds, [$lp, $artist->id];
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')->find({
183 title => $tracks{$track},
185 push @tracks, [$cdname->id, $track];
188 $schema->populate('Track',[
193 =head3 Create and run the test scripts
202 use MyDatabase::Main;
204 my $schema = MyDatabase::Main->connect('dbi:SQLite:db/example.db');
205 # for other DSNs, e.g. MySQL, see the perldoc for the relevant dbd
206 # driver, e.g perldoc L<DBD::mysql>.
208 get_tracks_by_cd('Bad');
209 get_tracks_by_artist('Michael Jackson');
211 get_cd_by_track('Stan');
212 get_cds_by_artist('Michael Jackson');
214 get_artist_by_track('Dirty Diana');
215 get_artist_by_cd('The Marshall Mathers LP');
218 sub get_tracks_by_cd {
220 print "get_tracks_by_cd($cdtitle):\n";
221 my $rs = $schema->resultset('Track')->search(
223 'cd.title' => $cdtitle
229 while (my $track = $rs->next) {
230 print $track->title . "\n";
235 sub get_tracks_by_artist {
236 my $artistname = shift;
237 print "get_tracks_by_artist($artistname):\n";
238 my $rs = $schema->resultset('Track')->search(
240 'artist.name' => $artistname
248 while (my $track = $rs->next) {
249 print $track->title . "\n";
255 sub get_cd_by_track {
256 my $tracktitle = shift;
257 print "get_cd_by_track($tracktitle):\n";
258 my $rs = $schema->resultset('Cd')->search(
260 'tracks.title' => $tracktitle
263 join => [qw/ tracks /],
267 print $cd->title . "\n\n";
270 sub get_cds_by_artist {
271 my $artistname = shift;
272 print "get_cds_by_artist($artistname):\n";
273 my $rs = $schema->resultset('Cd')->search(
275 'artist.name' => $artistname
278 join => [qw/ artist /],
281 while (my $cd = $rs->next) {
282 print $cd->title . "\n";
289 sub get_artist_by_track {
290 my $tracktitle = shift;
291 print "get_artist_by_track($tracktitle):\n";
292 my $rs = $schema->resultset('Artist')->search(
294 'tracks.title' => $tracktitle
302 my $artist = $rs->first;
303 print $artist->name . "\n\n";
306 sub get_artist_by_cd {
308 print "get_artist_by_cd($cdtitle):\n";
309 my $rs = $schema->resultset('Artist')->search(
311 'cds.title' => $cdtitle
317 my $artist = $rs->first;
318 print $artist->name . "\n\n";
325 get_tracks_by_cd(Bad):
330 get_tracks_by_artist(Michael Jackson):
337 get_cd_by_track(Stan):
338 The Marshall Mathers LP
340 get_cds_by_artist(Michael Jackson):
344 get_artist_by_track(Dirty Diana):
347 get_artist_by_cd(The Marshall Mathers LP):
352 A reference implementation of the database and scripts in this example
353 are available in the main distribution for DBIx::Class under the
354 directory F<t/examples/Schema>.
356 With these scripts we're relying on @INC looking in the current
357 working directory. You may want to add the MyDatabase namespaces to
358 @INC in a different way when it comes to deployment.
360 The F<testdb.pl> script is an excellent start for testing your database
363 This example uses L<DBIx::Class::Schema/load_namespaces> to load in the
364 appropriate L<Row|DBIx::Class::Row> classes from the MyDatabase::Main::Result namespace,
365 and any required resultset classes from the MyDatabase::Main::ResultSet
366 namespace (although we created the directory in the directions above we
367 did not add, or need to add, any resultset classes).
373 sc_ from irc.perl.org#dbix-class
374 Kieren Diment <kd@totaldatasolution.com>
375 Nigel Metheringham <nigelm@cpan.org>