[module.department.save] => [module.department.version] refactor + POST split into POST & PUT + used API 'error' return field BIGUPDATE
This commit is contained in:
parent
466d197246
commit
e221452295
|
@ -1,140 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Created by PhpStorm.
|
|
||||||
* User: lucas
|
|
||||||
* Date: 15/03/18
|
|
||||||
* Time: 15:50
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace api\module\department;
|
|
||||||
|
|
||||||
|
|
||||||
use database\core\Repo;
|
|
||||||
use database\repo\department;
|
|
||||||
use Ifsnop\Mysqldump\Mysqldump;
|
|
||||||
|
|
||||||
class saveController
|
|
||||||
{
|
|
||||||
|
|
||||||
private $backupPath = "";
|
|
||||||
private $originDBName = "";
|
|
||||||
|
|
||||||
private function initDir(string $dbName){
|
|
||||||
|
|
||||||
//match preview_DATABASENAME_sha1 in order to determine if we init the directory or not
|
|
||||||
$matches = [];
|
|
||||||
$reg = preg_match("/preview_(\w*)_\w*/",$dbName,$matches);
|
|
||||||
|
|
||||||
//if the dbname match we store the original database name
|
|
||||||
if($reg == 1){
|
|
||||||
$dbName = $matches[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->originDBName = $dbName;
|
|
||||||
|
|
||||||
if(!is_dir(__BACKUP__."/$dbName/")){
|
|
||||||
mkdir(__BACKUP__."/$dbName/");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->backupPath =__BACKUP__."/$dbName/";
|
|
||||||
}
|
|
||||||
|
|
||||||
private function scandir(string $path) : array {
|
|
||||||
//scan the directory
|
|
||||||
$arr = scandir($path);
|
|
||||||
|
|
||||||
//strip the useless "." and ".."
|
|
||||||
unset($arr[0],$arr[1]);
|
|
||||||
|
|
||||||
//make the arry start at 0 again
|
|
||||||
$arr = array_values($arr);
|
|
||||||
|
|
||||||
return $arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get($args){
|
|
||||||
$this->initDir($_SESSION["CurrentDatabase"]);
|
|
||||||
|
|
||||||
//strip extensions
|
|
||||||
$backupNames = array_map(function($e){
|
|
||||||
return pathinfo($e, PATHINFO_FILENAME);
|
|
||||||
}, $this->scandir($this->backupPath));
|
|
||||||
|
|
||||||
return ["data" => $backupNames];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($args){
|
|
||||||
$this->initDir($_SESSION["CurrentDatabase"]);
|
|
||||||
|
|
||||||
$backupName = "";
|
|
||||||
|
|
||||||
extract($args);
|
|
||||||
|
|
||||||
return ["success" => unlink($this->backupPath.$backupName.".sql")];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function post($args){
|
|
||||||
$this->initDir($_SESSION["CurrentDatabase"]);
|
|
||||||
|
|
||||||
$backupName = "";
|
|
||||||
$apply = false;
|
|
||||||
extract($args);
|
|
||||||
|
|
||||||
//if the backup name is empty we create it
|
|
||||||
if($backupName == ""){
|
|
||||||
try {
|
|
||||||
$conf = Repo::getDBConfig();
|
|
||||||
|
|
||||||
$dump = new Mysqldump("mysql:host={$conf["host"]};dbname={$conf["dbname"]}", $conf["username"], $conf["password"],
|
|
||||||
[
|
|
||||||
"compress" => Mysqldump::GZIP
|
|
||||||
]);
|
|
||||||
|
|
||||||
$date = date("Y-W-d");
|
|
||||||
|
|
||||||
$dump->start($this->backupPath.$date.".sql");
|
|
||||||
|
|
||||||
return ["success" => true,"backupName" => $date];
|
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return ["success" => false];
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
//read the backup
|
|
||||||
ob_start();
|
|
||||||
readgzfile($this->backupPath.$backupName.".sql");
|
|
||||||
$sql = ob_get_clean();
|
|
||||||
|
|
||||||
/** @var department $depRepo */
|
|
||||||
$depRepo = Repo::getRepo("department");
|
|
||||||
|
|
||||||
if($sql == "") return ["success" => false];
|
|
||||||
|
|
||||||
if($apply){
|
|
||||||
|
|
||||||
$depRepo->restore($this->originDBName,$sql);
|
|
||||||
|
|
||||||
return ["success" => true];
|
|
||||||
}else{
|
|
||||||
|
|
||||||
if($backupName == "origin"){
|
|
||||||
$_SESSION['CurrentDatabase'] = $this->originDBName;
|
|
||||||
return ["success" => true];
|
|
||||||
}
|
|
||||||
|
|
||||||
$previewDBName = $depRepo->previewExists($this->originDBName,$backupName);
|
|
||||||
|
|
||||||
if($previewDBName == null){
|
|
||||||
$previewDBName = $depRepo->createPreview($this->originDBName,$backupName);
|
|
||||||
$depRepo->restore($previewDBName,$sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
$_SESSION['CurrentDatabase'] = $previewDBName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ["success" => true, "currentDatabase" => $_SESSION['CurrentDatabase']];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,296 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: lucas
|
||||||
|
* Date: 15/03/18
|
||||||
|
* Time: 15:50
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace api\module\department;
|
||||||
|
|
||||||
|
|
||||||
|
use database\core\Repo;
|
||||||
|
use error\core\Error;
|
||||||
|
use error\core\Err;
|
||||||
|
use database\repo\department;
|
||||||
|
use Ifsnop\Mysqldump\Mysqldump;
|
||||||
|
|
||||||
|
class versionController{
|
||||||
|
|
||||||
|
|
||||||
|
/* Attributes
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
private $backup_path;
|
||||||
|
private $origin_dbname;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Initialize object
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
public function __construct(){
|
||||||
|
$this->backup_path = null;
|
||||||
|
$this->origin_dbname = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Initializes a directory
|
||||||
|
*
|
||||||
|
* @db_name<String> The database name
|
||||||
|
*
|
||||||
|
* @return outName<outType> outDesc
|
||||||
|
*
|
||||||
|
--------------------------------------------------------*/
|
||||||
|
private function initDir(string $db_name){
|
||||||
|
|
||||||
|
/* (1) Manage 'BACKUP' root directory
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) If not exists -> try to create it */
|
||||||
|
if( !is_dir(__BACKUP__) )
|
||||||
|
mkdir(__BACKUP__);
|
||||||
|
|
||||||
|
/* (2) Try to override permissions */
|
||||||
|
chmod(__BACKUP__, 0775);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Manage sub-directory
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) If @db_name is 'preview_@database_hash' -> extract @database */
|
||||||
|
if( preg_match('/^preview_(\w+)_[a-f0-9]+$/', $db_name, $m) )
|
||||||
|
$db_name = $m[1];
|
||||||
|
|
||||||
|
/* (2) Store @db_name as origin */
|
||||||
|
$this->origin_dbname = $db_name;
|
||||||
|
|
||||||
|
/* (3) Store backup path */
|
||||||
|
$this->backup_path =__BACKUP__."/$db_name";
|
||||||
|
|
||||||
|
/* (4) If dir. already exists -> do nothing more */
|
||||||
|
if( is_dir($this->backup_path) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* (4) Else -> try to create + set permissions */
|
||||||
|
mkdir($this->backup_path);
|
||||||
|
chmod($this->backup_path, 0775);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (3) Scan directory files
|
||||||
|
*
|
||||||
|
* @path<String> Directory path
|
||||||
|
*
|
||||||
|
* @return files<array> Array containing file names
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
private function scandir(string $path) : array {
|
||||||
|
|
||||||
|
/* (1) Return [] if not a directory */
|
||||||
|
if( !is_dir($path) )
|
||||||
|
return [];
|
||||||
|
|
||||||
|
/* (2) Scan the directory */
|
||||||
|
$files = scandir($path);
|
||||||
|
|
||||||
|
/* (3) Remove '.' and '..' (2 first elements) */
|
||||||
|
$files = array_slice($files, 2);
|
||||||
|
|
||||||
|
/* (4) Return file list */
|
||||||
|
return $files;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (4) List available versions for this department
|
||||||
|
*
|
||||||
|
* @return versions<array> Version list
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
public function get($args){
|
||||||
|
|
||||||
|
/* (1) Initialize directory for current database (department) */
|
||||||
|
$this->initDir( $_SESSION['CurrentDatabase'] );
|
||||||
|
|
||||||
|
/* (2) Strip extensions */
|
||||||
|
$versions = array_map(
|
||||||
|
function($e){ return pathinfo($e, PATHINFO_FILENAME); },
|
||||||
|
$this->scandir($this->backup_path)
|
||||||
|
);
|
||||||
|
|
||||||
|
/* (3) Return versions */
|
||||||
|
return ['versions' => $versions];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (5) Remove an existing version for this department
|
||||||
|
*
|
||||||
|
* @version<String> Version name (typically snapshot date)
|
||||||
|
*
|
||||||
|
* @return deleted<bool> Whether the version has been deleted
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
public function delete($args){
|
||||||
|
$version = null;
|
||||||
|
extract($args);
|
||||||
|
|
||||||
|
/* (1) Initialize directory for current database (department) */
|
||||||
|
$this->initDir( $_SESSION['CurrentDatabase'] );
|
||||||
|
|
||||||
|
/* (2) Dispatch 'unlink' result */
|
||||||
|
return [ 'deleted' => unlink($this->backup_path."/$version.sql") ];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (6) Creates a new version (snapshot of database) from now
|
||||||
|
*
|
||||||
|
* @return created_id<String> The created version id (date)
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
public function post($args){
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Initialize directory for current database (department) */
|
||||||
|
$this->initDir( $_SESSION['CurrentDatabase'] );
|
||||||
|
|
||||||
|
/* (2) Try to create the snapshot */
|
||||||
|
try{
|
||||||
|
|
||||||
|
/* (2.1) Get database configuration */
|
||||||
|
$conf = Repo::getDBConfig();
|
||||||
|
|
||||||
|
/* (2.2) Try to dump the database */
|
||||||
|
$dump = new Mysqldump(
|
||||||
|
'mysql:host='.$conf['host'].';dbname='.$conf['dbname'],
|
||||||
|
$conf['username'],
|
||||||
|
$conf['password'],
|
||||||
|
[ "compress" => Mysqldump::GZIP ]
|
||||||
|
);
|
||||||
|
|
||||||
|
/* (2.3) Get current date (for naming the version) */
|
||||||
|
$current_date = date('d-m-Y');
|
||||||
|
|
||||||
|
/* (2.4) Store the version */
|
||||||
|
$dump->start($this->backup_path."/$current_date.sql");
|
||||||
|
|
||||||
|
/* (2.5) Return status */
|
||||||
|
return ['created_id' => $current_date ];
|
||||||
|
|
||||||
|
/* (3) On error -> dispatch error */
|
||||||
|
}catch(\Exception $e){
|
||||||
|
|
||||||
|
return ['error' => new Error(Err::RepoError)];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (6) ( Switches to preview || Applies on prod ) for a version
|
||||||
|
*
|
||||||
|
* @apply<int> If 0 -> preview version
|
||||||
|
* If 1 -> apply version into prod database
|
||||||
|
* @version<String> [OPT] Version name to use (if ommited, switch back to prod database)
|
||||||
|
*
|
||||||
|
* @return created_id<String> The created version id (date)
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
public function put($args){
|
||||||
|
$apply = null;
|
||||||
|
$version = null;
|
||||||
|
extract($args);
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Initialisation
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Initialize directory for current database (department) */
|
||||||
|
$this->initDir( $_SESSION['CurrentDatabase'] );
|
||||||
|
|
||||||
|
/* (2) Get department repository */
|
||||||
|
/** @var department $dept_repo */
|
||||||
|
$dept_repo = Repo::getRepo('department');
|
||||||
|
|
||||||
|
/* (2) Check whether we have to [apply OR preview] */
|
||||||
|
$apply = ( $apply === '1' );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) If back to 'prod' database
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
if( is_null($version) ){
|
||||||
|
|
||||||
|
/* (1) Reset database to 'prod' */
|
||||||
|
$_SESSION['CurrentDatabase'] = $this->origin_dbname;
|
||||||
|
|
||||||
|
/* (2) Return success */
|
||||||
|
return [ 'updated' => true ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (3) Read the backup version
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Start buffer */
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
/* (2) Read backup file */
|
||||||
|
readgzfile($this->backup_path."/$version.sql");
|
||||||
|
|
||||||
|
/* (3) Store & Flush buffer into variable */
|
||||||
|
$snapshot = ob_get_clean();
|
||||||
|
|
||||||
|
/* (4) Manage error */
|
||||||
|
if( strlen($snapshot) === 0 )
|
||||||
|
return ['error' => new Error(Err::RepoError)];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (4) APPLY into 'prod' database
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
if( $apply ){
|
||||||
|
|
||||||
|
/* (1) Restore from this version */
|
||||||
|
$restored = $dept_repo->restore($this->origin_dbname, $snapshot);
|
||||||
|
|
||||||
|
/* (2) Dispatch repo execution status */
|
||||||
|
return [ 'updated' => $restored ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (5) PREVIEW version database
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Try to get 'preview' database name */
|
||||||
|
$preview_dbname = $dept_repo->previewExists($this->origin_dbname, $version);
|
||||||
|
|
||||||
|
/* (2) If does not exist -> create it */
|
||||||
|
if( is_null($preview_dbname) ){
|
||||||
|
|
||||||
|
/* 1. Try to create preview */
|
||||||
|
$preview_dbname = $dept_repo->createPreview($this->origin_dbname, $version);
|
||||||
|
|
||||||
|
/* 2. Switch to preview */
|
||||||
|
$dept_repo->restore($preview_dbname, $snapshot);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (3) Store 'preview' database in session */
|
||||||
|
$_SESSION['CurrentDatabase'] = $preview_dbname;
|
||||||
|
|
||||||
|
|
||||||
|
/* (4) Return status */
|
||||||
|
return [ 'updated' => true ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -98,26 +98,42 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"save":{
|
"version":{
|
||||||
"GET": {
|
"GET": {
|
||||||
"des": "Get the list of the saves of the department database",
|
"des": "Get the list of the versions of the department",
|
||||||
"per": [],
|
"per": [],
|
||||||
"par": {
|
"par": {},
|
||||||
|
"output": {
|
||||||
|
"versions": { "des": "List of available versions", "typ": "array" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"POST": {
|
"POST": {
|
||||||
"des": "Create a backup if the name is empty, execute the backup if the name is set",
|
"des": "Create a backup if the name is empty, execute the backup if the name is set",
|
||||||
"per": [],
|
"per": [],
|
||||||
|
"par": {},
|
||||||
|
"output": {
|
||||||
|
"created_id": { "des": "The id of the created version", "typ": "varchar(10,10,alphanumeric)" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PUT": {
|
||||||
|
"des": "Switches to a older version or to current state",
|
||||||
|
"per": [],
|
||||||
"par": {
|
"par": {
|
||||||
"backupName" : {"des": "Backup name", "typ": "varchar(1,10,alphanumeric)", "opt" : true},
|
"URL0": { "des": "0 to preview, 1 to apply", "typ": "id", "ren": "apply" },
|
||||||
"apply" : {"des": "Should we apply the backup on production or just preview it (true : apply, false : preview)", "typ": "boolean", "opt" : true}
|
"URL1": { "des": "The version name, current state if ommited", "typ": "varchar(10,10,alphanumeric)", "ren": "version", "opt": true }
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"updated": { "des": "Whether the version has been switched|applied", "typ": "bool" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"des": "Delete a backup",
|
"des": "Delete a backup",
|
||||||
"per": [],
|
"per": [],
|
||||||
"par": {
|
"par": {
|
||||||
"backupName": {"des": "Backup name", "typ": "varchar(1,10,alphanumeric)"}
|
"URL0": { "des": "The version name", "typ": "varchar(10,10,alphanumeric)", "ren": "version" }
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"deleted": { "des": "Whether the version has been deleted", "typ": "bool" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue