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
133 use MyDatabase::Main;
136 my $schema = MyDatabase::Main->connect('dbi:SQLite:db/example.db');
138 # here's some of the SQL that is going to be generated by the schema
139 # INSERT INTO artist VALUES (NULL,'Michael Jackson');
140 # INSERT INTO artist VALUES (NULL,'Eminem');
142 my @artists = (['Michael Jackson'], ['Eminem']);
143 $schema->populate('Artist', [
149 'Thriller' => 'Michael Jackson',
150 'Bad' => 'Michael Jackson',
151 'The Marshall Mathers LP' => 'Eminem',
155 foreach my $lp (keys %albums) {
156 my $artist = $schema->resultset('Artist')->find({
159 push @cds, [$lp, $artist->id];
162 $schema->populate('Cd', [
169 'Beat It' => 'Thriller',
170 'Billie Jean' => 'Thriller',
171 'Dirty Diana' => 'Bad',
172 'Smooth Criminal' => 'Bad',
173 'Leave Me Alone' => 'Bad',
174 'Stan' => 'The Marshall Mathers LP',
175 'The Way I Am' => 'The Marshall Mathers LP',
179 foreach my $track (keys %tracks) {
180 my $cdname = $schema->resultset('Cd')->find({
181 title => $tracks{$track},
183 push @tracks, [$cdname->id, $track];
186 $schema->populate('Track',[
191 =head3 Create and run the test scripts
197 use MyDatabase::Main;
200 my $schema = MyDatabase::Main->connect('dbi:SQLite:db/example.db');
201 # for other DSNs, e.g. MySQL, see the perldoc for the relevant dbd
202 # driver, e.g perldoc L<DBD::mysql>.
204 get_tracks_by_cd('Bad');
205 get_tracks_by_artist('Michael Jackson');
207 get_cd_by_track('Stan');
208 get_cds_by_artist('Michael Jackson');
210 get_artist_by_track('Dirty Diana');
211 get_artist_by_cd('The Marshall Mathers LP');
214 sub get_tracks_by_cd {
216 print "get_tracks_by_cd($cdtitle):\n";
217 my $rs = $schema->resultset('Track')->search(
219 'cd.title' => $cdtitle
225 while (my $track = $rs->next) {
226 print $track->title . "\n";
231 sub get_tracks_by_artist {
232 my $artistname = shift;
233 print "get_tracks_by_artist($artistname):\n";
234 my $rs = $schema->resultset('Track')->search(
236 'artist.name' => $artistname
244 while (my $track = $rs->next) {
245 print $track->title . "\n";
251 sub get_cd_by_track {
252 my $tracktitle = shift;
253 print "get_cd_by_track($tracktitle):\n";
254 my $rs = $schema->resultset('Cd')->search(
256 'tracks.title' => $tracktitle
259 join => [qw/ tracks /],
263 print $cd->title . "\n\n";
266 sub get_cds_by_artist {
267 my $artistname = shift;
268 print "get_cds_by_artist($artistname):\n";
269 my $rs = $schema->resultset('Cd')->search(
271 'artist.name' => $artistname
274 join => [qw/ artist /],
277 while (my $cd = $rs->next) {
278 print $cd->title . "\n";
285 sub get_artist_by_track {
286 my $tracktitle = shift;
287 print "get_artist_by_track($tracktitle):\n";
288 my $rs = $schema->resultset('Artist')->search(
290 'tracks.title' => $tracktitle
298 my $artist = $rs->first;
299 print $artist->name . "\n\n";
302 sub get_artist_by_cd {
304 print "get_artist_by_cd($cdtitle):\n";
305 my $rs = $schema->resultset('Artist')->search(
307 'cds.title' => $cdtitle
313 my $artist = $rs->first;
314 print $artist->name . "\n\n";
321 get_tracks_by_cd(Bad):
326 get_tracks_by_artist(Michael Jackson):
333 get_cd_by_track(Stan):
334 The Marshall Mathers LP
336 get_cds_by_artist(Michael Jackson):
340 get_artist_by_track(Dirty Diana):
343 get_artist_by_cd(The Marshall Mathers LP):
348 A reference implementation of the database and scripts in this example
349 are available in the main distribution for DBIx::Class under the
350 directory F<t/examples/Schema>.
352 With these scripts we're relying on @INC looking in the current
353 working directory. You may want to add the MyDatabase namespaces to
354 @INC in a different way when it comes to deployment.
356 The F<testdb.pl> script is an excellent start for testing your database
359 This example uses L<DBIx::Class::Schema/load_namespaces> to load in the
360 appropriate L<Row|DBIx::Class::Row> classes from the MyDatabase::Main::Result namespace,
361 and any required resultset classes from the MyDatabase::Main::ResultSet
362 namespace (although we created the directory in the directions above we
363 did not add, or need to add, any resultset classes).
369 sc_ from irc.perl.org#dbix-class
370 Kieren Diment <kd@totaldatasolution.com>
371 Nigel Metheringham <nigelm@cpan.org>