X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSource.pm;h=84c8df9c66d5079b4b01a9a14ed35c7b69f2eb49;hp=4efa0d7ef8349aac6bdc210a56802165d4c142b6;hb=68f3b0dd9e91421b02c818ca42543b79bc197dfd;hpb=aaf2403d17fd75fea98d22c2ef28c42d3285ef03 diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 4efa0d7..84c8df9 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -143,6 +143,12 @@ generate a new key value. If not specified, L will attempt to retrieve the name of the sequence from the database automatically. +=item auto_nextval + +Set this to a true value for a column whose value is retrieved +automatically from an oracle sequence. If you do not use an oracle +trigger to get the nextval, you have to set sequence as well. + =item extra This is used by L and L @@ -640,7 +646,7 @@ sub reverse_relationship_info { my $otherrel_info = $othertable->relationship_info($otherrel); my $back = $othertable->related_source($otherrel); - next unless $back->name eq $self->name; + next unless $back->source_name eq $self->source_name; my @othertestconds; @@ -762,6 +768,49 @@ sub resolve_join { } } +=head2 pk_depends_on + +=over 4 + +=item Arguments: $relname, $rel_data + +=back + +Determines whether a relation is dependent on an object from this source +having already been inserted. Takes the name of the relationship and a +hashref of columns of the related object. + +=cut + +sub pk_depends_on { + my ($self, $relname, $rel_data) = @_; + my $cond = $self->relationship_info($relname)->{cond}; + + return 0 unless ref($cond) eq 'HASH'; + + # map { foreign.foo => 'self.bar' } to { bar => 'foo' } + + my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond }; + + # assume anything that references our PK probably is dependent on us + # rather than vice versa, unless the far side is (a) defined or (b) + # auto-increment + + my $rel_source = $self->related_source($relname); + + foreach my $p ($self->primary_columns) { + if (exists $keyhash->{$p}) { + unless (defined($rel_data->{$keyhash->{$p}}) + || $rel_source->column_info($keyhash->{$p}) + ->{is_auto_increment}) { + return 0; + } + } + } + + return 1; +} + =head2 resolve_condition =over 4 @@ -776,6 +825,8 @@ a related conditional from that object. =cut +our $UNRESOLVABLE_CONDITION = \'1 = 0'; + sub resolve_condition { my ($self, $cond, $as, $for) = @_; #warn %$cond; @@ -790,7 +841,14 @@ sub resolve_condition { $self->throw_exception("Invalid rel cond val ${v}"); if (ref $for) { # Object #warn "$self $k $for $v"; - $ret{$k} = $for->get_column($v) if $for->has_column_loaded($v); + unless ($for->has_column_loaded($v)) { + if ($for->in_storage) { + $self->throw_exception("Column ${v} not loaded on ${for} trying to reolve relationship"); + } + return $UNRESOLVABLE_CONDITION; + } + $ret{$k} = $for->get_column($v); + #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v); #warn %ret; } elsif (!defined $for) { # undef, i.e. "no object" $ret{$k} = undef; @@ -899,6 +957,16 @@ sub resolve_prefetch { $self->throw_exception( "Can't prefetch has_many ${pre} (join cond too complex)") unless ref($rel_info->{cond}) eq 'HASH'; + my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}" + if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots } + keys %{$collapse}) { + my ($last) = ($fail =~ /([^\.]+)$/); + $self->throw_exception( + "Can't prefetch multiple has_many rels ${last} and ${pre}" + .(length($as_prefix) ? "at the same level (${as_prefix})" + : "at top level" + )); + } #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); } # values %{$rel_info->{cond}}; $collapse->{".${as_prefix}${pre}"} = [ $rel_source->primary_columns ]; @@ -980,7 +1048,9 @@ but is cached from then on unless resultset_class changes. Set the class of the resultset, this is useful if you want to create your own resultset methods. Create your own class derived from -L, and set it here. +L, and set it here. If called with no arguments, +this method returns the name of the existing resultset class, if one +exists. =head2 resultset_attributes @@ -1057,6 +1127,15 @@ sub throw_exception { } } +=head2 sqlt_deploy_hook($sqlt_table) + +An optional sub which you can declare in your own Schema class that will get +passed the L object when you deploy the schema +via L or L. + +For an example of what you can do with this, see +L. + =head1 AUTHORS Matt S. Trout