getPath(); if (! file_exists($sqlPath)) { $this->printMessageError('The sql file to check does not exist'); echo "\033[0;31m\033[0m" . PHP_EOL; return 1; } return $this->checkFile($sqlPath); } /** * Print a normal message * * @param $message * @param null $outputPath */ protected function printMessage($message, $outputPath = null) { echo "\033[0;32m" . $message . "\033[0m" . PHP_EOL; if (! empty($outputPath)) { file_put_contents($outputPath, $message . PHP_EOL, FILE_APPEND); } } /** * Print an error message * * @param $message * @param null $outputPath */ protected function printMessageError($message, $outputPath = null) { echo "\033[0;31m" . $message . "\033[0m" . PHP_EOL; if (! empty($outputPath)) { file_put_contents($outputPath, $message . PHP_EOL, FILE_APPEND); } } /** * Get the options from command line * * @return array */ protected function getOpts() { $shortOpts = "p:o:f::"; $longOpts = [ "path:", "output", ]; $options = getopt($shortOpts, $longOpts); return ($options); } /** * get the path of the schema file * * @return string */ protected function getPath() { $sqlPath = '../../db/tiki.sql'; $options = $this->getOpts(); if (! empty($options['p'])) { $sqlPath = $options['p']; } elseif (! empty($options['path'])) { $sqlPath = $options['path']; } if ($sqlPath[0] !== '/') { $sqlPath = __DIR__ . DIRECTORY_SEPARATOR . $sqlPath; } return $sqlPath; } /** * Validates the file * * @param $path * @return int */ protected function checkFile($path) { $sqlFile = file_get_contents($path); if (! $sqlFile) { $this->printMessageError('Unable to open file'); return 1; } $this->printMessage('Checking started...'); $options = $this->getOpts(); $shouldFix = isset($options['f']); if ($shouldFix) { $this->printMessage('Will fix problems automatically if exist'); } else { $this->printMessage('Just check and output problems'); } $outputPath = null; if (! empty($options['o'])) { $outputPath = $options['o']; } elseif (! empty($options['output'])) { $outputPath = $options['output']; } if (isset($outputPath)) { file_put_contents($outputPath, ""); } $errorCount = 0; $queries = explode(';', $sqlFile); $queryCount = sizeof($queries); for ($i = 1; $i < $queryCount; $i++) { $query = preg_replace('/\s*/m', '', $queries[$i]); $startPos = stripos($query, "CREATETABLE`"); if ($startPos !== false) { $endPos = strpos($query, "`", $startPos + 12); if ($endPos !== false) { $tableName = substr($query, $startPos + 12, $endPos - $startPos - 12); $prevQuery = preg_replace('/\s*/m', '', $queries[$i - 1]); $dropPos = stripos($prevQuery, "DROPTABLEIFEXISTS`" . $tableName . "`"); if ($dropPos === false) { $message = "CREATE TABLE `" . $tableName . "`: missing DROP TABLE IF EXISTS statement"; $this->printMessageError($message, $outputPath); if ($shouldFix) { $dropStatement = PHP_EOL . PHP_EOL . "DROP TABLE IF EXISTS `" . $tableName . "`"; array_splice($queries, $i++, 0, $dropStatement); $queryCount++; } $errorCount++; } } } } $fixedCount = 0; if ($errorCount > 0 and $shouldFix) { for ($i = 0; $i < sizeof($queries) - 1; $i++) { $curQuery = $queries[$i]; $nextQuery = $queries[$i + 1]; if ( strpos($curQuery, "DROP TABLE IF EXISTS") !== false && substr($nextQuery, 0, 2) === (PHP_EOL . PHP_EOL) ) { $queries[++$i] = substr($nextQuery, 1); } } $success = file_put_contents($path, implode(";", $queries)); if ($success === false) { $this->printMessageError('Failed to save fixed content', $outputPath); } else { $this->printMessage('Saved fixed content', $outputPath); $fixedCount = $errorCount; } } $this->printMessageError( $errorCount . " errors found" . ($shouldFix ? ", " . $fixedCount . " errors fixed" : "") ); $this->printMessage('Completed'); return $errorCount - $fixedCount; } } // Make sure script is run from a shell if (PHP_SAPI !== 'cli') { die("Please run from a shell"); } $checker = new CheckSchemaSqlDrop(); $errors = $checker->execute(); if ($errors > 0) { exit(1); } exit(0);