Skip to content

feat(database): use different text type declaration with mysql according to field length#1972

Open
MrYamous wants to merge 2 commits intotempestphp:3.xfrom
MrYamous:feat/use-mysql-text-declaration
Open

feat(database): use different text type declaration with mysql according to field length#1972
MrYamous wants to merge 2 commits intotempestphp:3.xfrom
MrYamous:feat/use-mysql-text-declaration

Conversation

@MrYamous
Copy link
Contributor

Fixes #1941

While working on it, I realized this may can be applied to Integer too

* 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, ?string $default = null, ?int $length = null): self
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that you can just specify a number here, and it will determine the correct type for you. However, I think I'd rather see it a bit more flexible:

  1. instead of constants on MySQLConfig, let's refactor to an enum (not sure about the name yet)
enum TextLength: int
{
    case TINY = 255;
    case DEFAULT = 65535;
    case MEDIUM = 16777215;
    case LONG = 4294967295;
}
  1. Then users could provide either an int or this enum: int|TextLength|null $length = null
  2. We could make the field non-optional for clarity: int|TextLength $length = TextLength::TEXT
  3. Improve the enum so that all logic is contained in one place:
enum TextLength: int
{
    case TINY = 255;
    case DEFAULT = 65535;
    case MEDIUM = 16777215;
    case LONG = 4294967295;

    public static function fromLength(int $length): self
    {
        return match (true) {
            $length > TextLength::LONG => TextLength::LONG,
            $length > TextLength::MEDIUM => TextLength::MEDIUM,
            $length > TextLength::DEFAULT => TextLength::DEFAULT,
            default => TextLength::TINY,
        };
    }

    public function toString(): string
    {
        return match($this) {
            TextLength::TINY => 'TINYTEXT',
            TextLength::DEFAULT => 'TEXT',
            TextLength::MEDIUM => 'MEDIUMTEXT',
            TextLength::LONG => 'LONGTEXT',
        };
    }
}

WDYT?

I'm only a bit concerned about names, because as far as I understand, this is only necessary for MySQL — right?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In SQLite, the limit of TEXT can be set in SQlite config, standard are 1 GB (1.000.000.000 Bytes): https://sqlite.org/limits.html

In PostgreSQL TEXT is without limit. https://www.postgresql.org/docs/current/datatype-character.html

From your three supported database types, only MySQL has TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT. https://dev.mysql.com/doc/refman/8.4/en/blob.html

MySQL is some times little bit frustating with this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point and looks good to me, it's probably more friendly to use if we allow an Enum here.
But I think TextLength is too generic, WDYT about DatabaseTextLength, FieldTextLength or MySQLTextLength ?

DevPandi added a commit to DevPandi/tempest-framework that referenced this pull request Feb 16, 2026
…bytes), integer (4 bytes) and smallint (2 bytes). Tiny INT is SQL.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text types in database schema

3 participants