diff --git a/Tests/dblayerooComplet.php b/Tests/dblayerooComplet.php index 36213e6..330a4fc 100644 --- a/Tests/dblayerooComplet.php +++ b/Tests/dblayerooComplet.php @@ -380,17 +380,45 @@ class test_dblayeroo_{ENGINE} extends PHPUnit_Framework_TestCase $res = $tbl3->getTableSchema ("usersoo"); $tbl3->disconnect (); $this->assertSame ( - array ("fields"=>array ( - "uid"=>array ("integer", "not null", "autoincrement"), - "gecos"=>array ("varchar(255)", "not null"), - "password"=>array ("varchar(255)", "not null"), + array ("table" => "usersoo", + "fields" => array ( + "uid" => array ("integer", "not null", "autoincrement"), + "gecos" => array ("varchar(255)", "not null"), + "password" => array ("varchar(255)", "not null"), "group" => array ("varchar(255)", "not null"), ), - "primary"=>"uid", - "unique"=>array ("gecos","password"), + "primary" => "uid", + "unique" => array ("gecos","password","uid"), "foreign" => array ( "group" => array ('groupedoo', 'group', 'ON DELETE CASCADE'), ), + "foreignUsed" => array ( + ), + ), $res); + } + + public function test_getTableSchema2 () + { + $tbl3 = $this->tbl3 (); + $res = $tbl3->getTableSchema ("groupedoo"); + $tbl3->disconnect (); + $this->assertSame ( + array ( + "table" => "groupedoo", + "fields" => array ( + "group" => array ("varchar(255)", "not null"), + "object" => array ("varchar(255)", "not null"), + "where" => array ("varchar(255)", "not null"), + "with space" => array ("varchar(255)")), + "primary" => "group", + "unique" => array ("group"), + "foreign" => array (), + "foreignUsed" => array ( + "group" => array ( + array ("rightsoo", "group"), + array ("usersoo", "group"), + ), + ), ), $res); } diff --git a/dblayeroo.php b/dblayeroo.php index 316e392..02b2ff9 100644 --- a/dblayeroo.php +++ b/dblayeroo.php @@ -308,7 +308,7 @@ class dblayeroo natsort ($res); return array_values ($res); } - /* }}} */ + /* }}} */ /** Create the table defined by the differents fields. * Define the SQL syntax based on SQL engines @@ -716,13 +716,15 @@ class dblayeroo } $unique[$content2[0]["cid"]-1] = $index; } - elseif (count ($content2) === 1) + elseif (count ($content2) === 1 && $content2[0]["cid"] >= 1) { $index = $content2[0]["name"]; $unique[$content2[0]["cid"]-1] = $index; } } ksort ($unique); + $unique[] = $primary; + $unique = array_unique ($unique); try { @@ -754,10 +756,29 @@ class dblayeroo $tmp[] = $cascade; $foreign[$for["from"]] = $tmp; } - return array ("fields" => $fields, - "primary" => $primary, - "unique" => $unique, - "foreign" => $foreign); + + $foreignUsed = array (); + foreach ($this->listTables () as $tbl) + { + $st = self::$instance[$this->dsn]->prepare ( + "PRAGMA foreign_key_list($tbl)"); + $st->execute (); + $content = $st->fetchAll (\PDO::FETCH_ASSOC); + foreach ($content as $row) + { + if ($row["table"] !== $tableName) + continue; + $foreignUsed[$row["to"]][] = array ( + $tbl, $row["from"] + ); + } + } + return array ("table" => $tableName, + "fields" => $fields, + "primary" => $primary, + "unique" => $unique, + "foreign" => $foreign, + "foreignUsed" => $foreignUsed); break; case "mysql": $st = self::$instance[$this->dsn]->prepare ( @@ -806,6 +827,8 @@ class dblayeroo } } $unique = array_values ($unique); + $unique[] = $primary; + $unique = array_unique ($unique); $st = self::$instance[$this->dsn]->prepare (" SELECT UPDATE_RULE,DELETE_RULE,COLUMN_NAME, kColUsage.REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME @@ -835,22 +858,55 @@ class dblayeroo unset ($tmp[2]); $foreign[$f["COLUMN_NAME"]] = $tmp; } - return array ("fields" => $fields, - "primary" => $primary, - "unique" => $unique, - "foreign" => $foreign); + + $st = self::$instance[$this->dsn]->prepare (" + SELECT TABLE_NAME,COLUMN_NAME, + REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME + FROM information_schema.KEY_COLUMN_USAGE + WHERE REFERENCED_TABLE_NAME=:table AND + TABLE_SCHEMA=:dbname"); + $st->execute (array(':dbname' => $this->databasename (), + ':table' => $tableName)); + $foreignUsedTmp = $st->fetchAll (\PDO::FETCH_ASSOC); + $foreignUsed = array (); + foreach ($foreignUsedTmp as $f) + { + $foreignUsed[$f["REFERENCED_COLUMN_NAME"]][] = array ( + $f["TABLE_NAME"], + $f["COLUMN_NAME"]); + } + return array ("table" => $tableName, + "fields" => $fields, + "primary" => $primary, + "unique" => $unique, + "foreign" => $foreign, + "foreignUsed" => $foreignUsed); break; case "pgsql": - $st = self::$instance[$this->dsn]->prepare ( - "SELECT * - FROM information_schema.columns - WHERE table_schema='public' and table_name='$tableName'"); - $st->execute (); - $content = $st->fetchAll (\PDO::FETCH_ASSOC); $fields = array (); $unique = array (); $foreign = array (); $primary = ""; + // Get the defined primary key if not autoincrement + $st = self::$instance[$this->dsn]->prepare (" + SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type + FROM pg_index i + JOIN pg_attribute a ON a.attrelid = i.indrelid + AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = :table::regclass + AND i.indisprimary; + "); + $st->execute (array(':table' => $tableName)); + $content = $st->fetchAll (\PDO::FETCH_ASSOC); + if (key_exists (0, $content)) + $primary = $content[0]["attname"]; + // Get the primary key if autoincrement + $st = self::$instance[$this->dsn]->prepare ( + "SELECT * + FROM information_schema.columns + WHERE table_schema='public' and table_name='$tableName'"); + $st->execute (); + $content = $st->fetchAll (\PDO::FETCH_ASSOC); foreach ($content as $col) { $tmp = array (); @@ -869,9 +925,9 @@ class dblayeroo } $st = self::$instance[$this->dsn]->prepare ( - "select * - from information_schema.constraint_column_usage - where table_name='$tableName'"); + "SELECT * + FROM information_schema.constraint_column_usage + WHERE table_name='$tableName'"); $st->execute (); $content = $st->fetchAll (\PDO::FETCH_ASSOC); foreach ($content as $col) @@ -889,6 +945,8 @@ class dblayeroo } } $unique = array_values ($unique); + $unique[] = $primary; + $unique = array_unique ($unique); $st = self::$instance[$this->dsn]->prepare (" SELECT kColUsage1.column_name COLUMN_NAME, kColUsage2.table_name REFERENCED_TABLE_NAME, @@ -924,10 +982,41 @@ class dblayeroo $foreign[$f["column_name"]] = $tmp; } - return array ("fields" => $fields, - "primary" => $primary, - "unique" => $unique, - "foreign" => $foreign); + $st = self::$instance[$this->dsn]->prepare (" + SELECT kColUsage1.table_name TABLE_NAME, + kColUsage1.column_name COLUMN_NAME, + kColUsage2.table_name REFERENCED_TABLE_NAME, + kColUsage2.column_name REFERENCED_COLUMN_NAME, + update_rule,delete_rule + FROM information_schema.KEY_COLUMN_USAGE AS kColUsage1, + information_schema.KEY_COLUMN_USAGE AS kColUsage2, + information_schema.REFERENTIAL_CONSTRAINTS AS rCons + WHERE + kColUsage1.table_catalog=:dbname + AND kColUsage2.table_name=:table + AND rCons.constraint_name=kColUsage1.constraint_name + AND rCons.unique_constraint_name=kColUsage2.constraint_name + ORDER BY kColUsage1.table_name + "); + $st->execute ( + array(':dbname' => $this->databasename (), + ':table' => $tableName)); + + $foreignUsedTmp = $st->fetchAll (\PDO::FETCH_ASSOC); + $foreignUsed = array (); + foreach ($foreignUsedTmp as $f) + { + $foreignUsed[$f["referenced_column_name"]][] = array ( + $f["table_name"], + $f["column_name"]); + } + + return array ("table" => $tableName, + "fields" => $fields, + "primary" => $primary, + "unique" => $unique, + "foreign" => $foreign, + "foreignUsed" => $foreignUsed); break; default: $this->DBException (dgettext("domframework",