Commit | Line | Data |
18fca96a |
1 | package DBIx::Class::Schema::Loader; |
a78e3fed |
2 | |
3 | use strict; |
a4a19f3c |
4 | use warnings; |
8a6b44ef |
5 | use base qw/DBIx::Class::Schema/; |
6 | use base qw/Class::Data::Accessor/; |
457eb8a6 |
7 | use Carp; |
8 | use UNIVERSAL::require; |
996be9ee |
9 | use Class::C3; |
10 | use Data::Dump qw/ dump /; |
c9f1d7b0 |
11 | use Scalar::Util qw/ weaken /; |
3980d69c |
12 | |
a4a19f3c |
13 | # Always remember to do all digits for the version even if they're 0 |
14 | # i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports |
15 | # brain damage and presumably various other packaging systems too |
996be9ee |
16 | our $VERSION = '0.02999_10'; |
457eb8a6 |
17 | |
996be9ee |
18 | __PACKAGE__->mk_classaccessor('dump_to_dir'); |
457eb8a6 |
19 | __PACKAGE__->mk_classaccessor('loader'); |
996be9ee |
20 | __PACKAGE__->mk_classaccessor('_loader_args'); |
a78e3fed |
21 | |
22 | =head1 NAME |
23 | |
18fca96a |
24 | DBIx::Class::Schema::Loader - Dynamic definition of a DBIx::Class::Schema |
a78e3fed |
25 | |
26 | =head1 SYNOPSIS |
27 | |
a4a19f3c |
28 | package My::Schema; |
29 | use base qw/DBIx::Class::Schema::Loader/; |
a78e3fed |
30 | |
996be9ee |
31 | __PACKAGE__->loader_options( |
32 | relationships => 1, |
33 | constraint => '^foo.*', |
34 | # debug => 1, |
a78e3fed |
35 | ); |
af6c2665 |
36 | |
a4a19f3c |
37 | # in seperate application code ... |
a78e3fed |
38 | |
a4a19f3c |
39 | use My::Schema; |
a78e3fed |
40 | |
a4a19f3c |
41 | my $schema1 = My::Schema->connect( $dsn, $user, $password, $attrs); |
42 | # -or- |
996be9ee |
43 | my $schema1 = "My::Schema"; $schema1->connection(as above); |
44 | =head1 DESCRIPTION |
fbd83464 |
45 | DBIx::Class::Schema::Loader automates the definition of a |
996be9ee |
46 | L<DBIx::Class::Schema> by scanning database table definitions and |
47 | setting up the columns and primary keys. |
a78e3fed |
48 | |
996be9ee |
49 | DBIx::Class::Schema::Loader currently supports DBI for MySQL, |
50 | Postgres, SQLite and DB2. |
a78e3fed |
51 | |
996be9ee |
52 | See L<DBIx::Class::Schema::Loader::DBI::Writing> for notes on writing |
53 | your own vendor-specific subclass for an unsupported DBD driver. |
a78e3fed |
54 | |
996be9ee |
55 | This module requires L<DBIx::Class> 0.06 or later, and obsoletes |
56 | the older L<DBIx::Class::Loader>. |
89ecd854 |
57 | |
996be9ee |
58 | This module is designed more to get you up and running quickly against |
59 | an existing database, or to be effective for simple situations, rather |
60 | than to be what you use in the long term for a complex database/project. |
89ecd854 |
61 | |
62 | That being said, transitioning your code from a Schema generated by this |
63 | module to one that doesn't use this module should be straightforward and |
996be9ee |
64 | painless (as long as you're not using any methods that are now deprecated |
65 | in this document), so don't shy away from it just for fears of the |
66 | transition down the road. |
89ecd854 |
67 | |
a78e3fed |
68 | =head1 METHODS |
69 | |
996be9ee |
70 | =head2 loader_options |
a78e3fed |
71 | |
996be9ee |
72 | Example in Synopsis above demonstrates a few common arguments. For |
73 | detailed information on all of the arguments, most of which are |
74 | only useful in fairly complex scenarios, see the |
75 | L<DBIx::Class::Schema::Loader::Base> documentation. |
a78e3fed |
76 | |
996be9ee |
77 | This method is *required*, for backwards compatibility reasons. If |
78 | you do not wish to change any options, just call it with an empty |
79 | argument list during schema class initialization. |
a78e3fed |
80 | |
996be9ee |
81 | =cut |
1031d4f6 |
82 | |
996be9ee |
83 | sub loader_options { |
84 | my $self = shift; |
85 | |
86 | my %args; |
87 | if(ref $_[0] eq 'HASH') { |
88 | %args = %{$_[0]}; |
1031d4f6 |
89 | } |
90 | else { |
996be9ee |
91 | %args = @_; |
1031d4f6 |
92 | } |
93 | |
996be9ee |
94 | my $class = ref $self || $self; |
95 | $args{schema} = $self; |
96 | $args{schema_class} = $class; |
c9f1d7b0 |
97 | weaken($args{schema}) if ref $self; |
98 | |
996be9ee |
99 | $self->_loader_args(\%args); |
100 | $self->_invoke_loader if $self->storage && !$class->loader; |
101 | |
102 | $self; |
103 | } |
104 | |
105 | sub _invoke_loader { |
106 | my $self = shift; |
107 | my $class = ref $self || $self; |
108 | |
109 | $self->_loader_args->{dump_directory} ||= $self->dump_to_dir; |
af6c2665 |
110 | |
996be9ee |
111 | # XXX this only works for relative storage_type, like ::DBI ... |
112 | my $impl = "DBIx::Class::Schema::Loader" . $self->storage_type; |
a78e3fed |
113 | $impl->require or |
996be9ee |
114 | croak qq/Could not load storage_type loader "$impl": / . |
3385ac62 |
115 | qq/"$UNIVERSAL::require::ERROR"/; |
af6c2665 |
116 | |
996be9ee |
117 | # XXX in the future when we get rid of ->loader, the next two |
118 | # lines can be replaced by "$impl->new(%{$self->_loader_args})->load;" |
119 | $class->loader($impl->new(%{$self->_loader_args})); |
2a4b8262 |
120 | $class->loader->load; |
996be9ee |
121 | |
122 | |
123 | $self; |
124 | } |
125 | |
126 | =head2 connection |
127 | |
128 | See L<DBIx::Class::Schema>. Our local override here is to |
129 | hook in the main functionality of the loader, which occurs at the time |
130 | the connection is specified for a given schema class/object. |
131 | |
132 | =cut |
133 | |
134 | sub connection { |
135 | my $self = shift->next::method(@_); |
136 | |
137 | my $class = ref $self || $self; |
138 | $self->_invoke_loader if $self->_loader_args && !$class->loader; |
139 | |
140 | return $self; |
141 | } |
142 | |
143 | =head2 clone |
144 | |
145 | See L<DBIx::Class::Schema>. Our local override here is to |
146 | make sure cloned schemas can still be loaded at runtime by |
147 | copying and altering a few things here. |
148 | |
149 | =cut |
150 | |
151 | sub clone { |
152 | my $self = shift; |
153 | |
154 | my $clone = $self->next::method(@_); |
155 | |
156 | $clone->_loader_args($self->_loader_args); |
157 | $clone->_loader_args->{schema} = $clone; |
c9f1d7b0 |
158 | weaken($clone->_loader_args->{schema}); |
996be9ee |
159 | |
160 | $clone; |
161 | } |
162 | |
163 | =head2 dump_to_dir |
164 | |
165 | Argument: directory name. |
166 | |
167 | Calling this as a class method on either L<DBIx::Class::Schema::Loader> |
168 | or any derived schema class will cause all affected schemas to dump |
169 | manual versions of themselves to the named directory when they are |
170 | loaded. In order to be effective, this must be set before defining a |
171 | connection on this schema class or any derived object (as the loading |
172 | happens at connection time, and only once per class). |
173 | |
174 | See L<DBIx::Class::Schema::Loader::Base/dump_directory> for more |
175 | details on the dumping mechanism. |
176 | |
177 | This can also be set at module import time via the import option |
178 | C<dump_to_dir:/foo/bar> to L<DBIx::Class::Schema::Loader>, where |
179 | C</foo/bar> is the target directory. |
180 | |
181 | Examples: |
182 | |
183 | # My::Schema isa DBIx::Class::Schema::Loader, and has connection info |
184 | # hardcoded in the class itself: |
185 | perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e1 |
186 | |
187 | # Same, but no hard-coded connection, so we must provide one: |
188 | perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e 'My::Schema->connection("dbi:Pg:dbname=foo", ...)' |
189 | |
190 | # Or as a class method, as long as you get it done *before* defining a |
191 | # connection on this schema class or any derived object: |
192 | use My::Schema; |
193 | My::Schema->dump_to_dir('/foo/bar'); |
194 | My::Schema->connection(........); |
195 | |
196 | # Or as a class method on the DBIx::Class::Schema::Loader itself, which affects all |
197 | # derived schemas |
198 | use My::Schema; |
199 | use My::OtherSchema; |
200 | DBIx::Class::Schema::Loader->dump_to_dir('/foo/bar'); |
201 | My::Schema->connection(.......); |
202 | My::OtherSchema->connection(.......); |
203 | |
204 | # Another alternative to the above: |
205 | use DBIx::Class::Schema::Loader qw| dump_to_dir:/foo/bar |; |
206 | use My::Schema; |
207 | use My::OtherSchema; |
208 | My::Schema->connection(.......); |
209 | My::OtherSchema->connection(.......); |
210 | |
211 | =cut |
212 | |
213 | sub import { |
214 | my $self = shift; |
215 | return if !@_; |
216 | foreach my $opt (@_) { |
217 | if($opt =~ m{^dump_to_dir:(.*)$}) { |
218 | $self->dump_to_dir($1) |
219 | } |
220 | elsif($opt eq 'make_schema_at') { |
221 | no strict 'refs'; |
222 | my $cpkg = (caller)[0]; |
223 | *{"${cpkg}::make_schema_at"} = \&make_schema_at; |
224 | } |
225 | } |
226 | } |
227 | |
228 | =head2 make_schema_at |
229 | |
230 | This simple function allows one to create a Loader-based schema |
231 | in-memory on the fly without any on-disk class files of any |
232 | kind. When used with the C<dump_directory> option, you can |
233 | use this to generate a rought draft manual schema from a dsn |
234 | without the intermediate step of creating a physical Loader-based |
235 | schema class. |
236 | |
237 | This function can be exported/imported by the normal means, as |
238 | illustrated in these Examples: |
239 | |
240 | # Simple example... |
241 | use DBIx::Class::Schema::Loader qw/ make_schema_at /; |
242 | make_schema_at( |
243 | 'New::Schema::Name', |
244 | { relationships => 1, debug => 1 }, |
245 | [ 'dbi:Pg:dbname="foo"','postgres' ], |
246 | ); |
247 | |
248 | # Complex: dump loaded schema to disk, all from the commandline: |
249 | perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at("New::Schema::Name", { relationships => 1 }, [ 'dbi:Pg:dbname="foo"','postgres' ])' |
250 | |
251 | # Same, but inside a script, and using a different way to specify the |
252 | # dump directory: |
253 | use DBIx::Class::Schema::Loader qw/ make_schema_at /; |
254 | make_schema_at( |
255 | 'New::Schema::Name', |
256 | { relationships => 1, debug => 1, dump_directory => './lib' }, |
257 | [ 'dbi:Pg:dbname="foo"','postgres' ], |
258 | ); |
259 | |
260 | =cut |
261 | |
262 | sub make_schema_at { |
263 | my ($target, $opts, $connect_info) = @_; |
264 | |
265 | my $opts_dumped = dump($opts); |
266 | my $cinfo_dumped = dump(@$connect_info); |
267 | eval qq| |
268 | package $target; |
269 | use base qw/DBIx::Class::Schema::Loader/; |
270 | __PACKAGE__->loader_options($opts_dumped); |
271 | __PACKAGE__->connection($cinfo_dumped); |
272 | |; |
273 | } |
274 | |
275 | =head1 EXAMPLE |
276 | |
277 | Using the example in L<DBIx::Class::Manual::ExampleSchema> as a basis |
278 | replace the DB::Main with the following code: |
279 | |
280 | package DB::Main; |
281 | |
282 | use base qw/DBIx::Class::Schema::Loader/; |
283 | |
284 | __PACKAGE__->loader_options( |
285 | relationships => 1, |
286 | debug => 1, |
287 | ); |
288 | __PACKAGE__->connection('dbi:SQLite:example.db'); |
289 | |
290 | 1; |
291 | |
292 | and remove the Main directory tree (optional). Every thing else |
293 | should work the same |
294 | |
295 | =head1 DEPRECATED METHODS |
296 | |
297 | You don't need to read anything in this section unless you're upgrading |
298 | code that was written against pre-0.03 versions of this module. This |
299 | version is intended to be backwards-compatible with pre-0.03 code, but |
300 | will issue warnings about your usage of deprecated features/methods. |
301 | |
302 | =head2 load_from_connection |
303 | |
304 | This deprecated method is now roughly an alias for L</loader_options>. |
305 | |
306 | In the past it was a common idiom to invoke this method |
307 | after defining a connection on the schema class. That usage is now |
308 | deprecated. The correct way to do things from now forward is to |
309 | always do C<loader_options> on the class before C<connect> or |
310 | C<connection> is invoked on the class or any derived object. |
311 | |
312 | This method *will* dissappear in a future version. |
313 | |
314 | For now, using this method will invoke the legacy behavior for |
315 | backwards compatibility, and merely emit a warning about upgrading |
316 | your code. |
317 | |
318 | It also reverts the default inflection scheme to |
319 | use L<Lingua::EN::Inflect> just like pre-0.03 versions of this |
320 | module did. |
321 | |
322 | You can force these legacy inflections with the |
323 | option C<legacy_default_inflections>, even after switch over |
324 | to the preferred L</loader_options> way of doing things. |
325 | |
326 | See the source of this method for more details. |
327 | |
328 | =cut |
329 | |
330 | sub load_from_connection { |
331 | my ($self, %args) = @_; |
332 | warn 'load_from_connection deprecated, please [re-]read the' |
333 | . ' [new] DBIx::Class::Schema::Loader documentation'; |
334 | |
335 | # Support the old connect_info / dsn / etc args... |
336 | $args{connect_info} = [ |
337 | delete $args{dsn}, |
338 | delete $args{user}, |
339 | delete $args{password}, |
340 | delete $args{options}, |
341 | ] if $args{dsn}; |
342 | |
343 | $self->connection(@{delete $args{connect_info}}) |
344 | if $args{connect_info}; |
345 | |
346 | $self->loader_options('legacy_default_inflections' => 1, %args); |
a78e3fed |
347 | } |
348 | |
457eb8a6 |
349 | =head2 loader |
350 | |
351 | This is an accessor in the generated Schema class for accessing |
996be9ee |
352 | the L<DBIx::Class::Schema::Loader::Base> -based loader object |
457eb8a6 |
353 | that was used during construction. See the |
996be9ee |
354 | L<DBIx::Class::Schema::Loader::Base> docs for more information |
457eb8a6 |
355 | on the available loader methods there. |
356 | |
996be9ee |
357 | This accessor is deprecated. Do not use it. Anything you can |
358 | get from C<loader>, you can get via the normal L<DBIx::Class::Schema> |
359 | methods, and your code will be more robust and forward-thinking |
360 | for doing so. |
361 | |
362 | If you're already using C<loader> in your code, make an effort |
363 | to get rid of it. If you think you've found a situation where it |
364 | is neccesary, let me know and we'll see what we can do to remedy |
365 | that situation. |
366 | |
367 | In some future version, this accessor *will* disappear. It was |
368 | apparently quite a design/API mistake to ever have exposed it to |
369 | user-land in the first place, all things considered. |
370 | |
371 | =head1 KNOWN ISSUES |
372 | |
373 | =head2 Multiple Database Schemas |
374 | |
375 | Currently the loader is limited to working within a single schema |
376 | (using the database vendors' definition of "schema"). If you |
377 | have a multi-schema database with inter-schema relationships (which |
378 | is easy to do in Postgres or DB2 for instance), you only get to |
379 | automatically load the tables of one schema, and any relationships |
380 | to tables in other schemas will be silently ignored. |
381 | |
382 | At some point in the future, an intelligent way around this might be |
383 | devised, probably by allowing the C<db_schema> option to be an |
384 | arrayref of schemas to load, or perhaps even offering schema |
385 | constraint/exclusion options just like the table ones. |
89ecd854 |
386 | |
996be9ee |
387 | In "normal" L<DBIx::Class::Schema> usage, manually-defined |
388 | source classes and relationships have no problems crossing vendor schemas. |
89ecd854 |
389 | |
a78e3fed |
390 | =head1 AUTHOR |
391 | |
f654c972 |
392 | Brandon Black, C<blblack@gmail.com> |
fbd83464 |
393 | |
8a6b44ef |
394 | Based on L<DBIx::Class::Loader> by Sebastian Riedel |
a78e3fed |
395 | |
396 | Based upon the work of IKEBE Tomohiro |
397 | |
398 | =head1 THANK YOU |
399 | |
400 | Adam Anderson, Andy Grundman, Autrijus Tang, Dan Kubb, David Naughton, |
996be9ee |
401 | Randal Schwartz, Simon Flack, Matt S Trout, everyone on #dbix-class, and |
402 | all the others who've helped. |
a78e3fed |
403 | |
404 | =head1 LICENSE |
405 | |
406 | This library is free software; you can redistribute it and/or modify it under |
407 | the same terms as Perl itself. |
408 | |
409 | =head1 SEE ALSO |
410 | |
996be9ee |
411 | L<DBIx::Class>, L<DBIx::Class::Manual::ExampleSchema> |
a78e3fed |
412 | |
413 | =cut |
414 | |
415 | 1; |