array( "namespace" => 'App\Dbo', "folder" => '../app/Dbo' ), "sp" => array( "namespace" => 'App\DataAccess\SP', "folder" => '../app/DataAccess/SP' ), "dataaccess" => array( "namespace" => 'App\DataAccess', "folder" => '../app/DataAccess' ), "business" => array( "namespace" => 'App\Business', "folder" => '../app/Business' ), "controller" => array( "namespace" => 'App\Controller', "folder" => '../app/Controller' ), "mode" => 0775, "ignore" => array( "tables" => array(), "sp" => array(), "controllers" => array() ) ); /** * @return array */ public function getConfig() { return $this->_config; } /** * @param array $config */ public function setConfig($config) { $this->_config = $config; } public function __construct($database) { $dsn = $database["driver"] . ":dbname=" . $database["database"] . ";host=" . $database["host"] . ";port=" . $database["port"]; $this->_pdo = new PDO($dsn, $database["username"], $database["password"]); } protected function printError($message) { echo $message . "\n"; var_dump($this->_pdo->errorInfo()); return null; } protected function buildTwigVars($vars) { foreach ($vars as $key => $value) { if (is_array($value)) $vars[$key] = $this->buildTwigVars($value); else if (is_string($value)) { $vars[$key] = array( "as_it" => $value, "camel_upper" => LuStringUtils::snakeToCamelCase($value, true), "camel_lower" => LuStringUtils::snakeToCamelCase($value, false) ); } } return $vars; } protected function buildTwig($templateFile, $destFile, $vars) { $vars["dbo_namespace"] = $this->_config["dbo"]["namespace"]; $vars["sp_namespace"] = $this->_config["sp"]["namespace"]; $vars["dataaccess_namespace"] = $this->_config["dataaccess"]["namespace"]; $vars["business_namespace"] = $this->_config["business"]["namespace"]; $vars["controller_namespace"] = $this->_config["controller"]["namespace"]; $twig_vars = $this->buildTwigVars($vars); Twig_Autoloader::register(); $loader = new Twig_Loader_Filesystem(__DIR__ ); $twig = new Twig_Environment($loader, array()); $template = $twig->loadTemplate('templates/' . $templateFile . '.twig'); $content = $template->render($twig_vars); file_put_contents($destFile, $content); } public function sqlTypesToPhpTypes($array) { $db = $this->getDbDataAccess(); foreach ($array as $key => $value) { $array[$key]["data_type"] = array( "sql" => $array[$key]["data_type"], "php" => $db->sqlTypeToPhpType($array[$key]["data_type"]) ); } return $array; } public function generateDbo($name, $columns, $file, $fileArray) { $vars = array( "dbo_name" => $name, "columns" => $columns ); $this->buildTwig('dbo.php', $file, $vars); $this->buildTwig('dbo_array.php', $fileArray, $vars); } public function generateSp($sp, $file, $spFile, $dboName, $dboFile, $dboFileArray) { file_put_contents($spFile, $sp["sp"]["prosrc"]); $args = []; $db = $this->getDbDataAccess(); foreach ($sp['args']['out'] as $arg) { $args[] = [ "name" => $arg["name"], "data_type" => [ "php" => $db->sqlTypeToPhpType($arg["data_type"]), "sql" => $arg["data_type"] ] ]; } $this->generateDbo($dboName, $args, $dboFile, $dboFileArray); $vars = [ "args" => $sp["args"], "sp" => $sp["sp"], "dboName" => $dboName ]; $this->buildTwig('sp.php', $file, $vars); } public function generateDataAccess($table_name, $connection_name, $dataAccessName, $dboName, $file) { if (file_exists($file)) return; $vars = array( "data_access_name" => $dataAccessName, "connection_name" => $connection_name, "table_name" => $table_name, "dbo_name" => $dboName ); $this->buildTwig('dataaccess.php', $file, $vars); } public function generateBusiness($businessName, $dataAccessName, $dboName, $file) { if (file_exists($file)) return; $vars = array( "business_name" => $businessName, "data_access_name" => $dataAccessName, "dbo_name" => $dboName ); $this->buildTwig('business.php', $file, $vars); } public function generateController($controllerName, $businessName, $dboName, $file) { if (file_exists($file)) return; $vars = array( "controller_name" => $controllerName, "business_name" => $businessName, "dbo_name" => $dboName ); $this->buildTwig('controller.php', $file, $vars); } public function mkdir($dir, $dir_mode) { if (!file_exists($dir)) mkdir($dir, $dir_mode, true); } public function matchIgnore($ignore, $name) { foreach ($this->_config["ignore"][$ignore] as $reg) { if (preg_match($reg, $name)) return true; } return false; } public function run() { $dbo_dir = $this->_config["dbo"]["folder"] . "/"; $sp_dir = $this->_config["sp"]["folder"] . "/"; $sp_src_dir = $this->_config["sp"]["folder"] . "/src/"; $manager_dir = $this->_config["dataaccess"]["folder"] . "/"; $business_dir = $this->_config["business"]["folder"] . "/"; $controller_dir = $this->_config["controller"]["folder"] . "/"; $connection_name = getenv("DB_CONNECTION_NAME"); $mode = $this->_config["mode"]; umask(0000); $this->mkdir($dbo_dir, $mode); $this->mkdir($sp_dir, $mode); $this->mkdir($sp_src_dir, $mode); $this->mkdir($manager_dir, $mode); $this->mkdir($business_dir, $mode); $this->mkdir($controller_dir, $mode); $tables = $this->getTables(); if (!is_null($tables)) { echo "Found " . count($tables) . " tables\n"; foreach ($tables as $table_name => $columns) { if ($this->matchIgnore("tables", $table_name)) { echo "Table $table_name ignored\n"; continue; } $columns = $this->sqlTypesToPhpTypes($columns); echo "Found " . count($columns) . " columns in table " . $table_name . "\n"; $baseName = LuStringUtils::snakeToCamelCase($table_name, true); $dboName = $baseName . "Dbo"; $dataAccessName = $baseName . "DataAccess"; $businessName = $baseName . "Business"; $controllerName = $baseName . "Controller"; $this->generateDbo($dboName, $columns, $dbo_dir . $dboName . ".php", $dbo_dir . $dboName . "Array.php"); $this->generateDataAccess($table_name, $connection_name, $dataAccessName, $dboName, $manager_dir . $dataAccessName . ".php"); $this->generateBusiness($businessName, $dataAccessName, $dboName, $business_dir . $businessName . ".php"); if ($this->matchIgnore("controllers", $controllerName)) { echo "Controller $controllerName ignored\n"; continue; } $this->generateController($controllerName, $businessName, $dboName, $controller_dir . $controllerName . ".php"); } } else { $this->printError("Failed to get tables"); } $sps = $this->getStoredProcedures(); if (!is_null($sps)) { echo "Found " . count($sps) . " stored procedures\n"; foreach ($sps as $sp_name => $sp) { if ($this->matchIgnore("sp", $sp_name)) { echo "Stored procedure $sp_name ignored\n"; continue; } $args = $sp["args"]; echo "Found " . count($args['in']) . " input and " . count($args['out']) . " output arguments in stored procedure " . $sp_name . "\n"; $args["in"] = $this->sqlTypesToPhpTypes($args["in"]); $args["out"] = $this->sqlTypesToPhpTypes($args["out"]); $sp_model_name = LuStringUtils::snakeToCamelCase($sp_name, true); $dboName = $sp_model_name . "Dbo"; $this->generateSp($sp, $sp_dir . $sp_model_name . ".php", $sp_src_dir . $sp_name . ".sql", $dboName, $dbo_dir . $dboName . ".php", $dbo_dir . $dboName . "Array.php"); } } else { $this->printError("Failed to get stored procedures"); } } public function getStoredProcedures() { return $this->getDbDataAccess()->getStoredProceduresFull($this->_pdo); } public function getTables() { return $this->getDbDataAccess()->getTablesFull($this->_pdo); } /** * @return AbstractDbDataAccess|null */ public function getDbDataAccess() { $driver = $this->_pdo->getAttribute(PDO::ATTR_DRIVER_NAME); if ($driver == "pgsql") { return new PgSqlDataAccess(); } return null; } }