From: Rafael Kitover Date: Thu, 31 Dec 2009 20:02:50 +0000 (+0000) Subject: got something working X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6c0230de282983fa588795e3f81ce16fcd9ef316;p=dbsrgits%2FDBIx-Class-Historic.git got something working --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 6af5f63..0605371 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -2522,7 +2522,8 @@ sub related_resultset { my $attrs = $self->_chain_relationship($rel); my $join_count = $attrs->{seen_join}{$rel}; - my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel); + + my $alias = $self->storage->relname_to_table_alias($rel, $join_count); #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi delete @{$attrs}{qw(result_class alias)}; diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index aaa31a3..541aa12 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -1228,7 +1228,9 @@ sub _resolve_join { $force_left ||= lc($rel_info->{attrs}{join_type}||'') eq 'left'; # the actual seen value will be incremented by the recursion - my $as = ($seen->{$rel} ? join ('_', $rel, $seen->{$rel} + 1) : $rel); + my $as = $self->storage->relname_to_table_alias( + $rel, ($seen->{$rel} && $seen->{$rel} + 1) + ); push @ret, ( $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left), @@ -1245,7 +1247,9 @@ sub _resolve_join { } else { my $count = ++$seen->{$join}; - my $as = ($count > 1 ? "${join}_${count}" : $join); + my $as = $self->storage->relname_to_table_alias( + $join, ($count > 1 && $count) + ); my $rel_info = $self->relationship_info($join) or $self->throw_exception("No such relationship ${join}"); diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 405041c..22477fe 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -2510,6 +2510,30 @@ sub lag_behind_master { sub _sqlt_minimum_version { $minimum_sqlt_version }; } +=head2 relname_to_table_alias + +=over 4 + +=item Arguments: $relname, $join_count + +=back + +L uses L names as table aliases in +queries. + +This hook is to allow specific C drivers to change the way these +aliases are named. + +=cut + +sub relname_to_table_alias { + my ($self, $relname, $join_count) = @_; + + my $alias = ($join_count > 1 ? join('_', $relname, $join_count) : $relname); + + return $alias; +} + sub DESTROY { my $self = shift; diff --git a/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm b/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm index 2b62826..0f0c97b 100644 --- a/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm +++ b/lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm @@ -17,7 +17,9 @@ DBIx::Class::Storage::DBI::Oracle::Generic - Oracle Support for DBIx::Class =head1 DESCRIPTION -This class implements autoincrements for Oracle. +This class implements base Oracle support. The subclass +L is for C<(+)> joins in Oracle +versions before 9. =head1 METHODS @@ -274,6 +276,37 @@ sub _svp_rollback { $self->_get_dbh->do("ROLLBACK TO SAVEPOINT $name") } +=head2 relname_to_table_alias + +L uses L names as table aliases in +queries. + +Unfortunately, Oracle doesn't support identifiers over 30 chars in length, so +if the L name is shortened here if necessary. + +See L. + +=cut + +sub relname_to_table_alias { + my $self = shift; + my ($relname, $join_count) = @_; + + my $alias = $self->next::method(@_); + + return $alias if length($alias) <= 30; + + $alias =~ s/[aeiou]//ig; + + return $alias if length($alias) <= 30; + + ($alias = $relname) =~ s/[aeiou]//ig; + substr($alias, 0, 30 - length($join_count) - 1) = ''; + $alias .= "_$join_count"; + + return $alias; +} + =head1 AUTHOR See L. diff --git a/t/73oracle.t b/t/73oracle.t index c44a3f0..04f1641 100644 --- a/t/73oracle.t +++ b/t/73oracle.t @@ -63,7 +63,7 @@ $dbh->do("CREATE SEQUENCE pkid2_seq START WITH 10 MAXVALUE 999999 MINVALUE 0"); $dbh->do("CREATE SEQUENCE nonpkid_seq START WITH 20 MAXVALUE 999999 MINVALUE 0"); $dbh->do("CREATE TABLE artist (artistid NUMBER(12), name VARCHAR(255), rank NUMBER(38), charfield VARCHAR2(10))"); $dbh->do("CREATE TABLE sequence_test (pkid1 NUMBER(12), pkid2 NUMBER(12), nonpkid NUMBER(12), name VARCHAR(255))"); -$dbh->do("CREATE TABLE cd (cdid NUMBER(12), artist NUMBER(12), title VARCHAR(255), year VARCHAR(4))"); +$dbh->do("CREATE TABLE cd (cdid NUMBER(12), artist NUMBER(12), title VARCHAR(255), year VARCHAR(4), genreid NUMBER(12), single_track NUMBER(12))"); $dbh->do("CREATE TABLE track (trackid NUMBER(12), cd NUMBER(12), position NUMBER(12), title VARCHAR(255), last_updated_on DATE, last_updated_at DATE, small_dt DATE)"); $dbh->do("ALTER TABLE artist ADD (CONSTRAINT artist_pk PRIMARY KEY (artistid))"); @@ -130,15 +130,31 @@ is( $new->artistid, 2, "Oracle Auto-PK worked with fully-qualified tablename" ); # test rel names over the 30 char limit my $query = $schema->resultset('Artist')->search({ - 'cds_very_very_very_long_relationship_name.title' => 'EP C' + artistid => 1 }, { prefetch => 'cds_very_very_very_long_relationship_name' }); lives_and { - is $query->first->cds_very_very_very_long_relationship_name->cdid, 1 + is $query->first->cds_very_very_very_long_relationship_name->first->cdid, 1 } 'query with rel name over 30 chars survived and worked'; +# rel name over 30 char limit with user condition +# This requires walking the SQLA data structure. +{ + local $TODO = 'user condition on rel longer than 30 chars'; + + $query = $schema->resultset('Artist')->search({ + 'cds_very_very_very_long_relationship_name.title' => 'EP C' + }, { + prefetch => 'cds_very_very_very_long_relationship_name' + }); + + lives_and { + is $query->first->cds_very_very_very_long_relationship_name->first->cdid, 1 + } 'query with rel name over 30 chars and user condition survived and worked'; +} + # test join with row count ambiguity my $track = $schema->resultset('Track')->create({ trackid => 1, cd => 1,