dadajuice/zephyrus

View on GitHub
src/Zephyrus/Database/Core/DatabaseConfiguration.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php namespace Zephyrus\Database\Core;

use PDO;
use Zephyrus\Exceptions\FatalDatabaseException;

class DatabaseConfiguration
{
    public const DEFAULT_CONFIGURATIONS = [
        'hostname' => 'localhost', // Specifies the database's server address (without port)
        'port' => '', // Port to access the database's server, leave empty to use the default port of your dbms
        'database' => '', // Database name
        'username' => '', // Username for database authentication
        'password' => '', // Password for database authentication
        'search_paths' => ['public'] // Default search_path configuration
    ];

    private array $configurations;
    private string $hostname = '';
    private string $port = '';
    private string $databaseName = '';
    private string $username = '';
    private string $password = '';
    private array $searchPaths = ['public'];

    /**
     * Wrapper to retrieve the list of currently installed DBMS's drivers.
     *
     * @return array
     */
    public static function getAvailableDrivers(): array
    {
        return PDO::getAvailableDrivers();
    }

    /**
     * @throws FatalDatabaseException
     */
    public function __construct(array $configurations = self::DEFAULT_CONFIGURATIONS)
    {
        $this->initializeConfigurations($configurations);
        $this->initializeDbms();
        $this->initializeHostname();
        $this->initializePort();
        $this->initializeDatabaseName();
        $this->initializeAuthentication();
        $this->initializeSearchPaths();
    }

    /**
     * Retrieve the configured host name indicating the network path to the database instance.
     *
     * @return string
     */
    public function getHostname(): string
    {
        return $this->hostname;
    }

    /**
     * Retrieve the configured database name to connect to once the adapter is built. Can be the filepath or ':memory:'
     * for SQLite databases.
     *
     * @return string
     */
    public function getDatabaseName(): string
    {
        return $this->databaseName;
    }

    /**
     * Retrieve the configured username (optional) for authentication purpose to the database.
     *
     * @return string
     */
    public function getUsername(): string
    {
        return $this->username;
    }

    /**
     * Retrieve the configured password (optional) for authentication purpose to the database.
     *
     * @return string
     */
    public function getPassword(): string
    {
        return $this->password;
    }

    /**
     * Retrieve the configured port (optional) to connect to the database instance.
     *
     * @return string
     */
    public function getPort(): string
    {
        return $this->port;
    }

    /**
     * Retrieve the configured search paths (optional) for the default search schema of the database.
     *
     * @return array
     */
    public function getSearchPaths(): array
    {
        return $this->searchPaths;
    }

    /**
     * Retrieves the PDO compatible DSN string for connection purpose.
     *
     * @return string
     */
    public function getDatabaseSourceName(): string
    {
        $port = (!empty($this->getPort())) ? "port={$this->getPort()};" : "";
        return 'pgsql:dbname=' . $this->getDatabaseName() . ';host=' . $this->getHostname() . ';' . $port;
    }

    private function initializeConfigurations(array $configurations): void
    {
        $this->configurations = $configurations;
    }

    /**
     * @codeCoverageIgnore
     * @throws FatalDatabaseException
     */
    private function initializeDbms(): void
    {
        if (!in_array('pgsql', self::getAvailableDrivers())) {
            throw FatalDatabaseException::driverNotAvailable('pgsql');
        }
    }

    /**
     * @throws FatalDatabaseException
     */
    private function initializeHostname(): void
    {
        if (!isset($this->configurations['hostname'])) {
            throw FatalDatabaseException::missingConfiguration('hostname');
        }
        $this->hostname = $this->configurations['hostname'];
    }

    /**
     * @throws FatalDatabaseException
     */
    private function initializeDatabaseName(): void
    {
        if (!isset($this->configurations['database'])) {
            throw FatalDatabaseException::missingConfiguration('database');
        }
        $this->databaseName = $this->configurations['database'];
    }

    /**
     * @throws FatalDatabaseException
     */
    private function initializePort(): void
    {
        if (isset($this->configurations['port']) && $this->configurations['port']) {
            if (!is_numeric($this->configurations['port'])) {
                throw FatalDatabaseException::invalidPortConfiguration();
            }
            $this->port = $this->configurations['port'];
        }
    }

    private function initializeAuthentication(): void
    {
        if (isset($this->configurations['username']) && $this->configurations['username']) {
            $this->username = $this->configurations['username'];
        }
        if (isset($this->configurations['password']) && $this->configurations['password']) {
            $this->password = $this->configurations['password'];
        }
    }

    /**
     * @throws FatalDatabaseException
     */
    private function initializeSearchPaths(): void
    {
        if (isset($this->configurations['search_paths']) && $this->configurations['search_paths']) {
            if (!is_array($this->configurations['search_paths'])) {
                throw FatalDatabaseException::invalidSearchPathsConfiguration();
            }
            $this->searchPaths = $this->configurations['search_paths'];
        }
    }
}