X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSchema%2FLoader%2FDBI%2FSQLAnywhere.pm;h=5d2ec939bca4205c28d8f7e9240b1dca935f1cc9;hb=dc783fab900d073db1fb0e86b709cbb65bd364b7;hp=ab0b4f312e6d6e64fabad7ba3ee9d56b9e742bd1;hpb=533d98c061845dd1d49e6ff94f7acee618b23764;p=dbsrgits%2FDBIx-Class-Schema-Loader.git diff --git a/lib/DBIx/Class/Schema/Loader/DBI/SQLAnywhere.pm b/lib/DBIx/Class/Schema/Loader/DBI/SQLAnywhere.pm index ab0b4f3..5d2ec93 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI/SQLAnywhere.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI/SQLAnywhere.pm @@ -4,11 +4,11 @@ use strict; use warnings; use base 'DBIx::Class::Schema::Loader::DBI::Component::QuotedDefault'; use mro 'c3'; -use List::MoreUtils 'any'; +use List::Util 'any'; use namespace::clean; use DBIx::Class::Schema::Loader::Table (); -our $VERSION = '0.07029'; +our $VERSION = '0.07045'; =head1 NAME @@ -48,7 +48,7 @@ sub _setup { } sub _tables_list { - my ($self, $opts) = @_; + my ($self) = @_; my @tables; @@ -73,7 +73,7 @@ EOF } } - return $self->_filter_tables(\@tables, $opts); + return $self->_filter_tables(\@tables); } sub _columns_info_for { @@ -165,13 +165,26 @@ sub _table_pk_info { return \@keydata; } +my %sqlany_rules = ( + C => 'CASCADE', + D => 'SET DEFAULT', + N => 'SET NULL', + R => 'RESTRICT', +); + sub _table_fk_info { my ($self, $table) = @_; - my ($local_cols, $remote_cols, $remote_table, @rels); + my ($local_cols, $remote_cols, $remote_table, $attrs, @rels); my $sth = $self->dbh->prepare(<<'EOF'); -SELECT fki.index_name fk_name, fktc.column_name local_column, pku.user_name remote_schema, pkt.table_name remote_table, pktc.column_name remote_column +SELECT fki.index_name fk_name, fktc.column_name local_column, pku.user_name remote_schema, pkt.table_name remote_table, pktc.column_name remote_column, on_delete.referential_action, on_update.referential_action FROM sysfkey fk +JOIN ( + select foreign_table_id, foreign_index_id, + row_number() over (partition by foreign_table_id order by foreign_index_id) foreign_key_num + from sysfkey +) fkid + ON fkid.foreign_table_id = fk.foreign_table_id and fkid.foreign_index_id = fk.foreign_index_id JOIN systab pkt ON fk.primary_table_id = pkt.table_id JOIN sysuser pku @@ -180,9 +193,9 @@ JOIN systab fkt ON fk.foreign_table_id = fkt.table_id JOIN sysuser fku ON fkt.creator = fku.user_id -JOIN sysidx pki +JOIN sysidx pki ON fk.primary_table_id = pki.table_id AND fk.primary_index_id = pki.index_id -JOIN sysidx fki +JOIN sysidx fki ON fk.foreign_table_id = fki.table_id AND fk.foreign_index_id = fki.index_id JOIN sysidxcol fkic ON fkt.table_id = fkic.table_id AND fki.index_id = fkic.index_id @@ -190,18 +203,39 @@ JOIN systabcol pktc ON pkt.table_id = pktc.table_id AND fkic.primary_column_id = pktc.column_id JOIN systabcol fktc ON fkt.table_id = fktc.table_id AND fkic.column_id = fktc.column_id +LEFT JOIN systrigger on_delete + ON on_delete.foreign_table_id = fkt.table_id AND on_delete.foreign_key_id = fkid.foreign_key_num + AND on_delete.event = 'D' +LEFT JOIN systrigger on_update + ON on_update.foreign_table_id = fkt.table_id AND on_update.foreign_key_id = fkid.foreign_key_num + AND on_update.event = 'C' WHERE fku.user_name = ? AND fkt.table_name = ? +ORDER BY fk.primary_table_id, pktc.column_id EOF $sth->execute($table->schema, $table->name); - while (my ($fk, $local_col, $remote_schema, $remote_tab, $remote_col) = $sth->fetchrow_array) { + while (my ($fk, $local_col, $remote_schema, $remote_tab, $remote_col, $on_delete, $on_update) + = $sth->fetchrow_array) { + push @{$local_cols->{$fk}}, $self->_lc($local_col); + push @{$remote_cols->{$fk}}, $self->_lc($remote_col); + $remote_table->{$fk} = DBIx::Class::Schema::Loader::Table->new( loader => $self, name => $remote_tab, schema => $remote_schema, ); + + $attrs->{$fk} ||= { + on_delete => $sqlany_rules{$on_delete||''} || 'RESTRICT', + on_update => $sqlany_rules{$on_update||''} || 'RESTRICT', +# We may be able to use the value of the 'CHECK ON COMMIT' option, as it seems +# to be some sort of workaround for lack of deferred constraints. Unclear on +# how good of a substitute it is, and it requires the 'RESTRICT' rule. Also it +# only works for INSERT and UPDATE, not DELETE. Will get back to this. + is_deferrable => 1, + }; } foreach my $fk (keys %$remote_table) { @@ -209,6 +243,7 @@ EOF local_columns => $local_cols->{$fk}, remote_columns => $remote_cols->{$fk}, remote_table => $remote_table->{$fk}, + attrs => $attrs->{$fk}, }; } return \@rels; @@ -239,8 +274,7 @@ EOF push @{$constraints->{$constraint_name}}, $self->_lc($column); } - my @uniqs = map { [ $_ => $constraints->{$_} ] } keys %$constraints; - return \@uniqs; + return [ map { [ $_ => $constraints->{$_} ] } sort keys %$constraints ]; } =head1 SEE ALSO @@ -248,9 +282,9 @@ EOF L, L, L -=head1 AUTHOR +=head1 AUTHORS -See L and L. +See L. =head1 LICENSE