Files
DomFramework/tools/modelGraph.php
2019-11-13 15:18:17 +00:00

167 lines
4.4 KiB
PHP
Executable File

#!/usr/bin/php
<?php
/** DomFramework
* @package domframework
* @author Dominique Fournier <dominique@fournier38.fr>
*/
require_once ("domframework/dblayeroo.php");
/** modelGraph
* Allow to create the relational graph of an existing database
* Use GraphViz to generate the graph
* Request the database DSN to operate
*/
class modelgraph
{
// PROPERTIES
/** The connected object dblayeroo
*/
private $db;
/** The output file
*/
private $output;
/** The constructor wait for $dsn
* @param string $dsn The DSN to connect to database
* @param string $output The output file to generate
*/
public function __construct ($dsn, $username, $password, $output)
// {{{
{
$this->output = $output;
$this->db = new \dblayeroo ($dsn, $username, $password);
$this->graphvizCommande ();
}
// }}}
/** Generate the output file
*/
public function generate ()
// {{{
{
$tables = array ();
foreach ($this->db->listTables () as $table)
{
$tables[$table] = $this->db->getTableSchema ($table);
}
$d = "digraph G {\n";
$d .= " node [shape=box];\n";
$d .= " rankdir=RL\n";
// Generate the tables objects with the fields
foreach ($tables as $table => $schema)
{
$d .= " /** TABLE '$table' */\n";
$d .= " \"$table\" [\n";
$d .= " shape = \"plaintext\"\n";
$d .= " label = <";
$d .= "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
// Display the name of the table as title
$d .= " <TR><TD COLSPAN=\"3\" BGCOLOR=\"#00B0E0\">";
$d .= "$table</TD></TR>\n";
// Display the fields
$i = 0;
foreach ($schema["fields"] as $field => $params)
{
$d .= " <TR>\n";
$d .= "<TD SIDES=\"TBL\" PORT=\"OUT-$field\">";
if (key_exists ($field, $schema["foreign"]))
{
// Foreign Key
$d .= "<FONT COLOR=\"#F02020\">!</FONT>";
}
elseif (key_exists ("primary", $schema) &&
$field === $schema["primary"])
$d .= "&#128273;"; // Primary key found
elseif (in_array ("not null", $params))
$d .= "<FONT COLOR=\"#00B0E0\">&#9670;</FONT>"; // NOT NULL
else
$d .= "&#9671;";
$d .= "</TD>\n";
$d .= "<TD ALIGN=\"LEFT\" SIDES=\"TB\">";
$d .= $field;
$d .= "</TD>\n";
$d .= "<TD ALIGN=\"LEFT\" PORT=\"IN-$field\" SIDES=\"TBR\">";
$d .= $params[0];
$d .= "</TD>\n";
$d .= "</TR>\n";
$i++;
}
$d .= "</TABLE>>\n";
$d .= " ];\n";
}
// Generate the links between the tables
foreach ($tables as $table => $schema)
{
// "node1":"f2" -> "node5":"f0" [];
foreach ($schema["foreign"] as $field => $params)
{
$d .= "\"$table\":\"OUT-$field\" -> \"". $params[0].
"\":\"IN-".$params[1]."\" ";
$d .= "[];\n";
}
}
$d .= "}\n";
//echo $d;
$this->createJPG ($d);
}
// }}}
/** Look for the dot command
* @return the full path of 'dot' command
*/
private function graphvizCommande ()
// {{{
{
foreach (explode (":", getenv ("PATH")) as $path)
{
if (file_exists ("$path/dot"))
return "$path/dot";
}
throw new \Exception ("Can not find 'dot' executable. Install graphviz",
500);
}
// }}}
/** Generate the JPEG file with graphviz
* @param string $content The content of the GV file
*/
private function createJPG ($content)
// {{{
{
$tmp = tempnam ("/tmp", "modelgraph_");
file_put_contents ($tmp, $content);
$cmd = $this->graphvizCommande (). " -T jpeg $tmp ".
"-o ".escapeshellarg ($this->output)." 2>&1";
exec ($cmd, $output);
unlink ($tmp);
if (!empty ($output))
{
echo "ERROR : ".implode ("\n", $output);
exit (2);
}
}
// }}}
}
// MAIN PROGRAM
if (isset ($argv[1]) && $argv[1] === "-h")
{
echo "Create the ER Diagram of a SQL database\n";
echo "Usage : \n";
echo $argv[0]." DSN username password outputfile.jpg\n";
echo "DSN Examples : 'mysql:dbname=databaseName'\n";
}
if (! isset ($argv[1]))
die ("No DSN provided\n");
if (! isset ($argv[2]))
die ("No username provided\n");
if (! isset ($argv[3]))
die ("No password provided\n");
if (! isset ($argv[4]))
die ("No output file provided\n");
$modelgraph = new modelgraph ($argv[1], $argv[2], $argv[3], $argv[4]);
$modelgraph->generate ();