X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSchema.pm;h=223dbd3fdf8be10f502687f5a2744cd8a1b407b9;hb=e287d9b08f5652a490eb7943ac07d5e38377852e;hp=77bd865397e4dc4adc2fbf4a2698fdf86f265385;hpb=c216324aa4b0f79ba056fbe74adbd735421e378a;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/Schema.pm b/lib/DBIx/Class/Schema.pm index 77bd865..223dbd3 100644 --- a/lib/DBIx/Class/Schema.pm +++ b/lib/DBIx/Class/Schema.pm @@ -5,6 +5,7 @@ use warnings; use Carp::Clan qw/^DBIx::Class/; use Scalar::Util qw/weaken/; +use File::Spec; require Module::Find; use base qw/DBIx::Class/; @@ -93,10 +94,15 @@ moniker. sub register_source { my ($self, $moniker, $source) = @_; + + %$source = %{ $source->new( { %$source, source_name => $moniker }) }; + my %reg = %{$self->source_registrations}; $reg{$moniker} = $source; $self->source_registrations(\%reg); + $source->schema($self); + weaken($source->{schema}) if ref($self); if ($source->result_class) { my %map = %{$self->class_mappings}; @@ -105,6 +111,19 @@ sub register_source { } } +sub _unregister_source { + my ($self, $moniker) = @_; + my %reg = %{$self->source_registrations}; + + my $source = delete $reg{$moniker}; + $self->source_registrations(\%reg); + if ($source->result_class) { + my %map = %{$self->class_mappings}; + delete $map{$source->result_class}; + $self->class_mappings(\%map); + } +} + =head2 class =over 4 @@ -275,9 +294,10 @@ sub load_classes { } } $class->ensure_class_loaded($comp_class); - $comp_class->source_name($comp) unless $comp_class->source_name; - push(@to_register, [ $comp_class->source_name, $comp_class ]); + $comp = $comp_class->source_name || $comp; +# $DB::single = 1; + push(@to_register, [ $comp, $comp_class ]); } } } @@ -558,9 +578,6 @@ will produce the output sub compose_namespace { my ($self, $target, $base) = @_; - my %reg = %{ $self->source_registrations }; - my %target; - my %map; my $schema = $self->clone; { no warnings qw/redefine/; @@ -659,6 +676,7 @@ sub connection { my $storage = $storage_class->new($self); $storage->connect_info(\@info); $self->storage($storage); + $self->on_connect() if($self->can('on_connect')); return $self; } @@ -831,7 +849,7 @@ sub populate { } return @created; } - $self->storage->insert_bulk($self->source($name)->from, \@names, $data); + $self->storage->insert_bulk($self->source($name), \@names, $data); } =head2 exception_action @@ -896,12 +914,17 @@ sub throw_exception { Attempts to deploy the schema to the current storage using L. Note that this feature is currently EXPERIMENTAL and may not work correctly -across all databases, or fully handle complex relationships. +across all databases, or fully handle complex relationships. Saying that, it +has been used successfully by many people, including the core dev team. See L for a list of values for C<$sqlt_args>. The most common value for this would be C<< { add_drop_table => 1, } >> to have the SQL produced include a DROP TABLE statement for each table created. +Additionally, the DBIx::Class parser accepts a C parameter as a hash +ref or an array ref, containing a list of source to deploy. If present, then +only the sources listed will get deployed. + =cut sub deploy { @@ -914,16 +937,41 @@ sub deploy { =over 4 -=item Arguments: \@databases, $version, $directory, $sqlt_args +=item Arguments: \@databases, $version, $directory, $preversion, $sqlt_args =back Creates an SQL file based on the Schema, for each of the specified -database types, in the given directory. +database types, in the given directory. Given a previous version number, +this will also create a file containing the ALTER TABLE statements to +transform the previous schema into the current one. Note that these +statements may contain DROP TABLE or DROP COLUMN statements that can +potentially destroy data. + +The file names are created using the C method below, please +override this method in your schema if you would like a different file +name format. For the ALTER file, the same format is used, replacing +$version in the name with "$preversion-$version". + +If no arguments are passed, then the following default values are used: + +=over 4 + +=item databases - ['MySQL', 'SQLite', 'PostgreSQL'] + +=item version - $schema->VERSION + +=item directory - './' + +=item preversion - + +=back Note that this feature is currently EXPERIMENTAL and may not work correctly across all databases, or fully handle complex relationships. +WARNING: Please check all SQL files created, before applying them. + =cut sub create_ddl_dir { @@ -935,19 +983,30 @@ sub create_ddl_dir { =head2 ddl_filename (EXPERIMENTAL) - my $filename = $table->ddl_filename($type, $dir, $version) +=over 4 + +=item Arguments: $directory, $database-type, $version, $preversion + +=back + + my $filename = $table->ddl_filename($type, $dir, $version, $preversion) + +This method is called by C to compose a file name out of +the supplied directory, database type and version number. The default file +name format is: C<$dir$schema-$version-$type.sql>. -Creates a filename for a SQL file based on the table class name. Not -intended for direct end user use. +You may override this method in your schema if you wish to use a different +format. =cut sub ddl_filename { - my ($self, $type, $dir, $version) = @_; + my ($self, $type, $dir, $version, $pversion) = @_; my $filename = ref($self); - $filename =~ s/::/-/; - $filename = "$dir$filename-$version-$type.sql"; + $filename =~ s/::/-/g; + $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql"); + $filename =~ s/$version/$pversion-$version/ if($pversion); return $filename; }