From 15d70bd3a988021706cf9357b5373bdaf290e573 Mon Sep 17 00:00:00 2001 From: Dominique Fournier Date: Mon, 3 Apr 2017 15:06:03 +0000 Subject: [PATCH] dblayeroo : review the join process and add the unit tests for it git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@3495 bf3deb0d-5f1a-0410-827f-c0cc1f45334c --- Tests/dblayerooComplet.php | 146 +++++++++++++++++++++++++++++++++++++ dblayeroo.php | 82 ++++++++++++++++++--- 2 files changed, 217 insertions(+), 11 deletions(-) diff --git a/Tests/dblayerooComplet.php b/Tests/dblayerooComplet.php index 571945d..e4bf06f 100644 --- a/Tests/dblayerooComplet.php +++ b/Tests/dblayerooComplet.php @@ -360,4 +360,150 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase ), ), $res); } + + // JOINS + public function test_insertJoin1 () + { + $db1 = $this->db1 (); + $db1->insert() + ->setValues(array ("group"=>"group2", + "object"=>"object", + "where"=>"where")) + ->execute (); + $db2 = $this->db2 (); + $db2->setForeignObj ($db1); + $res = $db2->insert() + ->setValues(array ("gecos"=>"name2", + "password"=>"pwd2", + "group"=>"group1")) + ->execute (); + $res = $db2->insert() + ->setValues(array ("gecos"=>"name3", + "password"=>"pwd3", + "group"=>"group1")) + ->execute (); + $res = $db2->insert() + ->setValues(array ("gecos"=>"name4", + "password"=>"pwd4", + "group"=>"group1")) + ->execute (); + $db1->disconnect (); + $db2->disconnect (); + } + + public function test_innerJoin1 () + { + $db1 = $this->db1 (); + $db2 = $this->db2 (); + $res = $db2->select () + ->joinInner ($db1, array ("group"=>"group")) + ->execute (); + $db1->disconnect (); + $db2->disconnect (); + $this->assertSame (array ( + array ( + 'usersoo.uid' => 1, + 'usersoo.gecos' => 'name', + 'usersoo.password' => 'toto', + 'usersoo.group' => 'group1', + 'groupedoo.group' => 'group1', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + ), + array ( + 'usersoo.uid' => 4, + 'usersoo.gecos' => 'name2', + 'usersoo.password' => 'pwd2', + 'usersoo.group' => 'group1', + 'groupedoo.group' => 'group1', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + ), + array ( + 'usersoo.uid' => 5, + 'usersoo.gecos' => 'name3', + 'usersoo.password' => 'pwd3', + 'usersoo.group' => 'group1', + 'groupedoo.group' => 'group1', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + ), + array ( + 'usersoo.uid' => 6, + 'usersoo.gecos' => 'name4', + 'usersoo.password' => 'pwd4', + 'usersoo.group' => 'group1', + 'groupedoo.group' => 'group1', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + ), + ), $res); + } + + public function test_leftJoin2 () + { + $db1 = $this->db1 (); + $db2 = $this->db2 (); + $res = $db1->select () + ->joinLeft ($db2, array ("group"=>"group")) + ->execute (); + $db1->disconnect (); + $db2->disconnect (); + $this->assertSame (array ( + array ( + 'groupedoo.group' => 'group1', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + 'usersoo.uid' => 1, + 'usersoo.gecos' => 'name', + 'usersoo.password' => 'toto', + 'usersoo.group' => 'group1', + ), + array ( + 'groupedoo.group' => 'group1', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + 'usersoo.uid' => 4, + 'usersoo.gecos' => 'name2', + 'usersoo.password' => 'pwd2', + 'usersoo.group' => 'group1', + ), + array ( + 'groupedoo.group' => 'group1', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + 'usersoo.uid' => 5, + 'usersoo.gecos' => 'name3', + 'usersoo.password' => 'pwd3', + 'usersoo.group' => 'group1', + ), + array ( + 'groupedoo.group' => 'group1', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + 'usersoo.uid' => 6, + 'usersoo.gecos' => 'name4', + 'usersoo.password' => 'pwd4', + 'usersoo.group' => 'group1', + ), + array ( + 'groupedoo.group' => 'group2', + 'groupedoo.object' => 'object', + 'groupedoo.where' => 'where', + 'groupedoo.with space' => NULL, + 'usersoo.uid' => 0, + 'usersoo.gecos' => NULL, + 'usersoo.password' => NULL, + 'usersoo.group' => NULL, + ), + ), $res); + } } diff --git a/dblayeroo.php b/dblayeroo.php index 550e5e4..b3860c2 100644 --- a/dblayeroo.php +++ b/dblayeroo.php @@ -1165,6 +1165,7 @@ class dblayeroo $this->setValues = array (); $this->setType = array (); $this->setForeignObj = array (); + unset ($this->fieldsTmp); } /** Define a new foreign object @@ -1374,6 +1375,25 @@ class dblayeroo $this->whereExpression = array_merge ($object->whereExpression, $this->whereExpression); $this->whereValues = array_merge ($object->whereValues, $this->whereValues); + // Add the new object fields to the this. The fields must be available to + // be normalized at the end + $tmp = array (); + foreach ($object->fields as $key=>$data) + { + $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; } @@ -1575,7 +1595,12 @@ class dblayeroo $sql .= " ".$this->distinct; $displayColumns = implode (",", $this->displayColumn); if ($displayColumns === "") - $displayColumns = "*"; + { + if (isset ($this->fieldsTmp)) + $displayColumns = implode (",", array_keys ($this->fieldsTmp)); + else + $displayColumns = "*"; + } $sql .= " $displayColumns FROM $this->sep$this->tableprefix". "$this->table$this->sep"; if (! empty ($this->joins)) @@ -2011,22 +2036,57 @@ class dblayeroo switch ($this->command) { case "SELECT": - $result = $st->fetchAll (\PDO::FETCH_ASSOC); - // Harmonize the fetchAll result between all the databases drivers - foreach ($result as &$row) + $result = $st->fetchAll (\PDO::FETCH_NUM); + // There is no fetchAll corresponding to the columnName->value. Assign the + // name to the value by index. + // FETCH_ASSOC doesn't work in empty left join (return NULL instead of + // the filled value) + if (isset ($this->fieldsTmp)) + $columns = array_keys ($this->fieldsTmp); + else + $columns = array_keys ($this->fields); + foreach ($result as $rownb=>$row) { - foreach ($row as $col=>&$val) + foreach ($row as $colNb=>$val) { - // The fields defined with "integer" type are translated to PHP - // integer type (Already done by PostgreSQL driver, but not by MySQL - // and SQLite - if (strtolower ($this->fields[$col][0]) === "integer") - $val = intval ($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); + } + $colName = str_replace ($this->sep, "", $columns[$colNb]); + $result[$rownb][$colName] = $val; + unset ($result[$rownb][$colNb]); } } return $result; case "INSERT": - return self::$instance[$this->dsn]->lastInsertId (); + // PostGres need the name of the column autoincrement to return something + // If there is no autoincrement column, do not request the lastInsertId + $autoInc = null; + if ($this->driver === "pgsql") + { + foreach ($this->fields as $col=>$params) + { + if (in_array ("autoincrement", $params)) + { + $autoInc = $col; + break; + } + } + if ($autoInc !== null) + $autoInc = $this->table."_${col}_seq"; + } + $this->debugLog ("INSERT: lastInsertId=", + self::$instance[$this->dsn]->lastInsertId ($autoInc)); + return self::$instance[$this->dsn]->lastInsertId ($autoInc); case "UPDATE": case "DELETE": return $st->rowCount ();