diff --git a/src/Config/DefaultConfiguration.php b/src/Config/DefaultConfiguration.php new file mode 100644 index 0000000..a4fd89f --- /dev/null +++ b/src/Config/DefaultConfiguration.php @@ -0,0 +1,40 @@ + $_ENV['DB_HOST'] ?? $_ENV['DB_PORT_3306_TCP_ADDR'] ?? 'localhost', + 'port' => $_ENV['DB_PORT'] ?? $_ENV['DB_PORT_3306_TCP_PORT'] ?? 3306, + 'user' => $_ENV['DB_USER'] ?? 'root', + 'pass' => $_ENV['DB_PASS'] ?? $_ENV['DB_ENV_MYSQL_ROOT_PASSWORD'] ?? '', + ]; + } + +} diff --git a/src/Runner/TasksMap.php b/src/Runner/TasksMap.php index 27bbae8..856e5b0 100644 --- a/src/Runner/TasksMap.php +++ b/src/Runner/TasksMap.php @@ -1,27 +1,29 @@ CreateDatabase::class, 'sites:bootstrap' => BootstrapSqliteRepository::class, ]; } public static function getTaskClassName (string $command) { foreach (self::getMap() as $taskCommand => $taskClassName) { if ($command === $taskCommand) { return $taskClassName; } } throw new InvalidArgumentException; } } diff --git a/src/SitesRepository/Repository.php b/src/SitesRepository/Repository.php index 842e13c..646ea63 100644 --- a/src/SitesRepository/Repository.php +++ b/src/SitesRepository/Repository.php @@ -1,7 +1,9 @@ id; + } + + public function setId (string $id) : Site { + $this->id = $id; + + if (!$this->hasValidIdentifiant()) { + throw new \InvalidArgumentException( + "ID must only contain letters, digits and underscore." + ); + } + + return $this; + } + + public function getHost () : string { + return $this->host; + } + + public function setHost (string $host) : Site { + $this->host = $host; + + return $this; + } + + public function getDatabaseUser () : string { + return $this->databaseUser; + } + + public function setDatabaseUser (string $databaseUser) : Site { + $this->databaseUser = $databaseUser; + + return $this; + } + + public function getDatabasePassword () : string { + return $this->databasePassword; + } + + public function setDatabasePassword (string $databasePassword) : Site { + $this->databasePassword = $databasePassword; + + return $this; + } + + public function getDatabasePrefix () : string { + return $this->databasePrefix; + } + + public function setDatabasePrefix (string $databasePrefix) : Site { + $this->databasePrefix = $databasePrefix; + + return $this; + } + + public function isActive () : bool { + return $this->active; + } + + public function setActive (bool $active) : Site { + $this->active = $active; + + return $this; + } + + /// + /// Identifiant validation + /// + + const VALID_ID_REGEXP = "/^[A-Za-z0-9_]+$/"; + + private function hasValidIdentifiant () : bool { + return (bool)preg_match(self::VALID_ID_REGEXP, $this->id); + } + +} diff --git a/src/SitesRepository/SqliteRepository.php b/src/SitesRepository/SqliteRepository.php index 30fd3a1..4aa67df 100644 --- a/src/SitesRepository/SqliteRepository.php +++ b/src/SitesRepository/SqliteRepository.php @@ -1,80 +1,102 @@ filename = $filename; + public function __construct (string $filename = null) { + $this->filename = $filename ?? DefaultConfiguration::getSqliteRepositoryFilename(); } /// /// Tasks methods /// public function bootstrap () : void { $db = $this->getDB(); $queries = $this->getSchema(); foreach ($queries as $query) { $db->query($query); } } + public function get (string $id) : Site { + $statement = $this->getDB()->prepare( + "SELECT * FROM sites WHERE id = ?" + ); + $result = $statement->execute([ $id ]); + $row = $statement->fetch(); + + if ($row === false) { + throw new \InvalidArgumentException("Site $id not found."); + } + + return (new Site()) + ->setId($row['id']) + ->setHost($row['host']) + ->setDatabaseUser($row['db_user']) + ->setDatabasePassword($row['db_password']) + ->setDatabasePrefix($row['db_prefix']) + ->setActive((bool)$row['active']); + } + /// /// Helper methods /// public function getDB() : PDO { if ($this->db === null) { if (!file_exists($this->filename)) { touch($this->filename); } $dsn = self::getDataSourceName($this->filename); $this->db = new PDO($dsn); } return $this->db; } private static function getDataSourceName (string $filename) : string { return "sqlite:" . realpath($filename); } private function getSchema () : iterable { yield <<filename = $filename ?? $this->getDefaultFilename(); + public function __construct (string $filename = null) { + $this->filename = $filename; } /// /// Public methods /// public function run () : void { (new SqliteRepository($this->filename))->bootstrap(); } public static function getUsage () : string { return <<id = $id; + } + + /// + /// Task methods + /// + + public function run () : void { + $this->initialize(); + $this->createDatabase(); + } + + private function initialize () : void { + $this->site = (new SqliteRepository)->get($this->id); + $this->db = $this->getMySQLDatabase(); + } + + private function createDatabase () : void { + $this->getMySQLDatabase() + ->prepare($this->getQueries()) + ->execute([ + 'db' => $this->site->getId(), + 'user' => $this->site->getDatabaseUser(), + 'pass' => $this->site->getDatabasePassword(), + ]); + } + + /// + /// Helper methods + /// + + private function getQueries () : string { + $queries = <<id, $queries); + } + + public static function getUsage () : string { + return <<: creates a MySQL database for the specified identifant +DOC; + } + +} diff --git a/src/Tasks/WithMySQL.php b/src/Tasks/WithMySQL.php new file mode 100644 index 0000000..2d661b6 --- /dev/null +++ b/src/Tasks/WithMySQL.php @@ -0,0 +1,22 @@ + PDO::ERRMODE_EXCEPTION ] + ); + } + +} diff --git a/tests/SitesRepository/SiteTest.php b/tests/SitesRepository/SiteTest.php new file mode 100644 index 0000000..b289c14 --- /dev/null +++ b/tests/SitesRepository/SiteTest.php @@ -0,0 +1,27 @@ +setId('acme'); + + $this->assertEquals('acme', $site->getId()); + } + + public function testSetIdWithInvalidIdentifiant () { + $this->expectException(InvalidArgumentException::class); + + $site = new Site; + $site->setId('invalid acme'); + } + +}