laravel/pulse

Migration fails with database prefix longer than 3 chars

pau1phi11ips opened this issue · 2 comments

Pulse Version

1.2.3

Laravel Version

11.14.0

PHP Version

8.3.8

Livewire Version

N/A

Database Driver & Version

MySQL 8.0.36

Description

In create_pulse_tables.php migration, this line fails if there's a database table prefix longer than 3 chars as it pushes index name over 64 characters. AFAIK the limit in MySQL and MariaDB is 64 chars, and 63 chars in PostgreSQL.

$table->unique(['bucket', 'period', 'type', 'aggregate', 'key_hash']); // Force "on duplicate update"...

Error on migrate:

SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'dev_pulse_aggregates_bucket_period_type_aggregate_key_hash_unique' is too long (Connection: mysql, SQL: alter table `dev_pulse_aggregates` add unique `dev_pulse_aggregates_bucket_period_type_aggregate_key_hash_unique`(`bucket`, `period`, `type`, `aggregate`, `key_hash`))

I'm not sure if this should be fixed in Pulse or indeed in the main Blueprint file?
vendor\laravel\framework\src\Illuminate\Database\Schema\Blueprint.php

Something like this:

    /**
     * Create a default index name for the table.
     *
     * @param  string  $type
     * @param  array  $columns
     * @return string
     */
    protected function createIndexName($type, array $columns, ?bool $noPrefix = false)
    {
        $table = str_contains($this->table, '.')
            ? substr_replace($this->table, '.'.$this->prefix, strrpos($this->table, '.'), 1)
            : $this->prefix.$this->table;

        $index = strtolower($table.'_'.implode('_', $columns).'_'.$type);

        if (strlen($index) > 63) {
            // try removing database prefix from indexName
            // mysql & mariadb max 64 chars, 63 in pgsql
            $index = substr($index, strlen($this->prefix));
        }

        return str_replace(['-', '.'], '_', $index);
    }

Steps To Reproduce

Add a table prefix in config/database.php.

['connections']['mysql']['prefix'] = 'dev_'; // <- anything over 3 chars

Thanks @pau1phi11ips,

We can look at providing a safer index name by default. In the meantime, you should pass a shorter name to the $name parameter on the index methods in your migrations. They're published into your code base so they won't be updated if we change them in the package.

We'd appreciate a PR for this if you're up for it @pau1phi11ips. Thanks