Advertisement
Guest User

Untitled

a guest
Apr 5th, 2018
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.98 KB | None | 0 0
  1. <?php
  2.  
  3. namespace AppBundle\Test;
  4.  
  5. use AppKernel;
  6. use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
  7. use Doctrine\Common\DataFixtures\Loader;
  8. use Doctrine\Common\DataFixtures\Purger\ORMPurger;
  9. use Symfony\Bundle\FrameworkBundle\Console\Application;
  10. use Symfony\Component\Console\Input\ArrayInput;
  11. use Symfony\Component\Console\Output\BufferedOutput;
  12. use Symfony\Component\DependencyInjection\ContainerInterface;
  13.  
  14. class DatabasePool
  15. {
  16.     const DB_DUMP_FILE = 'db-dump.sql';
  17.  
  18.     /**
  19.      * @var ContainerInterface
  20.      */
  21.     protected $container;
  22.  
  23.     /**
  24.      * @var string
  25.      */
  26.     protected $databaseName;
  27.  
  28.     /**
  29.      * @var string
  30.      */
  31.     protected $databaseHost;
  32.  
  33.     /**
  34.      * @var int
  35.      */
  36.     protected $databasePort;
  37.  
  38.     /**
  39.      * @var string
  40.      */
  41.     protected $databaseUser;
  42.  
  43.     /**
  44.      * @var string
  45.      */
  46.     protected $databasePassword;
  47.  
  48.     /**
  49.      * @var string
  50.      */
  51.     protected $createSchemaQueries;
  52.  
  53.     protected static $pdo;
  54.  
  55.     public function __construct(ContainerInterface $container, $databaseName, $databaseHost, $databasePort, $databaseUser, $databasePassword)
  56.     {
  57.         $this->container = $container;
  58.         $this->databaseName = $databaseName;
  59.         $this->databaseHost = $databaseHost;
  60.         $this->databasePort = $databasePort;
  61.         $this->databaseUser = $databaseUser;
  62.         $this->databasePassword = $databasePassword;
  63.  
  64.         if (is_null(self::$pdo)) {
  65.             self::$pdo = new \PDO("mysql:host=$this->databaseHost;port=$this->databasePort", $this->databaseUser, $this->databasePassword);
  66.             self::$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, 1);
  67.         }
  68.     }
  69.  
  70.     public function get()
  71.     {
  72.         $pooledDatabases = $this->getPool();
  73.  
  74.         $dbName = $this->databaseName;
  75.  
  76.         if (getenv('TEST_TOKEN') !== false) {
  77.             $token = getenv('TEST_TOKEN');
  78.  
  79.             if ($token > 0) {
  80.                 $dbName = $this->getDatabasePrefix() . getenv('TEST_TOKEN');
  81.             }
  82.         }
  83.  
  84.         if (count($pooledDatabases) == 0) {
  85. //            throw new \RuntimeException("Database pool is empty");
  86.         } else {
  87.             if (in_array($dbName, $pooledDatabases)) {
  88.                 return $dbName;
  89.             }
  90.  
  91.             throw new \RuntimeException("Test database '$dbName' not found");
  92.         }
  93.     }
  94.  
  95.     public function fillPool($size)
  96.     {
  97.         if ($size <= 0) {
  98.             throw new \UnexpectedValueException('Pool size must be greater than 0');
  99.         }
  100.  
  101.         foreach ($this->getPool() as $pooledDatabase) {
  102.             self::$pdo->exec("DROP DATABASE {$pooledDatabase}");
  103.         }
  104.  
  105.         $databaseName = $this->getDatabasePrefix();
  106.         $this->createDatabase($databaseName);
  107.         $this->createSchema();
  108.         $this->loadFixtures();
  109.         $this->dumpDatabase();
  110.  
  111.         for ($i = 1; $i <= $size; $i++) {
  112.             $databaseName = $this->getDatabasePrefix() . $i;
  113.             $this->createDatabase($databaseName);
  114.         }
  115.     }
  116.  
  117.     private function dumpDatabase()
  118.     {
  119.         $command = "mysqldump --opt --lock-tables=false --port=$this->databasePort --host=$this->databaseHost --user=$this->databaseUser --password=$this->databasePassword";
  120.  
  121.         $command .= sprintf(' %s > %s', $this->databaseName, $this->getDbDumpFilename($this->container));
  122.         $command .= ' 2>/dev/null';
  123.  
  124.         exec($command);
  125.     }
  126.  
  127.     public function loadDatabaseFromDump()
  128.     {
  129.         $command = "mysql --port=$this->databasePort --host=$this->databaseHost --user=$this->databaseUser --password=$this->databasePassword";
  130.  
  131.         $command .= sprintf(' %s < %s', $this->get(), $this->getDbDumpFilename($this->container));
  132.         $command .= ' 2>/dev/null';
  133.  
  134.         exec($command);
  135.     }
  136.  
  137.     /**
  138.      * @return array
  139.      */
  140.     protected function getPool()
  141.     {
  142.         $sql = "
  143.        SELECT `schema_name`
  144.        FROM information_schema.schemata
  145.        WHERE `schema_name` LIKE '{$this->getDatabasePrefix()}%'
  146.        ORDER BY `schema_name` DESC
  147.        ";
  148.  
  149.         return self::$pdo->query($sql)->fetchAll(\PDO::FETCH_COLUMN);
  150.     }
  151.  
  152.     protected function createDatabase($name)
  153.     {
  154.         self::$pdo->query("CREATE DATABASE IF NOT EXISTS $name");
  155.         self::$pdo->query("USE $name");
  156.     }
  157.  
  158.     protected function executeCommand($commandName, $parameters = [])
  159.     {
  160.         $kernel = new AppKernel('test', true);
  161.  
  162.         $application = new Application($kernel);
  163.         $application->setAutoExit(false);
  164.  
  165.         $input = new ArrayInput(array_merge(['command' => $commandName], $parameters));
  166.  
  167.         $output = new BufferedOutput();
  168.         $application->run($input, $output);
  169.  
  170.         return $output->fetch();
  171.     }
  172.  
  173.     protected function getDatabasePrefix()
  174.     {
  175.         return $this->databaseName;
  176.     }
  177.  
  178.     protected function createSchema()
  179.     {
  180.         $query = $this->executeCommand('doctrine:schema:create', ['--dump-sql' => true]);
  181.         self::$pdo->query($query);
  182.     }
  183.  
  184.     protected function loadFixtures()
  185.     {
  186.         $fixturesLoader = new Loader();
  187.  
  188.         $fixturesLoader->loadFromDirectory($this->container->getParameter('kernel.root_dir') . '/../tests/Fixtures');
  189.  
  190.         foreach ($fixturesLoader->getFixtures() as $fixture) {
  191.             if (method_exists($fixture, 'setContainer')) {
  192.                 $fixture->setContainer($this->container);
  193.             }
  194.         }
  195.  
  196.         $em = $this->container->get('doctrine.orm.entity_manager');
  197.  
  198.         $purger = new ORMPurger($em);
  199.         $purger->setPurgeMode(ORMPurger::PURGE_MODE_DELETE);
  200.  
  201.         $executor = new ORMExecutor($em, $purger);
  202.         $executor->execute($fixturesLoader->getFixtures());
  203.     }
  204.  
  205.     public function closeConnection()
  206.     {
  207.         self::$pdo = null;
  208.     }
  209.  
  210.     public static function getDbDumpFilename(ContainerInterface $container)
  211.     {
  212.         return $container->getParameter('kernel.cache_dir') . '/' . self::DB_DUMP_FILE;
  213.     }
  214. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement