Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 26
Updater
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 5
90.00
0.00% covered (danger)
0.00%
0 / 26
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 exists
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 getCurrentVersion
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 3
 update
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 runAllUpdatesFor
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 14
<?php
namespace Luxian\Database\Schema;
use Luxian\Database\DatabaseInterface;
use Luxian\Database\Schema\Version;
class Updater
{
    private $db;
    private static $schemaVersion = [
        0 => Version\SchemaVersion::class,
        1 => Version\SchemaVersion01::class,
    ];
    public function __construct(DatabaseInterface $db)
    {
        $this->db = $db;
    }
    public function exists(): bool
    {
        $result = $this->db->query('SHOW TABLES LIKE "schema_versions"');
        return $result->fetchColumn();
    }
    public function getCurrentVersion(): int
    {
        $sql = '
            SELECT version 
            FROM `schema_versions` 
            ORDER BY version DESC 
            LIMIT 0, 1
        ';
        $result = $this->db->query($sql);
        return $result->fetchColumn();
    }
    /** @throws \Exception */
    public function update(): void
    {
        $currentVersion = -1; // not installed
        if ($this->exists()) {
            $currentVersion = $this->getCurrentVersion();
        }
        $this->runAllUpdatesFor($currentVersion);
    }
    /** @throws \Exception */
    private function runAllUpdatesFor(int $currentVersion): void
    {
        foreach (self::$schemaVersion as $versionNumber => $versionClass) {
            if ($versionNumber <= $currentVersion) {
                continue; // ignore already installed versions
            }
            try {
                $this->db->beginTransaction();
                /** @var VersionInterface $version */
                $version = new $versionClass($this->db);
                $version->install();
                $sql = '
                    INSERT INTO `schema_versions` (`version`, `date`) 
                    VALUES (:version, :timestamp)
                ';
                $values = ['version' => $versionNumber, 'timestamp' => time()];
                $this->db->query($sql, $values);
                $this->db->commitTransaction();
            } catch (\Exception $e) {
                $this->db->rollBackTransaction();
                throw $e;
            }
        }
    }
}