File Coverage

blib/lib/DBIx/Class/Schema/Loader/Base.pm
Criterion Covered Total %
statement 970 1096 88.5
branch 429 558 76.8
condition 208 286 72.7
subroutine 107 122 87.7
pod 5 5 100.0
total 1719 2067 83.1


line stmt bran cond sub pod time code
1             package DBIx::Class::Schema::Loader::Base;
2              
3 52     52   4614 use strict;
  52         113  
  52         2204  
4 52     52   371 use warnings;
  52         102  
  52         3410  
5 52     52   317 use base qw/Class::Accessor::Grouped Class::C3::Componentised/;
  52         141  
  52         12194  
6 52     52   20634 use MRO::Compat;
  52         232  
  52         2080  
7 52     52   312 use mro 'c3';
  52         138  
  52         493  
8 52     52   2880 use Carp::Clan qw/^DBIx::Class/;
  52         6404  
  52         613  
9 52     52   43382 use DBIx::Class::Schema::Loader::RelBuilder ();
  52         268  
  52         2393  
10 52     52   34922 use Data::Dump 'dump';
  52         362670  
  52         5486  
11 52     52   31756 use POSIX ();
  52         397353  
  52         3064  
12 52     52   485 use File::Spec ();
  52         139  
  52         1006  
13 52     52   298 use Cwd ();
  52         192  
  52         826  
14 52     52   279 use Digest::MD5 ();
  52         137  
  52         849  
15 52     52   246 use Lingua::EN::Inflect::Number ();
  52         151  
  52         857  
16 52     52   255 use Lingua::EN::Inflect::Phrase ();
  52         103  
  52         747  
17 52     52   287 use String::ToIdentifier::EN ();
  52         124  
  52         933  
18 52     52   249 use String::ToIdentifier::EN::Unicode ();
  52         113  
  52         797  
19 52     52   35055 use File::Temp ();
  52         537273  
  52         1830  
20 52     52   469 use Class::Unload;
  52         153  
  52         3149  
21 52     52   311 use Class::Inspector ();
  52         106  
  52         1264  
22 52     52   349 use Scalar::Util 'looks_like_number';
  52         111  
  52         3434  
23 52     52   44555 use DBIx::Class::Schema::Loader::Column;
  52         249  
  52         2694  
24 52     52   442 use DBIx::Class::Schema::Loader::Utils qw/split_name dumper_squashed eval_package_without_redefine_warnings class_path slurp_file sigwarn_silencer firstidx uniq/;
  52         143  
  52         6096  
25 52     52   41684 use DBIx::Class::Schema::Loader::Optional::Dependencies ();
  52         276  
  52         2423  
26 52     52   469 use Try::Tiny;
  52         122  
  52         4469  
27 52     52   982 use DBIx::Class ();
  52         25817  
  52         1344  
28 52     52   1587 use Encode qw/encode decode/;
  52         28009  
  52         4174  
29 52     52   384 use List::Util qw/all any none/;
  52         140  
  52         4010  
30 52     52   456 use File::Temp 'tempfile';
  52         223  
  52         3482  
31 52     52   1159 use curry;
  52         676  
  52         1307  
32 52     52   267 use namespace::clean;
  52         104  
  52         471  
33              
34             our $VERSION = '0.07053';
35              
36             __PACKAGE__->mk_group_ro_accessors('simple', qw/
37             schema
38             schema_class
39              
40             exclude
41             constraint
42             additional_classes
43             additional_base_classes
44             left_base_classes
45             components
46             schema_components
47             skip_relationships
48             skip_load_external
49             moniker_map
50             col_accessor_map
51             custom_column_info
52             inflect_singular
53             inflect_plural
54             debug
55             dump_directory
56             dump_overwrite
57             really_erase_my_files
58             resultset_namespace
59             default_resultset_class
60             schema_base_class
61             result_base_class
62             result_roles
63             use_moose
64             only_autoclean
65             overwrite_modifications
66             dry_run
67             generated_classes
68             omit_version
69             omit_timestamp
70              
71             relationship_attrs
72              
73             _tables
74             classes
75             _upgrading_classes
76             monikers
77             dynamic
78             naming
79             datetime_timezone
80             datetime_locale
81             config_file
82             loader_class
83             table_comments_table
84             column_comments_table
85             class_to_table
86             moniker_to_table
87             uniq_to_primary
88             quiet
89             allow_extra_m2m_cols
90             /);
91              
92              
93             __PACKAGE__->mk_group_accessors('simple', qw/
94             version_to_dump
95             schema_version_to_dump
96             _upgrading_from
97             _upgrading_from_load_classes
98             _downgrading_to_load_classes
99             _rewriting_result_namespace
100             use_namespaces
101             result_namespace
102             generate_pod
103             pod_comment_mode
104             pod_comment_spillover_length
105             preserve_case
106             col_collision_map
107             rel_collision_map
108             rel_name_map
109             real_dump_directory
110             result_components_map
111             result_roles_map
112             datetime_undef_if_invalid
113             _result_class_methods
114             naming_set
115             filter_generated_code
116             db_schema
117             qualify_objects
118             moniker_parts
119             moniker_part_separator
120             moniker_part_map
121             /);
122              
123             my $CURRENT_V = 'v7';
124              
125             my @CLASS_ARGS = qw(
126             schema_components schema_base_class result_base_class
127             additional_base_classes left_base_classes additional_classes components
128             result_roles
129             );
130              
131             my $CR = "\x0d";
132             my $LF = "\x0a";
133             my $CRLF = "\x0d\x0a";
134              
135             =head1 NAME
136              
137             DBIx::Class::Schema::Loader::Base - Base DBIx::Class::Schema::Loader Implementation.
138              
139             =head1 SYNOPSIS
140              
141             See L.
142              
143             =head1 DESCRIPTION
144              
145             This is the base class for the storage-specific C
146             classes, and implements the common functionality between them.
147              
148             =head1 CONSTRUCTOR OPTIONS
149              
150             These constructor options are the base options for
151             L. Available constructor options are:
152              
153             =head2 skip_relationships
154              
155             Skip setting up relationships. The default is to attempt the loading
156             of relationships.
157              
158             =head2 skip_load_external
159              
160             Skip loading of other classes in @INC. The default is to merge all other classes
161             with the same name found in @INC into the schema file we are creating.
162              
163             =head2 naming
164              
165             Static schemas (ones dumped to disk) will, by default, use the new-style
166             relationship names and singularized Results, unless you're overwriting an
167             existing dump made by an older version of L, in
168             which case the backward compatible RelBuilder will be activated, and the
169             appropriate monikerization used.
170              
171             Specifying
172              
173             naming => 'current'
174              
175             will disable the backward-compatible RelBuilder and use
176             the new-style relationship names along with singularized Results, even when
177             overwriting a dump made with an earlier version.
178              
179             The option also takes a hashref:
180              
181             naming => {
182             relationships => 'v8',
183             monikers => 'v8',
184             column_accessors => 'v8',
185             force_ascii => 1,
186             }
187              
188             or
189              
190             naming => { ALL => 'v8', force_ascii => 1 }
191              
192             The keys are:
193              
194             =over 4
195              
196             =item ALL
197              
198             Set L, L and L to the specified
199             value.
200              
201             =item relationships
202              
203             How to name relationship accessors.
204              
205             =item monikers
206              
207             How to name Result classes.
208              
209             =item column_accessors
210              
211             How to name column accessors in Result classes.
212              
213             =item force_ascii
214              
215             For L mode and later, uses L instead of
216             L to force monikers and other identifiers to
217             ASCII.
218              
219             =back
220              
221             The values can be:
222              
223             =over 4
224              
225             =item current
226              
227             Latest style, whatever that happens to be.
228              
229             =item v4
230              
231             Unsingularlized monikers, C only relationships with no _id stripping.
232              
233             =item v5
234              
235             Monikers singularized as whole words, C relationships for FKs on
236             C constraints, C<_id> stripping for belongs_to relationships.
237              
238             Some of the C<_id> stripping edge cases in C<0.05003> have been reverted for
239             the v5 RelBuilder.
240              
241             =item v6
242              
243             All monikers and relationships are inflected using
244             L, and there is more aggressive C<_id> stripping
245             from relationship names.
246              
247             In general, there is very little difference between v5 and v6 schemas.
248              
249             =item v7
250              
251             This mode is identical to C mode, except that monikerization of CamelCase
252             table names is also done better (but best in v8.)
253              
254             CamelCase column names in case-preserving mode will also be handled better
255             for relationship name inflection (but best in v8.) See L.
256              
257             In this mode, CamelCase L are normalized based on case
258             transition instead of just being lowercased, so C becomes C.
259              
260             =item v8
261              
262             (EXPERIMENTAL)
263              
264             The default mode is L, to get L mode, you have to specify it in
265             L explicitly until C<0.08> comes out.
266              
267             L and L are created using
268             L or L if
269             L is set; this is only significant for names with non-C<\w>
270             characters such as C<.>.
271              
272             CamelCase identifiers with words in all caps, e.g. C are supported
273             correctly in this mode.
274              
275             For relationships, belongs_to accessors are made from column names by stripping
276             postfixes other than C<_id> as well, for example just C, C<_?ref>, C<_?cd>,
277             C<_?code> and C<_?num>, case insensitively.
278              
279             =item preserve
280              
281             For L, this option does not inflect the table names but makes
282             monikers based on the actual name. For L this option does
283             not normalize CamelCase column names to lowercase column accessors, but makes
284             accessors that are the same names as the columns (with any non-\w chars
285             replaced with underscores.)
286              
287             =item singular
288              
289             For L, singularizes the names using the most current inflector. This
290             is the same as setting the option to L.
291              
292             =item plural
293              
294             For L, pluralizes the names, using the most current inflector.
295              
296             =back
297              
298             Dynamic schemas will always default to the 0.04XXX relationship names and won't
299             singularize Results for backward compatibility, to activate the new RelBuilder
300             and singularization put this in your C file:
301              
302             __PACKAGE__->naming('current');
303              
304             Or if you prefer to use 0.07XXX features but insure that nothing breaks in the
305             next major version upgrade:
306              
307             __PACKAGE__->naming('v7');
308              
309             =head2 quiet
310              
311             If true, will not print the usual C
312             completed.> messages. Does not affect warnings (except for warnings related to
313             L.)
314              
315             =head2 dry_run
316              
317             If true, don't actually write out the generated files. This can only be
318             used with static schema generation.
319              
320             =head2 generate_pod
321              
322             By default POD will be generated for columns and relationships, using database
323             metadata for the text if available and supported.
324              
325             Comment metadata can be stored in two ways.
326              
327             The first is that you can create two tables named C and
328             C respectively. These tables must exist in the same database
329             and schema as the tables they describe. They both need to have columns named
330             C and C. The second one needs to have a column named
331             C. Then data stored in these tables will be used as a source of
332             metadata about tables and comments.
333              
334             (If you wish you can change the name of these tables with the parameters
335             L and L.)
336              
337             As a fallback you can use built-in commenting mechanisms. Currently this is
338             only supported for PostgreSQL, Oracle and MySQL. To create comments in
339             PostgreSQL you add statements of the form C
340             '...'>, the same syntax is used in Oracle. To create comments in MySQL you add
341             C to the end of the column or table definition. Note that MySQL
342             restricts the length of comments, and also does not handle complex Unicode
343             characters properly.
344              
345             Set this to C<0> to turn off all POD generation.
346              
347             =head2 pod_comment_mode
348              
349             Controls where table comments appear in the generated POD. Smaller table
350             comments are appended to the C section of the documentation, and larger
351             ones are inserted into C instead. You can force a C
352             section to be generated with the comment always, only use C, or choose
353             the length threshold at which the comment is forced into the description.
354              
355             =over 4
356              
357             =item name
358              
359             Use C section only.
360              
361             =item description
362              
363             Force C always.
364              
365             =item auto
366              
367             Use C if length > L, this is the
368             default.
369              
370             =back
371              
372             =head2 pod_comment_spillover_length
373              
374             When pod_comment_mode is set to C, this is the length of the comment at
375             which it will be forced into a separate description section.
376              
377             The default is C<60>
378              
379             =head2 table_comments_table
380              
381             The table to look for comments about tables in. By default C.
382             See L for details.
383              
384             This must not be a fully qualified name, the table will be looked for in the
385             same database and schema as the table whose comment is being retrieved.
386              
387             =head2 column_comments_table
388              
389             The table to look for comments about columns in. By default C.
390             See L for details.
391              
392             This must not be a fully qualified name, the table will be looked for in the
393             same database and schema as the table/column whose comment is being retrieved.
394              
395             =head2 relationship_attrs
396              
397             Hashref of attributes to pass to each generated relationship, listed by type.
398             Also supports relationship type 'all', containing options to pass to all
399             generated relationships. Attributes set for more specific relationship types
400             override those set in 'all', and any attributes specified by this option
401             override the introspected attributes of the foreign key if any.
402              
403             For example:
404              
405             relationship_attrs => {
406             has_many => { cascade_delete => 1, cascade_copy => 1 },
407             might_have => { cascade_delete => 1, cascade_copy => 1 },
408             },
409              
410             use this to turn L cascades to on on your
411             L and
412             L relationships, they default
413             to off.
414              
415             Can also be a coderef, for more precise control, in which case the coderef gets
416             this hash of parameters (as a list):
417              
418             rel_name # the name of the relationship
419             rel_type # the type of the relationship: 'belongs_to', 'has_many' or 'might_have'
420             local_source # the DBIx::Class::ResultSource object for the source the rel is *from*
421             remote_source # the DBIx::Class::ResultSource object for the source the rel is *to*
422             local_table # the DBIx::Class::Schema::Loader::Table object for the table of the source the rel is from
423             local_cols # an arrayref of column names of columns used in the rel in the source it is from
424             remote_table # the DBIx::Class::Schema::Loader::Table object for the table of the source the rel is to
425             remote_cols # an arrayref of column names of columns used in the rel in the source it is to
426             attrs # the attributes that would be set
427              
428             it should return the new hashref of attributes, or nothing for no changes.
429              
430             For example:
431              
432             relationship_attrs => sub {
433             my %p = @_;
434              
435             say "the relationship name is: $p{rel_name}";
436             say "the relationship is a: $p{rel_type}";
437             say "the local class is: ", $p{local_source}->result_class;
438             say "the remote class is: ", $p{remote_source}->result_class;
439             say "the local table is: ", $p{local_table}->sql_name;
440             say "the rel columns in the local table are: ", (join ", ", @{$p{local_cols}});
441             say "the remote table is: ", $p{remote_table}->sql_name;
442             say "the rel columns in the remote table are: ", (join ", ", @{$p{remote_cols}});
443              
444             if ($p{local_table} eq 'dogs' && @{$p{local_cols}} == 1 && $p{local_cols}[0] eq 'name') {
445             $p{attrs}{could_be_snoopy} = 1;
446              
447             return $p{attrs};
448             }
449             },
450              
451             These are the default attributes:
452              
453             has_many => {
454             cascade_delete => 0,
455             cascade_copy => 0,
456             },
457             might_have => {
458             cascade_delete => 0,
459             cascade_copy => 0,
460             },
461             belongs_to => {
462             on_delete => 'CASCADE',
463             on_update => 'CASCADE',
464             is_deferrable => 1,
465             },
466              
467             For L relationships, these
468             defaults are overridden by the attributes introspected from the foreign key in
469             the database, if this information is available (and the driver is capable of
470             retrieving it.)
471              
472             This information overrides the defaults mentioned above, and is then itself
473             overridden by the user's L for C if any are
474             specified.
475              
476             In general, for most databases, for a plain foreign key with no rules, the
477             values for a L relationship
478             will be:
479              
480             on_delete => 'NO ACTION',
481             on_update => 'NO ACTION',
482             is_deferrable => 0,
483              
484             In the cases where an attribute is not supported by the DB, a value matching
485             the actual behavior is used, for example Oracle does not support C
486             rules, so C is set to C. This is done so that the
487             behavior of the schema is preserved when cross deploying to a different RDBMS
488             such as SQLite for testing.
489              
490             In the cases where the DB does not support C foreign keys, the
491             value is set to C<1> if L has a working C<<
492             $storage->with_deferred_fk_checks >>. This is done so that the same
493             L code can be used, and cross deployed from and to such databases.
494              
495             =head2 debug
496              
497             If set to true, each constructive L statement the loader
498             decides to execute will be C-ed before execution.
499              
500             =head2 db_schema
501              
502             Set the name of the schema to load (schema in the sense that your database
503             vendor means it).
504              
505             Can be set to an arrayref of schema names for multiple schemas, or the special
506             value C<%> for all schemas.
507              
508             For MSSQL, Sybase ASE, and Informix can be set to a hashref of databases as
509             keys and arrays of owners as values, set to the value:
510              
511             { '%' => '%' }
512              
513             for all owners in all databases.
514              
515             Name clashes resulting from the same table name in different databases/schemas
516             will be resolved automatically by prefixing the moniker with the database
517             and/or schema.
518              
519             To prefix/suffix all monikers with the database and/or schema, see
520             L.
521              
522             =head2 moniker_parts
523              
524             The database table names are represented by the
525             L class in the loader, the
526             L class for Sybase ASE and
527             L for Informix.
528              
529             Monikers are created normally based on just the
530             L property, corresponding to
531             the table name, but can consist of other parts of the fully qualified name of
532             the table.
533              
534             The L option is an arrayref of methods on the table class
535             corresponding to parts of the fully qualified table name, defaulting to
536             C<['name']>, in the order those parts are used to create the moniker name.
537             The parts are joined together using L.
538              
539             The C<'name'> entry B be present.
540              
541             Below is a table of supported databases and possible L.
542              
543             =over 4
544              
545             =item * DB2, Firebird, mysql, Oracle, Pg, SQLAnywhere, SQLite, MS Access
546              
547             C, C
548              
549             =item * Informix, MSSQL, Sybase ASE
550              
551             C, C, C
552              
553             =back
554              
555             =head2 moniker_part_separator
556              
557             String used to join L when creating the moniker.
558             Defaults to the empty string. Use C<::> to get a separate namespace per
559             database and/or schema.
560              
561             =head2 constraint
562              
563             Only load matching tables.
564              
565             These can be specified either as a regex (preferably on the C
566             form), or as an arrayref of arrayrefs. Regexes are matched against
567             the (unqualified) table name, while arrayrefs are matched according to
568             L.
569              
570             For example:
571              
572             db_schema => [qw(some_schema other_schema)],
573             moniker_parts => [qw(schema name)],
574             constraint => [
575             [ qr/\Asome_schema\z/ => qr/\A(?:foo|bar)\z/ ],
576             [ qr/\Aother_schema\z/ => qr/\Abaz\z/ ],
577             ],
578              
579             In this case only the tables C and C in C and
580             C in C will be dumped.
581              
582             =head2 exclude
583              
584             Exclude matching tables.
585              
586             The tables to exclude are specified in the same way as for the
587             L option.
588              
589             =head2 moniker_map
590              
591             Overrides the default table name to moniker translation. Either
592              
593             =over
594              
595             =item *
596              
597             a nested hashref, which will be traversed according to L
598              
599             For example:
600              
601             moniker_parts => [qw(schema name)],
602             moniker_map => {
603             foo => {
604             bar => "FooishBar",
605             },
606             },
607              
608             In which case the table C in the C schema would get the moniker
609             C.
610              
611             =item *
612              
613             a hashref of unqualified table name keys and moniker values
614              
615             =item *
616              
617             a coderef that returns the moniker, which is called with the following
618             arguments:
619              
620             =over
621              
622             =item *
623              
624             the L object for the table
625              
626             =item *
627              
628             the default moniker that DBIC would ordinarily give this table
629              
630             =item *
631              
632             a coderef that can be called with either of the hashref forms to get
633             the moniker mapped accordingly. This is useful if you need to handle
634             some monikers specially, but want to use the hashref form for the
635             rest.
636              
637             =back
638              
639             =back
640              
641             If the hash entry does not exist, or the function returns a false
642             value, the code falls back to default behavior for that table name.
643              
644             The default behavior is to split on case transition and non-alphanumeric
645             boundaries, singularize the resulting phrase, then join the titlecased words
646             together. Examples:
647              
648             Table Name | Moniker Name
649             ---------------------------------
650             luser | Luser
651             luser_group | LuserGroup
652             luser-opts | LuserOpt
653             stations_visited | StationVisited
654             routeChange | RouteChange
655              
656             =head2 moniker_part_map
657              
658             Map for overriding the monikerization of individual L.
659             The keys are the moniker part to override, the value is either a
660             hashref or coderef for mapping the corresponding part of the
661             moniker. If a coderef is used, it gets called with the moniker part
662             and the hash key the code ref was found under.
663              
664             For example:
665              
666             moniker_part_map => {
667             schema => sub { ... },
668             },
669              
670             Given the table C, the code ref would be called with the
671             arguments C and C, plus a coderef similar to the one
672             described in L.
673              
674             L takes precedence over this.
675              
676             =head2 col_accessor_map
677              
678             Same as moniker_map, but for column accessor names. The nested
679             hashref form is traversed according to L, with an
680             extra level at the bottom for the column name. If a coderef is
681             passed, the code is called with the following arguments:
682              
683             =over
684              
685             =item *
686              
687             the L object for the column
688              
689             =item *
690              
691             the default accessor name that DBICSL would ordinarily give this column
692              
693             =item *
694              
695             a hashref of this form:
696              
697             {
698             table_class => name of the DBIC class we are building,
699             table_moniker => calculated moniker for this table (after moniker_map if present),
700             table => the DBIx::Class::Schema::Loader::Table object for the table,
701             full_table_name => schema-qualified name of the database table (RDBMS specific),
702             schema_class => name of the schema class we are building,
703             column_info => hashref of column info (data_type, is_nullable, etc),
704             }
705              
706             =item *
707              
708             a coderef that can be called with a hashref map
709              
710             =back
711              
712             =head2 rel_name_map
713              
714             Similar in idea to moniker_map, but different in the details. It can be
715             a hashref or a code ref.
716              
717             If it is a hashref, keys can be either the default relationship name, or the
718             moniker. The keys that are the default relationship name should map to the
719             name you want to change the relationship to. Keys that are monikers should map
720             to hashes mapping relationship names to their translation. You can do both at
721             once, and the more specific moniker version will be picked up first. So, for
722             instance, you could have
723              
724             {
725             bar => "baz",
726             Foo => {
727             bar => "blat",
728             },
729             }
730              
731             and relationships that would have been named C will now be named C
732             except that in the table whose moniker is C it will be named C.
733              
734             If it is a coderef, it will be passed a hashref of this form:
735              
736             {
737             name => default relationship name,
738             type => the relationship type eg: C,
739             local_class => name of the DBIC class we are building,
740             local_moniker => moniker of the DBIC class we are building,
741             local_columns => columns in this table in the relationship,
742             remote_class => name of the DBIC class we are related to,
743             remote_moniker => moniker of the DBIC class we are related to,
744             remote_columns => columns in the other table in the relationship,
745             # for type => "many_to_many" only:
746             link_class => name of the DBIC class for the link table,
747             link_moniker => moniker of the DBIC class for the link table,
748             link_rel_name => name of the relationship to the link table,
749             }
750              
751             In addition it is passed a coderef that can be called with a hashref map.
752              
753             DBICSL will try to use the value returned as the relationship name.
754              
755             =head2 inflect_plural
756              
757             Just like L above (can be hash/code-ref, falls back to default
758             if hash key does not exist or coderef returns false), but acts as a map
759             for pluralizing relationship names. The default behavior is to utilize
760             L.
761              
762             =head2 inflect_singular
763              
764             As L above, but for singularizing relationship names.
765             Default behavior is to utilize L.
766              
767             =head2 schema_base_class
768              
769             Base class for your schema classes. Defaults to 'DBIx::Class::Schema'.
770              
771             =head2 schema_components
772              
773             List of components to load into the Schema class.
774              
775             =head2 result_base_class
776              
777             Base class for your table classes (aka result classes). Defaults to
778             'DBIx::Class::Core'.
779              
780             =head2 additional_base_classes
781              
782             List of additional base classes all of your table classes will use.
783              
784             =head2 left_base_classes
785              
786             List of additional base classes all of your table classes will use
787             that need to be leftmost.
788              
789             =head2 additional_classes
790              
791             List of additional classes which all of your table classes will use.
792              
793             =head2 components
794              
795             List of additional components to be loaded into all of your Result
796             classes. A good example would be
797             L
798              
799             =head2 result_components_map
800              
801             A hashref of moniker keys and component values. Unlike L, which
802             loads the given components into every Result class, this option allows you to
803             load certain components for specified Result classes. For example:
804              
805             result_components_map => {
806             StationVisited => '+YourApp::Schema::Component::StationVisited',
807             RouteChange => [
808             '+YourApp::Schema::Component::RouteChange',
809             'InflateColumn::DateTime',
810             ],
811             }
812              
813             You may use this in conjunction with L.
814              
815             =head2 result_roles
816              
817             List of L roles to be applied to all of your Result classes.
818              
819             =head2 result_roles_map
820              
821             A hashref of moniker keys and role values. Unlike L, which
822             applies the given roles to every Result class, this option allows you to apply
823             certain roles for specified Result classes. For example:
824              
825             result_roles_map => {
826             StationVisited => [
827             'YourApp::Role::Building',
828             'YourApp::Role::Destination',
829             ],
830             RouteChange => 'YourApp::Role::TripEvent',
831             }
832              
833             You may use this in conjunction with L.
834              
835             =head2 use_namespaces
836              
837             This is now the default, to go back to L pass
838             a C<0>.
839              
840             Generate result class names suitable for
841             L and call that instead of
842             L. When using this option you can also
843             specify any of the options for C (i.e. C,
844             C, C), and they will be added
845             to the call (and the generated result class names adjusted appropriately).
846              
847             =head2 dump_directory
848              
849             The value of this option is a perl libdir pathname. Within
850             that directory this module will create a baseline manual
851             L module set, based on what it creates at runtime.
852              
853             The created schema class will have the same classname as the one on
854             which you are setting this option (and the ResultSource classes will be
855             based on this name as well).
856              
857             Normally you wouldn't hard-code this setting in your schema class, as it
858             is meant for one-time manual usage.
859              
860             See L for examples of the
861             recommended way to access this functionality.
862              
863             =head2 dump_overwrite
864              
865             Deprecated. See L below, which does *not* mean
866             the same thing as the old C setting from previous releases.
867              
868             =head2 really_erase_my_files
869              
870             Default false. If true, Loader will unconditionally delete any existing
871             files before creating the new ones from scratch when dumping a schema to disk.
872              
873             The default behavior is instead to only replace the top portion of the
874             file, up to and including the final stanza which contains
875             C<# DO NOT MODIFY THE FIRST PART OF THIS FILE>
876             leaving any customizations you placed after that as they were.
877              
878             When C is not set, if the output file already exists,
879             but the aforementioned final stanza is not found, or the checksum
880             contained there does not match the generated contents, Loader will
881             croak and not touch the file.
882              
883             You should really be using version control on your schema classes (and all
884             of the rest of your code for that matter). Don't blame me if a bug in this
885             code wipes something out when it shouldn't have, you've been warned.
886              
887             =head2 overwrite_modifications
888              
889             Default false. If false, when updating existing files, Loader will
890             refuse to modify any Loader-generated code that has been modified
891             since its last run (as determined by the checksum Loader put in its
892             comment lines).
893              
894             If true, Loader will discard any manual modifications that have been
895             made to Loader-generated code.
896              
897             Again, you should be using version control on your schema classes. Be
898             careful with this option.
899              
900             =head2 omit_version
901              
902             Omit the package version from the signature comment.
903              
904             =head2 omit_timestamp
905              
906             Omit the creation timestamp from the signature comment.
907              
908             =head2 custom_column_info
909              
910             Hook for adding extra attributes to the
911             L for a column.
912              
913             Must be a coderef that returns a hashref with the extra attributes.
914              
915             Receives the L object, column name
916             and column_info.
917              
918             For example:
919              
920             custom_column_info => sub {
921             my ($table, $column_name, $column_info) = @_;
922              
923             if ($column_name eq 'dog' && $column_info->{default_value} eq 'snoopy') {
924             return { is_snoopy => 1 };
925             }
926             },
927              
928             This attribute can also be used to set C on a non-datetime
929             column so it also receives the L and/or L.
930              
931             =head2 datetime_timezone
932              
933             Sets the timezone attribute for L for all
934             columns with the DATE/DATETIME/TIMESTAMP data_types.
935              
936             =head2 datetime_locale
937              
938             Sets the locale attribute for L for all
939             columns with the DATE/DATETIME/TIMESTAMP data_types.
940              
941             =head2 datetime_undef_if_invalid
942              
943             Pass a C<0> for this option when using MySQL if you B want C<<
944             datetime_undef_if_invalid => 1 >> in your column info for DATE, DATETIME and
945             TIMESTAMP columns.
946              
947             The default is recommended to deal with data such as C<00/00/00> which
948             sometimes ends up in such columns in MySQL.
949              
950             =head2 config_file
951              
952             File in Perl format, which should return a HASH reference, from which to read
953             loader options.
954              
955             =head2 preserve_case
956              
957             Normally database names are lowercased and split by underscore, use this option
958             if you have CamelCase database names.
959              
960             Drivers for case sensitive databases like Sybase ASE or MSSQL with a
961             case-sensitive collation will turn this option on unconditionally.
962              
963             B L = C is highly recommended with this option as the
964             semantics of this mode are much improved for CamelCase database names.
965              
966             L = C or greater is required with this option.
967              
968             =head2 qualify_objects
969              
970             Set to true to prepend the L to table names for C<<
971             __PACKAGE__->table >> calls, and to some other things like Oracle sequences.
972              
973             This attribute is automatically set to true for multi db_schema configurations,
974             unless explicitly set to false by the user.
975              
976             =head2 use_moose
977              
978             Creates Schema and Result classes that use L, L and
979             L (or L, see below). The default
980             content after the md5 sum also makes the classes immutable.
981              
982             It is safe to upgrade your existing Schema to this option.
983              
984             =head2 only_autoclean
985              
986             By default, we use L to remove imported functions from
987             your generated classes. It uses L to do this, after
988             telling your object's metaclass that any operator Ls in your class
989             are methods, which will cause namespace::autoclean to spare them from removal.
990              
991             This prevents the "Hey, where'd my overloads go?!" effect.
992              
993             If you don't care about operator overloads (or if you know your Moose is at at
994             least version 2.1400, where MooseX::MarkAsMethods is no longer necessary),
995             enabling this option falls back to just using L itself.
996              
997             If none of the above made any sense, or you don't have some pressing need to
998             only use L, leaving this set to the default is
999             just fine.
1000              
1001             =head2 col_collision_map
1002              
1003             This option controls how accessors for column names which collide with perl
1004             methods are named. See L for more information.
1005              
1006             This option takes either a single L format or a hashref of
1007             strings which are compiled to regular expressions that map to
1008             L formats.
1009              
1010             Examples:
1011              
1012             col_collision_map => 'column_%s'
1013              
1014             col_collision_map => { '(.*)' => 'column_%s' }
1015              
1016             col_collision_map => { '(foo).*(bar)' => 'column_%s_%s' }
1017              
1018             =head2 rel_collision_map
1019              
1020             Works just like L, but for relationship names/accessors
1021             rather than column names/accessors.
1022              
1023             The default is to just append C<_rel> to the relationship name, see
1024             L.
1025              
1026             =head2 uniq_to_primary
1027              
1028             Automatically promotes the largest unique constraints with non-nullable columns
1029             on tables to primary keys, assuming there is only one largest unique
1030             constraint.
1031              
1032             =head2 allow_extra_m2m_cols
1033              
1034             Generate C relationship bridges even if the link table has
1035             extra columns other than the foreign keys. The primary key must still
1036             equal the union of the foreign keys.
1037              
1038              
1039             =head2 filter_generated_code
1040              
1041             An optional hook that lets you filter the generated text for various classes
1042             through a function that change it in any way that you want. The function will
1043             receive the type of file, C or C, class and code; and returns
1044             the new code to use instead. For instance you could add custom comments, or do
1045             anything else that you want.
1046              
1047             The option can also be set to a string, which is then used as a filter program,
1048             e.g. C.
1049              
1050             If this exists but fails to return text matching C, no file will
1051             be generated.
1052              
1053             filter_generated_code => sub {
1054             my ($type, $class, $text) = @_;
1055             ...
1056             return $new_code;
1057             }
1058              
1059             You can also use this option to set L
1060             Selected Sections of Code> in your generated classes. This will leave
1061             the generated code in the default format, but will allow you to tidy
1062             your classes at any point in future, without worrying about changing the
1063             portions of the file which are checksummed, since C will just
1064             ignore all text between the markers.
1065              
1066             filter_generated_code => sub {
1067             return "#<<<\n$_[2]\n#>>>";
1068             }
1069              
1070             =head1 METHODS
1071              
1072             None of these methods are intended for direct invocation by regular
1073             users of L. Some are proxied via
1074             L.
1075              
1076             =cut
1077              
1078             # ensure that a piece of object data is a valid arrayref, creating
1079             # an empty one or encapsulating whatever's there.
1080             sub _ensure_arrayref {
1081 302     302   804 my $self = shift;
1082              
1083 302         982 foreach (@_) {
1084 1812   100     11908 $self->{$_} ||= [];
1085             $self->{$_} = [ $self->{$_} ]
1086 1812 100       5680 unless ref $self->{$_} eq 'ARRAY';
1087             }
1088             }
1089              
1090             =head2 new
1091              
1092             Constructor for L, used internally
1093             by L.
1094              
1095             =cut
1096              
1097             sub new {
1098 302     302 1 15885 my ( $class, %args ) = @_;
1099              
1100 302 50       1789 if (exists $args{column_accessor_map}) {
1101 0         0 $args{col_accessor_map} = delete $args{column_accessor_map};
1102             }
1103              
1104 302         3018 my $self = { %args };
1105              
1106             # don't lose undef options
1107 302         1524 for (values %$self) {
1108 1689 100       4140 $_ = 0 unless defined $_;
1109             }
1110              
1111 302         921 bless $self => $class;
1112              
1113 302 100       2417 if (my $config_file = $self->config_file) {
1114 4         2202 my $config_opts = do $config_file;
1115              
1116 4 50       40 croak "Error reading config from $config_file: $@" if $@;
1117              
1118 4 50       34 croak "Config file $config_file must be a hashref" unless ref($config_opts) eq 'HASH';
1119              
1120 4         440 while (my ($k, $v) = each %$config_opts) {
1121 4 50       95 $self->{$k} = $v unless exists $self->{$k};
1122             }
1123             }
1124              
1125 302 50       17858 if (defined $self->{result_component_map}) {
1126 0 0       0 if (defined $self->result_components_map) {
1127 0         0 croak "Specify only one of result_components_map or result_component_map";
1128             }
1129             $self->result_components_map($self->{result_component_map})
1130 0         0 }
1131              
1132 302 50       1164 if (defined $self->{result_role_map}) {
1133 0 0       0 if (defined $self->result_roles_map) {
1134 0         0 croak "Specify only one of result_roles_map or result_role_map";
1135             }
1136             $self->result_roles_map($self->{result_role_map})
1137 0         0 }
1138              
1139 302 50 33     5411 croak "the result_roles and result_roles_map options may only be used in conjunction with use_moose=1"
      33        
      33        
1140             if ((not defined $self->use_moose) || (not $self->use_moose))
1141             && ((defined $self->result_roles) || (defined $self->result_roles_map));
1142              
1143 302         34571 $self->_ensure_arrayref(qw/schema_components
1144             additional_classes
1145             additional_base_classes
1146             left_base_classes
1147             components
1148             result_roles
1149             /);
1150              
1151 302         2053 $self->_validate_class_args;
1152              
1153 300 50 66     2104 croak "result_components_map must be a hash"
1154             if defined $self->result_components_map
1155             && ref $self->result_components_map ne 'HASH';
1156              
1157 300 100       11651 if ($self->result_components_map) {
1158 2         5 my %rc_map = %{ $self->result_components_map };
  2         17  
1159 2         8 foreach my $moniker (keys %rc_map) {
1160 4 50       21 $rc_map{$moniker} = [ $rc_map{$moniker} ] unless ref $rc_map{$moniker};
1161             }
1162 2         9 $self->result_components_map(\%rc_map);
1163             }
1164             else {
1165 298         1529 $self->result_components_map({});
1166             }
1167 300         1566 $self->_validate_result_components_map;
1168              
1169 300 50 33     1540 croak "result_roles_map must be a hash"
1170             if defined $self->result_roles_map
1171             && ref $self->result_roles_map ne 'HASH';
1172              
1173 300 50       1085 if ($self->result_roles_map) {
1174 0         0 my %rr_map = %{ $self->result_roles_map };
  0         0  
1175 0         0 foreach my $moniker (keys %rr_map) {
1176 0 0       0 $rr_map{$moniker} = [ $rr_map{$moniker} ] unless ref $rr_map{$moniker};
1177             }
1178 0         0 $self->result_roles_map(\%rr_map);
1179             } else {
1180 300         1395 $self->result_roles_map({});
1181             }
1182 300         1703 $self->_validate_result_roles_map;
1183              
1184 300 50       1294 if ($self->use_moose) {
1185 0 0       0 if ($self->only_autoclean) {
1186 0 0       0 if (not DBIx::Class::Schema::Loader::Optional::Dependencies->req_ok_for('use_moose_only_autoclean')) {
1187 0         0 die sprintf "You must install the following CPAN modules to enable the use_moose and only_autoclean options: %s.\n",
1188             DBIx::Class::Schema::Loader::Optional::Dependencies->req_missing_for('use_moose_only_autoclean');
1189             }
1190             }
1191             else {
1192 0 0       0 if (not DBIx::Class::Schema::Loader::Optional::Dependencies->req_ok_for('use_moose')) {
1193 0         0 die sprintf "You must install the following CPAN modules to enable the use_moose option: %s.\n",
1194             DBIx::Class::Schema::Loader::Optional::Dependencies->req_missing_for('use_moose');
1195             }
1196             }
1197             }
1198              
1199 300         1645 $self->{_tables} = {};
1200 300         1227 $self->{monikers} = {};
1201 300         1426 $self->{moniker_to_table} = {};
1202 300         1252 $self->{class_to_table} = {};
1203 300         1341 $self->{classes} = {};
1204 300         1209 $self->{_upgrading_classes} = {};
1205 300         1383 $self->{generated_classes} = [];
1206              
1207 300   66     2819 $self->{schema_class} ||= ( ref $self->{schema} || $self->{schema} );
      66        
1208 300   33     1009 $self->{schema} ||= $self->{schema_class};
1209 300   50     2629 $self->{table_comments_table} ||= 'table_comments';
1210 300   50     2221 $self->{column_comments_table} ||= 'column_comments';
1211              
1212             croak "dump_overwrite is deprecated. Please read the"
1213             . " DBIx::Class::Schema::Loader::Base documentation"
1214 300 50       1038 if $self->{dump_overwrite};
1215              
1216 300         1583 $self->{dynamic} = ! $self->{dump_directory};
1217              
1218 300 50 66     2510 croak "dry_run can only be used with static schema generation"
1219             if $self->dynamic and $self->dry_run;
1220              
1221 300   33     18480 $self->{temp_directory} ||= File::Temp::tempdir( 'dbicXXXX',
1222             TMPDIR => 1,
1223             CLEANUP => 1,
1224             );
1225              
1226 300   66     250414 $self->{dump_directory} ||= $self->{temp_directory};
1227              
1228 300         2370 $self->real_dump_directory($self->{dump_directory});
1229              
1230 300         15582 $self->version_to_dump($DBIx::Class::Schema::Loader::VERSION);
1231 300         12502 $self->schema_version_to_dump($DBIx::Class::Schema::Loader::VERSION);
1232              
1233 300 100       12267 if (not defined $self->naming) {
1234 81         698 $self->naming_set(0);
1235             }
1236             else {
1237 219         10944 $self->naming_set(1);
1238             }
1239              
1240 300 100 100     15422 if ((not ref $self->naming) && defined $self->naming) {
    50 66        
1241 211         867 my $naming_ver = $self->naming;
1242             $self->{naming} = {
1243 211         2219 relationships => $naming_ver,
1244             monikers => $naming_ver,
1245             column_accessors => $naming_ver,
1246             };
1247             }
1248             elsif (ref $self->naming eq 'HASH' && exists $self->naming->{ALL}) {
1249 0         0 my $val = delete $self->naming->{ALL};
1250              
1251             $self->naming->{$_} = $val
1252 0         0 foreach qw/relationships monikers column_accessors/;
1253             }
1254              
1255 300 100       1433 if ($self->naming) {
1256 219         818 foreach my $key (qw/relationships monikers column_accessors/) {
1257 657 100 100     3675 $self->naming->{$key} = $CURRENT_V if ($self->naming->{$key}||'') eq 'current';
1258             }
1259             }
1260 300   100     1689 $self->{naming} ||= {};
1261              
1262 300 50 66     1958 if ($self->custom_column_info && ref $self->custom_column_info ne 'CODE') {
1263 0         0 croak 'custom_column_info must be a CODE ref';
1264             }
1265              
1266 300         12422 $self->_check_back_compat;
1267              
1268 300 100       1598 $self->use_namespaces(1) unless defined $self->use_namespaces;
1269 300 100       8052 $self->generate_pod(1) unless defined $self->generate_pod;
1270 300 50       12524 $self->pod_comment_mode('auto') unless defined $self->pod_comment_mode;
1271 300 50       13276 $self->pod_comment_spillover_length(60) unless defined $self->pod_comment_spillover_length;
1272              
1273 300 100       13061 if (my $col_collision_map = $self->col_collision_map) {
1274 2 50       307 if (my $reftype = ref $col_collision_map) {
1275 2 50       10 if ($reftype ne 'HASH') {
1276 0         0 croak "Invalid type $reftype for option 'col_collision_map'";
1277             }
1278             }
1279             else {
1280 0         0 $self->col_collision_map({ '(.*)' => $col_collision_map });
1281             }
1282             }
1283              
1284 300 100       11665 if (my $rel_collision_map = $self->rel_collision_map) {
1285 2 50       324 if (my $reftype = ref $rel_collision_map) {
1286 2 50       10 if ($reftype ne 'HASH') {
1287 0         0 croak "Invalid type $reftype for option 'rel_collision_map'";
1288             }
1289             }
1290             else {
1291 0         0 $self->rel_collision_map({ '(.*)' => $rel_collision_map });
1292             }
1293             }
1294              
1295 300 100       11563 if (defined(my $rel_name_map = $self->rel_name_map)) {
1296 10         154 my $reftype = ref $rel_name_map;
1297 10 50 66     75 if ($reftype ne 'HASH' && $reftype ne 'CODE') {
1298 0         0 croak "Invalid type $reftype for option 'rel_name_map', must be HASH or CODE";
1299             }
1300             }
1301              
1302 300 100       11745 if (defined(my $filter = $self->filter_generated_code)) {
1303 4         130 my $reftype = ref $filter;
1304 4 50 66     24 if ($reftype && $reftype ne 'CODE') {
1305 0         0 croak "Invalid type $reftype for option 'filter_generated_code, must be a scalar or a CODE reference";
1306             }
1307             }
1308              
1309 300 100       11423 if (defined $self->db_schema) {
1310 24 100       1157 if (ref $self->db_schema eq 'ARRAY') {
    50          
1311 4 50 33     20 if (@{ $self->db_schema } > 1 && not defined $self->{qualify_objects}) {
  4 50       80  
1312 0         0 $self->{qualify_objects} = 1;
1313             }
1314 4         42 elsif (@{ $self->db_schema } == 0) {
1315 0         0 $self->{db_schema} = undef;
1316             }
1317             }
1318             elsif (not ref $self->db_schema) {
1319 20 50 33     131 if ($self->db_schema eq '%' && not defined $self->{qualify_objects}) {
1320 0         0 $self->{qualify_objects} = 1;
1321             }
1322              
1323 20         181 $self->{db_schema} = [ $self->db_schema ];
1324             }
1325             }
1326              
1327 300 100       10545 if (not $self->moniker_parts) {
1328 284         10890 $self->moniker_parts(['name']);
1329             }
1330             else {
1331 16 50       651 if (not ref $self->moniker_parts) {
1332 0         0 $self->moniker_parts([ $self->moniker_parts ]);
1333             }
1334 16 50       126 if (ref $self->moniker_parts ne 'ARRAY') {
1335 0         0 croak 'moniker_parts must be an arrayref';
1336             }
1337 16 50   32   139 if (none { $_ eq 'name' } @{ $self->moniker_parts }) {
  32         132  
  16         127  
1338 0         0 croak "moniker_parts option *must* contain 'name'";
1339             }
1340             }
1341              
1342 300 100       1700 if (not defined $self->moniker_part_separator) {
1343 288         10979 $self->moniker_part_separator('');
1344             }
1345 300 100       1946 if (not defined $self->moniker_part_map) {
1346 296         11224 $self->moniker_part_map({}),
1347             }
1348              
1349 300         2575 return $self;
1350             }
1351              
1352             sub _check_back_compat {
1353 300     300   925 my ($self) = @_;
1354              
1355             # dynamic schemas will always be in 0.04006 mode, unless overridden
1356 300 100       1256 if ($self->dynamic) {
1357             # just in case, though no one is likely to dump a dynamic schema
1358 86         328 $self->schema_version_to_dump('0.04006');
1359              
1360 86 100       327 if (not $self->naming_set) {
1361 3 100       34 warn <
1362              
1363             Dynamic schema detected, will run in 0.04006 mode.
1364              
1365             Set the 'naming' attribute or the SCHEMA_LOADER_BACKCOMPAT environment variable
1366             to disable this warning.
1367              
1368             See perldoc DBIx::Class::Schema::Loader::Manual::UpgradingFromV4 for more
1369             details.
1370             EOF
1371             }
1372             else {
1373 83         409 $self->_upgrading_from('v4');
1374             }
1375              
1376 86 100 100     2486 if ((not defined $self->use_namespaces) && ($self->naming_set)) {
1377 25         84 $self->use_namespaces(1);
1378             }
1379              
1380 86   100     2103 $self->naming->{relationships} ||= 'v4';
1381 86   100     317 $self->naming->{monikers} ||= 'v4';
1382              
1383 86 100       316 if ($self->use_namespaces) {
1384 72         297 $self->_upgrading_from_load_classes(1);
1385             }
1386             else {
1387 14         51 $self->use_namespaces(0);
1388             }
1389              
1390 86         1929 return;
1391             }
1392              
1393             # otherwise check if we need backcompat mode for a static schema
1394 214         1801 my $filename = $self->get_dump_filename($self->schema_class);
1395 214 100       15945 return unless -e $filename;
1396              
1397 146         1367 my ($old_gen, $old_md5, $old_ver, $old_ts, $old_custom) =
1398             $self->_parse_generated_file($filename);
1399              
1400 146 100       913 return unless $old_ver;
1401              
1402             # determine if the existing schema was dumped with use_moose => 1
1403 142 50       1183 if (! defined $self->use_moose) {
1404 142 50       1172 $self->{use_moose} = 1 if $old_gen =~ /^ (?!\s*\#) use \s+ Moose/xm;
1405             }
1406              
1407 142 100       972 my $load_classes = ($old_gen =~ /^__PACKAGE__->load_classes;/m) ? 1 : 0;
1408              
1409 142 100       335 my $result_namespace = do { ($old_gen =~ /result_namespace => (.+)/) ? $1 : '' };
  142         922  
1410 142         7671 my $ds = eval $result_namespace;
1411 142 50       1040 die <<"EOF" if $@;
1412             Could not eval expression '$result_namespace' for result_namespace from
1413             $filename: $@
1414             EOF
1415 142   100     1081 $result_namespace = $ds || '';
1416              
1417 142 100 100     5032 if ($load_classes && (not defined $self->use_namespaces)) {
    100 100        
    100 100        
    100 100        
      100        
1418 10 50       138 warn <<"EOF" unless $ENV{SCHEMA_LOADER_BACKCOMPAT};
1419              
1420             'load_classes;' static schema detected, turning off 'use_namespaces'.
1421              
1422             Set the 'use_namespaces' attribute or the SCHEMA_LOADER_BACKCOMPAT environment
1423             variable to disable this warning.
1424              
1425             See perldoc DBIx::Class::Schema::Loader::Manual::UpgradingFromV4 for more
1426             details.
1427             EOF
1428 10         105 $self->use_namespaces(0);
1429             }
1430             elsif ($load_classes && $self->use_namespaces) {
1431 33         3669 $self->_upgrading_from_load_classes(1);
1432             }
1433             elsif ((not $load_classes) && defined $self->use_namespaces && ! $self->use_namespaces) {
1434 4   100     139 $self->_downgrading_to_load_classes(
1435             $result_namespace || 'Result'
1436             );
1437             }
1438             elsif ((not defined $self->use_namespaces) || $self->use_namespaces) {
1439 78 100       4088 if (not $self->result_namespace) {
    100          
1440 66   100     4373 $self->result_namespace($result_namespace || 'Result');
1441             }
1442             elsif ($result_namespace ne $self->result_namespace) {
1443 8   100     115 $self->_rewriting_result_namespace(
1444             $result_namespace || 'Result'
1445             );
1446             }
1447             }
1448              
1449             # XXX when we go past .0 this will need fixing
1450 142         7422 my ($v) = $old_ver =~ /([1-9])/;
1451 142         468 $v = "v$v";
1452              
1453 142 100 66     1126 return if ($v eq $CURRENT_V || $old_ver =~ /^0\.\d\d999/);
1454              
1455 32 100       80 if (not %{ $self->naming }) {
  32         181  
1456 8 50       120 warn <<"EOF" unless $ENV{SCHEMA_LOADER_BACKCOMPAT};
1457              
1458             Version $old_ver static schema detected, turning on backcompat mode.
1459              
1460             Set the 'naming' attribute or the SCHEMA_LOADER_BACKCOMPAT environment variable
1461             to disable this warning.
1462              
1463             See: 'naming' in perldoc DBIx::Class::Schema::Loader::Base .
1464              
1465             See perldoc DBIx::Class::Schema::Loader::Manual::UpgradingFromV4 if upgrading
1466             from version 0.04006.
1467             EOF
1468              
1469 8   33     298 $self->naming->{relationships} ||= $v;
1470 8   33     78 $self->naming->{monikers} ||= $v;
1471 8   33     80 $self->naming->{column_accessors} ||= $v;
1472              
1473 8         47 $self->schema_version_to_dump($old_ver);
1474             }
1475             else {
1476 24         177 $self->_upgrading_from($v);
1477             }
1478             }
1479              
1480             sub _validate_class_args {
1481 302     302   775 my $self = shift;
1482              
1483 302         1128 foreach my $k (@CLASS_ARGS) {
1484 2406 100       30319 next unless $self->$k;
1485              
1486 1829 100       65068 my @classes = ref $self->$k eq 'ARRAY' ? @{ $self->$k } : $self->$k;
  1802         4702  
1487 1829         5286 $self->_validate_classes($k, \@classes);
1488             }
1489             }
1490              
1491             sub _validate_result_components_map {
1492 300     300   658 my $self = shift;
1493              
1494 300         579 foreach my $classes (values %{ $self->result_components_map }) {
  300         1496  
1495 4         11 $self->_validate_classes('result_components_map', $classes);
1496             }
1497             }
1498              
1499             sub _validate_result_roles_map {
1500 300     300   698 my $self = shift;
1501              
1502 300         644 foreach my $classes (values %{ $self->result_roles_map }) {
  300         1344  
1503 0         0 $self->_validate_classes('result_roles_map', $classes);
1504             }
1505             }
1506              
1507             sub _validate_classes {
1508 1833     1833   3112 my $self = shift;
1509 1833         3307 my $key = shift;
1510 1833         3257 my $classes = shift;
1511              
1512             # make a copy to not destroy original
1513 1833         3318 my @classes = @$classes;
1514              
1515 1833         4928 foreach my $c (@classes) {
1516             # components default to being under the DBIx::Class namespace unless they
1517             # are preceded with a '+'
1518 72 100 100     615 if ( $key =~ m/component/ && $c !~ s/^\+// ) {
1519 15         70 $c = 'DBIx::Class::' . $c;
1520             }
1521              
1522             # 1 == installed, 0 == not installed, undef == invalid classname
1523 72         1863 my $installed = Class::Inspector->installed($c);
1524 72 50       8677 if ( defined($installed) ) {
1525 72 100       383 if ( $installed == 0 ) {
1526 2         31 croak qq/$c, as specified in the loader option "$key", is not installed/;
1527             }
1528             } else {
1529 0         0 croak qq/$c, as specified in the loader option "$key", is an invalid class name/;
1530             }
1531             }
1532             }
1533              
1534              
1535             sub _find_file_in_inc {
1536 997     997   2738 my ($self, $file) = @_;
1537              
1538 997         2886 foreach my $prefix (@INC) {
1539 8861         91587 my $fullpath = File::Spec->catfile($prefix, $file);
1540             # abs_path pure-perl fallback warns for non-existent files
1541 8861         76192 local $SIG{__WARN__} = sigwarn_silencer(qr/^stat\(.*\Q$file\E\)/);
1542             return $fullpath if -f $fullpath
1543             # abs_path throws on Windows for nonexistent files
1544 31     31   4030 and (try { Cwd::abs_path($fullpath) }) ne
1545 8861 100 100 31   161159 ((try { Cwd::abs_path(File::Spec->catfile($self->dump_directory, $file)) }) || '');
  31   66     4485  
1546             }
1547              
1548 966         4959 return;
1549             }
1550              
1551             sub _find_class_in_inc {
1552 997     997   2837 my ($self, $class) = @_;
1553              
1554 997         4592 return $self->_find_file_in_inc(class_path($class));
1555             }
1556              
1557             sub _rewriting {
1558 3541     3541   17817 my $self = shift;
1559              
1560 3541   100     50345 return $self->_upgrading_from
1561             || $self->_upgrading_from_load_classes
1562             || $self->_downgrading_to_load_classes
1563             || $self->_rewriting_result_namespace
1564             ;
1565             }
1566              
1567             sub _rewrite_old_classnames {
1568 2015     2015   5697 my ($self, $code) = @_;
1569              
1570 2015 100       7437 return $code unless $self->_rewriting;
1571              
1572 538         1318 my %old_classes = reverse %{ $self->_upgrading_classes };
  538         5228  
1573              
1574 538         2769 my $re = join '|', keys %old_classes;
1575 538         31909 $re = qr/\b($re)\b/;
1576              
1577 538 100       6087 $code =~ s/$re/$old_classes{$1} || $1/eg;
  2732         12309  
1578              
1579 538         4027 return $code;
1580             }
1581              
1582             sub _load_external {
1583 845     845   2739 my ($self, $class) = @_;
1584              
1585 845 100       3404 return if $self->{skip_load_external};
1586              
1587             # so that we don't load our own classes, under any circumstances
1588 839         9225 local *INC = [ grep $_ ne $self->dump_directory, @INC ];
1589              
1590 839         4841 my $real_inc_path = $self->_find_class_in_inc($class);
1591              
1592 839 100       5247 my $old_class = $self->_upgrading_classes->{$class}
1593             if $self->_rewriting;
1594              
1595 839 100 66     4048 my $old_real_inc_path = $self->_find_class_in_inc($old_class)
1596             if $old_class && $old_class ne $class;
1597              
1598 839 100 100     8380 return unless $real_inc_path || $old_real_inc_path;
1599              
1600 31 100       155 if ($real_inc_path) {
1601             # If we make it to here, we loaded an external definition
1602 21 50       156 warn qq/# Loaded external class definition for '$class'\n/
1603             if $self->debug;
1604              
1605 21         138 my $code = $self->_rewrite_old_classnames(slurp_file $real_inc_path);
1606              
1607 21 100       370 if ($self->dynamic) { # load the class too
1608 7         46 eval_package_without_redefine_warnings($class, $code);
1609             }
1610              
1611 21         404 $self->_ext_stmt($class,
1612             qq|# These lines were loaded from '$real_inc_path' found in \@INC.\n|
1613             .qq|# They are now part of the custom portion of this file\n|
1614             .qq|# for you to hand-edit. If you do not either delete\n|
1615             .qq|# this section or remove that file from \@INC, this section\n|
1616             .qq|# will be repeated redundantly when you re-create this\n|
1617             .qq|# file again via Loader! See skip_load_external to disable\n|
1618             .qq|# this feature.\n|
1619             );
1620 21         110 chomp $code;
1621 21         109 $self->_ext_stmt($class, $code);
1622 21         111 $self->_ext_stmt($class,
1623             qq|# End of lines loaded from '$real_inc_path'|
1624             );
1625             }
1626              
1627 31 100       260 if ($old_real_inc_path) {
1628 10         59 my $code = slurp_file $old_real_inc_path;
1629              
1630 10         126 $self->_ext_stmt($class, <<"EOF");
1631              
1632             # These lines were loaded from '$old_real_inc_path',
1633             # based on the Result class name that would have been created by an older
1634             # version of the Loader. For a static schema, this happens only once during
1635             # upgrade. See skip_load_external to disable this feature.
1636             EOF
1637              
1638 10         70 $code = $self->_rewrite_old_classnames($code);
1639              
1640 10 100       84 if ($self->dynamic) {
1641 3         54 warn <<"EOF";
1642              
1643             Detected external content in '$old_real_inc_path', a class name that would have
1644             been used by an older version of the Loader.
1645              
1646             * PLEASE RENAME THIS CLASS: from '$old_class' to '$class', as that is the
1647             new name of the Result.
1648             EOF
1649 3         30 eval_package_without_redefine_warnings($class, $code);
1650             }
1651              
1652 10         44 chomp $code;
1653 10         62 $self->_ext_stmt($class, $code);
1654 10         53 $self->_ext_stmt($class,
1655             qq|# End of lines loaded from '$old_real_inc_path'|
1656             );
1657             }
1658             }
1659              
1660             =head2 load
1661              
1662             Does the actual schema-construction work.
1663              
1664             =cut
1665              
1666             sub load {
1667 149     149 1 3180 my $self = shift;
1668              
1669 149         1088 $self->_load_tables($self->_tables_list);
1670             }
1671              
1672             =head2 rescan
1673              
1674             Arguments: schema
1675              
1676             Rescan the database for changes. Returns a list of the newly added table
1677             monikers.
1678              
1679             The schema argument should be the schema class or object to be affected. It
1680             should probably be derived from the original schema_class used during L.
1681              
1682             =cut
1683              
1684             sub rescan {
1685 5     5 1 180 my ($self, $schema) = @_;
1686              
1687 5         32 $self->{schema} = $schema;
1688 5         55 $self->_relbuilder->{schema} = $schema;
1689              
1690 5         22 my @created;
1691 5         41 my @current = $self->_tables_list;
1692              
1693 5         93 foreach my $table (@current) {
1694 260 100       556 if(!exists $self->_tables->{$table->sql_name}) {
1695 3         10 push(@created, $table);
1696             }
1697             }
1698              
1699 5         15 my %current;
1700 5         29 @current{map $_->sql_name, @current} = ();
1701 5         34 foreach my $table (values %{ $self->_tables }) {
  5         62  
1702 258 100       578 if (not exists $current{$table->sql_name}) {
1703 1         24 $self->_remove_table($table);
1704             }
1705             }
1706              
1707 5         6216 delete @$self{qw/_dump_storage _relations_started _uniqs_started/};
1708              
1709 5         99 my $loaded = $self->_load_tables(@current);
1710              
1711 5         61 foreach my $table (@created) {
1712 3         58 $self->monikers->{$table->sql_name} = $self->_table2moniker($table);
1713             }
1714              
1715 5         416 return map { $self->monikers->{$_->sql_name} } @created;
  3         20  
1716             }
1717              
1718             sub _relbuilder {
1719 154     154   822 my ($self) = @_;
1720              
1721 154 50       1580 return if $self->{skip_relationships};
1722              
1723 154   66     2245 return $self->{relbuilder} ||= do {
1724             my $relbuilder_suff =
1725             {qw{
1726             v4 ::Compat::v0_040
1727             v5 ::Compat::v0_05
1728             v6 ::Compat::v0_06
1729             v7 ::Compat::v0_07
1730             }}
1731 144   50     3812 ->{$self->naming->{relationships}||$CURRENT_V} || '';
1732              
1733 144         822 my $relbuilder_class = 'DBIx::Class::Schema::Loader::RelBuilder'.$relbuilder_suff;
1734 144         1603 $self->ensure_class_loaded($relbuilder_class);
1735 144         5519 $relbuilder_class->new($self);
1736             };
1737             }
1738              
1739             sub _load_tables {
1740 154     154   856 my ($self, @tables) = @_;
1741              
1742             # Save the new tables to the tables list and compute monikers
1743 154         588 foreach (@tables) {
1744 857         5095 $self->_tables->{$_->sql_name} = $_;
1745 857         4102 $self->monikers->{$_->sql_name} = $self->_table2moniker($_);
1746             }
1747              
1748             # check for moniker clashes
1749 154         824 my $inverse_moniker_idx;
1750 154         568 foreach my $imtable (values %{ $self->_tables }) {
  154         1159  
1751 857         1495 push @{ $inverse_moniker_idx->{$self->monikers->{$imtable->sql_name}} }, $imtable;
  857         2820  
1752             }
1753              
1754 154         729 my @clashes;
1755 154         891 foreach my $moniker (keys %$inverse_moniker_idx) {
1756 855         1905 my $imtables = $inverse_moniker_idx->{$moniker};
1757 855 100       2602 if (@$imtables > 1) {
1758 2   33     90 my $different_databases =
1759             $imtables->[0]->can('database') && (uniq map $_->database||'', @$imtables) > 1;
1760              
1761 2   50     28 my $different_schemas =
1762             (uniq map $_->schema||'', @$imtables) > 1;
1763              
1764 2 50 33     30 if ($different_databases || $different_schemas) {
1765 0         0 my ($use_schema, $use_database) = (1, 0);
1766              
1767 0 0       0 if ($different_databases) {
1768 0         0 $use_database = 1;
1769              
1770             # If any monikers are in the same database, we have to distinguish by
1771             # both schema and database.
1772 0         0 my %db_counts;
1773 0         0 $db_counts{$_}++ for map $_->database, @$imtables;
1774 0     0   0 $use_schema = any { $_ > 1 } values %db_counts;
  0         0  
1775             }
1776              
1777 0         0 foreach my $tbl (@$imtables) { delete $self->monikers->{$tbl->sql_name}; }
  0         0  
1778              
1779 0         0 my $moniker_parts = [ @{ $self->moniker_parts } ];
  0         0  
1780              
1781 0     0   0 my $have_schema = any { $_ eq 'schema' } @{ $self->moniker_parts };
  0         0  
  0         0  
1782 0     0   0 my $have_database = any { $_ eq 'database' } @{ $self->moniker_parts };
  0         0  
  0         0  
1783              
1784 0 0 0     0 unshift @$moniker_parts, 'schema' if $use_schema && !$have_schema;
1785 0 0 0     0 unshift @$moniker_parts, 'database' if $use_database && !$have_database;
1786              
1787 0         0 local $self->{moniker_parts} = $moniker_parts;
1788              
1789 0         0 my %new_monikers;
1790              
1791 0         0 foreach my $tbl (@$imtables) { $new_monikers{$tbl->sql_name} = $self->_table2moniker($tbl); }
  0         0  
1792 0         0 foreach my $name (map $_->sql_name, @$imtables) { $self->monikers->{$name} = $new_monikers{$name}; }
  0         0  
1793              
1794             # check if there are still clashes
1795 0         0 my %by_moniker;
1796              
1797 0         0 while (my ($t, $m) = each %new_monikers) {
1798 0         0 push @{ $by_moniker{$m} }, $t;
  0         0  
1799             }
1800              
1801 0         0 foreach my $m (grep @{ $by_moniker{$_} } > 1, keys %by_moniker) {
  0         0  
1802             push @clashes, sprintf ("tried disambiguating by moniker_parts, but tables %s still reduced to the same source moniker '%s'",
1803 0         0 join (', ', @{ $by_moniker{$m} }),
  0         0  
1804             $m,
1805             );
1806             }
1807             }
1808             else {
1809 2         20 push @clashes, sprintf ("tables %s reduced to the same source moniker '%s'",
1810             join (', ', map $_->sql_name, @$imtables),
1811             $moniker,
1812             );
1813             }
1814             }
1815             }
1816              
1817 154 100       1024 if (@clashes) {
1818 2         132 die 'Unable to load schema - chosen moniker/class naming style results in moniker clashes. '
1819             . 'Change the naming style, or supply an explicit moniker_map: '
1820             . join ('; ', @clashes)
1821             . "\n"
1822             ;
1823             }
1824              
1825 152         700 foreach my $tbl (@tables) { $self->_make_src_class($tbl); }
  851         4513  
1826 152         706 foreach my $tbl (@tables) { $self->_setup_src_meta($tbl); }
  851         8053  
1827              
1828 152 100       2139 if(!$self->skip_relationships) {
1829             # The relationship loader needs a working schema
1830 149         15535 local $self->{quiet} = 1;
1831 149         999 local $self->{dump_directory} = $self->{temp_directory};
1832 149         719 local $self->{generated_classes} = [];
1833 149         985 local $self->{dry_run} = 0;
1834 149         1816 $self->_reload_classes(\@tables);
1835 149         93453 $self->_load_relationships(\@tables);
1836              
1837             # Remove that temp dir from INC so it doesn't get reloaded
1838 146         4943 @INC = grep $_ ne $self->dump_directory, @INC;
1839             }
1840              
1841 149         1084 foreach my $tbl (@tables) { $self->_load_roles($tbl); }
  845         3314  
1842 149         586 foreach my $tbl (map { $self->classes->{$_->sql_name} } @tables) { $self->_load_external($tbl); }
  845         2778  
  845         3912  
1843              
1844             # Reload without unloading first to preserve any symbols from external
1845             # packages.
1846 149         2445 $self->_reload_classes(\@tables, { unload => 0 });
1847              
1848             # Drop temporary cache
1849 147         115457 delete $self->{_cache};
1850              
1851 147         6451 return \@tables;
1852             }
1853              
1854             sub _reload_classes {
1855 298     298   1350 my ($self, $tables, $opts) = @_;
1856              
1857 298         3896 my @tables = @$tables;
1858              
1859 298         1284 my $unload = $opts->{unload};
1860 298 100       1792 $unload = 1 unless defined $unload;
1861              
1862             # so that we don't repeat custom sections
1863 298         5568 @INC = grep $_ ne $self->dump_directory, @INC;
1864              
1865 298         3371 $self->_dump_to_dir(map { $self->classes->{$_->sql_name} } @tables);
  1690         6682  
1866              
1867 296         3859 unshift @INC, $self->dump_directory;
1868              
1869 296 100       2526 return if $self->dry_run;
1870              
1871 294         979 my @to_register;
1872 294         5730 my %have_source = map { $_ => $self->schema->source($_) }
  1118         55752  
1873             $self->schema->sources;
1874              
1875 294         26706 for my $table (@tables) {
1876 1682         16687 my $moniker = $self->monikers->{$table->sql_name};
1877 1682         9414 my $class = $self->classes->{$table->sql_name};
1878              
1879             {
1880 52     52   370999 no warnings 'redefine';
  52         167  
  52         5758  
  1682         4338  
1881 1682     631   14456 local *Class::C3::reinitialize = sub {}; # to speed things up, reinitialized below
1882 52     52   445 use warnings;
  52         130  
  52         346189  
1883              
1884 1682 50       9272 if (my $mc = $self->_moose_metaclass($class)) {
1885 0         0 $mc->make_mutable;
1886             }
1887 1682 100       13135 Class::Unload->unload($class) if $unload;
1888 1682         331061 my ($source, $resultset_class);
1889 1682 50 66     51946 if (
      66        
1890             ($source = $have_source{$moniker})
1891             && ($resultset_class = $source->resultset_class)
1892             && ($resultset_class ne 'DBIx::Class::ResultSet')
1893             ) {
1894 0         0 my $has_file = Class::Inspector->loaded_filename($resultset_class);
1895 0 0       0 if (my $mc = $self->_moose_metaclass($resultset_class)) {
1896 0         0 $mc->make_mutable;
1897             }
1898 0 0       0 Class::Unload->unload($resultset_class) if $unload;
1899 0 0       0 $self->_reload_class($resultset_class) if $has_file;
1900             }
1901 1682         54440 $self->_reload_class($class);
1902             }
1903 1682         57677 push @to_register, [$moniker, $class];
1904             }
1905              
1906 294         3684 Class::C3->reinitialize;
1907 294         1739 for (@to_register) {
1908 1682         803745 $self->schema->register_class(@$_);
1909             }
1910             }
1911              
1912             sub _moose_metaclass {
1913 1682 50   1682   11538 return undef unless $INC{'Class/MOP.pm'}; # if CMOP is not loaded the class could not have loaded in the 1st place
1914              
1915 0         0 my $class = $_[1];
1916              
1917 0     0   0 my $mc = try { Class::MOP::class_of($class) }
1918 0 0       0 or return undef;
1919              
1920 0 0       0 return $mc->isa('Moose::Meta::Class') ? $mc : undef;
1921             }
1922              
1923             # We use this instead of ensure_class_loaded when there are package symbols we
1924             # want to preserve.
1925             sub _reload_class {
1926 1682     1682   5496 my ($self, $class) = @_;
1927              
1928 1682         11965 delete $INC{ +class_path($class) };
1929              
1930             try {
1931 1682     1682   150197 eval_package_without_redefine_warnings ($class, "require $class");
1932             }
1933             catch {
1934 0     0   0 my $source = slurp_file $self->_get_dump_filename($class);
1935 0         0 die "Failed to reload class $class: $_.\n\nCLASS SOURCE:\n\n$source";
1936 1682         22350 };
1937             }
1938              
1939             sub _get_dump_filename {
1940 2735     2735   7884 my ($self, $class) = (@_);
1941              
1942 2735         18375 $class =~ s{::}{/}g;
1943 2735         36216 return $self->dump_directory . q{/} . $class . q{.pm};
1944             }
1945              
1946             =head2 get_dump_filename
1947              
1948             Arguments: class
1949              
1950             Returns the full path to the file for a class that the class has been or will
1951             be dumped to. This is a file in a temp dir for a dynamic schema.
1952              
1953             =cut
1954              
1955             sub get_dump_filename {
1956 429     429 1 63677 my ($self, $class) = (@_);
1957              
1958 429         3136 local $self->{dump_directory} = $self->real_dump_directory;
1959              
1960 429         2304 return $self->_get_dump_filename($class);
1961             }
1962              
1963             sub _ensure_dump_subdirs {
1964 1986     1986   5136 my ($self, $class) = (@_);
1965              
1966 1986 100       9413 return if $self->dry_run;
1967              
1968 1980         17165 my @name_parts = split(/::/, $class);
1969 1980         4844 pop @name_parts; # we don't care about the very last element,
1970             # which is a filename
1971              
1972 1980         6492 my $dir = $self->dump_directory;
1973 1980         4083 while (1) {
1974 7484 100       163432 if(!-d $dir) {
1975 608 50       82926 mkdir($dir) or croak "mkdir('$dir') failed: $!";
1976             }
1977 7484 100       25247 last if !@name_parts;
1978 5504         53427 $dir = File::Spec->catdir($dir, shift @name_parts);
1979             }
1980             }
1981              
1982             sub _dump_to_dir {
1983 298     298   1842 my ($self, @classes) = @_;
1984              
1985 298         1995 my $schema_class = $self->schema_class;
1986 298   100     3615 my $schema_base_class = $self->schema_base_class || 'DBIx::Class::Schema';
1987              
1988 298         1525 my $target_dir = $self->dump_directory;
1989 298 100 100     5308 warn "Dumping manual schema for $schema_class to directory $target_dir ...\n"
1990             unless $self->dynamic or $self->quiet;
1991              
1992 298         12310 my $schema_text =
1993             qq|use utf8;\n|
1994             . qq|package $schema_class;\n\n|
1995             . qq|# Created by DBIx::Class::Schema::Loader\n|
1996             . qq|# DO NOT MODIFY THE FIRST PART OF THIS FILE\n\n|;
1997              
1998 298 50       3553 my $autoclean
1999             = $self->only_autoclean
2000             ? 'namespace::autoclean'
2001             : 'MooseX::MarkAsMethods autoclean => 1'
2002             ;
2003              
2004 298 50       12333 if ($self->use_moose) {
2005              
2006 0         0 $schema_text.= qq|use Moose;\nuse $autoclean;\nextends '$schema_base_class';\n\n|;
2007             }
2008             else {
2009 298         1092 $schema_text .= qq|use strict;\nuse warnings;\n\nuse base '$schema_base_class';\n\n|;
2010             }
2011              
2012 298 50       843 my @schema_components = @{ $self->schema_components || [] };
  298         3311  
2013              
2014 298 100       1560 if (@schema_components) {
2015 16         113 my $schema_components = dump @schema_components;
2016 16 100       3441 $schema_components = "($schema_components)" if @schema_components == 1;
2017              
2018 16         70 $schema_text .= "__PACKAGE__->load_components${schema_components};\n\n";
2019             }
2020              
2021 298 100       2356 if ($self->use_namespaces) {
2022 172         566 $schema_text .= qq|__PACKAGE__->load_namespaces|;
2023 172         546 my $namespace_options;
2024              
2025 172         771 my @attr = qw/resultset_namespace default_resultset_class/;
2026              
2027 172 100 100     2174 unshift @attr, 'result_namespace'
2028             if $self->result_namespace && $self->result_namespace ne 'Result';
2029              
2030 172         776 for my $attr (@attr) {
2031 372 100       9053 if ($self->$attr) {
2032 56         1665 my $code = dumper_squashed $self->$attr;
2033 56         2773 $namespace_options .= qq| $attr => $code,\n|
2034             }
2035             }
2036 172 100       6900 $schema_text .= qq|(\n$namespace_options)| if $namespace_options;
2037 172         712 $schema_text .= qq|;\n|;
2038             }
2039             else {
2040 126         483 $schema_text .= qq|__PACKAGE__->load_classes;\n|;
2041             }
2042              
2043             {
2044 298         950 local $self->{version_to_dump} = $self->schema_version_to_dump;
  298         3098  
2045 298         2374 $self->_write_classfile($schema_class, $schema_text, 1);
2046             }
2047              
2048 298   100     4621 my $result_base_class = $self->result_base_class || 'DBIx::Class::Core';
2049              
2050 298         1351 foreach my $src_class (@classes) {
2051 1688         6863 my $src_text =
2052             qq|use utf8;\n|
2053             . qq|package $src_class;\n\n|
2054             . qq|# Created by DBIx::Class::Schema::Loader\n|
2055             . qq|# DO NOT MODIFY THE FIRST PART OF THIS FILE\n\n|;
2056              
2057 1688         8786 $src_text .= $self->_make_pod_heading($src_class);
2058              
2059 1688         4402 $src_text .= qq|use strict;\nuse warnings;\n\n|;
2060              
2061 1688 100       6658 $src_text .= $self->_base_class_pod($result_base_class)
2062             unless $result_base_class eq 'DBIx::Class::Core';
2063              
2064 1688 50       8585 if ($self->use_moose) {
2065 0         0 $src_text.= qq|use Moose;\nuse MooseX::NonMoose;\nuse $autoclean;|;
2066              
2067             # these options 'use base' which is compile time
2068 0 0 0     0 if (@{ $self->left_base_classes } || @{ $self->additional_base_classes }) {
  0         0  
  0         0  
2069 0         0 $src_text .= qq|\nBEGIN { extends '$result_base_class' }\n|;
2070             }
2071             else {
2072 0         0 $src_text .= qq|\nextends '$result_base_class';\n|;
2073             }
2074             }
2075             else {
2076 1688         4457 $src_text .= qq|use base '$result_base_class';\n|;
2077             }
2078              
2079 1688         6772 $self->_write_classfile($src_class, $src_text);
2080             }
2081              
2082             # remove Result dir if downgrading from use_namespaces, and there are no
2083             # files left.
2084 296 100 100     5117 if (my $result_ns = $self->_downgrading_to_load_classes
2085             || $self->_rewriting_result_namespace) {
2086 16         149 my $result_namespace = $self->_result_namespace(
2087             $schema_class,
2088             $result_ns,
2089             );
2090              
2091 16         128 (my $result_dir = $result_namespace) =~ s{::}{/}g;
2092 16         102 $result_dir = $self->dump_directory . '/' . $result_dir;
2093              
2094 16 100       1272 unless (my @files = glob "$result_dir/*") {
2095 13         671 rmdir $result_dir;
2096             }
2097             }
2098              
2099 296 100 100     10497 warn "Schema dump completed.\n" unless $self->dynamic or $self->quiet;
2100             }
2101              
2102             sub _sig_comment {
2103 2136     2136   32402 my ($self, $version, $ts) = @_;
2104 2136 100       15723 return qq|\n\n# Created by DBIx::Class::Schema::Loader|
    100          
2105             . (defined($version) ? q| v| . $version : '')
2106             . (defined($ts) ? q| @ | . $ts : '')
2107             . qq|\n# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:|;
2108             }
2109              
2110             sub _write_classfile {
2111 1986     1986   7081 my ($self, $class, $text, $is_schema) = @_;
2112              
2113 1986         8228 my $filename = $self->_get_dump_filename($class);
2114 1986         9413 $self->_ensure_dump_subdirs($class);
2115              
2116 1986 100 100     73685 if (-f $filename && $self->really_erase_my_files && !$self->dry_run) {
      66        
2117 33 100       1014 warn "Deleting existing file '$filename' due to "
2118             . "'really_erase_my_files' setting\n" unless $self->quiet;
2119 33         5200 unlink($filename);
2120             }
2121              
2122 1986         23271 my ($old_gen, $old_md5, $old_ver, $old_ts, $old_custom)
2123             = $self->_parse_generated_file($filename);
2124              
2125 1984 50 66     18665 if (! $old_gen && -f $filename) {
2126 0         0 croak "Cannot overwrite '$filename' without 'really_erase_my_files',"
2127             . " it does not appear to have been generated by Loader"
2128             }
2129              
2130 1984   100     9733 my $custom_content = $old_custom || '';
2131              
2132             # Use custom content from a renamed class, the class names in it are
2133             # rewritten below.
2134 1984 100       14951 if (my $renamed_class = $self->_upgrading_classes->{$class}) {
2135 320         1299 my $old_filename = $self->_get_dump_filename($renamed_class);
2136              
2137 320 100       15757 if (-f $old_filename) {
2138 73         310 $custom_content = ($self->_parse_generated_file ($old_filename))[4];
2139              
2140 73 50       11615 unlink $old_filename unless $self->dry_run;
2141             }
2142             }
2143              
2144 1984   66     20957 $custom_content ||= $self->_default_custom_content($is_schema);
2145              
2146             # If upgrading to use_moose=1 replace default custom content with default Moose custom content.
2147             # If there is already custom content, which does not have the Moose content, add it.
2148 1984 50 33     15271 if ($self->use_moose) {
    50          
2149              
2150 0         0 my $non_moose_custom_content = do {
2151 0         0 local $self->{use_moose} = 0;
2152 0         0 $self->_default_custom_content;
2153             };
2154              
2155 0 0       0 if ($custom_content eq $non_moose_custom_content) {
    0          
2156 0         0 $custom_content = $self->_default_custom_content($is_schema);
2157             }
2158 0         0 elsif ($custom_content !~ /\Q@{[$self->_default_moose_custom_content($is_schema)]}\E/) {
2159 0         0 $custom_content .= $self->_default_custom_content($is_schema);
2160             }
2161             }
2162             elsif (defined $self->use_moose && $old_gen) {
2163 0 0       0 croak 'It is not possible to "downgrade" a schema that was loaded with use_moose => 1 to use_moose => 0, due to differing custom content'
2164             if $old_gen =~ /use \s+ MooseX?\b/x;
2165             }
2166              
2167 1984         9076 $custom_content = $self->_rewrite_old_classnames($custom_content);
2168              
2169             $text .= qq|$_\n|
2170 1984 100       5068 for @{$self->{_dump_storage}->{$class} || []};
  1984         55729  
2171              
2172 1984 100       10619 if ($self->filter_generated_code) {
2173 12         60 my $filter = $self->filter_generated_code;
2174              
2175 12 100       4168 if (ref $filter eq 'CODE') {
2176 6 100       70 $text = $filter->(
2177             ($is_schema ? 'schema' : 'result'),
2178             $class,
2179             $text
2180             );
2181             }
2182             else {
2183 6         128 my ($fh, $temp_file) = tempfile();
2184              
2185 6         5891 binmode $fh, ':encoding(UTF-8)';
2186 6         2260 print $fh $text;
2187 6         531 close $fh;
2188              
2189 6 50       95909 open my $out, qq{$filter < "$temp_file"|}
2190             or croak "Could not open pipe to $filter: $!";
2191              
2192 6         176 $text = decode('UTF-8', do { local $/; <$out> });
  6         246  
  6         3817023  
2193              
2194 6         1881 $text =~ s/$CR?$LF/\n/g;
2195              
2196 6         436 close $out;
2197              
2198 6         121 my $exit_code = $? >> 8;
2199              
2200 6 50       2074 unlink $temp_file
2201             or croak "Could not remove temporary file '$temp_file': $!";
2202              
2203 6 50       509 if ($exit_code != 0) {
2204 0         0 croak "filter '$filter' exited non-zero: $exit_code";
2205             }
2206             }
2207 12 100 66     11539 if (not $text or not $text =~ /\bpackage\b/) {
2208 2 50       19 warn("$class skipped due to filter") if $self->debug;
2209 2         12 return;
2210             }
2211             }
2212              
2213             # Check and see if the dump is in fact different
2214              
2215 1982         4417 my $compare_to;
2216 1982 100       6308 if ($old_md5) {
2217 848         3872 $compare_to = $text . $self->_sig_comment($old_ver, $old_ts);
2218 848 100       8172 if (Digest::MD5::md5_base64(encode 'UTF-8', $compare_to) eq $old_md5) {
2219 720 100 100     44212 return unless $self->_upgrading_from && $is_schema;
2220             }
2221             }
2222              
2223 1294         9244 push @{$self->generated_classes}, $class;
  1294         6243  
2224              
2225 1294 100       17396 return if $self->dry_run;
2226              
2227 1288 100       64578 $text .= $self->_sig_comment(
    100          
2228             $self->omit_version ? undef : $self->version_to_dump,
2229             $self->omit_timestamp ? undef : POSIX::strftime('%Y-%m-%d %H:%M:%S', localtime)
2230             );
2231              
2232 1288 50   47   229089 open(my $fh, '>:raw:encoding(UTF-8)', $filename)
  47         39927  
  47         1052  
  47         341  
2233             or croak "Cannot open '$filename' for writing: $!";
2234              
2235             # Write the top half and its MD5 sum
2236 1288         147619 print $fh $text . Digest::MD5::md5_base64(encode 'UTF-8', $text) . "\n";
2237              
2238             # Write out anything loaded via external partial class file in @INC
2239             print $fh qq|$_\n|
2240 1288 100       111847 for @{$self->{_ext_storage}->{$class} || []};
  1288         16393  
2241              
2242             # Write out any custom content the user has added
2243 1288         13526 print $fh $custom_content;
2244              
2245 1288 50       120748 close($fh)
2246             or croak "Error closing '$filename': $!";
2247             }
2248              
2249             sub _default_moose_custom_content {
2250 0     0   0 my ($self, $is_schema) = @_;
2251              
2252 0 0       0 if (not $is_schema) {
2253 0         0 return qq|\n__PACKAGE__->meta->make_immutable;|;
2254             }
2255              
2256 0         0 return qq|\n__PACKAGE__->meta->make_immutable(inline_constructor => 0);|;
2257             }
2258              
2259             sub _default_custom_content {
2260 1063     1063   2934 my ($self, $is_schema) = @_;
2261 1063         2727 my $default = qq|\n\n# You can replace this text with custom|
2262             . qq| code or comments, and it will be preserved on regeneration|;
2263 1063 50       4780 if ($self->use_moose) {
2264 0         0 $default .= $self->_default_moose_custom_content($is_schema);
2265             }
2266 1063         4511 $default .= qq|\n1;\n|;
2267 1063         5244 return $default;
2268             }
2269              
2270             sub _parse_generated_file {
2271 2205     2205   6939 my ($self, $fn) = @_;
2272              
2273 2205 100       30881 return unless -f $fn;
2274              
2275 1069 50       62350 open(my $fh, '<:encoding(UTF-8)', $fn)
2276             or croak "Cannot open '$fn' for reading: $!";
2277              
2278 1069         133400 my $mark_re =
2279             qr{^(# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:)([A-Za-z0-9/+]{22})\r?\n};
2280              
2281 1069         2932 my ($real_md5, $ts, $ver, $gen);
2282 1069         2770 local $_;
2283 1069         32578 while(<$fh>) {
2284 104049 100       304491 if(/$mark_re/) {
2285 1069         4715 my $pre_md5 = $1;
2286 1069         3382 my $mark_md5 = $2;
2287              
2288             # Pull out the version and timestamp from the line above
2289 1069         15357 ($ver, $ts) = $gen =~ m/^# Created by DBIx::Class::Schema::Loader( v[\d._]+)?( @ [\d-]+ [\d:]+)?\r?\Z/m;
2290 1069 100       8092 $ver =~ s/^ v// if $ver;
2291 1069 100       14508 $ts =~ s/^ @ // if $ts;
2292              
2293 1069         5631 $gen .= $pre_md5;
2294 1069         11203 $real_md5 = Digest::MD5::md5_base64(encode 'UTF-8', $gen);
2295 1069 100       57739 if ($real_md5 ne $mark_md5) {
2296 4 100       48 if ($self->overwrite_modifications) {
2297             # Setting this to something that is not a valid MD5 forces
2298             # the file to be rewritten.
2299 2         6 $real_md5 = 'not an MD5';
2300             }
2301             else {
2302 2         411 croak "Checksum mismatch in '$fn', the auto-generated part of the file has been modified outside of this loader. Aborting.\nIf you want to overwrite these modifications, set the 'overwrite_modifications' loader option.\n";
2303             }
2304             }
2305 1067         6420 last;
2306             }
2307             else {
2308 102980         246597 $gen .= $_;
2309             }
2310             }
2311              
2312 1067 50       4187 my $custom = do { local $/; <$fh> }
  1067         5720  
  1067         28495  
2313             if $real_md5;
2314              
2315 1067   50     23703 $custom ||= '';
2316 1067         21781 $custom =~ s/$CRLF|$LF/\n/g;
2317              
2318 1067         19648 close $fh;
2319              
2320 1067         15514 return ($gen, $real_md5, $ver, $ts, $custom);
2321             }
2322              
2323             sub _use {
2324 851     851   1923 my $self = shift;
2325 851         1877 my $target = shift;
2326              
2327 851         2830 foreach (@_) {
2328 315 50       1146 warn "$target: use $_;" if $self->debug;
2329 315         1406 $self->_raw_stmt($target, "use $_;");
2330             }
2331             }
2332              
2333             sub _inject {
2334 1702     1702   3314 my $self = shift;
2335 1702         3195 my $target = shift;
2336              
2337 1702         4404 my $blist = join(q{ }, @_);
2338              
2339 1702 100       6347 return unless $blist;
2340              
2341 630 50       1917 warn "$target: use base qw/$blist/;" if $self->debug;
2342 630         1910 $self->_raw_stmt($target, "use base qw/$blist/;");
2343             }
2344              
2345             sub _with {
2346 0     0   0 my $self = shift;
2347 0         0 my $target = shift;
2348              
2349 0         0 my $rlist = join(q{, }, map { qq{'$_'} } @_);
  0         0  
2350              
2351 0 0       0 return unless $rlist;
2352              
2353 0 0       0 warn "$target: with $rlist;" if $self->debug;
2354 0         0 $self->_raw_stmt($target, "\nwith $rlist;");
2355             }
2356              
2357             sub _result_namespace {
2358 680     680   1892 my ($self, $schema_class, $ns) = @_;
2359 680         1279 my @result_namespace;
2360              
2361 680 100       2355 $ns = $ns->[0] if ref $ns;
2362              
2363 680 100       2575 if ($ns =~ /^\+(.*)/) {
2364             # Fully qualified namespace
2365 8         45 @result_namespace = ($1)
2366             }
2367             else {
2368             # Relative namespace
2369 672         2114 @result_namespace = ($schema_class, $ns);
2370             }
2371              
2372 680 100       3145 return wantarray ? @result_namespace : join '::', @result_namespace;
2373             }
2374              
2375             # Create class with applicable bases, setup monikers, etc
2376             sub _make_src_class {
2377 851     851   2256 my ($self, $table) = @_;
2378              
2379 851         2999 my $schema = $self->schema;
2380 851         3245 my $schema_class = $self->schema_class;
2381              
2382 851         10898 my $table_moniker = $self->monikers->{$table->sql_name};
2383 851         2704 my @result_namespace = ($schema_class);
2384 851 100       4368 if ($self->use_namespaces) {
2385 623   100     3290 my $result_namespace = $self->result_namespace || 'Result';
2386 623         7515 @result_namespace = $self->_result_namespace(
2387             $schema_class,
2388             $result_namespace,
2389             );
2390             }
2391 851         3339 my $table_class = join(q{::}, @result_namespace, $table_moniker);
2392              
2393 851 100 100     5781 if ((my $upgrading_v = $self->_upgrading_from)
2394             || $self->_rewriting) {
2395 209 100       1213 local $self->naming->{monikers} = $upgrading_v
2396             if $upgrading_v;
2397              
2398 209         643 my @result_namespace = @result_namespace;
2399 209 100       1454 if ($self->_upgrading_from_load_classes) {
    100          
    100          
2400 97         315 @result_namespace = ($schema_class);
2401             }
2402             elsif (my $ns = $self->_downgrading_to_load_classes) {
2403 23         114 @result_namespace = $self->_result_namespace(
2404             $schema_class,
2405             $ns,
2406             );
2407             }
2408             elsif ($ns = $self->_rewriting_result_namespace) {
2409 18         65 @result_namespace = $self->_result_namespace(
2410             $schema_class,
2411             $ns,
2412             );
2413             }
2414              
2415 209         1070 my $old_table_moniker = do {
2416 209         765 local $self->naming->{monikers} = $upgrading_v;
2417 209         948 $self->_table2moniker($table);
2418             };
2419              
2420 209         896 my $old_class = join(q{::}, @result_namespace, $old_table_moniker);
2421              
2422 209 100       1682 $self->_upgrading_classes->{$table_class} = $old_class
2423             unless $table_class eq $old_class;
2424             }
2425              
2426 851         29379 $self->classes->{$table->sql_name} = $table_class;
2427 851         4450 $self->moniker_to_table->{$table_moniker} = $table;
2428 851         15624 $self->class_to_table->{$table_class} = $table;
2429              
2430 851         13128 $self->_pod_class_list($table_class, 'ADDITIONAL CLASSES USED', @{$self->additional_classes});
  851         6157  
2431              
2432 851         1886 $self->_use ($table_class, @{$self->additional_classes});
  851         4135  
2433              
2434 851         2055 $self->_pod_class_list($table_class, 'LEFT BASE CLASSES', @{$self->left_base_classes});
  851         4160  
2435              
2436 851         1760 $self->_inject($table_class, @{$self->left_base_classes});
  851         3705  
2437              
2438 851 50       1956 my @components = @{ $self->components || [] };
  851         4975  
2439              
2440 12         53 push @components, @{ $self->result_components_map->{$table_moniker} }
2441 851 100       4582 if exists $self->result_components_map->{$table_moniker};
2442              
2443 851         2217 my @fq_components = @components;
2444 851         2298 foreach my $component (@fq_components) {
2445 953 100       2877 if ($component !~ s/^\+//) {
2446 321         966 $component = "DBIx::Class::$component";
2447             }
2448             }
2449              
2450 851         3097 $self->_pod_class_list($table_class, 'COMPONENTS LOADED', @fq_components);
2451              
2452 851 100       3532 $self->_dbic_stmt($table_class, 'load_components', @components) if @components;
2453              
2454 851         1946 $self->_pod_class_list($table_class, 'ADDITIONAL BASE CLASSES', @{$self->additional_base_classes});
  851         4748  
2455              
2456 851         1789 $self->_inject($table_class, @{$self->additional_base_classes});
  851         2813  
2457             }
2458              
2459             sub _is_result_class_method {
2460 3424     3424   10117 my ($self, $name, $table) = @_;
2461              
2462 3424 50       20673 my $table_moniker = $table ? $self->monikers->{$table->sql_name} : '';
2463              
2464 3424 100       17823 $self->_result_class_methods({})
2465             if not defined $self->_result_class_methods;
2466              
2467 3424 100       27390 if (not exists $self->_result_class_methods->{$table_moniker}) {
2468 590         1901 my (@methods, %methods);
2469 590   100     5541 my $base = $self->result_base_class || 'DBIx::Class::Core';
2470              
2471 590 50       1616 my @components = @{ $self->components || [] };
  590         4817  
2472              
2473 2         10 push @components, @{ $self->result_components_map->{$table_moniker} }
2474 590 100       4515 if exists $self->result_components_map->{$table_moniker};
2475              
2476 590         2597 for my $c (@components) {
2477 169 100       679 $c = $c =~ /^\+/ ? substr($c,1) : "DBIx::Class::$c";
2478             }
2479              
2480 590 50       1658 my @roles = @{ $self->result_roles || [] };
  590         5050  
2481              
2482 0         0 push @roles, @{ $self->result_roles_map->{$table_moniker} }
2483 590 50       4439 if exists $self->result_roles_map->{$table_moniker};
2484              
2485 590 50       4604 for my $class (
2486             $base, @components, @roles,
2487             ($self->use_moose ? 'Moose::Object' : ()),
2488             ) {
2489 759         174447 $self->ensure_class_loaded($class);
2490              
2491 759 50       5129937 push @methods, @{ Class::Inspector->methods($class) || [] };
  759         7740  
2492             }
2493              
2494 590         1695671 push @methods, @{ Class::Inspector->methods('UNIVERSAL') };
  590         4325  
2495              
2496 590         149171 @methods{@methods} = ();
2497              
2498 590         13953 $self->_result_class_methods->{$table_moniker} = \%methods;
2499             }
2500 3424         11450 my $result_methods = $self->_result_class_methods->{$table_moniker};
2501              
2502 3424         25942 return exists $result_methods->{$name};
2503             }
2504              
2505             sub _resolve_col_accessor_collisions {
2506 851     851   4590 my ($self, $table, $col_info) = @_;
2507              
2508 851         5575 while (my ($col, $info) = each %$col_info) {
2509 2385   33     10933 my $accessor = $info->{accessor} || $col;
2510              
2511 2385 100       12728 next if $accessor eq 'id'; # special case (very common column)
2512              
2513 2038 100       8448 if ($self->_is_result_class_method($accessor, $table)) {
2514 46         88 my $mapped = 0;
2515              
2516 46 100       268 if (my $map = $self->col_collision_map) {
2517 42         145 for my $re (keys %$map) {
2518 42 100       306 if (my @matches = $col =~ /$re/) {
2519 6         46 $info->{accessor} = sprintf $map->{$re}, @matches;
2520 6         18 $mapped = 1;
2521             }
2522             }
2523             }
2524              
2525 46 100       162 if (not $mapped) {
2526 40         198 warn <<"EOF";
2527             Column '$col' in table '$table' collides with an inherited method.
2528             See "COLUMN ACCESSOR COLLISIONS" in perldoc DBIx::Class::Schema::Loader::Base .
2529             EOF
2530 40         339 $info->{accessor} = undef;
2531             }
2532             }
2533             }
2534             }
2535              
2536             # use the same logic to run moniker_map, col_accessor_map
2537             sub _run_user_map {
2538 6164     6164   104366 my ( $self, $map, $default_code, $ident, @extra ) = @_;
2539              
2540 6164         17483 my $default_ident = $default_code->( $ident, @extra );
2541 6164         12365 my $new_ident;
2542 6164 100 100     40006 if( $map && ref $map eq 'HASH' ) {
    100 66        
2543 1323 100   1323   10655 if (my @parts = try { @{ $ident } }) {
  1323         64912  
  1323         7212  
2544 1319         20150 my $part_map = $map;
2545 1319         4897 while (@parts) {
2546 1397         3420 my $part = shift @parts;
2547 1397 100       7228 last unless exists $part_map->{ $part };
2548 94 100 66     643 if ( !ref $part_map->{ $part } && !@parts ) {
    50          
2549 16         71 $new_ident = $part_map->{ $part };
2550 16         55 last;
2551             }
2552             elsif ( ref $part_map->{ $part } eq 'HASH' ) {
2553 78         243 $part_map = $part_map->{ $part };
2554             }
2555             }
2556             }
2557 1323 100 100     13803 if( !$new_ident && !ref $map->{ $ident } ) {
2558 1306         4023 $new_ident = $map->{ $ident };
2559             }
2560             }
2561             elsif( $map && ref $map eq 'CODE' ) {
2562             my $cb = sub {
2563 1313     1313   13803 my ($cb_map) = @_;
2564 1313 50       5910 croak "reentered map must be a hashref"
2565             unless 'HASH' eq ref($cb_map);
2566 1313         5325 return $self->_run_user_map($cb_map, $default_code, $ident, @extra);
2567 1319         9616 };
2568 1319         6693 $new_ident = $map->( $ident, $default_ident, @extra, $cb );
2569             }
2570              
2571 6164   100     30059 $new_ident ||= $default_ident;
2572              
2573 6164         36982 return $new_ident;
2574             }
2575              
2576             sub _default_column_accessor_name {
2577 3384     3384   19999 my ( $self, $column_name ) = @_;
2578              
2579 3384   100     27835 my $preserve = ($self->naming->{column_accessors}||'') eq 'preserve';
2580              
2581 3384         13534 my $v = $self->_get_naming_v('column_accessors');
2582              
2583 3384 100       16470 my $accessor_name = $preserve ?
2584             $self->_to_identifier('column_accessors', $column_name) # assume CamelCase
2585             :
2586             $self->_to_identifier('column_accessors', $column_name, '_');
2587              
2588 3384         22383 $accessor_name =~ s/\W+/_/g; # only if naming < v8, otherwise to_identifier
2589             # takes care of it
2590              
2591 3384 100 100     38307 if ($preserve) {
    100          
2592 34         139 return $accessor_name;
2593             }
2594             elsif ($v < 7 || (not $self->preserve_case)) {
2595             # older naming just lc'd the col accessor and that's all.
2596 955         5153 return lc $accessor_name;
2597             }
2598              
2599 2395         10757 return join '_', map lc, split_name $column_name, $v;
2600             }
2601              
2602             sub _make_column_accessor_name {
2603 2385     2385   7063 my ($self, $column_name, $column_context_info ) = @_;
2604              
2605 2385         25111 my $accessor = $self->_run_user_map(
2606             $self->col_accessor_map,
2607             $self->curry::_default_column_accessor_name,
2608             $column_name,
2609             $column_context_info,
2610             );
2611              
2612 2385         43264 return $accessor;
2613             }
2614              
2615             sub _table_is_view {
2616             #my ($self, $table) = @_;
2617 0     0   0 return 0;
2618             }
2619              
2620 7     7   60 sub _view_definition { undef }
2621              
2622             # Set up metadata (cols, pks, etc)
2623             sub _setup_src_meta {
2624 851     851   3158 my ($self, $table) = @_;
2625              
2626 851         4056 my $schema = $self->schema;
2627 851         4284 my $schema_class = $self->schema_class;
2628              
2629 851         7456 my $table_class = $self->classes->{$table->sql_name};
2630 851         7235 my $table_moniker = $self->monikers->{$table->sql_name};
2631              
2632             # Must come before ->table
2633 851 100       6690 $self->_dbic_stmt($table_class, 'table_class', 'DBIx::Class::ResultSource::View')
2634             if my $is_view = $self->_table_is_view($table);
2635              
2636 851         7507 $self->_dbic_stmt($table_class, 'table', $table->dbic_name);
2637              
2638             # Must come after ->table
2639 851 50 66     6370 if ($is_view and my $view_def = $self->_view_definition($table)) {
2640 0         0 $self->_dbic_stmt($table_class, 'result_source_instance->view_definition', $view_def);
2641             }
2642              
2643 851         6521 my $cols = $self->_table_columns($table);
2644 851         5960 my $col_info = $self->__columns_info_for($table);
2645              
2646             ### generate all the column accessor names
2647 851         5491 while (my ($col, $info) = each %$col_info) {
2648             # hashref of other info that could be used by
2649             # user-defined accessor map functions
2650 2385         14008 my $context = {
2651             table_class => $table_class,
2652             table_moniker => $table_moniker,
2653             table_name => $table, # bugwards compatibility, RT#84050
2654             table => $table,
2655             full_table_name => $table->dbic_name,
2656             schema_class => $schema_class,
2657             column_info => $info,
2658             };
2659 2385         17533 my $col_obj = DBIx::Class::Schema::Loader::Column->new(
2660             table => $table,
2661             name => $col,
2662             );
2663              
2664 2385         11876 $info->{accessor} = $self->_make_column_accessor_name( $col_obj, $context );
2665             }
2666              
2667 851         6398 $self->_resolve_col_accessor_collisions($table, $col_info);
2668              
2669             # prune any redundant accessor names
2670 851         5682 while (my ($col, $info) = each %$col_info) {
2671 52     52   601 no warnings 'uninitialized';
  52         132  
  52         268377  
2672 2385 100       14969 delete $info->{accessor} if $info->{accessor} eq $col;
2673             }
2674              
2675 851         6334 my $fks = $self->_table_fk_info($table);
2676              
2677 851         4597 foreach my $fkdef (@$fks) {
2678 658         1930 for my $col (@{ $fkdef->{local_columns} }) {
  658         2785  
2679 707         3572 $col_info->{$col}{is_foreign_key} = 1;
2680             }
2681             }
2682              
2683 851   50     8105 my $pks = $self->_table_pk_info($table) || [];
2684              
2685 851         2563 my %uniq_tag; # used to eliminate duplicate uniqs
2686              
2687 851 100       6895 $uniq_tag{ join("\0", @$pks) }++ if @$pks; # pk is a uniq
2688              
2689 851   50     5941 my $uniqs = $self->_table_uniq_info($table) || [];
2690 851         3205 my @uniqs;
2691              
2692 851         4145 foreach my $uniq (@$uniqs) {
2693 278         1191 my ($name, $cols) = @$uniq;
2694 278 100       2109 next if $uniq_tag{ join("\0", @$cols) }++; # skip duplicates
2695 183         865 push @uniqs, [$name, $cols];
2696             }
2697              
2698             my @non_nullable_uniqs = grep {
2699 851     197   3267 all { $col_info->{$_}{is_nullable} == 0 } @{ $_->[1] }
  183         1162  
  197         1759  
  183         1245  
2700             } @uniqs;
2701              
2702 851 100 100     9350 if ($self->uniq_to_primary && (not @$pks) && @non_nullable_uniqs) {
      100        
2703 6         51 my @by_colnum = sort { $b->[0] <=> $a->[0] }
2704 6         23 map [ scalar @{ $_->[1] }, $_ ], @non_nullable_uniqs;
  12         57  
2705              
2706 6 50 33     68 if (not (@by_colnum > 1 && $by_colnum[0][0] == $by_colnum[1][0])) {
2707 6         31 my @keys = map $_->[1], @by_colnum;
2708              
2709 6         20 my $pk = $keys[0];
2710              
2711             # remove the uniq from list
2712 6         18 @uniqs = grep { $_->[0] ne $pk->[0] } @uniqs;
  18         55  
2713              
2714 6         53 $pks = $pk->[1];
2715             }
2716             }
2717              
2718 851         15990 foreach my $pkcol (@$pks) {
2719 931         5032 $col_info->{$pkcol}{is_nullable} = 0;
2720             }
2721              
2722             $self->_dbic_stmt(
2723             $table_class,
2724             'add_columns',
2725 851   50     4314 map { $_, ($col_info->{$_}||{}) } @$cols
  2385         16715  
2726             );
2727              
2728 851 100       8680 $self->_dbic_stmt($table_class, 'set_primary_key', @$pks)
2729             if @$pks;
2730              
2731             # Sort unique constraints by constraint name for repeatable results (rels
2732             # are sorted as well elsewhere.)
2733 851         3518 @uniqs = sort { $a->[0] cmp $b->[0] } @uniqs;
  25         147  
2734              
2735 851         20225 foreach my $uniq (@uniqs) {
2736 177         702 my ($name, $cols) = @$uniq;
2737 177         836 $self->_dbic_stmt($table_class,'add_unique_constraint', $name, $cols);
2738             }
2739             }
2740              
2741             sub __columns_info_for {
2742 851     851   3537 my ($self, $table) = @_;
2743              
2744 851         5861 my $result = $self->_columns_info_for($table);
2745              
2746 851         7068 while (my ($col, $info) = each %$result) {
2747 2385         7698 $info = { %$info, %{ $self->_custom_column_info ($table, $col, $info) } };
  2385         10935  
2748 2385         20832 $info = { %$info, %{ $self->_datetime_column_info($table, $col, $info) } };
  2385         11336  
2749              
2750 2385         13987 $result->{$col} = $info;
2751             }
2752              
2753 851         3470 return $result;
2754             }
2755              
2756             =head2 tables
2757              
2758             Returns a sorted list of loaded tables, using the original database table
2759             names.
2760              
2761             =cut
2762              
2763             sub tables {
2764 0     0 1 0 my $self = shift;
2765              
2766 0         0 return values %{$self->_tables};
  0         0  
2767             }
2768              
2769             sub _get_naming_v {
2770 12403     12403   27468 my ($self, $naming_key) = @_;
2771              
2772 12403         19151 my $v;
2773              
2774 12403 100 100     64703 if (($self->naming->{$naming_key}||'') =~ /^v(\d+)\z/) {
2775 4094         13257 $v = $1;
2776             }
2777             else {
2778 8309         35777 ($v) = $CURRENT_V =~ /^v(\d+)\z/;
2779             }
2780              
2781 12403         37096 return $v;
2782             }
2783              
2784             sub _to_identifier {
2785 5531     5531   28844 my ($self, $naming_key, $name, $sep_char, $force) = @_;
2786              
2787 5531         17783 my $v = $self->_get_naming_v($naming_key);
2788              
2789             my $to_identifier = $self->naming->{force_ascii} ?
2790 5531 50       25930 \&String::ToIdentifier::EN::to_identifier
2791             : \&String::ToIdentifier::EN::Unicode::to_identifier;
2792              
2793 5531 100 66     40733 return $v >= 8 || $force ? $to_identifier->($name, $sep_char) : $name;
2794             }
2795              
2796             # Make a moniker from a table
2797             sub _default_table2moniker {
2798 1383     1383   7668 my ($self, $table) = @_;
2799              
2800 1383         4452 my $v = $self->_get_naming_v('monikers');
2801              
2802 1383         2848 my @moniker_parts = @{ $self->moniker_parts };
  1383         7779  
2803 1383         6909 my @name_parts = map $table->$_, @moniker_parts;
2804              
2805 1383     1397   6528 my $name_idx = firstidx { $_ eq 'name' } @{ $self->moniker_parts };
  1397         7525  
  1383         7461  
2806              
2807 1383         5160 my @all_parts;
2808              
2809 1383         3573 foreach my $i (0 .. $#name_parts) {
2810 1397         3257 my $part = $name_parts[$i];
2811              
2812             my $moniker_part = $self->_run_user_map(
2813             $self->moniker_part_map->{$moniker_parts[$i]},
2814 1397     1397   3082 sub { '' },
2815 1397         10593 $part, $moniker_parts[$i],
2816             );
2817 1397 100       6330 if (length $moniker_part) {
2818 4         35 push @all_parts, $moniker_part;
2819 4         21 next;
2820             }
2821              
2822 1393 100 66     7202 if ($i != $name_idx || $v >= 8) {
2823 10         80 $part = $self->_to_identifier('monikers', $part, '_', 1);
2824             }
2825              
2826 1393 100 100     6578 if ($i == $name_idx && $v == 5) {
2827 14         77 $part = Lingua::EN::Inflect::Number::to_S($part);
2828             }
2829              
2830 1393 100       36867 my @part_parts = map lc, $v > 6 ?
    100          
2831             # use v8 semantics for all moniker parts except name
2832             ($i == $name_idx ? split_name $part, $v : split_name $part)
2833             : split /[\W_]+/, $part;
2834              
2835 1393 100 100     6789 if ($i == $name_idx && $v >= 6) {
2836 1159         4300 my $as_phrase = join ' ', @part_parts;
2837              
2838             my $inflected = ($self->naming->{monikers}||'') eq 'plural' ?
2839             Lingua::EN::Inflect::Phrase::to_PL($as_phrase)
2840             :
2841 1159 100 100     13271 ($self->naming->{monikers}||'') eq 'preserve' ?
    100 100        
2842             $as_phrase
2843             :
2844             Lingua::EN::Inflect::Phrase::to_S($as_phrase);
2845              
2846 1159         13766518 @part_parts = split /\s+/, $inflected;
2847             }
2848              
2849 1393         10472 push @all_parts, join '', map ucfirst, @part_parts;
2850             }
2851              
2852 1383         13308 return join $self->moniker_part_separator, @all_parts;
2853             }
2854              
2855             sub _table2moniker {
2856 1069     1069   2856 my ( $self, $table ) = @_;
2857              
2858 1069         11113 $self->_run_user_map(
2859             $self->moniker_map,
2860             $self->curry::_default_table2moniker,
2861             $table
2862             );
2863             }
2864              
2865             sub _load_relationships {
2866 149     149   985 my ($self, $tables) = @_;
2867              
2868 149         1176 my @tables;
2869              
2870 149         765 foreach my $table (@$tables) {
2871 845         7675 my $local_moniker = $self->monikers->{$table->sql_name};
2872              
2873 845         4493 my $tbl_fk_info = $self->_table_fk_info($table);
2874              
2875 845         3694 foreach my $fkdef (@$tbl_fk_info) {
2876 655         2882 $fkdef->{local_table} = $table;
2877 655         2912 $fkdef->{local_moniker} = $local_moniker;
2878             $fkdef->{remote_source} =
2879 655         6031 $self->monikers->{$fkdef->{remote_table}->sql_name};
2880             }
2881 845         4399 my $tbl_uniq_info = $self->_table_uniq_info($table);
2882              
2883 845         6103 push @tables, [ $local_moniker, $tbl_fk_info, $tbl_uniq_info ];
2884             }
2885              
2886 149         3378 my $rel_stmts = $self->_relbuilder->generate_code(\@tables);
2887              
2888 146         1305 foreach my $src_class (sort keys %$rel_stmts) {
2889             # sort by rel name
2890             my @src_stmts = map $_->[2],
2891             sort {
2892 800 50       3696 $a->[0] <=> $b->[0]
2893             ||
2894             $a->[1] cmp $b->[1]
2895             } map [
2896             ($_->{method} eq 'many_to_many' ? 1 : 0),
2897             $_->{args}[0],
2898             $_,
2899 737 100       1677 ], @{ $rel_stmts->{$src_class} };
  737         10474  
2900              
2901 737         2708 foreach my $stmt (@src_stmts) {
2902 1368         3626 $self->_dbic_stmt($src_class,$stmt->{method}, @{$stmt->{args}});
  1368         6478  
2903             }
2904             }
2905             }
2906              
2907             sub _load_roles {
2908 845     845   2126 my ($self, $table) = @_;
2909              
2910 845         3867 my $table_moniker = $self->monikers->{$table->sql_name};
2911 845         3332 my $table_class = $self->classes->{$table->sql_name};
2912              
2913 845 50       1705 my @roles = @{ $self->result_roles || [] };
  845         4052  
2914 0         0 push @roles, @{ $self->result_roles_map->{$table_moniker} }
2915 845 50       4047 if exists $self->result_roles_map->{$table_moniker};
2916              
2917 845 50       3182 if (@roles) {
2918 0         0 $self->_pod_class_list($table_class, 'L ROLES APPLIED', @roles);
2919              
2920 0         0 $self->_with($table_class, @roles);
2921             }
2922             }
2923              
2924             # Overload these in driver class:
2925              
2926             # Returns an arrayref of column names
2927 0     0   0 sub _table_columns { croak "ABSTRACT METHOD" }
2928              
2929             # Returns arrayref of pk col names
2930 0     0   0 sub _table_pk_info { croak "ABSTRACT METHOD" }
2931              
2932             # Returns an arrayref of uniqs [ [ foo => [ col1, col2 ] ], [ bar => [ ... ] ] ]
2933 0     0   0 sub _table_uniq_info { croak "ABSTRACT METHOD" }
2934              
2935             # Returns an arrayref of foreign key constraints, each
2936             # being a hashref with 3 keys:
2937             # local_columns (arrayref), remote_columns (arrayref), remote_table
2938 0     0   0 sub _table_fk_info { croak "ABSTRACT METHOD" }
2939              
2940             # Returns an array of lower case table names
2941 0     0   0 sub _tables_list { croak "ABSTRACT METHOD" }
2942              
2943             # Execute a constructive DBIC class method, with debug/dump_to_dir hooks.
2944             sub _dbic_stmt {
2945 4399     4399   10366 my $self = shift;
2946 4399         10319 my $class = shift;
2947 4399         9791 my $method = shift;
2948              
2949             # generate the pod for this statement, storing it with $self->_pod
2950 4399 100       37359 $self->_make_pod( $class, $method, @_ ) if $self->generate_pod;
2951              
2952 4399         25235 my $args = dump(@_);
2953 4399 100       2628836 $args = '(' . $args . ')' if @_ < 2;
2954 4399         14244 my $stmt = $method . $args . q{;};
2955              
2956 4399 50       23993 warn qq|$class\->$stmt\n| if $self->debug;
2957 4399         33773 $self->_raw_stmt($class, '__PACKAGE__->' . $stmt);
2958 4399         41462 return;
2959             }
2960              
2961             sub _make_pod_heading {
2962 1688     1688   5566 my ($self, $class) = @_;
2963              
2964 1688 100       9230 return '' if not $self->generate_pod;
2965              
2966 1680         8854 my $table = $self->class_to_table->{$class};
2967 1680         4029 my $pod;
2968              
2969 1680         6563 my $pcm = $self->pod_comment_mode;
2970 1680         4036 my ($comment, $comment_overflows, $comment_in_name, $comment_in_desc);
2971 1680         7133 $comment = $self->__table_comment($table);
2972 1680   100     6695 $comment_overflows = ($comment and length $comment > $self->pod_comment_spillover_length);
2973 1680   66     13671 $comment_in_name = ($pcm eq 'name' or ($pcm eq 'auto' and !$comment_overflows));
2974 1680   66     10729 $comment_in_desc = ($pcm eq 'description' or ($pcm eq 'auto' and $comment_overflows));
2975              
2976 1680         5774 $pod .= "=head1 NAME\n\n";
2977              
2978 1680         3968 my $table_descr = $class;
2979 1680 100 100     7836 $table_descr .= " - " . $comment if $comment and $comment_in_name;
2980              
2981 1680         5609 $pod .= "$table_descr\n\n";
2982              
2983 1680 100 100     6922 if ($comment and $comment_in_desc) {
2984 2         7 $pod .= "=head1 DESCRIPTION\n\n${comment}\n\n";
2985             }
2986 1680         5508 $pod .= "=cut\n\n";
2987              
2988 1680         6972 return $pod;
2989             }
2990              
2991             # generates the accompanying pod for a DBIC class method statement,
2992             # storing it with $self->_pod
2993             sub _make_pod {
2994 4383     4383   10224 my $self = shift;
2995 4383         10538 my $class = shift;
2996 4383         9957 my $method = shift;
2997              
2998 4383 100       37199 if ($method eq 'table') {
    100          
    100          
    100          
    100          
    100          
2999 847         2666 my $table = $_[0];
3000 847 50       4659 $table = $$table if ref $table eq 'SCALAR';
3001 847         6370 $self->_pod($class, "=head1 TABLE: C<$table>");
3002 847         3993 $self->_pod_cut($class);
3003             }
3004             elsif ( $method eq 'add_columns' ) {
3005 847         5551 $self->_pod( $class, "=head1 ACCESSORS" );
3006 847         2955 my $col_counter = 0;
3007 847         4428 my @cols = @_;
3008 847         6188 while( my ($name,$attrs) = splice @cols,0,2 ) {
3009 2375         5518 $col_counter++;
3010 2375         13236 $self->_pod( $class, '=head2 ' . $name );
3011             $self->_pod( $class,
3012             join "\n", map {
3013 2375         19207 my $s = $attrs->{$_};
  6940         16938  
3014 6940 100       47450 $s = !defined $s ? 'undef' :
    100          
    100          
    100          
    100          
3015             length($s) == 0 ? '(empty string)' :
3016             ref($s) eq 'SCALAR' ? $$s :
3017             ref($s) ? dumper_squashed $s :
3018             looks_like_number($s) ? $s : qq{'$s'};
3019              
3020 6940         32267 " $_: $s"
3021             } sort keys %$attrs,
3022             );
3023 2375 100       18661 if (my $comment = $self->__column_comment($self->class_to_table->{$class}, $col_counter, $name)) {
3024 2         6 $self->_pod( $class, $comment );
3025             }
3026             }
3027 847         5789 $self->_pod_cut( $class );
3028             } elsif ( $method =~ /^(?:belongs_to|has_many|might_have)\z/ ) {
3029 1300 100       8841 $self->_pod( $class, "=head1 RELATIONS" ) unless $self->{_relations_started} { $class } ;
3030 1300         4043 my ( $accessor, $rel_class ) = @_;
3031 1300         5367 $self->_pod( $class, "=head2 $accessor" );
3032 1300         4902 $self->_pod( $class, 'Type: ' . $method );
3033 1300         4900 $self->_pod( $class, "Related object: L<$rel_class>" );
3034 1300         4686 $self->_pod_cut( $class );
3035 1300         4777 $self->{_relations_started} { $class } = 1;
3036             } elsif ( $method eq 'many_to_many' ) {
3037 64 50       317 $self->_pod( $class, "=head1 RELATIONS" ) unless $self->{_relations_started} { $class } ;
3038 64         258 my ( $accessor, $rel1, $rel2 ) = @_;
3039 64         361 $self->_pod( $class, "=head2 $accessor" );
3040 64         269 $self->_pod( $class, 'Type: many_to_many' );
3041 64         283 $self->_pod( $class, "Composing rels: L -> $rel2" );
3042 64         244 $self->_pod_cut( $class );
3043 64         225 $self->{_relations_started} { $class } = 1;
3044             }
3045             elsif ($method eq 'add_unique_constraint') {
3046             $self->_pod($class, '=head1 UNIQUE CONSTRAINTS')
3047 177 100       1558 unless $self->{_uniqs_started}{$class};
3048              
3049 177         677 my ($name, $cols) = @_;
3050              
3051 177         1023 $self->_pod($class, "=head2 C<$name>");
3052 177         728 $self->_pod($class, '=over 4');
3053              
3054 177         750 foreach my $col (@$cols) {
3055 192         830 $self->_pod($class, "=item \* L");
3056             }
3057              
3058 177         743 $self->_pod($class, '=back');
3059 177         809 $self->_pod_cut($class);
3060              
3061 177         792 $self->{_uniqs_started}{$class} = 1;
3062             }
3063             elsif ($method eq 'set_primary_key') {
3064 826         4337 $self->_pod($class, "=head1 PRIMARY KEY");
3065 826         3781 $self->_pod($class, '=over 4');
3066              
3067 826         3620 foreach my $col (@_) {
3068 927         4058 $self->_pod($class, "=item \* L");
3069             }
3070              
3071 826         5741 $self->_pod($class, '=back');
3072 826         3179 $self->_pod_cut($class);
3073             }
3074             }
3075              
3076             sub _pod_class_list {
3077 3404     3404   8629 my ($self, $class, $title, @classes) = @_;
3078              
3079 3404 100 66     13223 return unless @classes && $self->generate_pod;
3080              
3081 1260         4424 $self->_pod($class, "=head1 $title");
3082 1260         3720 $self->_pod($class, '=over 4');
3083              
3084 1260         3129 foreach my $link (@classes) {
3085 1898         4352 $self->_pod($class, "=item * L<$link>");
3086             }
3087              
3088 1260         3296 $self->_pod($class, '=back');
3089 1260         3359 $self->_pod_cut($class);
3090             }
3091              
3092             sub _base_class_pod {
3093 16     16   95 my ($self, $base_class) = @_;
3094              
3095 16 50       95 return '' unless $self->generate_pod;
3096              
3097 16         56 return "\n=head1 BASE CLASS: L<$base_class>\n\n=cut\n\n";
3098             }
3099              
3100             sub _filter_comment {
3101 4055     4055   15941 my ($self, $txt) = @_;
3102              
3103 4055 100       18568 $txt = '' if not defined $txt;
3104              
3105 4055         11893 $txt =~ s/(?:\015?\012|\015\012?)/\n/g;
3106              
3107 4055         31260 return $txt;
3108             }
3109              
3110             sub __table_comment {
3111 1680     1680   3950 my $self = shift;
3112              
3113 1680 50       11975 if (my $code = $self->can('_table_comment')) {
3114 1680         9963 return $self->_filter_comment($self->$code(@_));
3115             }
3116              
3117 0         0 return '';
3118             }
3119              
3120             sub __column_comment {
3121 2375     2375   5971 my $self = shift;
3122              
3123 2375 50       17597 if (my $code = $self->can('_column_comment')) {
3124 2375         12636 return $self->_filter_comment($self->$code(@_));
3125             }
3126              
3127 0         0 return '';
3128             }
3129              
3130             # Stores a POD documentation
3131             sub _pod {
3132 21230     21230   48592 my ($self, $class, $stmt) = @_;
3133 21230         62711 $self->_raw_stmt( $class, "\n" . $stmt );
3134             }
3135              
3136             sub _pod_cut {
3137 5321     5321   12775 my ($self, $class ) = @_;
3138 5321         28637 $self->_raw_stmt( $class, "\n=cut\n" );
3139             }
3140              
3141             # Store a raw source line for a class (for dumping purposes)
3142             sub _raw_stmt {
3143 31895     31895   64647 my ($self, $class, $stmt) = @_;
3144 31895         48659 push(@{$self->{_dump_storage}->{$class}}, $stmt);
  31895         121159  
3145             }
3146              
3147             # Like above, but separately for the externally loaded stuff
3148             sub _ext_stmt {
3149 93     93   252 my ($self, $class, $stmt) = @_;
3150 93         172 push(@{$self->{_ext_storage}->{$class}}, $stmt);
  93         434  
3151             }
3152              
3153             sub _custom_column_info {
3154 2385     2385   6868 my ( $self, $table_name, $column_name, $column_info ) = @_;
3155              
3156 2385 100       11999 if (my $code = $self->custom_column_info) {
3157 1015   100     4598 return $code->($table_name, $column_name, $column_info) || {};
3158             }
3159 1370         6615 return {};
3160             }
3161              
3162             sub _datetime_column_info {
3163 2385     2385   6663 my ( $self, $table_name, $column_name, $column_info ) = @_;
3164 2385         4817 my $result = {};
3165 2385   100     9295 my $type = $column_info->{data_type} || '';
3166 2385 100 100     11798 if ((grep $_, @{ $column_info }{map "inflate_$_", qw/date datetime timestamp/})
  2385         28689  
3167             or ($type =~ /date|timestamp/i)) {
3168 146 100       1466 $result->{timezone} = $self->datetime_timezone if $self->datetime_timezone;
3169 146 100       12904 $result->{locale} = $self->datetime_locale if $self->datetime_locale;
3170             }
3171 2385         24271 return $result;
3172             }
3173              
3174             sub _lc {
3175 10215     10215   28050 my ($self, $name) = @_;
3176              
3177 10215 100       77436 return $self->preserve_case ? $name : lc($name);
3178             }
3179              
3180             sub _uc {
3181 0     0   0 my ($self, $name) = @_;
3182              
3183 0 0       0 return $self->preserve_case ? $name : uc($name);
3184             }
3185              
3186             sub _remove_table {
3187 1     1   6 my ($self, $table) = @_;
3188              
3189             try {
3190 1     1   56 my $schema = $self->schema;
3191             # in older DBIC it's a private method
3192 1   33     46 my $unregister = $schema->can('unregister_source') || $schema->can('_unregister_source');
3193 1         13 $schema->$unregister(delete $self->monikers->{$table->sql_name});
3194 1         583 delete $self->_upgrading_classes->{delete $self->classes->{$table->sql_name}};
3195 1         8 delete $self->_tables->{$table->sql_name};
3196 1         15 };
3197             }
3198              
3199             # remove the dump dir from @INC on destruction
3200             sub DESTROY {
3201 230     230   112606 my $self = shift;
3202              
3203 230         37960 @INC = grep $_ ne $self->dump_directory, @INC;
3204             }
3205              
3206             =head2 monikers
3207              
3208             Returns a hashref of loaded table to moniker mappings. There will
3209             be two entries for each table, the original name and the "normalized"
3210             name, in the case that the two are different (such as databases
3211             that like uppercase table names, or preserve your original mixed-case
3212             definitions, or what-have-you).
3213              
3214             =head2 classes
3215              
3216             Returns a hashref of table to class mappings. In some cases it will
3217             contain multiple entries per table for the original and normalized table
3218             names, as above in L.
3219              
3220             =head2 generated_classes
3221              
3222             Returns an arrayref of classes that were actually generated (i.e. not
3223             skipped because there were no changes).
3224              
3225             =head1 NON-ENGLISH DATABASES
3226              
3227             If you use the loader on a database with table and column names in a language
3228             other than English, you will want to turn off the English language specific
3229             heuristics.
3230              
3231             To do so, use something like this in your loader options:
3232              
3233             naming => { monikers => 'v4' },
3234             inflect_singular => sub { "$_[0]_rel" },
3235             inflect_plural => sub { "$_[0]_rel" },
3236              
3237             =head1 COLUMN ACCESSOR COLLISIONS
3238              
3239             Occasionally you may have a column name that collides with a perl method, such
3240             as C. In such cases, the default action is to set the C of the
3241             column spec to C.
3242              
3243             You can then name the accessor yourself by placing code such as the following
3244             below the md5:
3245              
3246             __PACKAGE__->add_column('+can' => { accessor => 'my_can' });
3247              
3248             Another option is to use the L option.
3249              
3250             =head1 RELATIONSHIP NAME COLLISIONS
3251              
3252             In very rare cases, you may get a collision between a generated relationship
3253             name and a method in your Result class, for example if you have a foreign key
3254             called C.
3255              
3256             This is a problem because relationship names are also relationship accessor
3257             methods in L.
3258              
3259             The default behavior is to append C<_rel> to the relationship name and print
3260             out a warning that refers to this text.
3261              
3262             You can also control the renaming with the L option.
3263              
3264             =head1 SEE ALSO
3265              
3266             L, L
3267              
3268             =head1 AUTHORS
3269              
3270             See L.
3271              
3272             =head1 LICENSE
3273              
3274             This library is free software; you can redistribute it and/or modify it under
3275             the same terms as Perl itself.
3276              
3277             =cut
3278              
3279             1;
3280             # vim:et sts=4 sw=4 tw=0: