X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSchema%2FLoader%2FBase.pm;h=47d965456f4ced92e3689b5769d1400f7d4b4621;hb=abaf2c66f2293cf951b6cd44b95ff1924e344f5f;hp=a7397c3af8ea0c5e373b482bc8ee3371906c977c;hpb=5223f24a6662ce33f7b60d2a3f6f83e83f5373cc;p=dbsrgits%2FDBIx-Class-Schema-Loader.git diff --git a/lib/DBIx/Class/Schema/Loader/Base.pm b/lib/DBIx/Class/Schema/Loader/Base.pm index a7397c3..47d9654 100644 --- a/lib/DBIx/Class/Schema/Loader/Base.pm +++ b/lib/DBIx/Class/Schema/Loader/Base.pm @@ -4,13 +4,15 @@ use strict; use warnings; use base qw/Class::Accessor::Fast/; use Class::C3; -use Carp; +use Carp::Clan qw/^DBIx::Class/; use UNIVERSAL::require; use DBIx::Class::Schema::Loader::RelBuilder; use Data::Dump qw/ dump /; use POSIX qw//; require DBIx::Class; +our $VERSION = '0.03999_01'; + __PACKAGE__->mk_ro_accessors(qw/ schema schema_class @@ -28,6 +30,7 @@ __PACKAGE__->mk_ro_accessors(qw/ inflect_plural debug dump_directory + dump_overwrite legacy_default_inflections @@ -64,6 +67,12 @@ Try to automatically detect/setup has_a and has_many relationships. If set to true, each constructive L statement the loader decides to execute will be C-ed before execution. +=head2 db_schema + +Set the name of the schema to load (schema in the sense that your database +vendor means it). Does not currently support loading more than one schema +name. + =head2 constraint Only load tables matching regex. Best specified as a qr// regex. @@ -74,8 +83,8 @@ Exclude tables matching regex. Best specified as a qr// regex. =head2 moniker_map -Overrides the default tablename -> moniker translation. Can be either -a hashref of table => moniker names, or a coderef for a translator +Overrides the default table name to moniker translation. Can be either +a hashref of table keys and moniker values, or a coderef for a translator function taking a single scalar table name argument and returning a scalar moniker. If the hash entry does not exist, or the function returns a false value, the code falls back to default behavior @@ -124,7 +133,7 @@ classes. A good example would be C. =head2 resultset_components -List of additional resultset components to be loaded into your table +List of additional ResultSet components to be loaded into your table classes. A good example would be C. Component C will be automatically added to the above C list if this option is set. @@ -132,12 +141,16 @@ C list if this option is set. =head2 legacy_default_inflections Setting this option changes the default fallback for L to -utilize L, and L to a no-op. -Those choices produce substandard results, but might be neccesary to support +utilize L, and L to a no-op. +Those choices produce substandard results, but might be necessary to support your existing code if you started developing on a version prior to 0.03 and don't wish to go around updating all your relationship names to the new defaults. +This option will continue to be supported until at least version 0.05xxx, +but may dissappear sometime thereafter. It is recommended that you update +your code to use the newer-style inflections when you have the time. + =head2 dump_directory This option is designed to be a tool to help you transition from this @@ -156,14 +169,22 @@ where that class is currently located, it will overwrite itself with a manual version of itself. This might be a really good or bad thing depending on your situation and perspective. -Normally you wouldn't hardcode this setting in your schema class, as it +Normally you wouldn't hard-code this setting in your schema class, as it is meant for one-time manual usage. See L for examples of the recommended way to access this functionality. +=head2 dump_overwrite + +If set to a true value, the dumping code will overwrite existing files. +The default is false, which means the dumping code will skip the already +existing files. + =head1 DEPRECATED CONSTRUCTOR OPTIONS +B + =head2 inflect_map Equivalent to L. @@ -177,7 +198,7 @@ Equivalent to L. You connect these schemas the same way you would any L, which is by calling either C or C on a schema class or object. These options are only supported via the deprecated -C interface, which will be removed in the future. +C interface, which is also being removed in 0.04000. =head1 METHODS @@ -230,7 +251,8 @@ sub new { # Support deprecated arguments for(qw/inflect_map inflect/) { warn "Argument $_ is deprecated in favor of 'inflect_plural'" - if $self->{$_}; + . ", and will be removed in 0.04000" + if $self->{$_}; } $self->{inflect_plural} ||= $self->{inflect_map} || $self->{inflect}; @@ -258,6 +280,7 @@ sub _load_external { if($self->dump_directory) { my $class_path = $table_class; $class_path =~ s{::}{/}g; + $class_path .= '.pm'; my $filename = $INC{$class_path}; croak 'Failed to locate actual external module file for ' . "'$table_class'" @@ -316,7 +339,7 @@ sub _ensure_dump_subdirs { foreach (@name_parts) { $dir .= q{/} . $_; if(! -d $dir) { - mkdir($dir) or die "mkdir('$dir') failed: $!"; + mkdir($dir) or croak "mkdir('$dir') failed: $!"; } } } @@ -326,37 +349,47 @@ sub _dump_to_dir { my $target_dir = $self->dump_directory; - die "Must specify target directory for dumping!" if ! $target_dir; + my $schema_class = $self->schema_class; + + croak "Must specify target directory for dumping!" if ! $target_dir; - warn "Dumping manual schema to $target_dir ...\n"; + warn "Dumping manual schema for $schema_class to directory $target_dir ...\n"; if(! -d $target_dir) { - mkdir($target_dir) or die "mkdir('$target_dir') failed: $!"; + mkdir($target_dir) or croak "mkdir('$target_dir') failed: $!"; } my $verstr = $DBIx::Class::Schema::Loader::VERSION; my $datestr = POSIX::strftime('%Y-%m-%d %H:%M:%S', localtime); my $tagline = qq|# Created by DBIx::Class::Schema::Loader v$verstr @ $datestr|; - my $schema_class = $self->schema_class; $self->_ensure_dump_subdirs($schema_class); my $schema_fn = $self->_get_dump_filename($schema_class); - open(my $schema_fh, '>', $schema_fn) - or die "Cannot open $schema_fn for writing: $!"; - print $schema_fh qq|package $schema_class;\n\n$tagline\n\n|; - print $schema_fh qq|use strict;\nuse warnings;\n\n|; - print $schema_fh qq|use base 'DBIx::Class::Schema';\n\n|; - print $schema_fh qq|__PACKAGE__->load_classes;\n|; - print $schema_fh qq|\n1;\n\n|; - close($schema_fh) - or die "Cannot close $schema_fn: $!"; + if (-f $schema_fn && !$self->dump_overwrite) { + warn "$schema_fn exists, will not overwrite\n"; + } + else { + open(my $schema_fh, '>', $schema_fn) + or croak "Cannot open $schema_fn for writing: $!"; + print $schema_fh qq|package $schema_class;\n\n$tagline\n\n|; + print $schema_fh qq|use strict;\nuse warnings;\n\n|; + print $schema_fh qq|use base 'DBIx::Class::Schema';\n\n|; + print $schema_fh qq|__PACKAGE__->load_classes;\n|; + print $schema_fh qq|\n1;\n\n|; + close($schema_fh) + or croak "Cannot close $schema_fn: $!"; + } foreach my $src_class (sort keys %{$self->{_dump_storage}}) { $self->_ensure_dump_subdirs($src_class); my $src_fn = $self->_get_dump_filename($src_class); + if (-f $src_fn && !$self->dump_overwrite) { + warn "$src_fn exists, will not overwrite\n"; + next; + } open(my $src_fh, '>', $src_fn) - or die "Cannot open $src_fn for writing: $!"; + or croak "Cannot open $src_fn for writing: $!"; print $src_fh qq|package $src_class;\n\n$tagline\n\n|; print $src_fh qq|use strict;\nuse warnings;\n\n|; print $src_fh qq|use base 'DBIx::Class';\n\n|; @@ -364,7 +397,7 @@ sub _dump_to_dir { for @{$self->{_dump_storage}->{$src_class}}; print $src_fh qq|\n1;\n\n|; close($src_fh) - or die "Cannot close $src_fn: $!"; + or croak "Cannot close $src_fn: $!"; } warn "Schema dump completed.\n"; @@ -373,14 +406,16 @@ sub _dump_to_dir { sub _use { my $self = shift; my $target = shift; + my $evalstr; foreach (@_) { - $_->require or croak ($_ . "->require: $@"); + warn "$target: use $_;" if $self->debug; $self->_raw_stmt($target, "use $_;"); - warn "$target: use $_" if $self->debug; - eval "package $target; use $_;"; - croak "use $_: $@" if $@; + $_->require or croak ($_ . "->require: $@"); + $evalstr .= "package $target; use $_;"; } + eval $evalstr if $evalstr; + croak $@ if $@; } sub _inject { @@ -389,8 +424,8 @@ sub _inject { my $schema_class = $self->schema_class; my $blist = join(q{ }, @_); + warn "$target: use base qw/ $blist /;" if $self->debug && @_; $self->_raw_stmt($target, "use base qw/ $blist /;") if @_; - warn "$target: use base qw/ $blist /" if $self->debug; foreach (@_) { $_->require or croak ($_ . "->require: $@"); $schema_class->inject_base($target, $_); @@ -401,12 +436,11 @@ sub _inject { sub _load_classes { my $self = shift; - my $schema = $self->schema; - my $schema_class = $self->schema_class; - - my $constraint = $self->constraint; - my $exclude = $self->exclude; - my @tables = sort $self->_tables_list; + my $schema = $self->schema; + my $schema_class = $self->schema_class; + my $constraint = $self->constraint; + my $exclude = $self->exclude; + my @tables = sort $self->_tables_list; warn "No tables found in database, nothing to load" if !@tables; @@ -434,9 +468,8 @@ sub _load_classes { local *Class::C3::reinitialize = sub { }; use warnings; - { no strict 'refs'; - @{"${table_class}::ISA"} = qw/DBIx::Class/; - } + { no strict 'refs'; @{"${table_class}::ISA"} = qw/DBIx::Class/ } + $self->_use ($table_class, @{$self->additional_classes}); $self->_inject($table_class, @{$self->additional_base_classes}); @@ -456,7 +489,19 @@ sub _load_classes { $self->_dbic_stmt($table_class,'table',$table); my $cols = $self->_table_columns($table); - $self->_dbic_stmt($table_class,'add_columns',@$cols); + my $col_info; + eval { $col_info = $schema->storage->columns_info_for($table) }; + if($@) { + $self->_dbic_stmt($table_class,'add_columns',@$cols); + } + else { + my %col_info_lc = map { lc($_), $col_info->{$_} } keys %$col_info; + $self->_dbic_stmt( + $table_class, + 'add_columns', + map { $_, ($col_info_lc{$_}||{}) } @$cols + ); + } my $pks = $self->_table_pk_info($table) || []; @$pks ? $self->_dbic_stmt($table_class,'set_primary_key',@$pks) @@ -578,7 +623,7 @@ sub _raw_stmt { =head2 monikers -Returns a hashref of loaded table-to-moniker mappings. There will +Returns a hashref of loaded table to moniker mappings. There will be two entries for each table, the original name and the "normalized" name, in the case that the two are different (such as databases that like uppercase table names, or preserve your original mixed-case @@ -586,7 +631,7 @@ definitions, or what-have-you). =head2 classes -Returns a hashref of table-to-classname mappings. In some cases it will +Returns a hashref of table to class mappings. In some cases it will contain multiple entries per table for the original and normalized table names, as above in L.