1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 17:59:55 +02:00
This commit is contained in:
Daniel Neto 2024-10-18 14:11:42 -03:00
parent e11818f353
commit 5f9e00d01d
6 changed files with 306 additions and 147 deletions

View file

@ -133,8 +133,8 @@ function _mysql_connect($persistent = false, $try = 0)
try {
if (!_mysql_is_open()) {
if(!class_exists('mysqli')){
_error_log('ERROR: mysqli class not loaded '.php_ini_loaded_file());
if (!class_exists('mysqli')) {
_error_log('ERROR: mysqli class not loaded ' . php_ini_loaded_file());
die('ERROR: mysqli class not loaded');
}
//_error_log('MySQL Connect '. json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)));
@ -156,7 +156,7 @@ function _mysql_connect($persistent = false, $try = 0)
}
} catch (Exception $exc) {
if (empty($try)) {
_error_log('Error on connect, trying again [' . mysqli_connect_error() . '] IP='.getRealIpAddr());
_error_log('Error on connect, trying again [' . mysqli_connect_error() . '] IP=' . getRealIpAddr());
_mysql_close();
sleep(5);
return _mysql_connect($persistent, $try + 1);
@ -263,4 +263,269 @@ function setDefaultSort($defaultSortColumn, $defaultSortOrder)
if (empty($_REQUEST['sort']) && empty($_GET['sort']) && empty($_POST['sort']) && empty($_GET['order'][0]['dir'])) {
$_POST['sort'][$defaultSortColumn] = $defaultSortOrder;
}
}
}
/**
* Function to dump MySQL database with optional parameters for exclusion and custom options.
*
* @param string $filePath The full path where the dump file will be saved.
* @param array $extraOptions Additional MySQL options for the dump (optional).
* @param array $status Array for tracking status (optional).
* @param string|null $bfile Path to the lock file (optional).
* @return string|false Returns the filename if success or false on failure.
*/
function dumpMySQLDatabase($filePath, $extraOptions = [], &$status = [], $bfile = null)
{
global $mysqlHost, $mysqlPort, $mysqlUser, $mysqlPass, $mysqlDatabase;
// Log the start of the process
_error_log("Starting MySQL database dump process");
// Initialize lock file with current step
$status = [
'step' => 'Starting database dump',
'currentFile' => $filePath,
'message' => 'Database dump is in progress'
];
updateLockFile($status, $bfile);
// Hardcoded tables to exclude from the dump
$excludeTables = ['CachesInDB', 'audit']; // Add more tables as needed
// Default MySQL port
if (empty($mysqlPort)) {
$mysqlPort = 3306;
}
// Create a connection to the database to retrieve all table names
$connection = new mysqli($mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, $mysqlPort);
if ($connection->connect_error) {
_error_log("Connection failed: " . $connection->connect_error);
return false;
}
// Get all tables from the database
_error_log("Fetching tables from database");
$res = sqlDAL::readSql("SHOW TABLES");
if (!$res) {
_error_log("Failed to retrieve tables from database");
return false;
}
$row = sqlDAL::fetchAllAssoc($res);
sqlDAL::close($res);
if (empty($row)) {
_error_log("No tables found in the database");
return false;
}
$tables = [];
foreach ($row as $value) {
$tableName = reset($value);
if (!in_array($tableName, $excludeTables)) {
$tables[] = $tableName;
} else {
_error_log("Excluding table from dump: $tableName");
}
}
if (empty($tables)) {
_error_log("No tables selected for the dump");
return false;
}
// Convert the tables array to a string
$tableList = implode(" ", $tables);
_error_log("Tables to be dumped: $tableList");
// Base mysqldump command with necessary options
$cmd = "mysqldump --host=$mysqlHost --port=$mysqlPort --user='$mysqlUser' --password='$mysqlPass' "
. "--default-character-set=utf8mb4 --column-statistics=0 --add-drop-table --add-locks "
. "--extended-insert --single-transaction --quick $mysqlDatabase $tableList";
// Append any additional options
if (!empty($extraOptions)) {
foreach ($extraOptions as $option) {
if (!empty($option)) {
$cmd .= " $option";
}
}
}
// Specify the file path to save the dump
$cmd .= " > {$filePath}";
_error_log("Executing dump command: $cmd");
// Update lock file before executing the dump
$status['step'] = 'Running mysqldump';
updateLockFile($status, $bfile);
// Execute the command and wait for completion
exec($cmd, $output, $result);
// Check if the dump was successful
if ($result !== 0 || !file_exists($filePath) || filesize($filePath) == 0) {
_error_log("Error occurred while taking the database dump. Command: $cmd");
return false;
}
_error_log("Database dumped successfully to {$filePath}");
// Final update for the lock file
$status['step'] = 'Database dump complete';
updateLockFile($status, $bfile);
return $filePath; // Return the file path on success
}
function updateLockFile($status, $bfile)
{
// Check if the 'startTime' is already set, if not, set it to the current time
if (!isset($status['startTime'])) {
$status['startTime'] = date("Y-m-d H:i:s"); // Set the start time when the process starts
}
// Update the 'lastUpdateTime' with the current time each time the lock file is updated
$status['lastUpdateTime'] = date("Y-m-d H:i:s");
// Write the status to the lock file
file_put_contents($bfile, json_encode($status, JSON_PRETTY_PRINT)); // Added JSON_PRETTY_PRINT for better readability
}
/**
* Function to restore a MySQL backup from a given SQL file.
*
* @param string $filename The path to the SQL file to restore.
* @return bool Returns true if successful, false if there were errors.
*/
function restoreMySQLBackup($filename)
{
global $global, $mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, $mysqlPort;
echo "Restoring MySQL backup from file: {$filename}" . PHP_EOL;
// Step 1: Create a connection to the MySQL server
$mysqli = new mysqli($mysqlHost, $mysqlUser, $mysqlPass, '', $mysqlPort);
if ($mysqli->connect_error) {
echo "Connection failed: " . $mysqli->connect_error . PHP_EOL;
return false;
}
// Step 2: Drop and recreate the database
try {
echo "Dropping existing database if it exists..." . PHP_EOL;
$dropSQL = "DROP DATABASE IF EXISTS {$mysqlDatabase};";
if (!$mysqli->query($dropSQL)) {
throw new Exception($mysqli->error);
}
echo "Creating database..." . PHP_EOL;
$createSQL = "CREATE DATABASE IF NOT EXISTS {$mysqlDatabase};";
if (!$mysqli->query($createSQL)) {
throw new Exception($mysqli->error);
}
$mysqli->select_db($mysqlDatabase);
// Step 3: Execute the SQL file to restore the backup
return executeSQLFile($mysqli, $filename);
} catch (Exception $e) {
echo "Error occurred: " . $e->getMessage() . PHP_EOL;
return false;
} finally {
$mysqli->close();
}
}
/**
* Executes an SQL file to restore the database.
*
* @param mysqli $mysqli MySQLi connection.
* @param string $filename Path to the SQL file to execute.
* @return bool Returns true if successful, false if errors occurred.
*/
function executeSQLFile($mysqli, $filename)
{
$templine = '';
$lockedTables = [];
$lines = file($filename); // Read in the SQL file
if (!$lines) {
echo "Failed to read SQL file: {$filename}" . PHP_EOL;
return false;
}
// Function to lock tables
function lockTables($mysqli, $tables)
{
$lockQuery = 'LOCK TABLES ' . implode(' WRITE, ', $tables) . ' WRITE;';
if (!$mysqli->query($lockQuery)) {
throw new Exception('Error locking tables: ' . $mysqli->error);
}
}
// Function to check if table exists
function tableExists($mysqli, $tableName)
{
$result = $mysqli->query("SHOW TABLES LIKE '$tableName'");
return $result && $result->num_rows > 0;
}
// Loop through each line of the SQL file
foreach ($lines as $line) {
// Skip comments and empty lines
if (substr($line, 0, 2) == '--' || trim($line) == '') {
continue;
}
$templine .= $line; // Append the line to the current SQL query
// If the line ends with a semicolon, execute the query
if (substr(trim($line), -1) == ';') {
try {
if (!$mysqli->query($templine)) {
throw new Exception($mysqli->error);
}
} catch (Exception $th) {
$error = $th->getMessage();
if (preg_match("/Table '(.*?)' was not locked with LOCK TABLES/", $error, $matches)) {
$tableName = $matches[1];
if (!in_array($tableName, $lockedTables) && tableExists($mysqli, $tableName)) {
$lockedTables[] = $tableName;
try {
lockTables($mysqli, $lockedTables);
// Retry the query after locking the tables
if (!$mysqli->query($templine)) {
throw new Exception('Error performing query after locking tables: ' . $mysqli->error);
}
} catch (Exception $lockException) {
echo 'ERROR: Failed to lock tables: ' . $lockException->getMessage() . PHP_EOL;
}
} else {
echo 'ERROR: Table was not locked and could not be locked: ' . $error . PHP_EOL;
}
} else {
echo 'ERROR: ' . $error . PHP_EOL;
}
}
$templine = ''; // Reset for the next query
}
}
// Unlock all tables at the end
try {
$mysqli->query('UNLOCK TABLES;');
} catch (Exception $th) {
echo 'ERROR: Failed to unlock tables: ' . $th->getMessage() . PHP_EOL;
}
return true;
}