POD fix for search.cpan.org
[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
3f341474 36
37This example uses SQLite which is a dependency of DBIx::Class, so you
38shouldn't have to install extra software.
39
40Save the following into a example.sql
41
90efcf94 42 CREATE TABLE artist (
49e87fbb 43 artistid INTEGER PRIMARY KEY,
44 name TEXT NOT NULL
90efcf94 45 );
3f341474 46
90efcf94 47 CREATE TABLE cd (
49e87fbb 48 cdid INTEGER PRIMARY KEY,
49 artist INTEGER NOT NULL REFERENCES artist(artistid),
50 title TEXT NOT NULL
51 );
3f341474 52
90efcf94 53 CREATE TABLE track (
49e87fbb 54 trackid INTEGER PRIMARY KEY,
55 cd INTEGER NOT NULL REFERENCES cd(cdid),
56 title TEXT NOT NULL
57 );
3f341474 58
59and create the sqlite database file:
60
61sqlite3 example.db < example.sql
62
63=head3 Set up DBIx::Class::Schema
64
65First, create some dirs and change working directory:
66
90efcf94 67 mkdir MyDatabase
68 mkdir MyDatabase/Main
3f341474 69
70Then, create the following DBIx::Class::Schema classes:
71
72MyDatabase/Main.pm:
90efcf94 73
74 package MyDatabase::Main;
75 use base qw/DBIx::Class::Schema/;
76 __PACKAGE__->load_classes(qw/Artist Cd Track/);
3f341474 77
90efcf94 78 1;
3f341474 79
80
81MyDatabase/Main/Artist.pm:
82
90efcf94 83 package MyDatabase::Main::Artist;
84 use base qw/DBIx::Class/;
85 __PACKAGE__->load_components(qw/Core/);
86 __PACKAGE__->table('artist');
87 __PACKAGE__->add_columns(qw/ artistid name /);
88 __PACKAGE__->set_primary_key('artistid');
89 __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Cd');
3f341474 90
90efcf94 91 1;
3f341474 92
93
94MyDatabase/Main/Cd.pm:
95
90efcf94 96 package MyDatabase::Main::Cd;
97 use base qw/DBIx::Class/;
98 __PACKAGE__->load_components(qw/Core/);
99 __PACKAGE__->table('cd');
100 __PACKAGE__->add_columns(qw/ cdid artist title/);
101 __PACKAGE__->set_primary_key('cdid');
102 __PACKAGE__->belongs_to('artist' => 'MyDatabase::Main::Artist');
103 __PACKAGE__->has_many('tracks' => 'MyDatabase::Main::Track');
3f341474 104
90efcf94 105 1;
3f341474 106
107
108MyDatabase/Main/Track.pm:
109
90efcf94 110 package MyDatabase::Main::Track;
111 use base qw/DBIx::Class/;
112 __PACKAGE__->load_components(qw/Core/);
113 __PACKAGE__->table('track');
114 __PACKAGE__->add_columns(qw/ trackid cd title/);
115 __PACKAGE__->set_primary_key('trackid');
116 __PACKAGE__->belongs_to('cd' => 'MyDatabase::Main::Cd');
3f341474 117
90efcf94 118 1;
3f341474 119
120
121=head3 Write a script to insert some records.
122
123insertdb.pl
124
90efcf94 125 #!/usr/bin/perl -w
126
127 use MyDatabase::Main;
128 use strict;
129
130 my $schema = MyDatabase::Main->connect('dbi:SQLite:example.db');
131
132 # here's some of the sql that is going to be generated by the schema
133 # INSERT INTO artist VALUES (NULL,'Michael Jackson');
134 # INSERT INTO artist VALUES (NULL,'Eminem');
135
136 my @artists = (['Michael Jackson'], ['Eminem']);
137 $schema->populate('Artist', [
49e87fbb 138 [qw/name/],
139 @artists,
90efcf94 140 ]);
141
142 my %albums = (
49e87fbb 143 'Thriller' => 'Michael Jackson',
144 'Bad' => 'Michael Jackson',
145 'The Marshall Mathers LP' => 'Eminem',
146 );
90efcf94 147
148 my @cds;
149 foreach my $lp (keys %albums) {
49e87fbb 150 my $artist = $schema->resultset('Artist')->search({
151 name => $albums{$lp}
152 });
153 push @cds, [$lp, $artist->first];
90efcf94 154 }
155
156 $schema->populate('Cd', [
49e87fbb 157 [qw/title artist/],
158 @cds,
90efcf94 159 ]);
160
161
162 my %tracks = (
49e87fbb 163 'Beat It' => 'Thriller',
164 'Billie Jean' => 'Thriller',
165 'Dirty Diana' => 'Bad',
166 'Smooth Criminal' => 'Bad',
167 'Leave Me Alone' => 'Bad',
168 'Stan' => 'The Marshall Mathers LP',
169 'The Way I Am' => 'The Marshall Mathers LP',
90efcf94 170 );
171
172 my @tracks;
173 foreach my $track (keys %tracks) {
49e87fbb 174 my $cdname = $schema->resultset('Cd')->search({
175 title => $tracks{$track},
176 });
177 push @tracks, [$cdname->first, $track];
90efcf94 178 }
179
180 $schema->populate('Track',[
49e87fbb 181 [qw/cd title/],
182 @tracks,
90efcf94 183 ]);
3f341474 184
185=head3 Create and run the scripts
186
187testdb.pl:
188
90efcf94 189 #!/usr/bin/perl -w
190
191 use MyDatabase::Main;
192 use strict;
193
194 my $schema = MyDatabase::Main->connect('dbi:SQLite:example.db');
195
196 get_tracks_by_cd('Bad');
197 get_tracks_by_artist('Michael Jackson');
198
199 get_cd_by_track('Stan');
200 get_cds_by_artist('Michael Jackson');
201
202 get_artist_by_track('Dirty Diana');
203 get_artist_by_cd('The Marshall Mathers LP');
204
205
206 sub get_tracks_by_cd {
49e87fbb 207 my $cdtitle = shift;
208 print "get_tracks_by_cd($cdtitle):\n";
209 my $rs = $schema->resultset('Track')->search(
210 {
211 'cd.title' => $cdtitle
212 },
213 {
214 join => [qw/ cd /],
215 prefetch => [qw/ cd /]
90efcf94 216 }
49e87fbb 217 );
218 while (my $track = $rs->next) {
219 print $track->title . "\n";
220 }
221 print "\n";
90efcf94 222 }
223
224 sub get_tracks_by_artist {
49e87fbb 225 my $artistname = shift;
226 print "get_tracks_by_artist($artistname):\n";
227 my $rs = $schema->resultset('Track')->search(
228 {
229 'artist.name' => $artistname
230 },
231 {
232 join => {
233 'cd' => 'artist'
234 },
90efcf94 235 }
49e87fbb 236 );
237 while (my $track = $rs->next) {
238 print $track->title . "\n";
239 }
240 print "\n";
90efcf94 241 }
242
243
90efcf94 244 sub get_cd_by_track {
49e87fbb 245 my $tracktitle = shift;
246 print "get_cd_by_track($tracktitle):\n";
247 my $rs = $schema->resultset('Cd')->search(
248 {
249 'tracks.title' => $tracktitle
250 },
251 {
252 join => [qw/ tracks /],
253 }
254 );
255 my $cd = $rs->first;
256 print $cd->title . "\n\n";
90efcf94 257 }
258
259 sub get_cds_by_artist {
49e87fbb 260 my $artistname = shift;
261 print "get_cds_by_artist($artistname):\n";
262 my $rs = $schema->resultset('Cd')->search(
263 {
264 'artist.name' => $artistname
265 },
266 {
267 join => [qw/ artist /],
268 prefetch => [qw/ artist /]
90efcf94 269 }
49e87fbb 270 );
271 while (my $cd = $rs->next) {
272 print $cd->title . "\n";
273 }
274 print "\n";
90efcf94 275 }
276
277
278
279 sub get_artist_by_track {
49e87fbb 280 my $tracktitle = shift;
281 print "get_artist_by_track($tracktitle):\n";
282 my $rs = $schema->resultset('Artist')->search(
283 {
284 'tracks.title' => $tracktitle
285 },
286 {
287 join => {
288 'cds' => 'tracks'
289 }
290 }
291 );
292 my $artist = $rs->first;
293 print $artist->name . "\n\n";
90efcf94 294 }
295
296 sub get_artist_by_cd {
49e87fbb 297 my $cdtitle = shift;
298 print "get_artist_by_cd($cdtitle):\n";
299 my $rs = $schema->resultset('Artist')->search(
300 {
301 'cds.title' => $cdtitle
302 },
303 {
304 join => [qw/ cds /],
305 }
306 );
307 my $artist = $rs->first;
308 print $artist->name . "\n\n";
90efcf94 309 }
3f341474 310
311
312
313It should output:
314
90efcf94 315 get_tracks_by_cd(Bad):
316 Dirty Diana
317 Smooth Criminal
318 Leave Me Alone
3f341474 319
90efcf94 320 get_tracks_by_artist(Michael Jackson):
321 Beat it
322 Billie Jean
323 Dirty Diana
324 Smooth Criminal
325 Leave Me Alone
3f341474 326
90efcf94 327 get_cd_by_track(Stan):
328 The Marshall Mathers LP
3f341474 329
90efcf94 330 get_cds_by_artist(Michael Jackson):
331 Thriller
332 Bad
3f341474 333
90efcf94 334 get_artist_by_track(Dirty Diana):
335 Michael Jackson
3f341474 336
90efcf94 337 get_artist_by_cd(The Marshall Mathers LP):
338 Eminem
3f341474 339
340=head1 Notes
341
342With these scripts we're relying on @INC looking in the current
343working directory. You may want to add the MyDatabase namespaces to
880a1a0c 344@INC in a different way when it comes to deployment.
3f341474 345
346The testdb.pl script is an excellent start for testing your database
347model.
348
349=head1 TODO
350
351=head1 AUTHOR
352
353 sc_ from irc.perl.org#dbix-class
354 Kieren Diment <kd@totaldatasolution.com>
355
356=cut