mautic / app /bundles /CoreBundle /Doctrine /Helper /ColumnSchemaHelper.php
chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
namespace Mautic\CoreBundle\Doctrine\Helper;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Table;
use Mautic\CoreBundle\Exception\SchemaException;
/**
* Used to manipulate the schema of an existing table.
*/
class ColumnSchemaHelper
{
/**
* @var \Doctrine\DBAL\Schema\AbstractSchemaManager<\Doctrine\DBAL\Platforms\AbstractMySQLPlatform>
*/
protected \Doctrine\DBAL\Schema\AbstractSchemaManager $sm;
/**
* @var string
*/
protected $tableName;
/**
* @var Table
*/
protected $fromTable;
/**
* @var Table
*/
protected $toTable;
private $columns;
/**
* @param string $prefix
*/
public function __construct(
protected Connection $db,
protected $prefix
) {
$this->sm = $db->createSchemaManager();
}
/**
* Set the table to be manipulated.
*
* @param bool $addPrefix
*
* @return $this
*
* @throws SchemaException
*/
public function setName($table, $addPrefix = true)
{
$this->tableName = ($addPrefix) ? $this->prefix.$table : $table;
// make sure the table exists
$this->checkTableExists($this->tableName, true);
// use the to schema to get table details so that changes will be calculated
$this->fromTable = $this->sm->introspectTable($this->tableName);
$this->toTable = clone $this->fromTable;
return $this;
}
/**
* Get the SchemaManager.
*
* @return \Doctrine\DBAL\Schema\AbstractSchemaManager<\Doctrine\DBAL\Platforms\AbstractMySQLPlatform>
*/
public function getSchemaManager()
{
return $this->sm;
}
/**
* Get table details.
*
* @return Table
*/
public function getTable()
{
return $this->toTable;
}
/**
* Get array of Doctrine\DBAL\Schema\Column instances for the table.
*
* @return array
*/
public function getColumns()
{
if (empty($this->columns)) {
$this->columns = $this->toTable->getColumns();
}
return $this->columns;
}
/**
* Add an array of columns to the table.
*
* @throws SchemaException
*/
public function addColumns(array $columns): void
{
// ensure none of the columns exist before manipulating the schema
foreach ($columns as $column) {
if (empty($column['name'])) {
throw new SchemaException('Column is missing required name key.');
}
$this->checkColumnExists($column['name'], true);
}
// now add the columns
foreach ($columns as $column) {
$this->addColumn($column, false);
}
}
/**
* Add a column to the table.
*
* ['name'] string (required) unique name of column; cannot already exist
* ['type'] string (optional) Doctrine type for column; defaults to text
* ['options'] array (optional) Defining options for column
*
* @param bool $checkExists Check if table exists; pass false if this has already been done
*
* @return $this
*
* @throws SchemaException
*/
public function addColumn(array $column, $checkExists = true)
{
if (empty($column['name'])) {
throw new SchemaException('Column is missing required name key.');
}
if ($checkExists) {
$this->checkColumnExists($column['name'], true);
}
$type = $column['type'] ?? 'text';
$options = $column['options'] ?? [];
$this->toTable->addColumn($column['name'], $type, $options);
return $this;
}
/**
* Drops a column from table.
*
* @return $this
*/
public function dropColumn($columnName)
{
if ($this->checkColumnExists($columnName)) {
$this->toTable->dropColumn($columnName);
}
return $this;
}
/**
* Computes and executes the changes.
*/
public function executeChanges(): void
{
// create a table diff
$comparator = new Comparator();
$diff = $comparator->compareTables($this->fromTable, $this->toTable);
if (!$diff->isEmpty()) {
$this->sm->alterTable($diff);
}
}
/**
* Determine if a column already exists.
*
* @param string $column
* @param bool $throwException
*
* @throws SchemaException
*/
public function checkColumnExists($column, $throwException = false): bool
{
// check to ensure column doesn't exist
if ($this->toTable->hasColumn($column)) {
if ($throwException) {
throw new SchemaException("The column {$column} already exists in {$this->tableName}");
}
return true;
}
return false;
}
/**
* Determine if a table exists.
*
* @param bool|false $throwException
*
* @return bool
*
* @throws SchemaException
*/
public function checkTableExists($table, $throwException = false)
{
if (!$this->sm->tablesExist($table)) {
if ($throwException) {
throw new SchemaException("Table $table does not exist!");
} else {
return false;
}
} else {
return true;
}
}
}