Para un sistema en el que estoy trabajando, he construido esta función, que, usada creativamente, puede que os sea útil.
A partir de una definición de qué tablas hay en el sistema, cuáles son sus primary key (sólo 1 campo por primary key es soportado), y cuáles son sus relaciones con otras tablas, intenta construir el path mínimo que conecta las tablas entre sí, y devuelve una query (inner join) por cada permutación de tablas:
Código PHP:
Ver originalfunction initializeSample()
{
$keys=array("A"=>"a0","B"=>"b0","C"=>"c0","D"=>"d0","E"=>"e0","F"=>"f0","Q"=>"q0","P"=>"p0","H"=>"h0"); "A"=>array("a1"=>"B", "a2"=>"H"), "B"=>array("b1"=>"D", "b2"=>"C"), "C"=>array("c1"=>"E", "c2"=>"F"), );
return array("objects"=>$objects,"relations"=>$nodes,"keys"=>$keys); }
function buildDistances($objects,$relations,$oKeys)
{
$curDistance=0;
while(1)
{
$cont=0;
for($k=0;$k<count($objects);$k++) {
$curObject=$objects[$k];
if($curDistance==0)
{
foreach($relations[$curObject] as $key=>$value)
{
$distances[$curObject][$value]=1;
$paths[$curObject][$value]="/".$value."[$key]";
$queries[$curObject][$value]=$curObject." INNER JOIN $value ON ".$curObject.".$key=$value.".$oKeys[$value];
$distances[$value][$curObject]=1;
$paths[$value][$curObject]="/".$curObject."|$key|";
$queries[$value][$curObject]=$value." INNER JOIN $curObject ON ".$curObject.".$key=$value.".$oKeys[$value];
}
$cont=1;
continue;
}
$adist=& $distances[$curObject];
foreach($adist as $bName=>$bdist)
{
if($bdist==$curDistance)
{
foreach($distances[$bName] as $cName=>$cDist)
{
if($cName == $curObject)
continue;
$fullDist=$cDist+$curDistance;
if(!$adist[$cName] || ($adist[$cName] > $fullDist))
{
$cont++;
$adist[$cName]=$fullDist;
$paths[$curObject][$cName]=$paths[$curObject][$bName].$paths[$bName][$cName];
$queries[$curObject][$cName]=$queries[$curObject][$bName]." ".substr($queries[$bName][$cName],strpos($queries[$bName][$cName]," ")+1); }
}
}
}
}
$curDistance++;
if($cont == 0)
break;
}
foreach($queries as $o1=>$val)
{
foreach($val as $o2=>$text)
$queries[$o1][$o2]="SELECT ".$o1.".*,".$o2.".* FROM ".$text;
}
return array($distances,$paths,$queries); }
$r = initializeSample();
var_dump(buildDistances
($r["objects"],$r["relations"],$r["keys"]));
Ejecutando esta funcion, se retorna, en el tercer elemento del array:
Código PHP:
Ver original'A' =>
'B' => string 'SELECT A.*,B.* FROM A INNER JOIN B ON A.a1=B.b0',
'H' => string 'SELECT A.*,H.* FROM A INNER JOIN H ON A.a2=H.h0',
'Q' => string 'SELECT A.*,Q.* FROM A INNER JOIN Q ON Q.q1=A.a0',
'D' => string 'SELECT A.*,D.* FROM A INNER JOIN B ON A.a1=B.b0 INNER JOIN D ON B.b1=D.d0',
'C' => string 'SELECT A.*,C.* FROM A INNER JOIN B ON A.a1=B.b0 INNER JOIN C ON B.b2=C.c0',
'E' => string 'SELECT A.*,E.* FROM A INNER JOIN H ON A.a2=H.h0 INNER JOIN E ON E.e1=H.h0',
'P' => string 'SELECT A.*,P.* FROM A INNER JOIN Q ON Q.q1=A.a0 INNER JOIN P ON P.p1=Q.q0',
'F' => string 'SELECT A.*,F.* FROM A INNER JOIN B ON A.a1=B.b0 INNER JOIN C ON B.b2=C.c0 INNER JOIN F ON C.c2=F.f0'
'B' =>
'A' => string 'SELECT B.*,A.* FROM B INNER JOIN A ON A.a1=B.b0',
'D' => string 'SELECT B.*,D.* FROM B INNER JOIN D ON B.b1=D.d0',
'C' => string 'SELECT B.*,C.* FROM B INNER JOIN C ON B.b2=C.c0',
'H' => string 'SELECT B.*,H.* FROM B INNER JOIN A ON A.a1=B.b0 INNER JOIN H ON A.a2=H.h0',
'Q' => string 'SELECT B.*,Q.* FROM B INNER JOIN A ON A.a1=B.b0 INNER JOIN Q ON Q.q1=A.a0',
'E' => string 'SELECT B.*,E.* FROM B INNER JOIN C ON B.b2=C.c0 INNER JOIN E ON C.c1=E.e0',
'P' => string 'SELECT B.*,P.* FROM B INNER JOIN A ON A.a1=B.b0 INNER JOIN Q ON Q.q1=A.a0 INNER JOIN P ON P.p1=Q.q0',
'F' => string 'SELECT B.*,F.* FROM B INNER JOIN C ON B.b2=C.c0 INNER JOIN F ON C.c2=F.f0',
.....