package Rose::DB::Object::Metadata::Auto::Oracle; use strict; use Carp(); use Rose::DB::Object::Metadata::UniqueKey; use Rose::DB::Object::Metadata::Auto; our @ISA = qw(Rose::DB::Object::Metadata::Auto); our $VERSION = '0.786'; sub auto_init_primary_key_columns { my($self) = shift; $self->SUPER::auto_init_primary_key_columns(@_); my $cm = $self->convention_manager; return if($cm->no_auto_sequences); my($db, @sequences); my $table = $self->table; # Check for sequence(s) for what look like non-null "serial" columns. foreach my $name ($self->primary_key_columns) { my $column = $self->column($name) or next; next unless ($column->not_null); my $sequence_name = uc $cm->auto_primary_key_column_sequence_name($table, $name); $db ||= $self->init_db; push(@sequences, $db->sequence_exists($sequence_name) ? $sequence_name : undef); } $self->primary_key_sequence_names($db, @sequences) if(@sequences); return; } use constant UNIQUE_INDEX_SQL => <<'EOF'; SELECT AI.INDEX_NAME FROM ALL_INDEXES AI, ALL_CONSTRAINTS AC WHERE AI.INDEX_NAME = AC.CONSTRAINT_NAME AND AC.CONSTRAINT_TYPE <> 'P' AND AI.UNIQUENESS = 'UNIQUE' AND AI.TABLE_NAME = ? AND AI.TABLE_OWNER = ? EOF use constant UNIQUE_INDEX_COLUMNS_SQL_STUB => <<'EOF'; SELECT COLUMN_NAME FROM ALL_IND_COLUMNS WHERE INDEX_NAME = ? ORDER BY COLUMN_POSITION EOF sub auto_generate_unique_keys { my($self) = shift; unless(defined wantarray) { Carp::croak "Useless call to auto_generate_unique_keys() in void context"; } my($class, @unique_keys, $error); TRY: { local $@; eval { $class = $self->class or die "Missing class!"; my $db = $self->db; my $dbh = $db->dbh or die $db->error; local $dbh->{'FetchHashKeyName'} = 'NAME'; my $schema = $self->select_schema($db); $schema = $db->default_implicit_schema unless(defined $schema); $schema = uc $schema if(defined $schema); my $table = uc $self->table; my $key_name; my $sth = $dbh->prepare(UNIQUE_INDEX_SQL); $sth->execute($table, $schema); $sth->bind_columns(\$key_name); while($sth->fetch) { my $uk = Rose::DB::Object::Metadata::UniqueKey->new(name => $key_name, parent => $self); my $col_sth = $dbh->prepare(UNIQUE_INDEX_COLUMNS_SQL_STUB); my($column, @columns); $col_sth->execute($key_name); $col_sth->bind_columns(\$column); while($col_sth->fetch) { push(@columns, $column); } unless(@columns) { die "No columns found for key $key_name"; } $uk->columns(\@columns); push(@unique_keys, $uk); } }; $error = $@; } if($error) { Carp::croak "Could not auto-retrieve unique keys for class $class - $error"; } # This sort order is part of the API, and is essential to make the # test suite work. @unique_keys = sort { lc $a->name cmp lc $b->name } @unique_keys; return wantarray ? @unique_keys : \@unique_keys; } 1;