add first draft of intro doc for schema-based use
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Manual / SchemaIntro.pod
1 =head1 NAME
2
3 DBIx::Class::Manual::SchemaIntro - Introduction to DBIx::Class::Schema
4
5 =head1 INTRODUCTION
6
7 This document describes how to set up DBIx::Class using the recommended
8 schema-based approach.
9
10 =head2 Setup
11
12 First, you should create your base schema class, which inherits from
13 L<DBIx::Class::Schema>:
14
15   package My::Schema;
16   use base qw/DBIx::Class::Schema/;
17
18 In this class you load your resultsource ("table", "model") classes, which
19 we will define later, using the load_classes() method. You can specify which
20 classes to load manually: 
21
22   # load My::Schema::Album and My::Schema::Artist
23   __PACKAGE__->load_classes(qw/ Album Artist /);
24
25 Or load classes by namespace:
26
27   # load My::Schema::Album, My::Schema::Artist and My::OtherSchema::LinerNotes
28   __PACKAGE__->load_classes(
29     {
30       'My::Schema' => qw/ Album Artist /,
31       'My::OtherSchema' => qw/ LinerNotes /
32     }
33   );
34
35 Or let your schema class load all classes in its namespace automatically:
36
37    # load My::Schema::*
38   __PACKAGE__->load_classes();
39
40 Next, create each of the classes you want to load as specified above:
41
42   package My::Schema::Album;
43   use base qw/DBIx::Class/;
44
45 Load any components required by each class with the load_components() method.
46 This should consist of "Core" plus any additional components you want to use.
47 For example, if you use SQLite and want serial/auto-incrementing primary keys:
48
49   __PACKAGE__->load_components(qw/ PK::Auto::SQLite Core /);
50
51 C<PK::Auto> classes exist for many databases; see
52 L<DBIx::Class::PK::Auto> for more information.
53
54 Set the table for your class:
55
56   __PACKAGE__->table('album');
57
58 Add columns to your class:
59
60   __PACKAGE__->add_columns(qw/ albumid artist title /);
61
62 Accessors are created for each column automatically, so My::Schema::Album will
63 have albumid(), artist() and title() methods.
64
65 Define a primary key for your class:
66
67   __PACKAGE__->set_primary_key('albumid');
68
69 If you have a multi-column primary key, just pass a list instead:
70
71   __PACKAGE__->set_primary_key( qw/ albumid artistid / );
72
73 You can define relationships for any of your classes. L<DBIx::Class> will
74 automatically fill in the correct namespace, so if you want to say
75 "a My::Schema::Album object belongs to a My::Schema::Artist object" you do not
76 need to include the namespace when declaring the relationship:
77
78   __PACKAGE__->belongs_to('artist' => 'Artist');
79
80 That's all you need in terms of setup.
81
82 =head2 Usage
83
84 In your application code, you should first create a connected schema object:
85
86   my $schema = My::Schema->connect( $dsn, $user, $password, $attrs );
87
88 You can create as many different schema instances as you need. So if you have
89 a second database you want to access:
90
91   my $other_schema = My::Schema->connect( $dsn, $user, $password, $attrs );
92
93 Note that L<DBIx::Class::Schema> does not cache connnections for you. If you
94 use multiple connections, you need to do this manually.
95
96 The simplest way to get a record is by primary key:
97
98   my $schema = My::Schema->connect( ... );
99   my $album = $schema->resultset('Album')->find(14);
100
101 This will run a C<SELECT> with C<albumid = 14> in the C<WHERE> clause,
102 and return an instance of C<My::Schema::Album> that represents this
103 row. Once you have that row, you can access and update columns:
104
105   $album->name('Physical Graffiti');
106   my $title = $album->title; # holds 'Physical Graffiti'
107
108 If you prefer, you can use the C<set_column> and C<get_column>
109 accessors instead:
110
111   $album->set_column('title', 'Presence');
112   $title = $album->get_column('title');
113
114 You use C<update> to commit your changes to the database:
115
116   $album->update();
117
118 If needed, you can throw away your local changes like this:
119
120   $album->discard_changes() if $album->is_changed();
121
122 As you can see, C<is_changed> allows you to check if there are local
123 changes to your object.
124
125 =head2 Adding and removing rows
126
127 To create a new record in the database, you can use the C<create>
128 method.  It returns an instance of C<My::Schema::Album> that can be
129 used to access the data in the new record:
130
131   my $new_album = $schema->resultset('Album')->create({
132     title  => 'Wish You Were Here',
133     artist => 'Pink Floyd'
134   });
135
136 Now you can add data to the new record:
137
138   $new_album->label('Capitol');
139   $new_album->year('1975');
140   $new_album->update;
141
142 Likewise, you can remove it from the database like this:
143
144   $new_album->delete;
145
146 You can also remove records without or retrieving first.  This
147 operation takes the same kind of arguments as a search.
148
149   # Delete all of Falco's albums
150   $schema->resultset('Album')->delete({ artist => 'Falco' });
151
152 =head2 Finding your objects
153
154 L<DBIx::Class> provides a few different ways to retrieve data from
155 your database.  Here's one example:
156
157   # Find all of Santana's albums
158   my $rs = $schema->resultset('Album')->search({ artist => 'Santana' });
159
160 In scalar context, as above, C<search> returns a
161 L<DBIx::Class::ResultSet> object.  It can be used to peek at the first
162 album returned by the database:
163
164   my $album = $rs->first;
165   print $album->title;
166
167 Or, you can loop over the albums and update each one:
168
169   while (my $album = $rs->next) {
170     print $album->artist . ' - ' . $album->title;
171     $album->year(2001);
172     $album->update;
173   }
174
175 For more information on what you can do with a
176 L<DBIx::Class::ResultSet>, see L<DBIx::Class::ResultSet/METHODS>.
177
178 In list context, the C<search> method returns all of the matching
179 rows:
180
181   # Fetch immediately all of Carlos Santana's albums
182   my @albums = @{ $schema->resultset('Album')->search(
183     { artist => 'Carlos Santana' }
184   ) };
185   foreach my $album (@albums) {
186     print $album->artist . ' - ' . $album->title;
187   }
188
189 We also provide a handy shortcut for doing a C<LIKE> search:
190
191   # Find albums whose artist starts with 'Jimi'
192   my $rs = MyApp::DB::Album->search_like({ artist => 'Jimi%' });
193
194 Or you can provide your own handmade C<WHERE> clause, like:
195
196   # Find Peter Frampton albums from the year 1986
197   my $where = 'artist = ? AND year = ?';
198   my @bind  = ( 'Peter Frampton', 1986 );
199   my $rs    = $schema->resultset('Album')->search_literal( $where, @bind );
200
201 The preferred way to generate complex queries is to provide a
202 L<SQL::Abstract> construct to C<search>:
203
204   my $rs = $schema->resultset('Album')->search({
205     artist  => { '!=', 'Janis Joplin' },
206     year    => { '<' => 1980 },
207     albumid => [ 1, 14, 15, 65, 43 ]
208   });
209
210 This results in something like the following C<WHERE> clause:
211
212   WHERE artist != 'Janis Joplin'
213     AND year < 1980
214     AND albumid IN (1, 14, 15, 65, 43)
215
216 For more examples of complex queries, see
217 L<DBIx::Class::Manual::Cookbook>.
218
219 The search can also be modified by passing another hash with
220 attributes:
221
222   my @albums = $schema->resultset('Album')->search(
223     { artist => 'Bob Marley' },
224     { rows => 2, order_by => 'year DESC' }
225   );
226
227 C<@albums> then holds the two most recent Bob Marley albums.
228
229 For a complete overview of the available attributes, see
230 L<DBIx::Class::ResultSet/ATTRIBUTES>.
231
232 =head1 SEE ALSO
233
234 =over 4
235
236 =item * L<DBIx::Class::Manual::Cookbook>
237
238 =item * L<DBIx::Class::Manual::FAQ>
239
240 =back
241
242 =cut