db = $db; $this->driver = $driver; } /** * @param TableSchema $targetSchema * * @throws EscapingException * @throws Exception\LineGeneratorException * @throws SchemaCreatorTableException * @throws TransactionException * * @return void */ public function ensureSchema(TableSchema $targetSchema): void { $this->applyTableSchema($targetSchema); } /** * @param TableSchema $currentSchema * @param TableSchema $targetSchema * * @throws EscapingException * * @return string */ public function getDiffSQL(TableSchema $currentSchema, TableSchema $targetSchema): string { return $this->driver->generateTableSchemaDiff($currentSchema, $targetSchema); } /** * @param string $table * * @throws Exception\LineGeneratorException * @throws SchemaCreatorTableException * * @return TableSchema */ public function createFromExistingTable(string $table): TableSchema { return $this->driver->loadFromTable($table); } /** * @param TableSchema $targetSchema * * @throws EscapingException * @throws Exception\LineGeneratorException * @throws SchemaCreatorTableException * @throws TransactionException * * @return void */ private function applyTableSchema(TableSchema $targetSchema): void { $sqlSchema = $this->getSqlSchema($targetSchema); $this->applySqlSchema($sqlSchema); } /** * Check whether the table exists * * @param string $tableName * * @return bool */ private function hasTable(string $tableName): bool { $tables = $this->db->fetchCol('SHOW TABLES'); return in_array($tableName, $tables, true); } /** * @param TableSchema $schema * * @throws EscapingException * * @return string */ private function generateSQLDefinition(TableSchema $schema): string { return $this->driver->getTableDefinition($schema); } /** * @param TableSchema $schema * * @throws EscapingException * @throws Exception\LineGeneratorException * @throws SchemaCreatorTableException * * @return string */ public function getSqlSchema(TableSchema $schema): string { $table = $schema->getTable(); if (!$this->hasTable($table)) { return $this->generateSQLDefinition($schema); } $currentSchema = $this->createFromExistingTable($table); $diffSQL = $this->getDiffSQL($currentSchema, $schema); if (empty($diffSQL)) { return ''; } return $diffSQL; } /** * @param string $sql * * @throws SchemaCreatorTableException * @throws TransactionException * * @return void */ private function applySqlSchema(string $sql): void { if (empty($sql)) { return; } $this->db->beginTransaction(); try { $this->db->exec($sql); $this->db->commit(); } catch (DatabaseExceptionInterface $e) { $this->db->rollBack(); throw new SchemaCreatorTableException($e->getMessage(), (int)$e->getCode(), $e); } } }