dblayeroo: supports foreign keys on multiple columns with syntax "col1,col2"

git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@3779 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
2017-06-16 11:17:05 +00:00
parent 64640a1d2b
commit f2e8763cc6

View File

@@ -401,6 +401,10 @@ class dblayeroo
$i = 0; $i = 0;
foreach ($this->foreign as $field=>$k) foreach ($this->foreign as $field=>$k)
{ {
$field = explode (",", $field);
$field = implode ($this->sep.",".$this->sep, $field);
$k[1] = explode (",", $k[1]);
$k[1] = implode ($this->sep.",".$this->sep, $k[1]);
$sql .= ",\n FOREIGN KEY($this->sep$field$this->sep) ". $sql .= ",\n FOREIGN KEY($this->sep$field$this->sep) ".
"REFERENCES $this->sep".$k[0]."$this->sep($this->sep". "REFERENCES $this->sep".$k[0]."$this->sep($this->sep".
$k[1]."$this->sep)"; $k[1]."$this->sep)";
@@ -492,6 +496,10 @@ class dblayeroo
$i = 0; $i = 0;
foreach ($this->foreign as $field=>$k) foreach ($this->foreign as $field=>$k)
{ {
$field = explode (",", $field);
$field = implode ($this->sep.",".$this->sep, $field);
$k[1] = explode (",", $k[1]);
$k[1] = implode ($this->sep.",".$this->sep, $k[1]);
$sql .= ",\n FOREIGN KEY($this->sep$field$this->sep) ". $sql .= ",\n FOREIGN KEY($this->sep$field$this->sep) ".
"REFERENCES $this->sep".$k[0]."$this->sep($this->sep". "REFERENCES $this->sep".$k[0]."$this->sep($this->sep".
$k[1]."$this->sep)"; $k[1]."$this->sep)";
@@ -586,6 +594,10 @@ class dblayeroo
$i = 0; $i = 0;
foreach ($this->foreign as $field=>$k) foreach ($this->foreign as $field=>$k)
{ {
$field = explode (",", $field);
$field = implode ($this->sep.",".$this->sep, $field);
$k[1] = explode (",", $k[1]);
$k[1] = implode ($this->sep.",".$this->sep, $k[1]);
$sql .= ",\n FOREIGN KEY(\"$field\") REFERENCES \"".$k[0]."\"(\"". $sql .= ",\n FOREIGN KEY(\"$field\") REFERENCES \"".$k[0]."\"(\"".
$k[1]."\")"; $k[1]."\")";
if (isset ($k[2])) if (isset ($k[2]))
@@ -1136,6 +1148,11 @@ class dblayeroo
/** Get/Set the foreign property /** Get/Set the foreign property
* @param array|null $foreign The definition of the foreign constraint * @param array|null $foreign The definition of the foreign constraint
* The format is :
* array (
* "field" => array ("parentTable", "parentField", "options if needed"),
* )
* Multiple field and parnentField can be provided, separated by comma
*/ */
public function foreign ($foreign=null) public function foreign ($foreign=null)
/* {{{ */ /* {{{ */
@@ -1145,31 +1162,39 @@ class dblayeroo
return $this->foreign; return $this->foreign;
if (! is_array ($foreign)) if (! is_array ($foreign))
$this->DBException ("Parameter foreign invalid: not an array"); $this->DBException ("Parameter foreign invalid: not an array");
foreach ($foreign as $col=>$params) foreach ($foreign as $cols=>$params)
{ {
if (! array_key_exists ($col, $this->fields)) foreach (explode (",", $cols) as $col)
$this->DBException ("Parameter foreign invalid: column doesn't exists"); {
if (! is_array ($params)) if (! array_key_exists ($col, $this->fields))
$this->DBException (
"Parameter foreign invalid: column doesn't exists");
if (! is_array ($params))
$this->DBException ("Parameter foreign invalid: ".
"parameters not in array");
if (! array_key_exists (0, $params))
$this->DBException ("Parameter foreign invalid: ".
"ParentTable is not provided");
if (! array_key_exists (1, $params))
$this->DBException ("Parameter foreign invalid: ".
"ParentField is not provided");
if (! is_string ($params[0]))
$this->DBException ("Parameter foreign invalid: ".
"parameter 0 is not a string");
if (! is_string ($params[1]))
$this->DBException ("Parameter foreign invalid: ".
"parameter 1 is not a string");
if (mb_strlen ($params[0] > 64))
$this->DBException ("Parameter foreign invalid: ".
"parameter 0 is too long");
if (mb_strlen ($params[1] > 64))
$this->DBException ("Parameter foreign invalid: ".
"parameter 1 is too long");
}
if (substr_count ($cols, ",") !== substr_count ($params[1], ","))
$this->DBException ("Parameter foreign invalid: ". $this->DBException ("Parameter foreign invalid: ".
"parameters not in array"); "Not the same number of comma between the local ".
if (! array_key_exists (0, $params)) "field and the parent field");
$this->DBException ("Parameter foreign invalid: ".
"parameter 0 doesn't exists");
if (! array_key_exists (1, $params))
$this->DBException ("Parameter foreign invalid: ".
"parameter 1 doesn't exists");
if (! is_string ($params[0]))
$this->DBException ("Parameter foreign invalid: ".
"parameter 0 is not a string");
if (! is_string ($params[1]))
$this->DBException ("Parameter foreign invalid: ".
"parameter 1 is not a string");
if (mb_strlen ($params[0] > 64))
$this->DBException ("Parameter foreign invalid: ".
"parameter 0 is too long");
if (mb_strlen ($params[1] > 64))
$this->DBException ("Parameter foreign invalid: ".
"parameter 1 is too long");
if (array_key_exists (2, $params)) if (array_key_exists (2, $params))
{ {
preg_match_all ("#^(ON UPDATE ". preg_match_all ("#^(ON UPDATE ".
@@ -2500,31 +2525,36 @@ class dblayeroo
} }
// - If foreign keys, check if the value is set in the constraint // - If foreign keys, check if the value is set in the constraint
foreach ($this->foreign as $field=>$params) foreach ($this->foreign as $fields=>$params)
{ {
// Do not test in update if the field is not provided as it was already foreach (explode (",", $fields) as $field)
// recorded
if ($update === true && ! array_key_exists ($field, $values))
continue;
if (! array_key_exists ($field, $values))
{ {
$errors[$field] = sprintf (dgettext ("domframework", // Do not test in update if the field is not provided as it was already
"The field '%s' must be test on foreign, but is not provided"), // recorded
$field); if ($update === true && ! array_key_exists ($field, $values))
continue; continue;
if (! array_key_exists ($field, $values))
{
$errors[$field] = sprintf (dgettext ("domframework",
"The field '%s' must be test on foreign, but is not provided"),
$field);
continue;
}
if (! array_key_exists ($params[0], $this->setForeignObj))
$this->DBException (sprintf (dgettext ("domframework",
"No foreign object configured to test the foreign key for table ".
"'%s'"), $this->table));
} }
if (! array_key_exists ($params[0], $this->setForeignObj)) $this->debugLog ("CLONE to check foreign constraint [$fields]");
$this->DBException (sprintf (dgettext ("domframework",
"No foreign object configured to test the foreign key for table '%s'"),
$this->table));
$this->debugLog ("CLONE to check foreign constraint [$field]");
$objTmp = clone $this->setForeignObj[$params[0]]; $objTmp = clone $this->setForeignObj[$params[0]];
$objTmp->debug = $this->debug; $objTmp->debug = $this->debug;
$objTmp->debugDepth++; $objTmp->debugDepth++;
$objTmp->clearRequest (); $objTmp->clearRequest ();
$objTmp->Select (); $objTmp->Select ();
$objTmp->displayAdd ($objTmp->primary); $objTmp->displayAdd ($objTmp->primary);
$objTmp->whereAdd ($params[1], "=", $values[$field]); $parentField = explode (",", $params[1]);
foreach (explode (",", $fields) as $key=>$field)
$objTmp->whereAdd ($parentField[$key], "=", $values[$field]);
if (count ($objTmp->execute ()) === 0) if (count ($objTmp->execute ()) === 0)
$errors[$field] = sprintf (dgettext ("domframework", $errors[$field] = sprintf (dgettext ("domframework",
"The value of the foreign key '%s' doesn't exists in foreign table"), "The value of the foreign key '%s' doesn't exists in foreign table"),