diff --git a/packages/database/src/Enums/DatabaseTextLength.php b/packages/database/src/Enums/DatabaseTextLength.php new file mode 100644 index 0000000000..e132b19323 --- /dev/null +++ b/packages/database/src/Enums/DatabaseTextLength.php @@ -0,0 +1,34 @@ + DatabaseTextLength::TINY, + $length <= DatabaseTextLength::DEFAULT => DatabaseTextLength::DEFAULT, + $length <= DatabaseTextLength::MEDIUM => DatabaseTextLength::MEDIUM, + $length <= DatabaseTextLength::LONG => DatabaseTextLength::LONG, + default => DatabaseTextLength::DEFAULT, + }; + } + + public function toString(): string + { + return match ($this) { + DatabaseTextLength::TINY => 'TINYTEXT', + DatabaseTextLength::DEFAULT => 'TEXT', + DatabaseTextLength::MEDIUM => 'MEDIUMTEXT', + DatabaseTextLength::LONG => 'LONGTEXT', + }; + } +} diff --git a/packages/database/src/QueryStatements/CreateTableStatement.php b/packages/database/src/QueryStatements/CreateTableStatement.php index ab3bba8d73..ebd681fc7c 100644 --- a/packages/database/src/QueryStatements/CreateTableStatement.php +++ b/packages/database/src/QueryStatements/CreateTableStatement.php @@ -7,6 +7,7 @@ use BackedEnum; use Tempest\Database\Builder\TableDefinition; use Tempest\Database\Config\DatabaseDialect; +use Tempest\Database\Enums\DatabaseTextLength; use Tempest\Database\HasTrailingStatements; use Tempest\Database\QueryStatement; use Tempest\Support\Json; @@ -143,12 +144,13 @@ public function foreignKey(string $local, string $foreign, OnDelete $onDelete = /** * Adds a `TEXT` column to the table. */ - public function text(string $name, bool $nullable = false, ?string $default = null): self + public function text(string $name, bool $nullable = false, int|DatabaseTextLength $length = DatabaseTextLength::DEFAULT, ?string $default = null): self { $this->statements[] = new TextStatement( name: $name, nullable: $nullable, default: $default, + length: $length, ); return $this; diff --git a/packages/database/src/QueryStatements/TextStatement.php b/packages/database/src/QueryStatements/TextStatement.php index 0d65cbccba..88c5441584 100644 --- a/packages/database/src/QueryStatements/TextStatement.php +++ b/packages/database/src/QueryStatements/TextStatement.php @@ -5,6 +5,7 @@ namespace Tempest\Database\QueryStatements; use Tempest\Database\Config\DatabaseDialect; +use Tempest\Database\Enums\DatabaseTextLength; use Tempest\Database\QueryStatement; final readonly class TextStatement implements QueryStatement @@ -12,6 +13,7 @@ public function __construct( private string $name, private bool $nullable = false, + private int|DatabaseTextLength $length = DatabaseTextLength::DEFAULT, private ?string $default = null, ) {} @@ -19,8 +21,9 @@ public function compile(DatabaseDialect $dialect): string { return match ($dialect) { DatabaseDialect::MYSQL => sprintf( - '`%s` TEXT %s', + '`%s` %s %s', $this->name, + $this->getSQLTypeDeclaration($this->length), $this->nullable ? '' : 'NOT NULL', ), default => sprintf( @@ -31,4 +34,13 @@ public function compile(DatabaseDialect $dialect): string ), }; } + + private function getSQLTypeDeclaration(int|DatabaseTextLength $length): string + { + if ($length instanceof DatabaseTextLength) { + return $length->toString(); + } + + return DatabaseTextLength::fromLength($length)->toString(); + } } diff --git a/tests/Integration/Database/QueryStatements/CreateTableStatementTest.php b/tests/Integration/Database/QueryStatements/CreateTableStatementTest.php index cefccf14af..797df39c21 100644 --- a/tests/Integration/Database/QueryStatements/CreateTableStatementTest.php +++ b/tests/Integration/Database/QueryStatements/CreateTableStatementTest.php @@ -8,6 +8,7 @@ use Tempest\Database\Config\DatabaseDialect; use Tempest\Database\Database; use Tempest\Database\DialectWasNotSupported; +use Tempest\Database\Enums\DatabaseTextLength; use Tempest\Database\Exceptions\DefaultValueWasInvalid; use Tempest\Database\Exceptions\ValueWasInvalid; use Tempest\Database\MigratesUp; @@ -235,6 +236,35 @@ public function test_string_method_with_custom_parameters(): void $this->assertSame($varcharStatement, $stringStatement); } + public function test_text_with_length_limit(): void + { + $tinyText = new CreateTableStatement('test-table') + ->text('content', false, DatabaseTextLength::TINY, null) + ->compile(dialect: DatabaseDialect::MYSQL); + $mediumText = new CreateTableStatement('test-table') + ->text('content', false, DatabaseTextLength::DEFAULT) + ->compile(dialect: DatabaseDialect::MYSQL); + $text = new CreateTableStatement('test-table') + ->text('content', false, DatabaseTextLength::MEDIUM) + ->compile(dialect: DatabaseDialect::MYSQL); + $longText = new CreateTableStatement('test-table') + ->text('content', false, DatabaseTextLength::LONG) + ->compile(dialect: DatabaseDialect::MYSQL); + $default = new CreateTableStatement('test-table') + ->text('content', false) + ->compile(dialect: DatabaseDialect::MYSQL); + $value = new CreateTableStatement('test-table') + ->text('content', false, 180) + ->compile(dialect: DatabaseDialect::MYSQL); + + $this->assertStringContainsString('TINYTEXT', $tinyText); + $this->assertStringContainsString('MEDIUMTEXT', $mediumText); + $this->assertStringContainsString('TEXT', $text); + $this->assertStringContainsString('LONGTEXT', $longText); + $this->assertStringContainsString('TEXT', $default); + $this->assertStringContainsString('TINYTEXT', $value); + } + public function test_object_field(): void { $migration = new class() implements MigratesUp {