feat(dbal): Add missing stuff in DBAL wrapper

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
pull/63152/head
Carl Schwan 1 week ago
parent c849c3b903
commit 723db4b4a3
No known key found for this signature in database
GPG Key ID: 02325448204E452A
  1. 1
      apps/dav/lib/Migration/Version1034Date20250605132605.php
  2. 3
      lib/composer/composer/autoload_classmap.php
  3. 3
      lib/composer/composer/autoload_static.php
  4. 12
      lib/private/DB/Schema/Column.php
  5. 30
      lib/private/DB/Schema/ForeignKeyConstraint.php
  6. 5
      lib/private/DB/Schema/Index.php
  7. 33
      lib/private/DB/Schema/Table.php
  8. 60
      lib/public/AppFramework/Db/Entity.php
  9. 166
      lib/public/DB/Schema/ColumnType.php
  10. 12
      lib/public/DB/Schema/IColumn.php
  11. 26
      lib/public/DB/Schema/IForeignKeyConstraint.php
  12. 8
      lib/public/DB/Schema/IIndex.php
  13. 57
      lib/public/DB/Schema/ITable.php

@ -60,6 +60,7 @@ class Version1034Date20250605132605 extends SimpleMigrationStep {
'notnull' => true,
'length' => 255,
]);
/** @psalm-suppress InvalidArgument legacy column */
$federatedCalendarsTable->addColumn('remote_Url', Types::STRING, [
'notnull' => true,
'length' => 255,

@ -372,7 +372,9 @@ return array(
'OCP\\DB\\QueryBuilder\\IQueryFunction' => $baseDir . '/lib/public/DB/QueryBuilder/IQueryFunction.php',
'OCP\\DB\\QueryBuilder\\ITypedQueryBuilder' => $baseDir . '/lib/public/DB/QueryBuilder/ITypedQueryBuilder.php',
'OCP\\DB\\QueryBuilder\\Sharded\\IShardMapper' => $baseDir . '/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php',
'OCP\\DB\\Schema\\ColumnType' => $baseDir . '/lib/public/DB/Schema/ColumnType.php',
'OCP\\DB\\Schema\\IColumn' => $baseDir . '/lib/public/DB/Schema/IColumn.php',
'OCP\\DB\\Schema\\IForeignKeyConstraint' => $baseDir . '/lib/public/DB/Schema/IForeignKeyConstraint.php',
'OCP\\DB\\Schema\\IIndex' => $baseDir . '/lib/public/DB/Schema/IIndex.php',
'OCP\\DB\\Schema\\ITable' => $baseDir . '/lib/public/DB/Schema/ITable.php',
'OCP\\DB\\Schema\\IType' => $baseDir . '/lib/public/DB/Schema/IType.php',
@ -1785,6 +1787,7 @@ return array(
'OC\\DB\\SQLiteSessionInit' => $baseDir . '/lib/private/DB/SQLiteSessionInit.php',
'OC\\DB\\SchemaWrapper' => $baseDir . '/lib/private/DB/SchemaWrapper.php',
'OC\\DB\\Schema\\Column' => $baseDir . '/lib/private/DB/Schema/Column.php',
'OC\\DB\\Schema\\ForeignKeyConstraint' => $baseDir . '/lib/private/DB/Schema/ForeignKeyConstraint.php',
'OC\\DB\\Schema\\Index' => $baseDir . '/lib/private/DB/Schema/Index.php',
'OC\\DB\\Schema\\Table' => $baseDir . '/lib/private/DB/Schema/Table.php',
'OC\\DB\\Schema\\Type' => $baseDir . '/lib/private/DB/Schema/Type.php',

@ -413,7 +413,9 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\DB\\QueryBuilder\\IQueryFunction' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/IQueryFunction.php',
'OCP\\DB\\QueryBuilder\\ITypedQueryBuilder' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/ITypedQueryBuilder.php',
'OCP\\DB\\QueryBuilder\\Sharded\\IShardMapper' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php',
'OCP\\DB\\Schema\\ColumnType' => __DIR__ . '/../../..' . '/lib/public/DB/Schema/ColumnType.php',
'OCP\\DB\\Schema\\IColumn' => __DIR__ . '/../../..' . '/lib/public/DB/Schema/IColumn.php',
'OCP\\DB\\Schema\\IForeignKeyConstraint' => __DIR__ . '/../../..' . '/lib/public/DB/Schema/IForeignKeyConstraint.php',
'OCP\\DB\\Schema\\IIndex' => __DIR__ . '/../../..' . '/lib/public/DB/Schema/IIndex.php',
'OCP\\DB\\Schema\\ITable' => __DIR__ . '/../../..' . '/lib/public/DB/Schema/ITable.php',
'OCP\\DB\\Schema\\IType' => __DIR__ . '/../../..' . '/lib/public/DB/Schema/IType.php',
@ -1826,6 +1828,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\DB\\SQLiteSessionInit' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteSessionInit.php',
'OC\\DB\\SchemaWrapper' => __DIR__ . '/../../..' . '/lib/private/DB/SchemaWrapper.php',
'OC\\DB\\Schema\\Column' => __DIR__ . '/../../..' . '/lib/private/DB/Schema/Column.php',
'OC\\DB\\Schema\\ForeignKeyConstraint' => __DIR__ . '/../../..' . '/lib/private/DB/Schema/ForeignKeyConstraint.php',
'OC\\DB\\Schema\\Index' => __DIR__ . '/../../..' . '/lib/private/DB/Schema/Index.php',
'OC\\DB\\Schema\\Table' => __DIR__ . '/../../..' . '/lib/private/DB/Schema/Table.php',
'OC\\DB\\Schema\\Type' => __DIR__ . '/../../..' . '/lib/private/DB/Schema/Type.php',

@ -12,6 +12,7 @@ namespace OC\DB\Schema;
use Doctrine\DBAL\Schema\Column as DBALColumn;
use Doctrine\DBAL\Schema\SchemaException as DBALSchemaException;
use Doctrine\DBAL\Types\Type as DBALType;
use OCP\DB\Schema\ColumnType;
use OCP\DB\Schema\IColumn;
use OCP\DB\Schema\IType;
use OCP\DB\Schema\SchemaException;
@ -33,11 +34,15 @@ class Column implements IColumn {
}
#[\Override]
public function setType(string|IType|DBALType $type): self {
public function setType(string|IType|DBALType|ColumnType $type): self {
if ($type instanceof IType) {
$type = $type->getName();
}
if ($type instanceof ColumnType) {
$type = $type->value;
}
$this->column->setType($type instanceof DBALType ? $type : DBALType::getType($type));
return $this;
@ -97,6 +102,11 @@ class Column implements IColumn {
return new Type($this->column->getType());
}
#[\Override]
public function getColumnType(): ColumnType {
return ColumnType::from(DBALType::lookupName($this->column->getType()));
}
#[\Override]
public function getLength(): ?int {
return $this->column->getLength();

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH
* SPDX-FileContributor: Carl Schwan
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\DB\Schema;
use Doctrine\DBAL\Schema\ForeignKeyConstraint as DBALForeignKeyConstraint;
use OCP\DB\Schema\IForeignKeyConstraint;
use Override;
class ForeignKeyConstraint implements IForeignKeyConstraint {
public function __construct(
private readonly DBALForeignKeyConstraint $keyConstraint,
) {
}
#[Override]
public function getName(): string {
/** @var non-empty-string $value */
$value = $this->keyConstraint->getName();
return $value;
}
}

@ -53,6 +53,11 @@ class Index implements IIndex {
return $this->index->isSimpleIndex();
}
#[\Override]
public function hasColumnAtPosition(string $name, int $position = 0): bool {
return $this->index->hasColumnAtPosition($name, $position);
}
/**
* Forwards any method not declared on IIndex to the wrapped Doctrine
* DBAL index, e.g. mutators like `addFlag()` or `removeFlag()` that are

@ -10,10 +10,14 @@ declare(strict_types=1);
namespace OC\DB\Schema;
use Doctrine\DBAL\Schema\Column as DBALColumn;
use Doctrine\DBAL\Schema\ForeignKeyConstraint as DBALForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index as DBALIndex;
use Doctrine\DBAL\Schema\SchemaException as DBALSchemaException;
use Doctrine\DBAL\Schema\Table as DBALTable;
use Doctrine\DBAL\Types\Type as DBALType;
use OCP\DB\Schema\ColumnType;
use OCP\DB\Schema\IColumn;
use OCP\DB\Schema\IForeignKeyConstraint;
use OCP\DB\Schema\IIndex;
use OCP\DB\Schema\ITable;
use OCP\DB\Schema\SchemaException;
@ -36,7 +40,9 @@ class Table implements ITable {
#[\Override]
public function getName(): string {
return $this->table->getName();
/** @var non-empty-lowercase-string $name */
$name = $this->table->getName();
return $name;
}
#[\Override]
@ -134,8 +140,11 @@ class Table implements ITable {
}
#[\Override]
public function addColumn(string $name, string $typeName, array $options = []): IColumn {
public function addColumn(string $name, string|ColumnType $typeName, array $options = []): IColumn {
try {
if ($typeName instanceof ColumnType) {
$typeName = $typeName->value;
}
return new Column($this->table->addColumn($name, $typeName, $options));
} catch (DBALSchemaException $e) {
throw new SchemaException($e->getMessage(), $e->getCode(), $e);
@ -145,6 +154,14 @@ class Table implements ITable {
#[\Override]
public function modifyColumn(string $name, array $options): self {
try {
if (isset($options['type'])) {
if ($options['type'] instanceof ColumnType) {
$options['type'] = $options['type']->value;
}
if (is_string($options['type'])) {
$options['type'] = DBALType::getType($options['type']);
}
}
$this->table->modifyColumn($name, $options);
} catch (DBALSchemaException $e) {
throw new SchemaException($e->getMessage(), $e->getCode(), $e);
@ -210,8 +227,8 @@ class Table implements ITable {
}
#[\Override]
public function hasColumn(string $string): bool {
return $this->table->hasColumn($string);
public function hasColumn(string $name): bool {
return $this->table->hasColumn($name);
}
#[\Override]
@ -238,4 +255,12 @@ class Table implements ITable {
$this->table->getIndexes(),
));
}
#[\Override]
public function getForeignKeys(): array {
return array_values(array_map(
static fn (DBALForeignKeyConstraint $keyConstraint): IForeignKeyConstraint => new ForeignKeyConstraint($keyConstraint),
$this->table->getForeignKeys(),
));
}
}

@ -8,6 +8,7 @@
namespace OCP\AppFramework\Db;
use OCP\DB\Schema\ColumnType;
use OCP\DB\Types;
use function lcfirst;
use function substr;
@ -23,8 +24,8 @@ abstract class Entity {
public $id;
/** @var array<string, true> $_updatedFields */
private array $_updatedFields = [];
/** @var array<string, Types::*> $_fieldTypes */
protected array $_fieldTypes = ['id' => 'integer'];
/** @var array<string, ColumnType> $_fieldTypes */
protected array $_fieldTypes = ['id' => ColumnType::Integer];
/**
* Simple alternative constructor for building entities from a request
@ -66,7 +67,7 @@ abstract class Entity {
* @since 7.0.0
*/
public function getFieldTypes(): array {
return $this->_fieldTypes;
return array_map(fn (ColumnType $type) => $type->value, $this->_fieldTypes);
}
/**
@ -98,47 +99,47 @@ abstract class Entity {
// if type definition exists, cast to correct type
if ($args[0] !== null && array_key_exists($name, $this->_fieldTypes)) {
$type = $this->_fieldTypes[$name];
if ($type === Types::BLOB) {
if ($type === ColumnType::Blob) {
// (B)LOB is treated as string when we read from the DB
if (is_resource($args[0])) {
$args[0] = stream_get_contents($args[0]);
}
$type = Types::STRING;
$type = ColumnType::String;
}
switch ($type) {
case Types::BIGINT:
case Types::SMALLINT:
case ColumnType::Bigint:
case ColumnType::Smallint:
settype($args[0], Types::INTEGER);
break;
case Types::BINARY:
case Types::DECIMAL:
case Types::TEXT:
case ColumnType::Binary:
case ColumnType::Decimal:
case ColumnType::Text:
settype($args[0], Types::STRING);
break;
case Types::TIME:
case Types::DATE:
case Types::DATETIME:
case Types::DATETIME_TZ:
case ColumnType::Time:
case ColumnType::Date:
case ColumnType::Datetime:
case ColumnType::DatetimeTz:
if (!$args[0] instanceof \DateTime) {
$args[0] = new \DateTime($args[0]);
}
break;
case Types::TIME_IMMUTABLE:
case Types::DATE_IMMUTABLE:
case Types::DATETIME_IMMUTABLE:
case Types::DATETIME_TZ_IMMUTABLE:
case ColumnType::TimeImmutable:
case ColumnType::DateImmutable:
case ColumnType::DatetimeImmutable:
case ColumnType::DatetimeTzImmutable:
if (!$args[0] instanceof \DateTimeImmutable) {
$args[0] = new \DateTimeImmutable($args[0]);
}
break;
case Types::JSON:
case ColumnType::Json:
if (!is_array($args[0])) {
$args[0] = json_decode($args[0], true);
}
break;
default:
settype($args[0], $type);
settype($args[0], $type->value);
}
}
$this->$name = $args[0];
@ -187,7 +188,7 @@ abstract class Entity {
protected function isGetterForBoolProperty(string $methodName): bool {
if (str_starts_with($methodName, 'is')) {
$fieldName = lcfirst(substr($methodName, 2));
return isset($this->_fieldTypes[$fieldName]) && str_starts_with($this->_fieldTypes[$fieldName], 'bool');
return isset($this->_fieldTypes[$fieldName]) && str_starts_with($this->_fieldTypes[$fieldName]->value, 'bool');
}
return false;
}
@ -258,23 +259,28 @@ abstract class Entity {
* that value once its being returned from the database
*
* @param string $fieldName the name of the attribute
* @param Types::* $type the type which will be used to match a cast
* @param Types::*|ColumnType $type the type which will be used to match a cast
* @since 31.0.0 Parameter $type is now restricted to {@see Types} constants. The formerly accidentally supported types 'int'|'bool'|'double' are mapped to Types::INTEGER|Types::BOOLEAN|Types::FLOAT accordingly.
* @since 35.0.0 Parameter $type now prefers using one of the {@see ColumnType} enum values.
* @since 7.0.0
*/
protected function addType(string $fieldName, string $type): void {
protected function addType(string $fieldName, string|ColumnType $type): void {
/** @psalm-suppress TypeDoesNotContainType */
if (in_array($type, ['bool', 'double', 'int', 'array', 'object'], true)) {
// Mapping legacy strings to the actual types
$type = match ($type) {
'int' => Types::INTEGER,
'bool' => Types::BOOLEAN,
'double' => Types::FLOAT,
'int' => ColumnType::Integer,
'bool' => ColumnType::Boolean,
'double' => ColumnType::Float,
'array',
'object' => Types::STRING,
'object' => ColumnType::String,
};
}
if (is_string($type)) {
$type = ColumnType::from($type);
}
$this->_fieldTypes[$fieldName] = $type;
}

@ -0,0 +1,166 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCP\DB\Schema;
/**
* Database column types supported by Nextcloud's DBs.
*
* @since 35.0.0
*/
enum ColumnType: string {
/**
* @since 35.0.0
*/
case Bigint = 'bigint';
/**
* @since 35.0.0
*/
case Binary = 'binary';
/**
* @since 35.0.0
*/
case Blob = 'blob';
/**
* @since 35.0.0
*/
case Boolean = 'boolean';
/**
* A datetime instance with only the date set.
* This will be (de)serialized into a \DateTime instance,
* it is recommended to instead use the `DateImmutable` instead.
*
* Warning: When deserialized the timezone will be set to UTC.
*
* @since 35.0.0
*/
case Date = 'date';
/**
* An immutable datetime instance with only the date set.
* This will be (de)serialized into a \DateTimeImmutable instance,
* It is recommended to use this over the `Date` case because
* out `Entity` class works detecting changes through the setter,
* changes on mutable objects can not be detected.
*
* Warning: When deserialized the timezone will be set to UTC.
*
* @since 35.0.0
*/
case DateImmutable = 'date_immutable';
/**
* A datetime instance with date and time support.
* This will be (de)serialized into a \DateTime instance,
* it is recommended to instead use the `DatetimeImmutable` instead.
*
* Warning: When deserialized the timezone will be set to UTC.
*
* @since 35.0.0
*/
case Datetime = 'datetime';
/**
* An immutable datetime instance with date and time set.
* This will be (de)serialized into a \DateTimeImmutable instance,
* It is recommended to use this over the `Datetime` case because
* out `Entity` class works detecting changes through the setter,
* changes on mutable objects can not be detected.
*
* Warning: When deserialized the timezone will be set to UTC.
*
* @since 35.0.0
*/
case DatetimeImmutable = 'datetime_immutable';
/**
* A datetime instance with timezone support
* This will be (de)serialized into a \DateTime instance,
* it is recommended to instead use the `DatetimeTzImmutable` instead.
*
* @since 35.0.0
*/
case DatetimeTz = 'datetimetz';
/**
* An immutable timezone aware datetime instance with date and time set.
* This will be (de)serialized into a \DateTimeImmutable instance,
* It is recommended to use this over the `DatetimeTz` case because
* out `Entity` class works detecting changes through the setter,
* changes on mutable objects can not be detected.
*
* @since 35.0.0
*/
case DatetimeTzImmutable = 'datetimetz_immutable';
/**
* @since 35.0.0
*/
case Decimal = 'decimal';
/**
* @since 35.0.0
*/
case Float = 'float';
/**
* @since 35.0.0
*/
case Integer = 'integer';
/**
* @since 35.0.0
*/
case Smallint = 'smallint';
/**
* @since 35.0.0
*/
case String = 'string';
/**
* @since 35.0.0
*/
case Text = 'text';
/**
* A datetime instance with only the time set.
* This will be (de)serialized into a \DateTime instance,
* it is recommended to instead use the `TimeImmutable` instead.
*
* Warning: When deserialized the timezone will be set to UTC.
*
* @since 35.0.0
*/
case Time = 'time';
/**
* A datetime instance with only the time set.
* This will be (de)serialized into a \DateTime instance.
*
* It is recommended to use this over the `DatetimeTz` case because
* out `Entity` class works detecting changes through the setter,
* changes on mutable objects can not be detected.
*
* @since 35.0.0
*/
case TimeImmutable = 'time_immutable';
/**
* JSON fields can not properly be used in WHERE statements of Oracle and MySQL.
* It is recommended to use a simple {@see self::String} field and handle JSON within PHP.
*
* @since 35.0.0
*/
case Json = 'json';
}

@ -19,10 +19,10 @@ use OCP\AppFramework\Attribute\Consumable;
#[Consumable(since: '35.0.0')]
interface IColumn {
/**
* @param \OCP\DB\Types::*|IType $type
* @param \OCP\DB\Types::*|IType|ColumnType $type
* @since 35.0.0
*/
public function setType(string|IType $type): self;
public function setType(string|IType|ColumnType $type): self;
/**
* @since 35.0.0
@ -65,9 +65,17 @@ interface IColumn {
* Note that {@see IType::getName()} returns a `\OCP\DB\Types::*` value.
*
* @since 35.0.0
* @note Prefer using getColumnType, this method is here for legacy compatibility.
*/
public function getType(): IType;
/**
* Returns the type of this column.
*
* @since 35.0.0
*/
public function getColumnType(): ColumnType;
/**
* @return int|null
* @since 35.0.0

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCP\DB\Schema;
/**
* Object representation of a foreign key constraint.
*
* @since 35.0.0
*/
interface IForeignKeyConstraint {
/**
* Return the name of the foreign key constraint
*
* @return non-empty-string
* @since 35.0.0
*/
public function getName(): string;
}

@ -53,4 +53,12 @@ interface IIndex {
* @since 35.0.0
*/
public function isSimpleIndex(): bool;
/**
* Returns whether this index has a column at a specified position.
*
* @param non-empty-lowercase-string $name
* @since 35.0.0
*/
public function hasColumnAtPosition(string $name, int $position = 0): bool;
}

@ -10,6 +10,7 @@ declare(strict_types=1);
namespace OCP\DB\Schema;
use OCP\AppFramework\Attribute\Consumable;
use OCP\DB\Types;
/**
* Object representation of a table.
@ -22,13 +23,14 @@ interface ITable {
* Returns the name of this table.
*
* @since 35.0.0
* @return non-empty-lowercase-string
*/
public function getName(): string;
/**
* Sets the Primary Key.
*
* @param list<string> $columnNames
* @param list<non-empty-string> $columnNames
* @param string|false $indexName
*
* @throws SchemaException
@ -37,9 +39,9 @@ interface ITable {
public function setPrimaryKey(array $columnNames, string|false $indexName = false): self;
/**
* @param list<string> $columnNames
* @param list<string> $flags
* @param array<string, mixed> $options
* @param list<non-empty-lowercase-string> $columnNames
* @param list<non-empty-lowercase-string> $flags
* @param array<non-empty-lowercase-string, mixed> $options
*
* @throws SchemaException
* @since 35.0.0
@ -77,7 +79,7 @@ interface ITable {
/**
* Drops an index from this table.
*
* @param string $name The index name.
* @param non-empty-lowercase-string $name The index name.
*
* @throws SchemaException If the index does not exist.
* @since 35.0.0
@ -87,7 +89,7 @@ interface ITable {
/**
* Returns whether this table has an index with the given name.
*
* @param string $name The index name.
* @param non-empty-lowercase-string $name The index name.
* @since 35.0.0
*/
public function hasIndex(string $name): bool;
@ -105,9 +107,9 @@ interface ITable {
/**
* Renames an index.
*
* @param string $oldName The name of the index to rename from.
* @param string|null $newName The name of the index to rename to.
* If null is given, the index name will be auto-generated.
* @param non-empty-lowercase-string $oldName The name of the index to rename from.
* @param non-empty-lowercase-string|null $newName The name of the index to rename to.
* If null is given, the index name will be auto-generated.
*
* @return self This table instance.
*
@ -118,8 +120,8 @@ interface ITable {
public function renameIndex(string $oldName, ?string $newName = null): self;
/**
* @param string $name
* @param string $typeName
* @param non-empty-lowercase-string $name
* @param Types::*|ColumnType $typeName
* @param array{
* notnull?: bool,
* length?: ?int,
@ -127,15 +129,17 @@ interface ITable {
* unsigned?: bool,
* autoincrement?: bool,
* fixed?: bool,
* precision?: int,
* scale?: int,
* } $options
*
* @throws SchemaException
* @since 35.0.0
*/
public function addColumn(string $name, string $typeName, array $options = []): IColumn;
public function addColumn(string $name, string|ColumnType $typeName, array $options = []): IColumn;
/**
* @param string $name
* @param non-empty-lowercase-string $name
* @param array{
* notnull?: bool,
* length?: ?int,
@ -143,6 +147,9 @@ interface ITable {
* unsigned?: bool,
* autoincrement?: bool,
* fixed?: bool,
* precision?: int,
* scale?: int,
* type?: Types::*|ColumnType,
* } $options
*
* @throws SchemaException
@ -152,6 +159,8 @@ interface ITable {
/**
* Drops a Column from the Table.
*
* @param non-empty-lowercase-string $name
* @since 35.0.0
*/
public function dropColumn(string $name): self;
@ -159,15 +168,15 @@ interface ITable {
/**
* Returns whether this table has a Column with the given name.
*
* @param string $name The column name.
* @param non-empty-lowercase-string $name The column name.
* @since 35.0.0
*/
public function hasColumn(string $string): bool;
public function hasColumn(string $name): bool;
/**
* Returns the Column with the given name.
*
* @param string $name The column name.
* @param non-empty-lowercase-string $name The column name.
*
* @throws SchemaException If the column does not exist.
* @since 35.0.0
@ -195,9 +204,9 @@ interface ITable {
*
* Name is inferred from the local columns.
*
* @param ITable|string $foreignTable Table schema instance or table name
* @param list<string> $localColumnNames
* @param list<string> $foreignColumnNames
* @param ITable|non-empty-lowercase-string $foreignTable Table schema instance or table name
* @param list<non-empty-lowercase-string> $localColumnNames
* @param list<non-empty-lowercase-string> $foreignColumnNames
* @param array<string, mixed> $options
*
* @throws SchemaException
@ -213,6 +222,8 @@ interface ITable {
/**
* Returns whether this table has a foreign key constraint with the given name.
*
* @param non-empty-string $name The foreign key name.
* @since 35.0.0
*/
public function hasForeignKey(string $name): bool;
@ -220,10 +231,16 @@ interface ITable {
/**
* Removes the foreign key constraint with the given name.
*
* @param string $name The constraint name.
* @param non-empty-string $name The constraint name.
*
* @throws SchemaException
* @since 35.0.0
*/
public function removeForeignKey(string $name): void;
/**
* @since 35.0.0
* @return list<IForeignKeyConstraint>
*/
public function getForeignKeys(): array;
}

Loading…
Cancel
Save