From 22276c273cc158cf12fd7b63e581b08cdae7b6f1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 30 Nov 2013 02:58:02 -0500 Subject: Adding Many To Many relationships support! --- framework/Wsat/TWsatARGenerator.php | 457 +++++++++++++++------------- framework/Wsat/TWsatService.php | 69 +++-- framework/Wsat/pages/TWsatGenerateAR.php | 77 +++-- framework/Wsat/pages/TWsatHome.php | 2 +- framework/Wsat/pages/TWsatLogin.php | 36 +-- framework/Wsat/pages/layout/TWsatLayout.php | 68 +++-- 6 files changed, 372 insertions(+), 337 deletions(-) (limited to 'framework/Wsat') diff --git a/framework/Wsat/TWsatARGenerator.php b/framework/Wsat/TWsatARGenerator.php index a4846306..5c812ef5 100644 --- a/framework/Wsat/TWsatARGenerator.php +++ b/framework/Wsat/TWsatARGenerator.php @@ -12,244 +12,277 @@ class TWsatARGenerator { - /** - * Gets the current Db connection, the connection object is obtained from - * the TActiveRecordManager if connection is currently null. - * @return TDbConnection current db connection for this object. - */ - private $_conn; - - /** - * @return TActiveRecordGateway record table gateway. - */ - private $_gateway; - - /** - * Output folder where AR classes will be generated. - */ - private $_op_file; - - /** - * Class name prefix - */ - private $_clas_prefix; - - /** - * Class name sufix - */ - private $_class_sufix; - - /** - * all table relations array - */ - private $_relations; - - /** - * unquote chars - * @var array - */ - private $uq_chars = array('[', ']', '"', '`', "'"); - - function __construct() - { - $ar_manager = TActiveRecordManager::getInstance(); - $this->_conn = $ar_manager->getDbConnection(); - $this->_conn->Active = true; - $this->_gateway = $ar_manager->getRecordGateway(); - } - - /** - * Destructor. - * Disconnect the db connection. - */ - public function __destruct() - { - if ($this->_conn !== null) - $this->_conn->Active = false; - } - - public function setOpFile($op_file_namespace) - { - $op_file = Prado::getPathOfNamespace($op_file_namespace); - if (empty($op_file)) - throw new Exception("You need to fix your output folder namespace."); - if (!is_dir($op_file)) - mkdir($op_file, 0777, true); - $this->_op_file = $op_file; - } - - public function setClasPrefix($_clas_prefix) - { - $this->_clas_prefix = $_clas_prefix; - } - - public function setClassSufix($_clas_sufix) - { - $this->_class_sufix = $_clas_sufix; - } + /** + * Gets the current Db connection, the connection object is obtained from + * the TActiveRecordManager if connection is currently null. + * @return TDbConnection current db connection for this object. + */ + private $_conn; + + /** + * @return TActiveRecordGateway record table gateway. + */ + private $_gateway; + + /** + * Output folder where AR classes will be generated. + */ + private $_op_file; + + /** + * Class name prefix + */ + private $_clas_prefix; + + /** + * Class name sufix + */ + private $_class_sufix; + + /** + * all table relations array + */ + private $_relations; + + /** + * unquote chars + * @var array + */ + private $uq_chars = array('[', ']', '"', '`', "'"); + + function __construct() + { + $ar_manager = TActiveRecordManager::getInstance(); + $this->_conn = $ar_manager->getDbConnection(); + $this->_conn->Active = true; + $this->_gateway = $ar_manager->getRecordGateway(); + } -//----------------------------------------------------------------------------- - // - public function generate($tableName) - { - $tableInfo = $this->_gateway->getTableInfo($this->_conn, $tableName); - if (count($tableInfo->getColumns()) === 0) + /** + * Destructor. + * Disconnect the db connection. + */ + public function __destruct() + { + if ($this->_conn !== null) + $this->_conn->Active = false; + } + + public function setOpFile($op_file_namespace) { - throw new Exception("Unable to find table or view $tableName in " . $this->_conn->getConnectionString() . "."); - } else + $op_file = Prado::getPathOfNamespace($op_file_namespace); + if (empty($op_file)) + throw new Exception("You need to fix your output folder namespace."); + if (!is_dir($op_file)) + mkdir($op_file, 0777, true); + $this->_op_file = $op_file; + } + + public function setClasPrefix($_clas_prefix) + { + $this->_clas_prefix = $_clas_prefix; + } + + public function setClassSufix($_clas_sufix) { - $properties = array(); - foreach ($tableInfo->getColumns() as $field => $column) - $properties[] = $this->generateProperty($field, $column); - $toString = $this->_buildSmartToString($tableInfo); + $this->_class_sufix = $_clas_sufix; } - $clasName = $this->_getProperClassName($tableName); - $class = $this->generateClass($properties, $tableName, $clasName, $toString); - $output = $this->_op_file . DIRECTORY_SEPARATOR . $clasName . ".php"; - file_put_contents($output, $class); - } +//----------------------------------------------------------------------------- + // + public function generate($tableName) + { + $tableInfo = $this->_gateway->getTableInfo($this->_conn, $tableName); + $this->_commonGenerate($tableName, $tableInfo); + } - public function generateAll() - { - foreach ($this->_getAllTableNames() as $tableName) + public function generateAll() { - if ($tableName == "pradocache") - { - continue; - } - $this->generate($tableName); + foreach ($this->_getAllTableNames() as $tableName) + { + if ($tableName == "pradocache") + continue; + $tableInfo = $this->_gateway->getTableInfo($this->_conn, $tableName); + if (!empty($this->_relations)) + { + // Cancel generation of M-M relationships middle table + if (count($tableInfo->getPrimaryKeys()) === 2 && count($tableInfo->getColumns()) === 2)//M-M relationships + continue; + } + $this->_commonGenerate($tableName, $tableInfo); + } } - } - public function buildRelations() - { - $this->_relations = array(); - foreach ($this->_getAllTableNames() as $table_name) + public function buildRelations() { - $tableInfo = $this->_gateway->getTableInfo($this->_conn, $table_name); - foreach ($tableInfo->getForeignKeys() as $fk_data) - { - $owner_table = $fk_data["table"]; - $slave_table = $table_name; - $fk_prop = key($fk_data["keys"]); - - $this->_relations[$owner_table][] = array( - "prop_name" => strtolower($slave_table), - "rel_type" => "self::HAS_MANY", - "ref_class_name" => $this->_getProperClassName($slave_table), - "prop_ref" => $fk_prop - ); - - $this->_relations[$slave_table][] = array( - "prop_name" => strtolower($owner_table), - "rel_type" => "self::BELONGS_TO", - "ref_class_name" => $this->_getProperClassName($owner_table), - "prop_ref" => $fk_prop - ); - } + $this->_relations = array(); + foreach ($this->_getAllTableNames() as $table_name) + { + $tableInfo = $this->_gateway->getTableInfo($this->_conn, $table_name); + $pks = $tableInfo->getPrimaryKeys(); + $fks = $tableInfo->getForeignKeys(); + + if (count($pks) === 2 && count($tableInfo->getColumns()) === 2)//M-M relationships + { + $table_name_mm = $fks[0]["table"]; + $table_name_mm2 = $fks[1]["table"]; + + $this->_relations[$table_name_mm][] = array( + "prop_name" => strtolower($table_name_mm2), + "rel_type" => "self::MANY_TO_MANY", + "ref_class_name" => $this->_getProperClassName($table_name_mm2), + "prop_ref" => $table_name + ); + + $this->_relations[$table_name_mm2][] = array( + "prop_name" => strtolower($table_name_mm), + "rel_type" => "self::MANY_TO_MANY", + "ref_class_name" => $this->_getProperClassName($table_name_mm), + "prop_ref" => $table_name + ); + continue; + } + foreach ($fks as $fk_data)//1-M relationships + { + $owner_table = $fk_data["table"]; + $slave_table = $table_name; + $fk_prop = key($fk_data["keys"]); + + $this->_relations[$owner_table][] = array( + "prop_name" => strtolower($slave_table), + "rel_type" => "self::HAS_MANY", + "ref_class_name" => $this->_getProperClassName($slave_table), + "prop_ref" => $fk_prop + ); + + $this->_relations[$slave_table][] = array( + "prop_name" => strtolower($owner_table), + "rel_type" => "self::BELONGS_TO", + "ref_class_name" => $this->_getProperClassName($owner_table), + "prop_ref" => $fk_prop + ); + } + } } - } // //----------------------------------------------------------------------------- - // - - private function _getAllTableNames() - { - $command = $this->_conn->createCommand("Show Tables"); - $dataReader = $command->query(); - $dataReader->bindColumn(1, $table); - $tables = array(); - while ($dataReader->read()) - $tables[] = $table; - return $tables; - } - - private function _getProperClassName($tableName) - { - $table_name_words = str_replace("_", " ", strtolower($tableName)); - $final_conversion = str_replace(" ", "", ucwords($table_name_words)); - return $this->_clas_prefix . $final_conversion . $this->_class_sufix; - } - - public function renderAllTablesInformation() - { - foreach ($this->_getAllTableNames() as $table_name) + // + + private function _commonGenerate($tableName, $tableInfo) { - echo $table_name . "
"; + if (count($tableInfo->getColumns()) === 0) + throw new Exception("Unable to find table or view $tableName in " . $this->_conn->getConnectionString() . "."); + else + { + $properties = array(); + foreach ($tableInfo->getColumns() as $field => $column) + $properties[] = $this->generateProperty($field, $column); + $toString = $this->_buildSmartToString($tableInfo); + } - $tableInfo = $this->_gateway->getTableInfo($this->_conn, $table_name); - echo "Table info:" . "
"; - echo "
";
-            var_dump($tableInfo);
-            echo "
"; + $clasName = $this->_getProperClassName($tableName); + $class = $this->generateClass($properties, $tableName, $clasName, $toString); + $output = $this->_op_file . DIRECTORY_SEPARATOR . $clasName . ".php"; + file_put_contents($output, $class); } - } -//----------------------------------------------------------------------------- + private function _getAllTableNames() + { + $command = $this->_conn->createCommand("Show Tables"); + $dataReader = $command->query(); + $dataReader->bindColumn(1, $table); + $tables = array(); + while ($dataReader->read()) + $tables[] = $table; + return $tables; + } - protected function generateProperty($field, $column) - { - $prop = ''; - $name = '$' . $field; - - /* TODO use in version 2.0 */ - // $type = $column->getPHPType(); - - $prop .= "\tpublic $name;"; - return $prop; - } - - private function _renderRelations($tablename) - { - if (!isset($this->_relations[$tablename])) - return ""; - - $code = "\tpublic static \$RELATIONS = array ("; - foreach ($this->_relations[$tablename] as $rel_data) - $code .= "\n\t\t'" . $rel_data["prop_name"] . "' => array(" . $rel_data["rel_type"] . ", '" . $rel_data["ref_class_name"] . "', '" . $rel_data["prop_ref"] . "'),"; - - $code = substr($code, 0, -1); - $code .= "\n\t);"; - return $code; - } - - private function _buildSmartToString($tableInfo) - { - $code = "\tpublic function __toString() {"; - $property = "throw new THttpException(500, 'Not implemented yet.');"; - try + private function _getProperClassName($tableName) { - foreach ($tableInfo->getColumns() as $column) - { - if (isset($column->IsPrimaryKey) && $column->IsPrimaryKey) - $property = str_replace($this->uq_chars, "", $column->ColumnName); - elseif ($column->PHPType == "string" && $column->DBType != "date") + $table_name_words = str_replace("_", " ", strtolower($tableName)); + $final_conversion = str_replace(" ", "", ucwords($table_name_words)); + return $this->_clas_prefix . $final_conversion . $this->_class_sufix; + } + + public function renderAllTablesInformation() + { + foreach ($this->_getAllTableNames() as $table_name) { - $property = str_replace($this->uq_chars, "", $column->ColumnName); - break; + echo $table_name . "
"; + + $tableInfo = $this->_gateway->getTableInfo($this->_conn, $table_name); + echo "Table info:" . "
"; + echo "
";
+                        var_dump($tableInfo);
+                        echo "
"; } - } - } catch (Exception $ex) + } + +//----------------------------------------------------------------------------- + + protected function generateProperty($field, $column) + { + $prop = ''; + $name = '$' . $field; + + /* TODO use in version 2.0 */ + // $type = $column->getPHPType(); + + $prop .= "\tpublic $name;"; + return $prop; + } + + private function _renderRelations($tablename) + { + if (!isset($this->_relations[$tablename])) + return ""; + + $code = "\tpublic static \$RELATIONS = array ("; + foreach ($this->_relations[$tablename] as $rel_data) + $code .= "\n\t\t'" . $rel_data["prop_name"] . "' => array(" . $rel_data["rel_type"] . ", '" . $rel_data["ref_class_name"] . "', '" . $rel_data["prop_ref"] . "'),"; + + $code = substr($code, 0, -1); + $code .= "\n\t);"; + return $code; + } + + private function _buildSmartToString($tableInfo) { - Prado::trace($ex->getMessage()); + $code = "\tpublic function __toString() {"; + $property = "throw new THttpException(500, 'Not implemented yet.');"; + try + { + foreach ($tableInfo->getColumns() as $column) + { + if (isset($column->IsPrimaryKey) && $column->IsPrimaryKey) + $property = str_replace($this->uq_chars, "", $column->ColumnName); + elseif ($column->PHPType == "string" && $column->DBType != "date") + { + $property = str_replace($this->uq_chars, "", $column->ColumnName); + break; + } + } + } catch (Exception $ex) + { + Prado::trace($ex->getMessage()); + } + $code .= "\n\t\treturn \$this->$property;"; + $code .= "\n\t}"; + return $code; } - $code .= "\n\t\treturn \$this->$property;"; - $code .= "\n\t}"; - return $code; - } - - protected function generateClass($properties, $tablename, $classname, $toString) - { - $props = implode("\n", $properties); - $relations = $this->_renderRelations($tablename); - $date = date('Y-m-d h:i:s'); - return <<_renderRelations($tablename); + $date = date('Y-m-d h:i:s'); + $env_user = getenv("username"); + return << } \ No newline at end of file diff --git a/framework/Wsat/TWsatService.php b/framework/Wsat/TWsatService.php index 5aa86dbd..85b062e5 100644 --- a/framework/Wsat/TWsatService.php +++ b/framework/Wsat/TWsatService.php @@ -36,47 +36,46 @@ class TWsatService extends TPageService { - private $_pass = ''; + private $_pass = ''; + + public function init($config) + { + if ($this->getApplication()->getMode() === TApplicationMode::Performance || $this->getApplication()->getMode() === TApplicationMode::Normal) + throw new TInvalidOperationException("You should not use Prado WSAT in any of the production modes."); -//----------------------------------------------------------------------------- - public function init($config) - { - if ($this->getApplication()->getMode() === TApplicationMode::Performance || $this->getApplication()->getMode() === TApplicationMode::Normal) - throw new TInvalidOperationException("You should not use Prado WSAT in any of the production modes."); + if (empty($this->_pass)) + throw new TConfigurationException("You need to specify the Password attribute."); - if (empty($this->_pass)) - throw new TConfigurationException("You need to specify the Password attribute."); + $this->setDefaultPage("TWsatHome"); + $this->_startThemeManager(); + parent::init($config); + } - $this->setDefaultPage("TWsatHome"); - $this->_startThemeManager(); - parent::init($config); - } + public function getBasePath() + { + $basePath = Prado::getPathOfNamespace("System.Wsat.pages"); + return realpath($basePath); + } - public function getBasePath() - { - $basePath = Prado::getPathOfNamespace("System.Wsat.pages"); - return realpath($basePath); - } + private function _startThemeManager() + { + $themeManager = new TThemeManager; + $themeManager->BasePath = "System.Wsat.themes"; + $url = Prado::getApplication()->getAssetManager()->publishFilePath(Prado::getPathOfNamespace('System.Wsat')); + $themeManager->BaseUrl = $url . "/themes"; - private function _startThemeManager() - { - $themeManager = new TThemeManager; - $themeManager->BasePath = "System.Wsat.themes"; - $url = Prado::getApplication()->getAssetManager()->publishFilePath(Prado::getPathOfNamespace('System.Wsat')); - $themeManager->BaseUrl = $url . "/themes"; + $themeManager->init(null); + $this->setThemeManager($themeManager); + } - $themeManager->init(null); - $this->setThemeManager($themeManager); - } + public function getPassword() + { + return $this->_pass; + } - public function getPassword() - { - return $this->_pass; - } - - public function setPassword($_pass) - { - $this->_pass = $_pass; - } + public function setPassword($_pass) + { + $this->_pass = $_pass; + } } \ No newline at end of file diff --git a/framework/Wsat/pages/TWsatGenerateAR.php b/framework/Wsat/pages/TWsatGenerateAR.php index 14e14983..c9584038 100644 --- a/framework/Wsat/pages/TWsatGenerateAR.php +++ b/framework/Wsat/pages/TWsatGenerateAR.php @@ -14,49 +14,46 @@ Prado::using("System.Wsat.TWsatARGenerator"); class TWsatGenerateAR extends TPage { - public function generate($sender) - { - if ($this->IsValid) + public function generate($sender) { - $table_name = $this->table_name->Text; - $output_folder_ns = $this->output_folder->Text; - $class_prefix = $this->class_prefix->Text; - $class_sufix = $this->class_sufix->Text; - - try - { - $ar_generator = new TWsatARGenerator(); - $ar_generator->setOpFile($output_folder_ns); - $ar_generator->setClasPrefix($class_prefix); - $ar_generator->setClassSufix($class_sufix); - - if ($this->build_rel->Checked) + if ($this->IsValid) { - $ar_generator->buildRelations(); - } - if ($table_name != "*") - { - $ar_generator->generate($table_name); - } else - { - $ar_generator->generateAll(); + $table_name = $this->table_name->Text; + $output_folder_ns = $this->output_folder->Text; + $class_prefix = $this->class_prefix->Text; + $class_sufix = $this->class_sufix->Text; + + try + { + $ar_generator = new TWsatARGenerator(); + $ar_generator->setOpFile($output_folder_ns); + $ar_generator->setClasPrefix($class_prefix); + $ar_generator->setClassSufix($class_sufix); + + if ($this->build_rel->Checked) + $ar_generator->buildRelations(); + + if ($table_name != "*") + $ar_generator->generate($table_name); + else + $ar_generator->generateAll(); + + $this->feedback_panel->CssClass = "green_panel"; + $this->generation_msg->Text = "The code has been generated successfully."; + } catch (Exception $ex) + { + $this->feedback_panel->CssClass = "red_panel"; + $this->generation_msg->Text = $ex->getMessage(); + } + $this->feedback_panel->Visible = true; } - $this->feedback_panel->CssClass = "green_panel"; - $this->generation_msg->Text = "The code has been generated successfully."; - } catch (Exception $ex) - { - $this->feedback_panel->CssClass = "red_panel"; - $this->generation_msg->Text = $ex->getMessage(); - } - $this->feedback_panel->Visible = true; } - } - - public function preview($sender) - { -// $ar_generator = new TWsatARGenerator(); -// $ar_generator->renderAllTablesInformation(); - throw new THttpException(500, "Not implemented yet."); - } + + public function preview($sender) + { +// $ar_generator = new TWsatARGenerator(); +// $ar_generator->renderAllTablesInformation(); + throw new THttpException(500, "Not implemented yet."); + } } \ No newline at end of file diff --git a/framework/Wsat/pages/TWsatHome.php b/framework/Wsat/pages/TWsatHome.php index c5291ed7..b5ae1bb4 100644 --- a/framework/Wsat/pages/TWsatHome.php +++ b/framework/Wsat/pages/TWsatHome.php @@ -13,5 +13,5 @@ Prado::using("System.Wsat.TWsatARGenerator"); class TWsatHome extends TPage { - + } \ No newline at end of file diff --git a/framework/Wsat/pages/TWsatLogin.php b/framework/Wsat/pages/TWsatLogin.php index 4b3ba0c1..02d5c9fd 100644 --- a/framework/Wsat/pages/TWsatLogin.php +++ b/framework/Wsat/pages/TWsatLogin.php @@ -12,27 +12,27 @@ class TWsatLogin extends TPage { - public function login() - { - if ($this->IsValid) + public function login() { - $this->Session["wsat_password"] = $this->getService()->getPassword(); + if ($this->IsValid) + { + $this->Session["wsat_password"] = $this->getService()->getPassword(); - $authManager = $this->Application->getModule('auth'); - $url = $authManager->ReturnUrl; - if (empty($url)) - { - $url = $this->Service->constructUrl('TWsatHome'); - } - $this->Response->redirect($url); + $authManager = $this->Application->getModule('auth'); + $url = $authManager->ReturnUrl; + if (empty($url)) + { + $url = $this->Service->constructUrl('TWsatHome'); + } + $this->Response->redirect($url); + } } - } - public function validatePassword($sender, $param) - { - $config_pass = $this->getService()->getPassword(); - $user_pass = $this->password->Text; - $param->IsValid = $user_pass === $config_pass; - } + public function validatePassword($sender, $param) + { + $config_pass = $this->getService()->getPassword(); + $user_pass = $this->password->Text; + $param->IsValid = $user_pass === $config_pass; + } } \ No newline at end of file diff --git a/framework/Wsat/pages/layout/TWsatLayout.php b/framework/Wsat/pages/layout/TWsatLayout.php index e799125b..4a7c578c 100644 --- a/framework/Wsat/pages/layout/TWsatLayout.php +++ b/framework/Wsat/pages/layout/TWsatLayout.php @@ -1,32 +1,38 @@ -validateSecurity(); - } - - private function validateSecurity() { - if ($this->Session["wsat_password"] !== $this->getService()->getPassword()) { - if (!$this->getPage() instanceof TWsatLogin) { - $url = $this->Service->constructUrl('TWsatLogin'); - $this->Response->redirect($url); - } - } - } - - public function logout() { - $this->Session["wsat_password"] = ""; - $url = $this->Service->constructUrl('TWsatLogin'); - $this->Response->redirect($url); - } - -} - +validateSecurity(); + } + + private function validateSecurity() + { + if ($this->Session["wsat_password"] !== $this->getService()->getPassword()) + { + if (!$this->getPage() instanceof TWsatLogin) + { + $url = $this->Service->constructUrl('TWsatLogin'); + $this->Response->redirect($url); + } + } + } + + public function logout() + { + $this->Session["wsat_password"] = ""; + $url = $this->Service->constructUrl('TWsatLogin'); + $this->Response->redirect($url); + } + +} + ?> \ No newline at end of file -- cgit v1.2.3