#!/usr/bin/php */ 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 .= "\n"; // Display the name of the table as title $d .= " \n"; // Display the fields $i = 0; foreach ($schema["fields"] as $field => $params) { $d .= " \n"; $d .= "\n"; $d .= "\n"; $d .= "\n"; $d .= "\n"; $i++; } $d .= "
"; $d .= "$table
"; if (key_exists ($field, $schema["foreign"])) { // Foreign Key $d .= "!"; } elseif (key_exists ("primary", $schema) && $field === $schema["primary"]) $d .= "🔑"; // Primary key found elseif (in_array ("not null", $params)) $d .= ""; // NOT NULL else $d .= "◇"; $d .= ""; $d .= $field; $d .= ""; $d .= $params[0]; $d .= "
>\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 ();