diff --git a/Tests/dblayerooComplet.php b/Tests/dblayerooComplet.php index ad32f72..243e5c4 100644 --- a/Tests/dblayerooComplet.php +++ b/Tests/dblayerooComplet.php @@ -38,7 +38,7 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase { $dbconfig = $this->confs["{ENGINE}"]; $db1 = new dblayeroo ($dbconfig["dsn"], $dbconfig["username"], - $dbconfig["password"], $dbconfig["driver_options"]); + $dbconfig["password"], $dbconfig["driver_options"]); $db1->table ("groupedoo"); $db1->fields (array ("group"=>array ("varchar(255)", "not null"), "object"=>array ("varchar(255)", "not null"), @@ -53,7 +53,7 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase { $dbconfig = $this->confs["{ENGINE}"]; $db2 = new dblayeroo ($dbconfig["dsn"], $dbconfig["username"], - $dbconfig["password"], $dbconfig["driver_options"]); + $dbconfig["password"], $dbconfig["driver_options"]); $db2->table ("usersoo"); $db2->fields (array ("uid"=>array ("integer", "not null", "autoincrement"), "gecos"=>array ("varchar(255)", "not null"), @@ -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; } @@ -70,16 +71,34 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase { $dbconfig = $this->confs["{ENGINE}"]; $db3 = new dblayeroo ($dbconfig["dsn"], $dbconfig["username"], - $dbconfig["password"], $dbconfig["driver_options"]); + $dbconfig["password"], $dbconfig["driver_options"]); 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); } diff --git a/dblayeroo.php b/dblayeroo.php index 55c3784..dbe7217 100644 --- a/dblayeroo.php +++ b/dblayeroo.php @@ -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)); - else - $displayColumns = "*"; - } - $sql .= " $displayColumns FROM $this->sep$this->tableprefix". + if ($this->joinObject) + $displayColumns = implode (",", $this->displayGet (true)); + elseif (count ($this->displayGet (false))) + $displayColumns = implode (",", $this->displayGet (false)); + else + $displayColumns = "*"; + 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)) + $fieldsAll = $this->fieldsAll (false); + if ($this->joinObject === null && count ($this->displayGet (false))) { - if (isset ($this->fieldsTmp)) + // Remove the columns names as there is no collisions risk + $columns = array (); + foreach ($this->displayGet (false) as $col) { - $columns = $this->displayColumn; + $columns[] = substr ($col, 1 + strrpos ($col, $this->sep, -2), -1); } - else - { - // Remove the columns names as there is no collisions risk - $columns = array (); - foreach ($this->displayColumn 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]) === - "integer") - $val = intval ($val); - } - elseif (isset ($this->fields)) - { - if (strtolower ($this->fields[$columns[$colNb]][0]) === "integer") - $val = intval ($val); - } + if (strtolower ($fieldsAll[$columns[$colNb]][0]) === + "integer") + $val = intval ($val); $colName = str_replace ($this->sep, "", $columns[$colNb]); $result[$rownb][$colName] = $val; unset ($result[$rownb][$colNb]);