2

哪種方法可以將DBIx :: Class子類foo中具有外鍵依賴關係(直接和間接關係)的表列表最快捷地獲得?我有一個基於DBIx :: Class :: Schema的MySQL數據庫。可以直接使用DBIx :: Class,還是可以通過生成一個圖來幫助SQL :: Translator?遞歸遍歷DBIx :: Class關係

鑑於以下類:

package MySchema::Foo; 

... 

package MySchema::Bar; 

__PACKAGE__->belongs_to('foo', 'MySchema::Foo'); 

package MySchema::Baz; 

__PACKAGE__->belongs_to('bar', 'MySchema::Bar'); 

對於輸入的Foo,輸出應該是[酒吧,巴茲]。

回答

1

DBIx::Class's ::Schema::ResultSource煮熟。首先建立引用類的哈希(ref),然後遍歷它:

#!/usr/bin/perl 

use strict; 
use warnings; 
use MySchema; 
use Set::Scalar; 

# add_sfk: adds a foreign key reference from $src to $dst 
sub add_sfk { 
    my ($sfks, $src, $dst) = @_; 

    $sfks->{$src} ||= Set::Scalar->new; 
    $sfks->{$src}->insert($dst); 
} 

my $conn = MySchema->connect(...); 

my $scname = ref $conn; 
my $sfks = {}; # the foreign key hash 

# now we build the hash from sources relationships 
foreach my $sname ($conn->sources) { 
    my $s = $conn->source($sname); 
    my $cname = $conn->class($sname); 
    foreach my $rname ($s->relationships) { 
     my $rel = $s->relationship_info($rname); 
     my @conds = keys %{ $rel->{cond} }; 
     next if scalar @conds > 1; # reckon this should never happen 
     (my $stgt = $rel->{source}) =~ s/^${scname}:://; 
     foreach my $ckey (@conds) { 
      add_sfk($sfks, $stgt, $sname) if ('foreign.id' eq $ckey); # belongs_to 
      add_sfk($sfks, $sname, $stgt) if ('self.id' eq $rel->{cond}->{$ckey}); # has_(one|many) 
     } 
    } 
} 

my $sname = shift or die("No class given as input"); 

# time to traverse our hash to include indirect relationships 
my $deps = $sfks->{$sname}; 
my $lastdeps = $deps; 
my $newdeps; 
do { 
    $newdeps = Set::Scalar->new; 
    foreach my $sn ($lastdeps->elements) { 
     my $sdeps = $sfks->{$sn} or next; 
     if ($sdeps -= $lastdeps) { 
      $newdeps += $sdeps; 
     } 
    } 
    $deps += $lastdeps; 
    $lastdeps = $newdeps; 
} while ($newdeps); 

print "Dependencies of $sname:\n" . join("\n", map { $conn->source($_)->from } @$deps);