📄 AbstractAsset.php
📁 Path: /home/skhata/chandrasons.com/vendor/doctrine/dbal/src/Schema/AbstractAsset.php
📊 Size: 14.39 KB
🔒 Perm: 0644
📝 MIME: text/x-php
<?php
declare(strict_types=1);
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\Exception\NotImplemented;
use Doctrine\DBAL\Schema\Name\GenericName;
use Doctrine\DBAL\Schema\Name\Identifier;
use Doctrine\DBAL\Schema\Name\OptionallyQualifiedName;
use Doctrine\DBAL\Schema\Name\Parser;
use Doctrine\DBAL\Schema\Name\UnqualifiedName;
use Doctrine\Deprecations\Deprecation;
use Throwable;
use function array_map;
use function count;
use function crc32;
use function dechex;
use function explode;
use function implode;
use function sprintf;
use function str_contains;
use function str_replace;
use function strtolower;
use function strtoupper;
use function substr;
/**
* The abstract asset allows to reset the name of all assets without publishing this to the public userland.
*
* This encapsulation hack is necessary to keep a consistent state of the database schema. Say we have a list of tables
* array($tableName => Table($tableName)); if you want to rename the table, you have to make sure this does not get
* recreated during schema migration.
*
* @internal This class should be extended only by DBAL itself.
*
* @template N of Name
*/
abstract class AbstractAsset
{
protected string $_name = '';
/**
* Indicates whether the object name has been initialized.
*/
protected bool $isNameInitialized = false;
/**
* Namespace of the asset. If none isset the default namespace is assumed.
*
* @deprecated Use {@see NamedObject::getObjectName()} and {@see OptionallyQualifiedName::getQualifier()} instead.
*/
protected ?string $_namespace = null;
/** @deprecated */
protected bool $_quoted = false;
/** @var list<Identifier> */
private array $identifiers = [];
private bool $validateFuture = false;
public function __construct(?string $name = null)
{
if ($name === null) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6610',
'Not passing $name to %s is deprecated.',
__METHOD__,
);
return;
}
$this->_setName($name);
}
/**
* Returns a parser for parsing the object name.
*
* @deprecated Parse the name in the constructor instead.
*
* @return Parser<N>
*/
protected function getNameParser(): Parser
{
throw NotImplemented::fromMethod(static::class, __FUNCTION__);
}
/**
* Sets the object name.
*
* @deprecated Set the name in the constructor instead.
*
* @param ?N $name
*/
protected function setName(?Name $name): void
{
throw NotImplemented::fromMethod(static::class, __FUNCTION__);
}
/**
* Sets the name of this asset.
*
* @deprecated Use the constructor instead.
*/
protected function _setName(string $name): void
{
$this->isNameInitialized = false;
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6610',
'%s is deprecated. Use the constructor instead.',
__METHOD__,
);
$input = $name;
if ($this->isIdentifierQuoted($name)) {
$this->_quoted = true;
$name = $this->trimQuotes($name);
}
if (str_contains($name, '.')) {
$parts = explode('.', $name);
$this->_namespace = $parts[0];
$name = $parts[1];
}
$this->_name = $name;
$this->validateFuture = false;
if ($input !== '') {
try {
$parsedName = $this->getNameParser()->parse($input);
} catch (NotImplemented $e) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6592',
'Unable to parse object name: %s.',
$e->getMessage(),
);
return;
} catch (Throwable $e) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6592',
'Unable to parse object name: %s.',
$e->getMessage(),
);
return;
}
} else {
$parsedName = null;
}
try {
$this->setName($parsedName);
} catch (Throwable $e) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6646',
'Using invalid database object names is deprecated: %s.',
$e->getMessage(),
);
return;
}
$this->isNameInitialized = true;
if ($parsedName === null) {
$this->identifiers = [];
return;
}
if ($parsedName instanceof UnqualifiedName) {
$identifiers = [$parsedName->getIdentifier()];
} elseif ($parsedName instanceof OptionallyQualifiedName) {
$unqualifiedName = $parsedName->getUnqualifiedName();
$qualifier = $parsedName->getQualifier();
$identifiers = $qualifier !== null
? [$qualifier, $unqualifiedName]
: [$unqualifiedName];
} elseif ($parsedName instanceof GenericName) {
$identifiers = $parsedName->getIdentifiers();
} else {
return;
}
switch (count($identifiers)) {
case 1:
$namespace = null;
$name = $identifiers[0];
break;
case 2:
[$namespace, $name] = $identifiers;
break;
default:
return;
}
$this->identifiers = $identifiers;
$this->validateFuture = true;
$futureName = $name->getValue();
$futureNamespace = $namespace?->getValue();
if ($this->_name !== $futureName) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6592',
'Instead of "%s", this name will be interpreted as "%s" in 5.0',
$this->_name,
$futureName,
);
}
if ($this->_namespace === $futureNamespace) {
return;
}
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6592',
'Instead of %s, the namespace in this name will be interpreted as %s in 5.0.',
$this->_namespace !== null ? sprintf('"%s"', $this->_namespace) : 'null',
$futureNamespace !== null ? sprintf('"%s"', $futureNamespace) : 'null',
);
}
/**
* Is this asset in the default namespace?
*
* @deprecated
*/
public function isInDefaultNamespace(string $defaultNamespaceName): bool
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6664',
'%s is deprecated and will be removed in 5.0.',
__METHOD__,
);
return $this->_namespace === $defaultNamespaceName || $this->_namespace === null;
}
/**
* Gets the namespace name of this asset.
*
* If NULL is returned this means the default namespace is used.
*
* @deprecated Use {@see NamedObject::getObjectName()} and {@see OptionallyQualifiedName::getQualifier()} instead.
*/
public function getNamespaceName(): ?string
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6664',
'%s is deprecated and will be removed in 5.0. Use NamedObject::getObjectName()'
. ' and OptionallyQualifiedName::getQualifier() instead.',
__METHOD__,
);
return $this->_namespace;
}
/**
* The shortest name is stripped of the default namespace. All other
* namespaced elements are returned as full-qualified names.
*
* @deprecated Use {@see NamedObject::getObjectName()} instead.
*/
public function getShortestName(?string $defaultNamespaceName): string
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6657',
'%s is deprecated and will be removed in 5.0.',
__METHOD__,
);
$shortestName = $this->getName();
if ($this->_namespace === $defaultNamespaceName) {
$shortestName = $this->_name;
}
return strtolower($shortestName);
}
/**
* Checks if this asset's name is quoted.
*
* @deprecated Depending on the concrete class of the object, use {@see NamedObject::getObjectName()} or
* {@see OptionallyNamedObject::getObjectName()} to get the name. Then, depending on the type of the
* name, use {@see UnqualifiedName::getIdentifier()}, {@see OptionallyQualifiedName::getQualifier()},
* or {@see OptionallyQualifiedName::getUnqualifiedName()} to get the corresponding identifiers. Then,
* use {@see Identifier::$isQuoted()}.
*/
public function isQuoted(): bool
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/7084',
'%s is deprecated and will be removed in 5.0.',
__METHOD__,
);
return $this->_quoted;
}
/**
* Checks if this identifier is quoted.
*
* @deprecated Parse the name and introspect its identifiers individually using {@see Identifier::isQuoted()}
* instead.
*/
protected function isIdentifierQuoted(string $identifier): bool
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6677',
'%s is deprecated and will be removed in 5.0.',
__METHOD__,
);
return isset($identifier[0]) && ($identifier[0] === '`' || $identifier[0] === '"' || $identifier[0] === '[');
}
/**
* Trim quotes from the identifier.
*/
protected function trimQuotes(string $identifier): string
{
return str_replace(['`', '"', '[', ']'], '', $identifier);
}
/**
* Returns the name of this schema asset.
*
* @deprecated Use {@see NamedObject::getObjectName()} or {@see OptionallyQualifiedName::getObjectName()} instead.
* In SQL context, convert the resulting {@see Name} to SQL using {@see Name::toSQL()}. In other
* contexts, convert the resulting name to string using {@see Name::toString()}.
*/
public function getName(): string
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/7094',
'%s is deprecated and will be removed in 5.0.',
__METHOD__,
);
if ($this->_namespace !== null) {
return $this->_namespace . '.' . $this->_name;
}
return $this->_name;
}
/**
* Gets the quoted representation of this asset but only if it was defined with one. Otherwise
* return the plain unquoted value as inserted.
*
* @deprecated Use {@see NamedObject::getObjectName()} or {@see OptionallyQualifiedName::getObjectName()} followed
* by {@see Name::toSQL()} instead.
*/
public function getQuotedName(AbstractPlatform $platform): string
{
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6674',
'%s is deprecated and will be removed in 5.0.',
__METHOD__,
);
$keywords = $platform->getReservedKeywordsList();
$folding = $platform->getUnquotedIdentifierFolding();
$parts = $normalizedParts = [];
foreach (explode('.', $this->getName()) as $identifier) {
$isQuoted = $this->_quoted || $keywords->isKeyword($identifier);
if (! $isQuoted) {
$parts[] = $identifier;
/** @phpstan-ignore argument.type */
$normalizedParts[] = $folding->foldUnquotedIdentifier($identifier);
} else {
$parts[] = $platform->quoteSingleIdentifier($identifier);
$normalizedParts[] = $identifier;
}
}
$name = implode('.', $parts);
if ($this->validateFuture) {
$futureParts = array_map(static function (Identifier $identifier) use ($folding): string {
$value = $identifier->getValue();
if (! $identifier->isQuoted()) {
$value = $folding->foldUnquotedIdentifier($value);
}
return $value;
}, $this->identifiers);
if ($normalizedParts !== $futureParts) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6592',
'Relying on implicitly quoted identifiers preserving their original case is deprecated. '
. 'The current name %s will become %s in 5.0. '
. 'Please quote the name if the case needs to be preserved.',
$name,
implode('.', array_map([$platform, 'quoteSingleIdentifier'], $futureParts)),
);
}
}
return $name;
}
/**
* Generates an identifier from a list of column names obeying a certain string length.
*
* This is especially important for Oracle, since it does not allow identifiers larger than 30 chars,
* however building idents automatically for foreign keys, composite keys or such can easily create
* very long names.
*
* @param array<int, string> $columnNames
* @param positive-int $maxSize
*
* @return non-empty-string
*/
protected function _generateIdentifierName(array $columnNames, string $prefix = '', int $maxSize = 30): string
{
$hash = implode('', array_map(static function ($column): string {
return dechex(crc32($column));
}, $columnNames));
return strtoupper(substr($prefix . '_' . $hash, 0, $maxSize));
}
}