From 1c513acaa4fcc1dbd9eb025dffe06a2820a62617 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 8 Mar 2018 20:09:02 +0100 Subject: [PATCH 1/2] Implemented Wrapper and Stacker + optimized Excel import --- build/api/module/excelController.php | 51 ++++++++--- build/database/core/DatabaseDriver.php | 14 ++- .../core/PDOWrapper/PDOStatementWrapper.php | 51 +++++++++++ build/database/core/PDOWrapper/PDOWrapper.php | 91 +++++++++++++++++++ build/database/core/Repo.php | 12 +++ 5 files changed, 205 insertions(+), 14 deletions(-) create mode 100644 build/database/core/PDOWrapper/PDOStatementWrapper.php create mode 100644 build/database/core/PDOWrapper/PDOWrapper.php diff --git a/build/api/module/excelController.php b/build/api/module/excelController.php index e3c4a4d..6c786e5 100644 --- a/build/api/module/excelController.php +++ b/build/api/module/excelController.php @@ -348,6 +348,10 @@ class excelController /** @var tp $tpRepo */ $tpRepo = Repo::getRepo("tp"); + $CoursToLink = []; + $TDToLink = []; + $TPToLink = []; + foreach ($allUE as $codeUE => $UE){ if($UE["defaultFormation"]){ @@ -377,22 +381,25 @@ class excelController switch ($type){ case "Course": - $coursRepo->create( $codeUE, - $allProf[$group["professor"]]["dbId"], - $UE["disabled"] ? $UE["CourseVH"] : $group["VH"], - $formations); + $CoursToLink[] = ["id" => $coursRepo->create( $codeUE, + $allProf[$group["professor"]]["dbId"], + $UE["disabled"] ? $UE["CourseVH"] : $group["VH"], + []), + "form" => $formations]; break; case "TD": - $tdRepo->create($codeUE, - $allProf[$group["professor"]]["dbId"], - $UE["disabled"] ? $UE["TdVH"] : $group["VH"], - $formations); + $TDToLink[] = ["id" => $tdRepo->create($codeUE, + $allProf[$group["professor"]]["dbId"], + $UE["disabled"] ? $UE["TdVH"] : $group["VH"], + []), + "form" => $formations]; break; case "TP": - $tpRepo->create($codeUE, - $allProf[$group["professor"]]["dbId"], - $UE["disabled"] ? $UE["TpVH"] : $group["VH"], - $formations); + $TPToLink[] = ["id" => $tpRepo->create($codeUE, + $allProf[$group["professor"]]["dbId"], + $UE["disabled"] ? $UE["TpVH"] : $group["VH"], + []), + "form" => $formations]; break; } @@ -401,6 +408,26 @@ class excelController } } + Repo::enableStacking(); + + foreach ($CoursToLink as $cour){ + foreach ($cour["form"] as $formation){ + $coursRepo->linkFormation($formation,$cour["id"]); + } + } + foreach ($TDToLink as $cour){ + foreach ($cour["form"] as $formation){ + $tdRepo->linkFormation($formation,$cour["id"]); + } + } + foreach ($TPToLink as $cour){ + foreach ($cour["form"] as $formation){ + $tpRepo->linkFormation($formation,$cour["id"]); + } + } + + Repo::flushStack(); + return [ 'data' => ["professors" => $allProf, "formations" => $allFormations, "UEs" => $allUE ] ]; }catch (Exception $e){ return [ 'error' => new Error(Err::UnknownError) ]; diff --git a/build/database/core/DatabaseDriver.php b/build/database/core/DatabaseDriver.php index a7553fd..7ffe06d 100755 --- a/build/database/core/DatabaseDriver.php +++ b/build/database/core/DatabaseDriver.php @@ -11,6 +11,7 @@ **************************/ namespace database\core; + use database\core\PDOWrapper\PDOWrapper; use \error\core\Error; use \error\core\Err; @@ -69,9 +70,10 @@ try{ - $this->pdo = new \PDO('mysql:host='.$this->host.';dbname='.$this->dbname.';charset=utf8', $this->username, $this->password, [ + $this->pdo = new PDOWrapper('mysql:host='.$this->host.';dbname='.$this->dbname.';charset=utf8', $this->username, $this->password, [ \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, - \PDO::ATTR_TIMEOUT => 5 + \PDO::ATTR_TIMEOUT => 5, + \PDO::ERRMODE_EXCEPTION => true ]); $this->pdo->setAttribute(\PDO::ATTR_STRINGIFY_FETCHES, false); @@ -194,6 +196,14 @@ ]; } + public function enableStacking(){ + $this->pdo->enableStacking(); + } + + public function flushStack(){ + $this->pdo->executeStack(); + } + } diff --git a/build/database/core/PDOWrapper/PDOStatementWrapper.php b/build/database/core/PDOWrapper/PDOStatementWrapper.php new file mode 100644 index 0000000..704d5bb --- /dev/null +++ b/build/database/core/PDOWrapper/PDOStatementWrapper.php @@ -0,0 +1,51 @@ +statement = $statement; + $this->connexion = $connexion; + + + } + + public function execute($input_parameters = []) + { + $this->parameters = $input_parameters; + $this->connexion->stackStatement($this); + return true; + } + + /** + * @return string + */ + public function getStatement() + { + return $this->statement; + } + + /** + * @return array + */ + public function getParameters() + { + return $this->parameters; + } + + + +} \ No newline at end of file diff --git a/build/database/core/PDOWrapper/PDOWrapper.php b/build/database/core/PDOWrapper/PDOWrapper.php new file mode 100644 index 0000000..d8526c2 --- /dev/null +++ b/build/database/core/PDOWrapper/PDOWrapper.php @@ -0,0 +1,91 @@ +stacking){ + return new PDOStatementWrapper($statement, $this); + }else{ + parent::setAttribute(\PDO::ATTR_EMULATE_PREPARES, true); + return parent::prepare($statement, $options); + + } + } + + public function enableStacking(){ + $this->stacking = true; + } + + public function stackStatement(PDOStatementWrapper $st){ + array_push($this->statements,$st); + } + + public function executeStack(){ + //init the statements and the generator of number + $finalStatement = ''; + $finalExecute = []; + $i = 0; + + //for each request stacked + foreach ($this->statements as $request){ + $statement = $request->getStatement(); + + // we have to modify the parameters index at the same time that we modify the request, so we use static class attribute + $tempParametes = $request->getParameters(); + + //find the given pattern in the request, then call our function and replace the matched string by the return value of our function + $finalStatement .= rtrim(preg_replace_callback("/(:[a-z_\-0-9]*)/is",function($matches) use (&$i,&$tempParametes){ + //get next number + $i++; + + //delete the ':' at the beginning of the string + $tempKey = ltrim($matches[0],':'); + + //copy the parameter with the modified index + $tempParametes[$tempKey.$i] = $tempParametes[$tempKey]; + + //delete the old index + unset($tempParametes[$tempKey]); + + //return the modified string for replacement + return $matches[0].$i; + },$statement),';').';'; + + $finalExecute = array_merge($finalExecute,$tempParametes); + } + + //disable stacking + $this->stacking = false; + + $this->beginTransaction(); + + $req = $this->prepare($finalStatement); + + $success = $req->execute($finalExecute); + //as we execute multiple query that we don't fetch, we have to close the cursor if we want to do other requests later + $req->closeCursor(); + $this->commit(); + //using beginTransaction/commit disable the autocommit, we re-activate it + $this->setAttribute(\PDO::ATTR_AUTOCOMMIT,1); + parent::setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); + return $success; + } +} \ No newline at end of file diff --git a/build/database/core/Repo.php b/build/database/core/Repo.php index 6a09828..88b88f7 100644 --- a/build/database/core/Repo.php +++ b/build/database/core/Repo.php @@ -12,6 +12,7 @@ namespace database\core; + use database\core\PDOWrapper\PDOWrapper; use \error\core\Error; use \error\core\Err; @@ -20,6 +21,9 @@ /* (1) Driver ---------------------------------------------------------*/ + /** + * @var DatabaseDriver + */ private static $driver = null; public static function setDriver(DatabaseDriver $driver){ self::$driver = $driver; } @@ -57,6 +61,14 @@ return $instance; } + public static function enableStacking(){ + static::$driver->enableStacking(); + } + + public static function flushStack(){ + static::$driver->flushStack(); + } + From 3b853644e0b79a6b41e81ab23e8527f8442bae16 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 8 Mar 2018 20:53:40 +0100 Subject: [PATCH 2/2] implemented debugging of the repo --- build/api/core/Request.php | 8 ++- build/api/module/excelController.php | 11 ++-- build/database/core/DatabaseDriver.php | 16 +++++- build/database/core/PDOWrapper/PDOWrapper.php | 56 +++++++++++++++++++ build/database/core/Repo.php | 8 +++ config/database-driver.json | 3 +- 6 files changed, 94 insertions(+), 8 deletions(-) diff --git a/build/api/core/Request.php b/build/api/core/Request.php index dce1f28..f9a9ac3 100755 --- a/build/api/core/Request.php +++ b/build/api/core/Request.php @@ -5,7 +5,8 @@ use \api\core\AuthSystem; use \api\core\ModuleFactory; use \api\core\Config; - use \error\core\Error; +use database\core\Repo; +use \error\core\Error; use \error\core\Err; @@ -503,6 +504,11 @@ /* (3) On ajoute les données */ $response->appendAll($returned); + /* (4) Si le Debug est actif on ajoute le debug des repo */ + if(Repo::isDebugEnabled()){ + $response->append("repoDebug" , Repo::getDebug()); + } + /* (4) On retourne la réponse */ return $response; diff --git a/build/api/module/excelController.php b/build/api/module/excelController.php index 6c786e5..2e1fb4b 100644 --- a/build/api/module/excelController.php +++ b/build/api/module/excelController.php @@ -63,9 +63,11 @@ class excelController $addEU = function() use (&$UECode,&$allUE,&$UE){ //determine if UE is disabled (if cours+td+tp = 0) $totalVH = 0; - foreach ($UE["groups"] as $groups){ - foreach ($groups as $group){ - $totalVH += $group["VH"]; + if(is_array($UE["groups"]) && count($UE["groups"]) > 0){ + foreach ($UE["groups"] as $groups){ + foreach ($groups as $group){ + $totalVH += $group["VH"]; + } } } @@ -428,7 +430,8 @@ class excelController Repo::flushStack(); - return [ 'data' => ["professors" => $allProf, "formations" => $allFormations, "UEs" => $allUE ] ]; + //return [ 'data' => ["professors" => $allProf, "formations" => $allFormations, "UEs" => $allUE ] ]; + return["data" => true]; }catch (Exception $e){ return [ 'error' => new Error(Err::UnknownError) ]; } diff --git a/build/database/core/DatabaseDriver.php b/build/database/core/DatabaseDriver.php index 7ffe06d..695b06d 100755 --- a/build/database/core/DatabaseDriver.php +++ b/build/database/core/DatabaseDriver.php @@ -61,7 +61,7 @@ * @password Database password * */ - private function __construct($host, $dbname, $username, $password){ + private function __construct($host, $dbname, $username, $password, $debug = false){ /* (2) Stores configuration */ $this->host = $host; $this->dbname = $dbname; @@ -79,6 +79,10 @@ $this->pdo->setAttribute(\PDO::ATTR_STRINGIFY_FETCHES, false); $this->pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); + if($debug){ + $this->pdo->enableDebug(); + } + // On signale que tout s'est bien passe $this->error = new Error(Err::Success); @@ -120,7 +124,7 @@ /* (1) If local -> instanciates with local configuration */ // if( !checkdnsrr($_SERVER['SERVER_NAME'], 'NS') ) - self::$instance[$label] = new DatabaseDriver($conf[$label]['local']['host'], $conf[$label]['local']['dbname'], $conf[$label]['local']['user'], $conf[$label]['local']['password']); + self::$instance[$label] = new DatabaseDriver($conf[$label]['local']['host'], $conf[$label]['local']['dbname'], $conf[$label]['local']['user'], $conf[$label]['local']['password'],$conf[$label]['local']['debug']); /* (2) If Remote -> instanciates with Remote configuration */ // else // self::$instance[$label] = new DatabaseDriver($conf[$label]['remote']['host'], $conf[$label]['remote']['dbname'], $conf[$label]['remote']['user'], $conf[$label]['remote']['password']); @@ -204,6 +208,14 @@ $this->pdo->executeStack(); } + public function getDebug() : array{ + return $this->pdo->getDebug(); + } + + public function isDebugEnabled() : bool { + return $this->pdo->isDebugEnabled(); + } + } diff --git a/build/database/core/PDOWrapper/PDOWrapper.php b/build/database/core/PDOWrapper/PDOWrapper.php index d8526c2..5674744 100644 --- a/build/database/core/PDOWrapper/PDOWrapper.php +++ b/build/database/core/PDOWrapper/PDOWrapper.php @@ -13,6 +13,8 @@ class PDOWrapper extends \PDO { private $statements = []; private $stacking = false; + private $debug = []; + private $debugEnabled = false; public function __construct(String $dsn, String $username, String $passwd, array $options = []) { @@ -21,6 +23,10 @@ class PDOWrapper extends \PDO public function prepare($statement, $options = []) { + if($this->debugEnabled){ + $this->storeDebug(); + } + if($this->stacking){ return new PDOStatementWrapper($statement, $this); }else{ @@ -30,14 +36,64 @@ class PDOWrapper extends \PDO } } + private function storeDebug(){ + //get all the debug info about the repo + $prepareStack = debug_backtrace(0,3)[1]; + $stack = debug_backtrace(0,3)[2]; + //create the reflection object + $f = new \ReflectionMethod($stack["class"],$stack["function"]); + //get only the repo name + $className = explode("\\",$stack["class"]); + $className = $className[count($className)-1]; + + $result = []; + + //if we are flushing a stack, just count the number of request stacked + if($stack["function"] == "executeStack"){ + + $result["StackedRequest"] = true; + $result["numberOfStackedRequest"] = substr_count($prepareStack["args"][0],";"); + //if we are not stacking, log the repo call + }else if(!$this->stacking){ + //store results + $result["repoName"] = $className; + $result["methodName"] = $stack["function"]; + $result["args"] = []; + + foreach ($f->getParameters() as $key => $param) { + $result["args"][$param->name] = $stack["args"][$key]; + } + //else we are stacking a request, we should not log it + }else{ + return; + } + + $this->debug[] = $result; + } + public function getDebug() : array{ + return $this->debug; + } + public function enableStacking(){ $this->stacking = true; } + public function isDebugEnabled() : bool{ + return $this->debugEnabled; + } + public function stackStatement(PDOStatementWrapper $st){ array_push($this->statements,$st); } + public function enableDebug(){ + $this->debugEnabled = true; + } + + public function disableDebug(){ + $this->debugEnabled = false; + } + public function executeStack(){ //init the statements and the generator of number $finalStatement = ''; diff --git a/build/database/core/Repo.php b/build/database/core/Repo.php index 88b88f7..d5d86f3 100644 --- a/build/database/core/Repo.php +++ b/build/database/core/Repo.php @@ -69,6 +69,14 @@ static::$driver->flushStack(); } + public static function getDebug() : array{ + return static::$driver->getDebug(); + } + + public static function isDebugEnabled() : bool{ + return static::$driver->isDebugEnabled(); + } + diff --git a/config/database-driver.json b/config/database-driver.json index fb2da3c..0c99f5d 100755 --- a/config/database-driver.json +++ b/config/database-driver.json @@ -4,7 +4,8 @@ "host" : "mariadb", "dbname" : "vhost", "user" : "php", - "password" : "4JB1dtbrIC8pT935" + "password" : "4JB1dtbrIC8pT935", + "debug" : true }, "remote": { "host" : "db_remote_host",