X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSchema.pm;h=8f8d846ef790b994d041f2e848695f17c2197332;hb=096f421241;hp=98387b44c776ffdce0cfabca75918be16171e52b;hpb=c037c03aa6089d35c8a62ce5e1ed8b19e765c8bc;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Schema.pm b/lib/DBIx/Class/Schema.pm index 98387b4..8f8d846 100644 --- a/lib/DBIx/Class/Schema.pm +++ b/lib/DBIx/Class/Schema.pm @@ -169,6 +169,12 @@ For example: sub sources { return keys %{shift->source_registrations}; } +=head2 storage + + my $storage = $schema->storage; + +Returns the L object for this Schema. + =head2 resultset =over 4 @@ -263,6 +269,13 @@ sub load_classes { foreach my $prefix (keys %comps_for) { foreach my $comp (@{$comps_for{$prefix}||[]}) { my $comp_class = "${prefix}::${comp}"; + { # try to untaint module name. mods where this fails + # are left alone so we don't have to change the old behavior + no locale; # localized \w doesn't untaint expression + if ( $comp_class =~ m/^( (?:\w+::)* \w+ )$/x ) { + $comp_class = $1; + } + } $class->ensure_class_loaded($comp_class); $comp_class->source_name($comp) unless $comp_class->source_name; @@ -390,6 +403,8 @@ sub compose_namespace { $target_class => $source->result_class, ($base ? $base : ()) ); $source->result_class($target_class); + $target_class->result_source_instance($source) + if $target_class->can('result_source_instance'); } } Class::C3->reinitialize(); @@ -423,6 +438,26 @@ sub setup_connection_class { $target->connection(@info); } +=head2 storage_type + +=over 4 + +=item Arguments: $storage_type + +=item Return Value: $storage_type + +=back + +Set the storage class that will be instantiated when L is called. +If the classname starts with C<::>, the prefix C is +assumed by L. Defaults to C<::DBI>, +which is L. + +You want to use this to hardcoded subclasses of L +in cases where the appropriate subclass is not autodetected, such as when +dealing with MSSQL via L, in which case you'd set it to +C<::DBI::Sybase::MSSQL>. + =head2 connection =over 4 @@ -522,12 +557,11 @@ exception) an exception is thrown that includes a "Rollback failed" message. For example, my $author_rs = $schema->resultset('Author')->find(1); + my @titles = qw/Night Day It/; my $coderef = sub { - my ($author, @titles) = @_; - # If any one of these fails, the entire transaction fails - $author->create_related('books', { + $author_rs->create_related('books', { title => $_ }) foreach (@titles); @@ -536,16 +570,14 @@ For example, my $rs; eval { - $rs = $schema->txn_do($coderef, $author_rs, qw/Night Day It/); + $rs = $schema->txn_do($coderef); }; - if ($@) { - my $error = $@; - if ($error =~ /Rollback failed/) { - die "something terrible has happened!"; - } else { - deal_with_failed_transaction(); - } + if ($@) { # Transaction failed + die "something terrible has happened!" # + if ($@ =~ /Rollback failed/); # Rollback failed + + deal_with_failed_transaction(); } In a nested transaction (calling txn_do() from within a txn_do() coderef) only @@ -558,8 +590,8 @@ context and it will behave as expected. sub txn_do { my ($self, $coderef, @args) = @_; - ref $self or $self->throw_exception - ('Cannot execute txn_do as a class method'); + $self->storage or $self->throw_exception + ('txn_do called on $schema without storage'); ref $coderef eq 'CODE' or $self->throw_exception ('$coderef must be a CODE reference'); @@ -626,7 +658,9 @@ copy. sub clone { my ($self) = @_; - my $clone = bless({ (ref $self ? %$self : ()) }, ref $self || $self); + my $clone = { (ref $self ? %$self : ()) }; + bless $clone, (ref $self || $self); + foreach my $moniker ($self->sources) { my $source = $self->source($moniker); my $new = $source->new($source); @@ -639,13 +673,17 @@ sub clone { =over 4 -=item Arguments: $moniker, \@data; +=item Arguments: $source_name, \@data; =back -Populates the source registered with the given moniker with the supplied data. -@data should be a list of listrefs -- the first containing column names, the -second matching values. +Pass this method a resultsource name, and an arrayref of +arrayrefs. The arrayrefs should contain a list of column names, +followed by one or many sets of matching data for the given columns. + +Each set of data is inserted into the database using +L, and a arrayref of the resulting row +objects is returned. i.e., @@ -693,7 +731,7 @@ sub throw_exception { =over 4 -=item Arguments: $sqlt_args +=item Arguments: $sqlt_args, $dir =back @@ -702,12 +740,16 @@ 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. +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. + =cut sub deploy { - my ($self, $sqltargs) = @_; + my ($self, $sqltargs, $dir) = @_; $self->throw_exception("Can't deploy without storage") unless $self->storage; - $self->storage->deploy($self, undef, $sqltargs); + $self->storage->deploy($self, undef, $sqltargs, $dir); } =head2 create_ddl_dir (EXPERIMENTAL) @@ -726,20 +768,27 @@ across all databases, or fully handle complex relationships. =cut -sub create_ddl_dir -{ +sub create_ddl_dir { my $self = shift; $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage; $self->storage->create_ddl_dir($self, @_); } -sub ddl_filename -{ +=head2 ddl_filename (EXPERIMENTAL) + + my $filename = $table->ddl_filename($type, $dir, $version) + +Creates a filename for a SQL file based on the table class name. Not +intended for direct end user use. + +=cut + +sub ddl_filename { my ($self, $type, $dir, $version) = @_; my $filename = ref($self); - $filename =~ s/^.*:://; + $filename =~ s/::/-/; $filename = "$dir$filename-$version-$type.sql"; return $filename; @@ -756,4 +805,3 @@ Matt S. Trout You may distribute this code under the same terms as Perl itself. =cut -