dblayeroo : review the join process and add the unit tests for it

git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@3538 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
2017-04-25 11:49:19 +00:00
parent 369536faae
commit b6b9573813
2 changed files with 320 additions and 79 deletions

View File

@@ -62,7 +62,8 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase
));
$db2->unique (array ("gecos","password"));
$db2->primary ("uid");
$db2->foreign (array ("group" => array ("groupedoo", "group", "ON DELETE CASCADE")));
$db2->foreign (array ("group" => array ("groupedoo", "group",
"ON DELETE CASCADE")));
return $db2;
}
@@ -74,12 +75,30 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase
return $db3;
}
private function db4 ()
{
$dbconfig = $this->confs["{ENGINE}"];
$db4 = new dblayeroo ($dbconfig["dsn"], $dbconfig["username"],
$dbconfig["password"], $dbconfig["driver_options"]);
$db4->table ("rightsoo");
$db4->fields (array ("id"=>array ("integer", "not null", "autoincrement"),
"name"=>array ("varchar(255)", "not null"),
"group" => array ("varchar(255)", "not null"),
));
$db4->unique (array ("name"));
$db4->primary ("id");
$db4->foreign (array ("group" => array ("groupedoo", "group",
"ON DELETE CASCADE")));
return $db4;
}
public function test_dropTable ()
{
$dbconfig = $this->confs["{ENGINE}"];
$db = new dblayeroo ($dbconfig["dsn"], $dbconfig["username"],
$dbconfig["password"], $dbconfig["driver_options"]);
foreach (array ("usersoo", "groupedoo", "multipleoo", "multiple2oo", "users3oo",
foreach (array ("rightsoo", "usersoo", "groupedoo",
"multipleoo", "multiple2oo", "users3oo",
"readORoo") as
$table)
{
@@ -115,6 +134,15 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase
$this->assertSame (0, $res);
}
public function test_createTable4 ()
{
// Create a table named rightsoo
$db4 = $this->db4 ();
$res = $db4->createTable ();
$db4->disconnect ();
$this->assertSame (0, $res);
}
public function test_select1 ()
{
// Select all on the table : nothing
@@ -511,9 +539,10 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase
public function test_leftJoin3 ()
{
// Filter on the db1
// Filter on the db1, do not display db2
$db1 = $this->db1 ();
$db2 = $this->db2 ();
$db2->displayColumn ();
$res = $db1->select ()
->displayColumn ("group")
->joinLeft ($db2, array ("group"=>"group"))
@@ -541,7 +570,7 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase
public function test_leftJoin4 ()
{
// Filter on the db1
// Filter on the db1, display one column in db2
$db1 = $this->db1 ();
$db2 = $this->db2 ();
$db2->displayColumn ("group");
@@ -553,24 +582,125 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase
$db2->disconnect ();
$this->assertSame (array (
array (
'usersoo.group' => 'group1',
'groupedoo.group' => 'group1',
'usersoo.group' => 'group1',
),
array (
'usersoo.group' => 'group1',
'groupedoo.group' => 'group1',
'usersoo.group' => 'group1',
),
array (
'usersoo.group' => 'group1',
'groupedoo.group' => 'group1',
'usersoo.group' => 'group1',
),
array (
'usersoo.group' => 'group1',
'groupedoo.group' => 'group1',
'usersoo.group' => 'group1',
),
array (
'usersoo.group' => NULL,
'groupedoo.group' => 'group2',
'usersoo.group' => NULL,
),
), $res);
}
public function test_leftJoin5 ()
{
// Filter on the db1 and add order in full mode
$db1 = $this->db1 ();
$db2 = $this->db2 ();
$db2->displayColumn ("group");
$res = $db1->select ()
->displayColumn ("group")
->joinLeft ($db2, array ("group"=>"group"))
->orderAdd ("group", "DESC")
->execute ();
$db1->disconnect ();
$db2->disconnect ();
$this->assertSame (array (
array (
'groupedoo.group' => 'group2',
'usersoo.group' => NULL,
),
array (
'groupedoo.group' => 'group1',
'usersoo.group' => 'group1',
),
array (
'groupedoo.group' => 'group1',
'usersoo.group' => 'group1',
),
array (
'groupedoo.group' => 'group1',
'usersoo.group' => 'group1',
),
array (
'groupedoo.group' => 'group1',
'usersoo.group' => 'group1',
),
), $res);
}
/// THREE TABLES ///
public function test_insert6 ()
{
$db1 = $this->db1 ();
$db4 = $this->db4 ();
$db4->setForeignObj ($db1);
$res = $db4->insert ()
->setValues(array ("name"=>"RO",
"group"=>"group1"))
->execute ();
$db4->disconnect ();
// As the key is not an autoincrement, the lastInsertID can be 0 or 1
$this->assertGreaterThanOrEqual ($res, "0");
}
public function test_leftJoin6 ()
{
// Two joins tables in left join
$db1 = $this->db1 (); // Do not display anything from groupedoo
$db1->displayColumn ("group");
$db2 = $this->db2 (); // Display the gecos and group from usersoo
$db2->displayColumn ("gecos")
->orderAdd ("gecos", "ASC");
$db4 = $this->db4 (); // Display the name in rightsoo
$db4->displayColumn ("name");
$db1->joinLeft ($db4, array ("group"=>"group"));
$res = $db1->select ()
->joinLeft ($db2, array ("group"=>"group"))
->orderAdd ("group", "DESC")
->execute ();
$db1->disconnect ();
$db2->disconnect ();
$db4->disconnect ();
$this->assertSame (array (
array (
'groupedoo.group' => 'group1',
'rightsoo.name' => 'RO',
'usersoo.gecos' => 'name',
),
array (
'groupedoo.group' => 'group1',
'rightsoo.name' => 'RO',
'usersoo.gecos' => 'name2',
),
array (
'groupedoo.group' => 'group1',
'rightsoo.name' => 'RO',
'usersoo.gecos' => 'name3',
),
array (
'groupedoo.group' => 'group1',
'rightsoo.name' => 'RO',
'usersoo.gecos' => 'name4',
),
array (
'groupedoo.group' => 'group2',
'rightsoo.name' => NULL,
'usersoo.gecos' => NULL,
),
), $res);
}

View File

@@ -976,6 +976,32 @@ class dblayeroo
}
/* }}} */
/** Get all the fields with the table name if needed.
* If the objectJoin is set, return the fields name too
* @param bool $full Add the table name if the $full is set
*/
public function fieldsAll ($full = false)
/* {{{ */
{
$fields = array ();
if ($this->joinObject)
{
foreach ($this->joinObject as $obj)
$fields = array_merge ($fields, $obj->fieldsAll (true));
$full = true;
}
foreach ($this->fields as $f=>$val)
{
if ($full !== false)
$fields[$this->sep.$this->tableprefix.$this->table.$this->sep.".".
$this->sep.$f.$this->sep] = $val;
else
$fields[$f] = $val;
}
return $fields;
}
/* }}} */
/** Get/Set the primary property
* @param string|null $primary The primary key to use
*/
@@ -1162,7 +1188,7 @@ class dblayeroo
/** The columns to display in SELECT, with the tables names and the separators
* correctely defined
*/
private $displayColumn = array ();
private $displayColumn = null;
/** Manage the joins
*/
private $joins = array ();
@@ -1188,6 +1214,11 @@ class dblayeroo
*/
private $setForeignObj = array ();
/** If we need to join this object with another one, save the second one in
* this property
*/
private $joinObject;
/** The debug depth (as we clone object, the depth is increased to debug
* easily the functions
*/
@@ -1201,7 +1232,7 @@ class dblayeroo
$this->debugLog ("Entering clearRequest ()");
$this->command = "";
$this->distinct = "";
$this->displayColumn = array ();
$this->displayColumn = null;
$this->joins = array ();
$this->whereExpression = array ();
$this->whereValues = array ();
@@ -1210,7 +1241,6 @@ class dblayeroo
$this->setValues = array ();
$this->setType = array ();
$this->setForeignObj = array ();
unset ($this->fieldsTmp);
}
/* }}} */
@@ -1304,10 +1334,12 @@ class dblayeroo
/* }}} */
/** Set the columns to display for the next SELECT request
* @param array|string $columnNames The columns name, separated by comma
* By default, display all the columns
* @param array|string|null $columnNames The columns name, separated by comma
* By default, display all the columns if this method is not called
* If the value is null or not provided or an empty array, do not display
* any field
*/
public function displayColumn ($columnNames)
public function displayColumn ($columnNames = array ())
/* {{{ */
{
$this->debugLog ("Entering displayColumn (",$columnNames,")");
@@ -1316,19 +1348,82 @@ class dblayeroo
"Invalid columnNames provided (not string and not array)");
if (is_string ($columnNames))
$columnNames = explode (",", $columnNames);
if ($this->displayColumn === null)
$this->displayColumn = array ();
foreach ($columnNames as $name)
{
$name = trim ($name);
if (! array_key_exists ($name, $this->fields))
$this->DBException (sprintf (
"Invalid field to display '%s' : not defined in table", $name));
$this->displayColumn[] = $this->sep.$this->tableprefix.$this->table.
$this->sep.".".
$this->sep.$name.$this->sep;
$this->displayColumn[] = $this->sep.$name.$this->sep;
}
return $this;
}
/* }}} */
/** Get the columns set in the query by displayColumn. If the $full parameter
* is set, add the table prefix/name to the result.
* If the join object is set, ask to it the columns too
* @param bool $full Add the table prefix/name if set
*/
public function displayGet ($full = false)
/* {{{ */
{
$columns = array ();
$displayColumn = array ();
if ($this->joinObject)
{
// The join object will be added at the end
$full = true;
}
// If empty $this->displayColumn list the fields of the table (like
// tablename.*)
if ($full !== false)
{
if ($this->displayColumn === null)
{
foreach (array_keys ($this->fields) as $name)
{
$displayColumn[] = $this->sep.$name.$this->sep;
}
}
else
{
$displayColumn = $this->displayColumn;
}
}
else
{
if ($this->displayColumn === null)
{
foreach (array_keys ($this->fields) as $name)
{
$displayColumn[] = $this->sep.$name.$this->sep;
}
}
else
{
$displayColumn = $this->displayColumn;
}
}
foreach ($displayColumn as $d)
{
if ($full !== false)
$columns[] = $this->sep.$this->tableprefix.$this->table.$this->sep.".".
$d;
else
$columns[] = $d;
}
if ($this->joinObject)
{
foreach ($this->joinObject as $obj)
$columns = array_merge ($columns, $obj->displayGet (true));
}
return $columns;
}
/* }}} */
/** Do a inner join between two dblayer objects
* The join array is a associated array with local field as key and distant
* field as value
@@ -1420,6 +1515,7 @@ class dblayeroo
$this->DBException ("No table defined in the local object");
if (! isset ($object->tableprefix) || $object->tableprefix === null)
$this->DBException ("No tableprefix defined in the Join object");
$this->joinObject[] = $object;
$tmp = "";
foreach ($joinArray as $fieldLocal=>$fieldToJoin)
{
@@ -1436,10 +1532,6 @@ class dblayeroo
// fields of object
$this->joins[] = "$joinType JOIN ".
$this->sep.$object->tableprefix.$object->table.$this->sep." ON $tmp";
foreach ($object->displayColumn as $col)
{
array_unshift ($this->displayColumn, $col);
}
// Correct the WHERE in the main with the object WHERE
$this->whereExpression = array_merge ($object->whereExpression,
$this->whereExpression);
@@ -1452,21 +1544,30 @@ class dblayeroo
$tmp[$this->sep.$object->tableprefix.$object->table.$this->sep.".".
$this->sep.$key.$this->sep] = $data;
}
if (!isset ($this->fieldsTmp))
{
$tmpThis = array ();
foreach ($this->fields as $key=>$data)
{
$tmpThis[$this->sep.$this->tableprefix.$this->table.$this->sep.".".
$this->sep.$key.$this->sep] = $data;
}
$this->fieldsTmp = $tmpThis;
}
$this->fieldsTmp = array_merge ($this->fieldsTmp, $tmp);
return $this;
}
/* }}} */
/** Get the join SQL part with recursive call of the child joins
* @param object|null $joinObject The joinObject to examine too
*/
public function joinsGet ($joinObject = null)
/* {{{ */
{
$joins = "";
if ($joinObject === null)
$joinObject = $this;
if ($joinObject->joins !== array ())
$joins = implode ("\n ", $joinObject->joins);
if ($joinObject->joinObject !== null)
{
foreach ($joinObject->joinObject as $obj)
$joins .= "\n ".$joinObject->joinsGet ($obj);
}
return trim ($joins);
}
/* }}} */
/** Set a new WHERE expression value
* @param string $field The field to check
* @param string $operator The operator ("=", "<=", ">=", "!=", "NOT LIKE",
@@ -1589,6 +1690,33 @@ class dblayeroo
}
/* }}} */
/** Get the ORDER fields defined. If a joinObject is set with ORDER statement,
* return the joinObject order with its tableprefix/name in addition of
* the ones of this object
* If the parameter $full is set, add the table prefix/name to the result
* @param bool|null $full Add the table prefix/name if set
*/
public function orderGet ($full=false)
/* {{{ */
{
$order = array ();
if ($this->joinObject)
{
foreach ($this->joinObject as $obj)
$order = array_merge ($order, $obj->orderGet (true));
$full = true;
}
foreach ($this->orderExpression as $o)
{
if ($full !== false)
$order[] = $this->sep.$this->tableprefix.$this->table.$this->sep.".".$o;
else
$order[] = $o;
}
return $order;
}
/* }}} */
/** Define a LIMIT for the request.
* To use only the nbLines, put a 0 on startLine
* @param integer $startLine The starting line in the result list
@@ -1682,24 +1810,25 @@ class dblayeroo
$sql = "SELECT";
if ($this->distinct !== "")
$sql .= " ".$this->distinct;
$displayColumns = implode (",", $this->displayColumn);
if ($displayColumns === "")
{
if (isset ($this->fieldsTmp))
$displayColumns = implode (",", array_keys ($this->fieldsTmp));
if ($this->joinObject)
$displayColumns = implode (",", $this->displayGet (true));
elseif (count ($this->displayGet (false)))
$displayColumns = implode (",", $this->displayGet (false));
else
$displayColumns = "*";
}
$sql .= " $displayColumns FROM $this->sep$this->tableprefix".
if ($this->joinObject)
$order = $this->orderGet (true);
else
$order = $this->orderGet (false);
$sql .= " $displayColumns\n FROM $this->sep$this->tableprefix".
"$this->table$this->sep";
if (! empty ($this->joins))
$sql .= " ". implode (" ", $this->joins);
$sql .= "\n ".$this->joinsGet ();
if (! empty ($this->whereExpression))
$sql .= " WHERE ". implode (" ", $this->whereExpression);
if (! empty ($this->orderExpression))
$sql .= " ORDER BY ". implode (",", $this->orderExpression);
$sql .= "\n WHERE ". implode (" ", $this->whereExpression);
if (count ($order))
$sql .= "\n ORDER BY ". implode (",", $order);
if (! empty ($this->limitExpression))
$sql .= " LIMIT $this->limitExpression";
$sql .= "\n LIMIT $this->limitExpression";
// No set Values for SELECT
$this->setValues = array ();
break;
@@ -2140,46 +2269,28 @@ class dblayeroo
// name to the value by index.
// FETCH_ASSOC doesn't work in empty left join (return NULL instead of
// the filled value)
if (count ($this->displayColumn))
{
if (isset ($this->fieldsTmp))
{
$columns = $this->displayColumn;
}
else
$fieldsAll = $this->fieldsAll (false);
if ($this->joinObject === null && count ($this->displayGet (false)))
{
// Remove the columns names as there is no collisions risk
$columns = array ();
foreach ($this->displayColumn as $col)
foreach ($this->displayGet (false) as $col)
{
$columns[] = substr ($col, 1 + strrpos ($col, $this->sep, -2), -1);
}
}
}
elseif (isset ($this->fieldsTmp))
{
$columns = array_keys ($this->fieldsTmp);
}
else
{
$columns = array_keys ($this->fields);
$columns = $this->displayGet (true);
}
foreach ($result as $rownb=>$row)
{
foreach ($row as $colNb=>$val)
{
// Harmonize the fetchAll result between all the databases drivers
if (isset ($this->fieldsTmp))
{
if (strtolower ($this->fieldsTmp[$columns[$colNb]][0]) ===
if (strtolower ($fieldsAll[$columns[$colNb]][0]) ===
"integer")
$val = intval ($val);
}
elseif (isset ($this->fields))
{
if (strtolower ($this->fields[$columns[$colNb]][0]) === "integer")
$val = intval ($val);
}
$colName = str_replace ($this->sep, "", $columns[$colNb]);
$result[$rownb][$colName] = $val;
unset ($result[$rownb][$colNb]);