Commit | Line | Data |
18fca96a |
1 | package DBIx::Class::Schema::Loader; |
a78e3fed |
2 | |
3 | use strict; |
a4a19f3c |
4 | use warnings; |
f6148834 |
5 | use base qw/DBIx::Class::Schema Class::Data::Accessor/; |
fa994d3c |
6 | use Carp::Clan qw/^DBIx::Class/; |
457eb8a6 |
7 | use UNIVERSAL::require; |
996be9ee |
8 | use Class::C3; |
c9f1d7b0 |
9 | use Scalar::Util qw/ weaken /; |
3980d69c |
10 | |
a4a19f3c |
11 | # Always remember to do all digits for the version even if they're 0 |
12 | # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports |
13 | # brain damage and presumably various other packaging systems too |
eb1de218 |
14 | our $VERSION = '0.04006'; |
457eb8a6 |
15 | |
59cfa251 |
16 | __PACKAGE__->mk_classaccessor('_loader_args' => {}); |
79fe0081 |
17 | __PACKAGE__->mk_classaccessors(qw/dump_to_dir _loader_invoked _loader/); |
a78e3fed |
18 | |
19 | =head1 NAME |
20 | |
18fca96a |
21 | DBIx::Class::Schema::Loader - Dynamic definition of a DBIx::Class::Schema |
a78e3fed |
22 | |
23 | =head1 SYNOPSIS |
24 | |
a4a19f3c |
25 | package My::Schema; |
26 | use base qw/DBIx::Class::Schema::Loader/; |
a78e3fed |
27 | |
996be9ee |
28 | __PACKAGE__->loader_options( |
996be9ee |
29 | constraint => '^foo.*', |
30 | # debug => 1, |
a78e3fed |
31 | ); |
af6c2665 |
32 | |
a4a19f3c |
33 | # in seperate application code ... |
a78e3fed |
34 | |
a4a19f3c |
35 | use My::Schema; |
a78e3fed |
36 | |
a4a19f3c |
37 | my $schema1 = My::Schema->connect( $dsn, $user, $password, $attrs); |
38 | # -or- |
996be9ee |
39 | my $schema1 = "My::Schema"; $schema1->connection(as above); |
074e81cd |
40 | |
996be9ee |
41 | =head1 DESCRIPTION |
074e81cd |
42 | |
fbd83464 |
43 | DBIx::Class::Schema::Loader automates the definition of a |
996be9ee |
44 | L<DBIx::Class::Schema> by scanning database table definitions and |
d65cda9e |
45 | setting up the columns, primary keys, and relationships. |
a78e3fed |
46 | |
d65cda9e |
47 | DBIx::Class::Schema::Loader currently supports only the DBI storage type. |
3fe9c5d9 |
48 | It has explicit support for L<DBD::Pg>, L<DBD::mysql>, L<DBD::DB2>, |
49 | L<DBD::SQLite>, and L<DBD::Oracle>. Other DBI drivers may function to |
50 | a greater or lesser degree with this loader, depending on how much of the |
51 | DBI spec they implement, and how standard their implementation is. |
52 | |
53 | Patches to make other DBDs work correctly welcome. |
a78e3fed |
54 | |
996be9ee |
55 | See L<DBIx::Class::Schema::Loader::DBI::Writing> for notes on writing |
56 | your own vendor-specific subclass for an unsupported DBD driver. |
a78e3fed |
57 | |
3fe9c5d9 |
58 | This module requires L<DBIx::Class> 0.07006 or later, and obsoletes |
996be9ee |
59 | the older L<DBIx::Class::Loader>. |
89ecd854 |
60 | |
996be9ee |
61 | This module is designed more to get you up and running quickly against |
62 | an existing database, or to be effective for simple situations, rather |
63 | than to be what you use in the long term for a complex database/project. |
89ecd854 |
64 | |
65 | That being said, transitioning your code from a Schema generated by this |
66 | module to one that doesn't use this module should be straightforward and |
59cfa251 |
67 | painless, so don't shy away from it just for fears of the transition down |
68 | the road. |
89ecd854 |
69 | |
a78e3fed |
70 | =head1 METHODS |
71 | |
996be9ee |
72 | =head2 loader_options |
a78e3fed |
73 | |
996be9ee |
74 | Example in Synopsis above demonstrates a few common arguments. For |
75 | detailed information on all of the arguments, most of which are |
76 | only useful in fairly complex scenarios, see the |
77 | L<DBIx::Class::Schema::Loader::Base> documentation. |
a78e3fed |
78 | |
3fe9c5d9 |
79 | If you intend to use C<loader_options>, you must call |
80 | C<loader_options> before any connection is made, or embed the |
81 | C<loader_options> in the connection information itself as shown |
82 | below. Setting C<loader_options> after the connection has |
59cfa251 |
83 | already been made is useless. |
a78e3fed |
84 | |
996be9ee |
85 | =cut |
1031d4f6 |
86 | |
996be9ee |
87 | sub loader_options { |
88 | my $self = shift; |
89 | |
d65cda9e |
90 | my %args = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_; |
996be9ee |
91 | $self->_loader_args(\%args); |
996be9ee |
92 | |
93 | $self; |
94 | } |
95 | |
96 | sub _invoke_loader { |
97 | my $self = shift; |
98 | my $class = ref $self || $self; |
99 | |
59cfa251 |
100 | my $args = $self->_loader_args; |
101 | |
102 | # set up the schema/schema_class arguments |
103 | $args->{schema} = $self; |
104 | $args->{schema_class} = $class; |
105 | weaken($args->{schema}) if ref $self; |
106 | $args->{dump_directory} ||= $self->dump_to_dir; |
af6c2665 |
107 | |
996be9ee |
108 | # XXX this only works for relative storage_type, like ::DBI ... |
109 | my $impl = "DBIx::Class::Schema::Loader" . $self->storage_type; |
a78e3fed |
110 | $impl->require or |
996be9ee |
111 | croak qq/Could not load storage_type loader "$impl": / . |
3385ac62 |
112 | qq/"$UNIVERSAL::require::ERROR"/; |
af6c2665 |
113 | |
b97c2c1e |
114 | $self->_loader($impl->new(%$args)); |
115 | $self->_loader->load; |
59cfa251 |
116 | $self->_loader_invoked(1); |
996be9ee |
117 | |
996be9ee |
118 | $self; |
119 | } |
120 | |
121 | =head2 connection |
122 | |
d65cda9e |
123 | See L<DBIx::Class::Schema> for basic usage. |
124 | |
125 | If the final argument is a hashref, and it contains a key C<loader_options>, |
126 | that key will be deleted, and its value will be used for the loader options, |
127 | just as if set via the L</loader_options> method above. |
128 | |
129 | The actual auto-loading operation (the heart of this module) will be invoked |
130 | as soon as the connection information is defined. |
996be9ee |
131 | |
132 | =cut |
133 | |
134 | sub connection { |
d65cda9e |
135 | my $self = shift; |
136 | |
137 | if($_[-1] && ref $_[-1] eq 'HASH') { |
138 | if(my $loader_opts = delete $_[-1]->{loader_options}) { |
139 | $self->loader_options($loader_opts); |
fd64d90d |
140 | pop @_ if !keys %{$_[-1]}; |
d65cda9e |
141 | } |
142 | } |
143 | |
144 | $self = $self->next::method(@_); |
996be9ee |
145 | |
146 | my $class = ref $self || $self; |
59cfa251 |
147 | if(!$class->_loader_invoked) { |
fa994d3c |
148 | $self->_invoke_loader |
149 | } |
996be9ee |
150 | |
151 | return $self; |
152 | } |
153 | |
154 | =head2 clone |
155 | |
074e81cd |
156 | See L<DBIx::Class::Schema>. |
996be9ee |
157 | |
158 | =cut |
159 | |
160 | sub clone { |
161 | my $self = shift; |
162 | |
163 | my $clone = $self->next::method(@_); |
164 | |
fa994d3c |
165 | if($clone->_loader_args) { |
166 | $clone->_loader_args->{schema} = $clone; |
167 | weaken($clone->_loader_args->{schema}); |
168 | } |
996be9ee |
169 | |
170 | $clone; |
171 | } |
172 | |
173 | =head2 dump_to_dir |
174 | |
175 | Argument: directory name. |
176 | |
177 | Calling this as a class method on either L<DBIx::Class::Schema::Loader> |
178 | or any derived schema class will cause all affected schemas to dump |
179 | manual versions of themselves to the named directory when they are |
180 | loaded. In order to be effective, this must be set before defining a |
181 | connection on this schema class or any derived object (as the loading |
074e81cd |
182 | happens as soon as both a connection and loader_options are set, and |
183 | only once per class). |
996be9ee |
184 | |
185 | See L<DBIx::Class::Schema::Loader::Base/dump_directory> for more |
186 | details on the dumping mechanism. |
187 | |
188 | This can also be set at module import time via the import option |
189 | C<dump_to_dir:/foo/bar> to L<DBIx::Class::Schema::Loader>, where |
190 | C</foo/bar> is the target directory. |
191 | |
192 | Examples: |
193 | |
194 | # My::Schema isa DBIx::Class::Schema::Loader, and has connection info |
195 | # hardcoded in the class itself: |
196 | perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e1 |
197 | |
198 | # Same, but no hard-coded connection, so we must provide one: |
199 | perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e 'My::Schema->connection("dbi:Pg:dbname=foo", ...)' |
200 | |
201 | # Or as a class method, as long as you get it done *before* defining a |
202 | # connection on this schema class or any derived object: |
203 | use My::Schema; |
204 | My::Schema->dump_to_dir('/foo/bar'); |
205 | My::Schema->connection(........); |
206 | |
207 | # Or as a class method on the DBIx::Class::Schema::Loader itself, which affects all |
208 | # derived schemas |
209 | use My::Schema; |
210 | use My::OtherSchema; |
211 | DBIx::Class::Schema::Loader->dump_to_dir('/foo/bar'); |
212 | My::Schema->connection(.......); |
213 | My::OtherSchema->connection(.......); |
214 | |
215 | # Another alternative to the above: |
216 | use DBIx::Class::Schema::Loader qw| dump_to_dir:/foo/bar |; |
217 | use My::Schema; |
218 | use My::OtherSchema; |
219 | My::Schema->connection(.......); |
220 | My::OtherSchema->connection(.......); |
221 | |
222 | =cut |
223 | |
224 | sub import { |
225 | my $self = shift; |
226 | return if !@_; |
227 | foreach my $opt (@_) { |
228 | if($opt =~ m{^dump_to_dir:(.*)$}) { |
229 | $self->dump_to_dir($1) |
230 | } |
231 | elsif($opt eq 'make_schema_at') { |
232 | no strict 'refs'; |
233 | my $cpkg = (caller)[0]; |
234 | *{"${cpkg}::make_schema_at"} = \&make_schema_at; |
235 | } |
236 | } |
237 | } |
238 | |
239 | =head2 make_schema_at |
240 | |
241 | This simple function allows one to create a Loader-based schema |
242 | in-memory on the fly without any on-disk class files of any |
243 | kind. When used with the C<dump_directory> option, you can |
8f9d7ce5 |
244 | use this to generate a rough draft manual schema from a dsn |
996be9ee |
245 | without the intermediate step of creating a physical Loader-based |
246 | schema class. |
247 | |
483987b9 |
248 | The return value is the input class name. |
249 | |
996be9ee |
250 | This function can be exported/imported by the normal means, as |
251 | illustrated in these Examples: |
252 | |
5223f24a |
253 | # Simple example, creates as a new class 'New::Schema::Name' in |
254 | # memory in the running perl interpreter. |
996be9ee |
255 | use DBIx::Class::Schema::Loader qw/ make_schema_at /; |
256 | make_schema_at( |
257 | 'New::Schema::Name', |
59cfa251 |
258 | { debug => 1 }, |
996be9ee |
259 | [ 'dbi:Pg:dbname="foo"','postgres' ], |
260 | ); |
261 | |
262 | # Complex: dump loaded schema to disk, all from the commandline: |
59cfa251 |
263 | perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at("New::Schema::Name", { debug => 1 }, [ "dbi:Pg:dbname=foo","postgres" ])' |
996be9ee |
264 | |
265 | # Same, but inside a script, and using a different way to specify the |
266 | # dump directory: |
267 | use DBIx::Class::Schema::Loader qw/ make_schema_at /; |
268 | make_schema_at( |
269 | 'New::Schema::Name', |
59cfa251 |
270 | { debug => 1, dump_directory => './lib' }, |
996be9ee |
271 | [ 'dbi:Pg:dbname="foo"','postgres' ], |
272 | ); |
273 | |
274 | =cut |
275 | |
276 | sub make_schema_at { |
277 | my ($target, $opts, $connect_info) = @_; |
278 | |
483987b9 |
279 | { |
280 | no strict 'refs'; |
281 | @{$target . '::ISA'} = qw/DBIx::Class::Schema::Loader/; |
282 | } |
283 | |
284 | $target->loader_options($opts); |
285 | $target->connection(@$connect_info); |
996be9ee |
286 | } |
287 | |
b97c2c1e |
288 | =head2 rescan |
289 | |
290 | Re-scans the database for newly added tables since the initial |
291 | load, and adds them to the schema at runtime, including relationships, |
292 | etc. Does not process drops or changes. |
293 | |
a60b5b8d |
294 | Returns a list of the new monikers added. |
295 | |
b97c2c1e |
296 | =cut |
297 | |
a60b5b8d |
298 | sub rescan { my $self = shift; $self->_loader->rescan($self) } |
b97c2c1e |
299 | |
996be9ee |
300 | =head1 EXAMPLE |
301 | |
302 | Using the example in L<DBIx::Class::Manual::ExampleSchema> as a basis |
303 | replace the DB::Main with the following code: |
304 | |
305 | package DB::Main; |
306 | |
307 | use base qw/DBIx::Class::Schema::Loader/; |
308 | |
309 | __PACKAGE__->loader_options( |
996be9ee |
310 | debug => 1, |
311 | ); |
312 | __PACKAGE__->connection('dbi:SQLite:example.db'); |
313 | |
314 | 1; |
315 | |
316 | and remove the Main directory tree (optional). Every thing else |
317 | should work the same |
318 | |
996be9ee |
319 | =head1 KNOWN ISSUES |
320 | |
321 | =head2 Multiple Database Schemas |
322 | |
323 | Currently the loader is limited to working within a single schema |
324 | (using the database vendors' definition of "schema"). If you |
325 | have a multi-schema database with inter-schema relationships (which |
8f9d7ce5 |
326 | is easy to do in PostgreSQL or DB2 for instance), you only get to |
996be9ee |
327 | automatically load the tables of one schema, and any relationships |
328 | to tables in other schemas will be silently ignored. |
329 | |
330 | At some point in the future, an intelligent way around this might be |
331 | devised, probably by allowing the C<db_schema> option to be an |
d65cda9e |
332 | arrayref of schemas to load. |
89ecd854 |
333 | |
996be9ee |
334 | In "normal" L<DBIx::Class::Schema> usage, manually-defined |
335 | source classes and relationships have no problems crossing vendor schemas. |
89ecd854 |
336 | |
a78e3fed |
337 | =head1 AUTHOR |
338 | |
f654c972 |
339 | Brandon Black, C<blblack@gmail.com> |
fbd83464 |
340 | |
8a6b44ef |
341 | Based on L<DBIx::Class::Loader> by Sebastian Riedel |
a78e3fed |
342 | |
343 | Based upon the work of IKEBE Tomohiro |
344 | |
345 | =head1 THANK YOU |
346 | |
d65cda9e |
347 | Matt S Trout, all of the #dbix-class folks, and everyone who's ever sent |
348 | in a bug report or suggestion. |
a78e3fed |
349 | |
350 | =head1 LICENSE |
351 | |
352 | This library is free software; you can redistribute it and/or modify it under |
353 | the same terms as Perl itself. |
354 | |
355 | =head1 SEE ALSO |
356 | |
996be9ee |
357 | L<DBIx::Class>, L<DBIx::Class::Manual::ExampleSchema> |
a78e3fed |
358 | |
359 | =cut |
360 | |
361 | 1; |