123 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php namespace MapGuesser\Cli;
 | 
						|
 | 
						|
use SokoWeb\Database\Query\Modify;
 | 
						|
use SokoWeb\Database\Query\Select;
 | 
						|
use SokoWeb\Interfaces\Database\IResultSet;
 | 
						|
use Symfony\Component\Console\Command\Command;
 | 
						|
use Symfony\Component\Console\Input\InputInterface;
 | 
						|
use Symfony\Component\Console\Output\OutputInterface;
 | 
						|
 | 
						|
class MigrateDatabaseCommand extends Command
 | 
						|
{
 | 
						|
    public function configure(): void
 | 
						|
    {
 | 
						|
        $this->setName('db:migrate')
 | 
						|
            ->setDescription('Migration of database changes.');
 | 
						|
    }
 | 
						|
 | 
						|
    public function execute(InputInterface $input, OutputInterface $output): int
 | 
						|
    {
 | 
						|
        $db = \Container::$dbConnection;
 | 
						|
 | 
						|
        $db->startTransaction();
 | 
						|
 | 
						|
        $success = [];
 | 
						|
        try {
 | 
						|
            foreach ($this->readDir('structure') as $file) {
 | 
						|
                $db->multiQuery(file_get_contents($file));
 | 
						|
 | 
						|
                $success[] = $this->saveToDB($file, 'structure');
 | 
						|
            }
 | 
						|
 | 
						|
            foreach ($this->readDir('data') as $file) {
 | 
						|
                require $file;
 | 
						|
 | 
						|
                $success[] = $this->saveToDB($file, 'data');
 | 
						|
            }
 | 
						|
        } catch (\Exception $e) {
 | 
						|
            $db->rollback();
 | 
						|
 | 
						|
            $output->writeln('<error>Migration failed!</error>');
 | 
						|
            $output->writeln('');
 | 
						|
 | 
						|
            $output->writeln((string) $e);
 | 
						|
            $output->writeln('');
 | 
						|
 | 
						|
            return 1;
 | 
						|
        }
 | 
						|
 | 
						|
        $db->commit();
 | 
						|
 | 
						|
        $output->writeln('<info>Migration was successful!</info>');
 | 
						|
        $output->writeln('');
 | 
						|
 | 
						|
        if (count($success) > 0) {
 | 
						|
            foreach ($success as $migration) {
 | 
						|
                $output->writeln($migration);
 | 
						|
            }
 | 
						|
 | 
						|
            $output->writeln('');
 | 
						|
        }
 | 
						|
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    private function readDir(string $type): array
 | 
						|
    {
 | 
						|
        $done = [];
 | 
						|
 | 
						|
        $migrationTableExists = \Container::$dbConnection->query('SELECT count(*)
 | 
						|
            FROM information_schema.tables
 | 
						|
            WHERE table_schema = \'' . $_ENV['DB_NAME'] . '\'
 | 
						|
            AND table_name = \'migrations\';')
 | 
						|
            ->fetch(IResultSet::FETCH_NUM)[0];
 | 
						|
 | 
						|
        if ($migrationTableExists != 0) {
 | 
						|
            $select = new Select(\Container::$dbConnection, 'migrations');
 | 
						|
            $select->columns(['migration']);
 | 
						|
            $select->where('type', '=', $type);
 | 
						|
            $select->orderBy('migration');
 | 
						|
 | 
						|
            $result = $select->execute();
 | 
						|
 | 
						|
            while ($migration = $result->fetch(IResultSet::FETCH_ASSOC)) {
 | 
						|
                $done[] = $migration['migration'];
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        $path = ROOT . '/database/migrations/' . $type;
 | 
						|
        $dir = opendir($path);
 | 
						|
 | 
						|
        if ($dir === false) {
 | 
						|
            throw new \Exception('Cannot open dir: ' . $path);
 | 
						|
        }
 | 
						|
 | 
						|
        $files = [];
 | 
						|
        while ($file = readdir($dir)) {
 | 
						|
            $filePath = $path . '/' . $file;
 | 
						|
 | 
						|
            if (!is_file($filePath) || in_array(pathinfo($file, PATHINFO_FILENAME), $done)) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
 | 
						|
            $files[] = $filePath;
 | 
						|
        }
 | 
						|
 | 
						|
        natsort($files);
 | 
						|
 | 
						|
        return $files;
 | 
						|
    }
 | 
						|
 | 
						|
    private function saveToDB(string $file, string $type): string
 | 
						|
    {
 | 
						|
        $baseName = pathinfo($file, PATHINFO_FILENAME);
 | 
						|
 | 
						|
        $modify = new Modify(\Container::$dbConnection, 'migrations');
 | 
						|
        $modify->set('migration', $baseName);
 | 
						|
        $modify->set('type', $type);
 | 
						|
        $modify->save();
 | 
						|
 | 
						|
        return $baseName . ' (' . $type . ')';
 | 
						|
    }
 | 
						|
}
 |