From 8c294ababa55cc4d1d2ead16cc7262068a72e687 Mon Sep 17 00:00:00 2001 From: jhassine Date: Sun, 27 Aug 2006 02:21:20 +0000 Subject: [PATCH] * Added some test cases for the importing part. The new tests will fail for now because of the lacking implementation. Refs #11 --- Doctrine/DataDict.php | 19 +++- Doctrine/Import.php | 90 +++++++++++++++++ Doctrine/Import/Builder.php | 60 +++++++++++ Doctrine/Import/Builder/BaseClass.php | 83 ++++++++++++++++ Doctrine/Import/Builder/Exception.php | 50 ++++++++++ Doctrine/Import/Reader.php | 60 +++++++++++ Doctrine/Import/Reader/Db.php | 75 ++++++++++++++ Doctrine/Import/Reader/Exception.php | 50 ++++++++++ Doctrine/Import/Reader/Propel.php | 64 ++++++++++++ Doctrine/Schema.php | 2 +- Doctrine/Schema/Database.php | 2 +- Doctrine/Schema/Table.php | 2 +- tests/ImportTestCase.php | 137 ++++++++++++++++++++++++-- 13 files changed, 684 insertions(+), 10 deletions(-) create mode 100644 Doctrine/Import.php create mode 100644 Doctrine/Import/Builder.php create mode 100644 Doctrine/Import/Builder/BaseClass.php create mode 100644 Doctrine/Import/Builder/Exception.php create mode 100644 Doctrine/Import/Reader.php create mode 100644 Doctrine/Import/Reader/Db.php create mode 100644 Doctrine/Import/Reader/Exception.php create mode 100644 Doctrine/Import/Reader/Propel.php diff --git a/Doctrine/DataDict.php b/Doctrine/DataDict.php index 1cbe25b59..5bb1fcacb 100644 --- a/Doctrine/DataDict.php +++ b/Doctrine/DataDict.php @@ -109,6 +109,23 @@ class Doctrine_DataDict { throw new Doctrine_Exception("Unknown column type $type"); endswitch; } + + /** + * Converts native database column type to doctrine data type + * + * @param string $column column type + * @param integer $length column length + * @param string $dbType Database driver name as returned by PDO::getAttribute(PDO::ATTR_DRIVER_NAME) + * @param string $dbVersion Database server version as return by PDO::getAttribute(PDO::ATTR_SERVER_VERSION) + * @return array of doctrine column type and column length. In future may also return a validator name. + * @throws Doctrine_Exception on unknown column type + * @author Jukka Hassinen + */ + public static function getDoctrineType($colType,$colLength, $dbType = null, $dbVersion = null) + { + return array($colType, $colLength); /* @todo FIXME i am incomplete*/ + } + /** * checks for valid class name (uses camel case and underscores) * @@ -121,4 +138,4 @@ class Doctrine_DataDict { return true; } } -?> + diff --git a/Doctrine/Import.php b/Doctrine/Import.php new file mode 100644 index 000000000..97cd65b28 --- /dev/null +++ b/Doctrine/Import.php @@ -0,0 +1,90 @@ +. + */ + +/** + * @package Doctrine + * @url http://www.phpdoctrine.com + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Jukka Hassinen + * @version $Id$ + */ + + + +/** + * class Doctrine_Import + * Main responsible of performing import operation. Delegates database schema + * reading to a reader object and passes the result to a builder object which + * builds a Doctrine data model. + */ +class Doctrine_Import +{ + + /** Aggregations: */ + + /** Compositions: */ + + /*** Attributes: ***/ + + /** + * @access private + */ + private $reader; + + /** + * @access private + */ + private $builder; + + + /** + * + * @return + * @access public + */ + public function import( ) { + + } // end of member function import + + /** + * + * @param Doctrine_Import_Reader reader * @return + * @access public + */ + public function setReader( $reader ) { + + } // end of member function setReader + + /** + * + * @param Doctrine_Import_Builder builder * @return + * @access public + */ + public function setBuilder( $builder ) { + + } // end of member function setBuilder + + + + + +} // end of Doctrine_Import +?> diff --git a/Doctrine/Import/Builder.php b/Doctrine/Import/Builder.php new file mode 100644 index 000000000..a43e7de34 --- /dev/null +++ b/Doctrine/Import/Builder.php @@ -0,0 +1,60 @@ +. + */ + +/** + * @package Doctrine + * @url http://www.phpdoctrine.com + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Jukka Hassinen + * @version $Id$ + */ + + + +/** + * class Doctrine_Import_Builder + * Is responsible of building Doctrine structure based on a database schema. + */ +abstract class Doctrine_Import_Builder +{ + + /** Aggregations: */ + + /** Compositions: */ + + /*** Attributes: ***/ + + + /** + * + * @param Doctrine_Schema schema + * @return + * @abstract + * @access public + */ + abstract public function build(Doctrine_Schema $schema ); + + + + + +} // end of Doctrine_Import_Builder +?> diff --git a/Doctrine/Import/Builder/BaseClass.php b/Doctrine/Import/Builder/BaseClass.php new file mode 100644 index 000000000..4c42a89de --- /dev/null +++ b/Doctrine/Import/Builder/BaseClass.php @@ -0,0 +1,83 @@ +. + */ + +/** + * @package Doctrine + * @url http://www.phpdoctrine.com + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Jukka Hassinen + * @version $Id$ + */ + + + +/** + * class Doctrine_Import_Builder_BaseClass + * Builds a Doctrine_Record base class definition based on a schema. + */ +class Doctrine_Import_Builder_BaseClass extends Doctrine_Import_Builder +{ + + /** Aggregations: */ + + /** Compositions: */ + + /*** Attributes: ***/ + + private $path = ''; + private $suffix = '.php'; + + + /** + * + * @param string path + * @return + * @access public + */ + public function setOutputPath( $path ) { + $this->path = $path; + } // end of member function setOuputPath + + /** + * + * @param string path + * @return + * @access public + */ + public function setFileSuffix( $suffix ) { + $this->suffix = $suffix; + } // end of member function setOuputPath + + + /** + * + * @param Doctrine_Schema schema + * @return + * @access public + * @throws Doctrine_Import_Exception + */ + public function build(Doctrine_Schema $schema ) + { + /* @todo FIXME i am incomplete*/ + } + +} // end of Doctrine_Import_Builder_BaseClass + diff --git a/Doctrine/Import/Builder/Exception.php b/Doctrine/Import/Builder/Exception.php new file mode 100644 index 000000000..a5a77b662 --- /dev/null +++ b/Doctrine/Import/Builder/Exception.php @@ -0,0 +1,50 @@ +. + */ + +/** + * @package Doctrine + * @url http://www.phpdoctrine.com + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Jukka Hassinen + * @version $Id$ + */ + + + +/** + * class Doctrine_Import_Builder_Exception + */ +class Doctrine_Import_Builder_Exception +{ + + /** Aggregations: */ + + /** Compositions: */ + + /*** Attributes: ***/ + + + + + + +} // end of Doctrine_Import_Builder_Exception +?> diff --git a/Doctrine/Import/Reader.php b/Doctrine/Import/Reader.php new file mode 100644 index 000000000..409eb0d3a --- /dev/null +++ b/Doctrine/Import/Reader.php @@ -0,0 +1,60 @@ +. + */ + +/** + * @package Doctrine + * @url http://www.phpdoctrine.com + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Jukka Hassinen + * @version $Id$ + */ + + + +/** + * class Doctrine_Import_Reader + * Is responsible of reading a database definitions from a source and costructing a + * database schema + */ +abstract class Doctrine_Import_Reader +{ + + /** Aggregations: */ + + /** Compositions: */ + + /*** Attributes: ***/ + + + /** + * + * @return Doctrine_Schema + * @abstract + * @access public + */ + abstract public function read( ); + + + + + +} // end of Doctrine_Import_Reader +?> diff --git a/Doctrine/Import/Reader/Db.php b/Doctrine/Import/Reader/Db.php new file mode 100644 index 000000000..c7f27bcbc --- /dev/null +++ b/Doctrine/Import/Reader/Db.php @@ -0,0 +1,75 @@ +. + */ + +/** + * @package Doctrine + * @url http://www.phpdoctrine.com + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Jukka Hassinen + * @version $Id$ + */ + + + +/** + * class Doctrine_Import_Reader_Db + * Reads a database using the given PDO connection and constructs a database + * schema + */ +class Doctrine_Import_Reader_Db extends Doctrine_Import_Reader +{ + + /** Aggregations: */ + + /** Compositions: */ + + /*** Attributes: ***/ + + /** + * @access private + */ + private $pdo; + + + /** + * + * @param object pdo * @return + * @access public + */ + public function setPdo( $pdo ) { + + } // end of member function setPdo + + + /** + * + * @return Doctrine_Schema + * @access public + */ + public function read( ) + { + return new Doctrine_Schema(); /* @todo FIXME i am incomplete*/ + } + + + +} // end of Doctrine_Import_Reader_Db +?> diff --git a/Doctrine/Import/Reader/Exception.php b/Doctrine/Import/Reader/Exception.php new file mode 100644 index 000000000..55d5cb6f8 --- /dev/null +++ b/Doctrine/Import/Reader/Exception.php @@ -0,0 +1,50 @@ +. + */ + +/** + * @package Doctrine + * @url http://www.phpdoctrine.com + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Jukka Hassinen + * @version $Id$ + */ + + + +/** + * class Doctrine_Import_Reader_Exception + */ +class Doctrine_Import_Reader_Exception +{ + + /** Aggregations: */ + + /** Compositions: */ + + /*** Attributes: ***/ + + + + + + +} // end of Doctrine_Import_Reader_Exception +?> diff --git a/Doctrine/Import/Reader/Propel.php b/Doctrine/Import/Reader/Propel.php new file mode 100644 index 000000000..655f3596f --- /dev/null +++ b/Doctrine/Import/Reader/Propel.php @@ -0,0 +1,64 @@ +. + */ + +/** + * @package Doctrine + * @url http://www.phpdoctrine.com + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Jukka Hassinen + * @version $Id$ + */ + + + +/** + * class Doctrine_Import_Reader_Xml_Propel + */ +class Doctrine_Import_Reader_Xml_Propel extends Doctrine_Import_Reader +{ + + /** Aggregations: */ + + /** Compositions: */ + + /*** Attributes: ***/ + + /** + * @access private + */ + private $xml; + + + /** + * + * @param string xml * @return + * @access public + */ + public function setXml( $xml ) { + + } // end of member function setXml + + + + + +} // end of Doctrine_Import_Reader_Xml_Propel +?> diff --git a/Doctrine/Schema.php b/Doctrine/Schema.php index 66491eb54..423ecbafc 100644 --- a/Doctrine/Schema.php +++ b/Doctrine/Schema.php @@ -82,4 +82,4 @@ class Doctrine_Schema extends Doctrine_Schema_Object } // end of Doctrine_Schema -?> + diff --git a/Doctrine/Schema/Database.php b/Doctrine/Schema/Database.php index 8c0c7764f..43a5a3287 100644 --- a/Doctrine/Schema/Database.php +++ b/Doctrine/Schema/Database.php @@ -128,4 +128,4 @@ class Doctrine_Schema_Database extends Doctrine_Schema_Object } // end of Doctrine_Schema_Database -?> + diff --git a/Doctrine/Schema/Table.php b/Doctrine/Schema/Table.php index aec7bf689..6b93db0de 100644 --- a/Doctrine/Schema/Table.php +++ b/Doctrine/Schema/Table.php @@ -134,4 +134,4 @@ class Doctrine_Schema_Table extends Doctrine_Schema_Object } // end of Doctrine_Schema_Table -?> + diff --git a/tests/ImportTestCase.php b/tests/ImportTestCase.php index 44aace5bd..f08ff3d77 100644 --- a/tests/ImportTestCase.php +++ b/tests/ImportTestCase.php @@ -1,25 +1,150 @@ * @version $Id$ - * @package doctrine + * @package Doctrine */ class Doctrine_ImportTestCase extends Doctrine_UnitTestCase { - function testDatabaseConnectionIsReverseEngineeredToSchema() + private $tmpdir; + + private $suffix; + + private $schema; + + public function setUp() { + parent::setUp(); + + //reading + $reader = new Doctrine_Import_Reader_Db(); + $reader->setPdo($this->dbh); + $this->schema = $reader->read(); + + //and building + $this->tmpdir = $this->getTempDir(); + $this->suffix = '__Base'; + + $builder = new Doctrine_Import_Builder_BaseClass(); + $builder->setOutputPath($this->tmpdir); + $builder->setFileSuffix($this->suffix.'.php'); + $builder->build($this->schema); + } + + public function testDatabaseConnectionIsReverseEngineeredToSchema() + { + + $this->assertTrue($this->schema instanceof Doctrine_Schema); + //table count should match + $this->assertEqual(count($this->schema), count($this->tables)); + } - function testNativeColumnDefinitionsAreTranslatedCorrectly() - { + public function testBaseClassesAreWritten() + { + //now lets match the original with the result + foreach($this->tables as $name) + { + $name = ucwords($name); + $filename = $this->tmpdir.$name.$this->suffix.'.php'; + $this->assertTrue(file_exists($filename)); + } + } + + + public function testNativeColumnDefinitionsAreTranslatedCorrectly() + { + $transArr = array(); + + /* From SQLite column types */ + $transArr['sqlite'] = array( + /* array(native type, native length, doctrine type, doctrine length), */ + array('int', 11, 'int', 11), + //array('varchar', 255, 'string', 255), + ); + + + foreach ($transArr as $dbType => $colArr) + { + foreach($colArr as $colDef) + { + list($natType, $natLen, $expType, $expLen) = $colDef; + list($resType, $resLen) = Doctrine_DataDict::getDoctrineType($natType, $natLen, $dbType); + $this->assertEqual($resType, $expType); + $this->assertEqual($resLen, $expLen); + } + } } - function testDoctrineRecordBaseClassesAreBuildCorrectlyAndToPath() + public function testDoctrineRecordBaseClassesAreBuildCorrectly() { - + foreach($this->tables as $name) + { + $name = ucwords($name); + $filename = $this->tmpdir.$name.$this->suffix.'.php'; + if(file_exists($filename)) + { + require_once $filename; + $obj = new $name.$this->suffix; + + list($oType, $oLength,) = $this->connection->getTable($name)->getColumns(); + list($rType, $rLength,) = $this->connection->getTable($name.$this->suffix)->getColumns(); + + $this->assertEquals($rType, $oType); + $this->assertEquals($rLength, $oLength); + } + } } + + public function tearDown() + { + @unlink($this->tmpdir); + @rmdir($this->tmpdir); + } + + + /** + * Gets the system temporary directory name + * @return null on failure to resolve the system temp dir + */ + private function getTempDir() + { + if(function_exists('sys_get_temp_dir')) { + $tempdir = sys_get_temp_dir(); + } elseif (!empty($_ENV['TMP'])) { + $tempdir = $_ENV['TMP']; + } elseif (!empty($_ENV['TMPDIR'])) { + $tempdir = $_ENV['TMPDIR']; + } elseif (!empty($_ENV['TEMP'])) { + $tempdir = $_ENV['TEMP']; + } else { + //a little bit of chewing gum here will do the trick + $tempdir = dirname(tempnam('/THIS_REALLY_SHOULD_NOT_EXISTS', 'na')); + } + + if (empty($tempdir)) { return null; } + + $tempdir = rtrim($tempdir, '/'); + $tempdir .= DIRECTORY_SEPARATOR; + + if (is_writable($tempdir) == false) { + return null; + } + $dir = tempnam($tempdir, 'doctrine_tests'); + + @unlink($dir); + @rmdir($dir); + + mkdir($dir); + $dir .= DIRECTORY_SEPARATOR; + + return $dir; + } } \ No newline at end of file