I hate you all.
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Manual / Example.pod
CommitLineData
3f341474 1=head1 NAME
2
3DBIx::Class::Manual::Example - Simple CD database example
4
5=head1 DESCRIPTION
6
880a1a0c 7This tutorial will guide you through the process of setting up and
3f341474 8testing a very basic CD database using SQLite, with DBIx::Class::Schema
9as the database frontend.
10
11The database consists of the following:
12
90efcf94 13 table 'artist' with columns: artistid, name
14 table 'cd' with columns: cdid, artist, title
15 table 'track' with columns: trackid, cd, title
3f341474 16
17
18And these rules exists:
19
90efcf94 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
3f341474 24
25
26=head2 Installation
27
28Install DBIx::Class via CPAN should be sufficient.
29
30=head3 Create the database/tables.
31
32First make and change the directory:
33
90efcf94 34 mkdir app
35 cd app
d3c2fbd8 36 mkdir db
37 cd db
3f341474 38
39This example uses SQLite which is a dependency of DBIx::Class, so you
40shouldn't have to install extra software.
41
d3c2fbd8 42Save the following into a example.sql in the directory db
3f341474 43
90efcf94 44 CREATE TABLE artist (
49e87fbb 45 artistid INTEGER PRIMARY KEY,
46 name TEXT NOT NULL
90efcf94 47 );
3f341474 48
90efcf94 49 CREATE TABLE cd (
49e87fbb 50 cdid INTEGER PRIMARY KEY,
51 artist INTEGER NOT NULL REFERENCES artist(artistid),
52 title TEXT NOT NULL
53 );
3f341474 54
90efcf94 55 CREATE TABLE track (
49e87fbb 56 trackid INTEGER PRIMARY KEY,
57 cd INTEGER NOT NULL REFERENCES cd(cdid),
58 title TEXT NOT NULL
59 );
3f341474 60
61and create the sqlite database file:
62
63sqlite3 example.db < example.sql
64
65=head3 Set up DBIx::Class::Schema
66
d3c2fbd8 67Change directory back from db to the directory app:
68
69 cd ../
70
71Now create some more directories:
3f341474 72
90efcf94 73 mkdir MyDatabase
74 mkdir MyDatabase/Main
3f341474 75
76Then, create the following DBIx::Class::Schema classes:
77
78MyDatabase/Main.pm:
90efcf94 79
80 package MyDatabase::Main;
81 use base qw/DBIx::Class::Schema/;
82 __PACKAGE__->load_classes(qw/Artist Cd Track/);
3f341474 83
90efcf94 84 1;
3f341474 85
86
87MyDatabase/Main/Artist.pm:
88
90efcf94 89 package MyDatabase::Main::Artist;
90 use base qw/DBIx::Class/;
e8cc984c 91 __PACKAGE__->load_components(qw/PK::Auto Core/);
90efcf94 92 __PACKAGE__->table('artist');
93 __PACKAGE__->add_columns(qw/ artistid name /);
94 __PACKAGE__->set_primary_key('artistid');
95 __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Cd');
3f341474 96
90efcf94 97 1;
3f341474 98
99
100MyDatabase/Main/Cd.pm:
101
90efcf94 102 package MyDatabase::Main::Cd;
103 use base qw/DBIx::Class/;
e8cc984c 104 __PACKAGE__->load_components(qw/PK::Auto Core/);
90efcf94 105 __PACKAGE__->table('cd');
106 __PACKAGE__->add_columns(qw/ cdid artist title/);
107 __PACKAGE__->set_primary_key('cdid');
108 __PACKAGE__->belongs_to('artist' => 'MyDatabase::Main::Artist');
109 __PACKAGE__->has_many('tracks' => 'MyDatabase::Main::Track');
3f341474 110
90efcf94 111 1;
3f341474 112
113
114MyDatabase/Main/Track.pm:
115
90efcf94 116 package MyDatabase::Main::Track;
117 use base qw/DBIx::Class/;
e8cc984c 118 __PACKAGE__->load_components(qw/PK::Auto Core/);
90efcf94 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::Cd');
3f341474 123
90efcf94 124 1;
3f341474 125
126
127=head3 Write a script to insert some records.
128
129insertdb.pl
130
90efcf94 131 #!/usr/bin/perl -w
132
133 use MyDatabase::Main;
134 use strict;
135
d3c2fbd8 136 my $schema = MyDatabase::Main->connect('dbi:SQLite:db/example.db');
90efcf94 137
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');
141
142 my @artists = (['Michael Jackson'], ['Eminem']);
143 $schema->populate('Artist', [
49e87fbb 144 [qw/name/],
145 @artists,
90efcf94 146 ]);
147
148 my %albums = (
49e87fbb 149 'Thriller' => 'Michael Jackson',
150 'Bad' => 'Michael Jackson',
151 'The Marshall Mathers LP' => 'Eminem',
152 );
90efcf94 153
154 my @cds;
155 foreach my $lp (keys %albums) {
49e87fbb 156 my $artist = $schema->resultset('Artist')->search({
157 name => $albums{$lp}
158 });
159 push @cds, [$lp, $artist->first];
90efcf94 160 }
161
162 $schema->populate('Cd', [
49e87fbb 163 [qw/title artist/],
164 @cds,
90efcf94 165 ]);
166
167
168 my %tracks = (
49e87fbb 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',
90efcf94 176 );
177
178 my @tracks;
179 foreach my $track (keys %tracks) {
49e87fbb 180 my $cdname = $schema->resultset('Cd')->search({
181 title => $tracks{$track},
182 });
183 push @tracks, [$cdname->first, $track];
90efcf94 184 }
185
186 $schema->populate('Track',[
49e87fbb 187 [qw/cd title/],
188 @tracks,
90efcf94 189 ]);
3f341474 190
e8cc984c 191=head3 Create and run the test scripts
3f341474 192
193testdb.pl:
194
90efcf94 195 #!/usr/bin/perl -w
196
197 use MyDatabase::Main;
198 use strict;
199
d3c2fbd8 200 my $schema = MyDatabase::Main->connect('dbi:SQLite:db/example.db');
e8cc984c 201 # for other DSNs, e.g. MySql, see the perldoc for the relevant dbd
202 # driver, e.g perldoc L<DBD::mysql>.
90efcf94 203
204 get_tracks_by_cd('Bad');
205 get_tracks_by_artist('Michael Jackson');
206
207 get_cd_by_track('Stan');
208 get_cds_by_artist('Michael Jackson');
209
210 get_artist_by_track('Dirty Diana');
211 get_artist_by_cd('The Marshall Mathers LP');
212
213
214 sub get_tracks_by_cd {
49e87fbb 215 my $cdtitle = shift;
216 print "get_tracks_by_cd($cdtitle):\n";
217 my $rs = $schema->resultset('Track')->search(
218 {
219 'cd.title' => $cdtitle
220 },
221 {
222 join => [qw/ cd /],
223 prefetch => [qw/ cd /]
90efcf94 224 }
49e87fbb 225 );
226 while (my $track = $rs->next) {
227 print $track->title . "\n";
228 }
229 print "\n";
90efcf94 230 }
231
232 sub get_tracks_by_artist {
49e87fbb 233 my $artistname = shift;
234 print "get_tracks_by_artist($artistname):\n";
235 my $rs = $schema->resultset('Track')->search(
236 {
237 'artist.name' => $artistname
238 },
239 {
240 join => {
241 'cd' => 'artist'
242 },
90efcf94 243 }
49e87fbb 244 );
245 while (my $track = $rs->next) {
246 print $track->title . "\n";
247 }
248 print "\n";
90efcf94 249 }
250
251
90efcf94 252 sub get_cd_by_track {
49e87fbb 253 my $tracktitle = shift;
254 print "get_cd_by_track($tracktitle):\n";
255 my $rs = $schema->resultset('Cd')->search(
256 {
257 'tracks.title' => $tracktitle
258 },
259 {
260 join => [qw/ tracks /],
261 }
262 );
263 my $cd = $rs->first;
264 print $cd->title . "\n\n";
90efcf94 265 }
266
267 sub get_cds_by_artist {
49e87fbb 268 my $artistname = shift;
269 print "get_cds_by_artist($artistname):\n";
270 my $rs = $schema->resultset('Cd')->search(
271 {
272 'artist.name' => $artistname
273 },
274 {
275 join => [qw/ artist /],
276 prefetch => [qw/ artist /]
90efcf94 277 }
49e87fbb 278 );
279 while (my $cd = $rs->next) {
280 print $cd->title . "\n";
281 }
282 print "\n";
90efcf94 283 }
284
285
286
287 sub get_artist_by_track {
49e87fbb 288 my $tracktitle = shift;
289 print "get_artist_by_track($tracktitle):\n";
290 my $rs = $schema->resultset('Artist')->search(
291 {
292 'tracks.title' => $tracktitle
293 },
294 {
295 join => {
296 'cds' => 'tracks'
297 }
298 }
299 );
300 my $artist = $rs->first;
301 print $artist->name . "\n\n";
90efcf94 302 }
303
304 sub get_artist_by_cd {
49e87fbb 305 my $cdtitle = shift;
306 print "get_artist_by_cd($cdtitle):\n";
307 my $rs = $schema->resultset('Artist')->search(
308 {
309 'cds.title' => $cdtitle
310 },
311 {
312 join => [qw/ cds /],
313 }
314 );
315 my $artist = $rs->first;
316 print $artist->name . "\n\n";
90efcf94 317 }
3f341474 318
319
320
321It should output:
322
90efcf94 323 get_tracks_by_cd(Bad):
324 Dirty Diana
325 Smooth Criminal
326 Leave Me Alone
3f341474 327
90efcf94 328 get_tracks_by_artist(Michael Jackson):
329 Beat it
330 Billie Jean
331 Dirty Diana
332 Smooth Criminal
333 Leave Me Alone
3f341474 334
90efcf94 335 get_cd_by_track(Stan):
336 The Marshall Mathers LP
3f341474 337
90efcf94 338 get_cds_by_artist(Michael Jackson):
339 Thriller
340 Bad
3f341474 341
90efcf94 342 get_artist_by_track(Dirty Diana):
343 Michael Jackson
3f341474 344
90efcf94 345 get_artist_by_cd(The Marshall Mathers LP):
346 Eminem
3f341474 347
348=head1 Notes
349
d3c2fbd8 350A reference implentation of the database and scripts in this example
351are available in the main distribution for DBIx::Class under the
352directory t/examples/Schema
353
3f341474 354With these scripts we're relying on @INC looking in the current
355working directory. You may want to add the MyDatabase namespaces to
880a1a0c 356@INC in a different way when it comes to deployment.
3f341474 357
358The testdb.pl script is an excellent start for testing your database
359model.
360
361=head1 TODO
362
363=head1 AUTHOR
364
365 sc_ from irc.perl.org#dbix-class
366 Kieren Diment <kd@totaldatasolution.com>
367
368=cut