Skip to content

Commit

Permalink
[9.x] Improve UUID and ULID support for Eloquent (#44146)
Browse files Browse the repository at this point in the history
* Add ulid column type to Blueprint

* Improve uuid and ulid support

* Apply fixes from StyleCI

* Adjust test

* wip

* formatting

Co-authored-by: StyleCI Bot <[email protected]>
Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
3 people authored Sep 16, 2022
1 parent 85ca3fb commit 9235af3
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 94 deletions.
14 changes: 4 additions & 10 deletions src/Illuminate/Database/Eloquent/Concerns/HasUlids.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,10 @@ public function uniqueIds()
*/
public function getKeyType()
{
return 'string';
}
if (in_array($this->getKeyName(), $this->uniqueIds())) {
return 'string';
}

/**
* Get the value indicating whether the IDs are incrementing.
*
* @return bool
*/
public function getIncrementing()
{
return false;
return $this->keyType;
}
}
14 changes: 4 additions & 10 deletions src/Illuminate/Database/Eloquent/Concerns/HasUuids.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,10 @@ public function uniqueIds()
*/
public function getKeyType()
{
return 'string';
}
if (in_array($this->getKeyName(), $this->uniqueIds())) {
return 'string';
}

/**
* Get the value indicating whether the IDs are incrementing.
*
* @return bool
*/
public function getIncrementing()
{
return false;
return $this->keyType;
}
}
4 changes: 4 additions & 0 deletions src/Illuminate/Database/Eloquent/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,10 @@ public function setKeyType($type)
*/
public function getIncrementing()
{
if ($this->getKeyType() === 'string') {
return false;
}

return $this->incrementing;
}

Expand Down
30 changes: 29 additions & 1 deletion src/Illuminate/Database/Schema/Blueprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ public function binary($column)
}

/**
* Create a new uuid column on the table.
* Create a new UUID column on the table.
*
* @param string $column
* @return \Illuminate\Database\Schema\ColumnDefinition
Expand All @@ -1267,6 +1267,34 @@ public function foreignUuid($column)
]));
}

/**
* Create a new ULID column on the table.
*
* @param string $column
* @param int|null $length
* @return \Illuminate\Database\Schema\ColumnDefinition
*/
public function ulid($column = 'uuid', $length = 26)
{
return $this->char($column, $length);
}

/**
* Create a new ULID column on the table with a foreign key constraint.
*
* @param string $column
* @param int|null $length
* @return \Illuminate\Database\Schema\ForeignIdColumnDefinition
*/
public function foreignUlid($column, $length = 26)
{
return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [
'type' => 'char',
'name' => $column,
'length' => $length,
]));
}

/**
* Create a new IP address column on the table.
*
Expand Down
4 changes: 3 additions & 1 deletion tests/Database/DatabaseEloquentModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2214,8 +2214,10 @@ public function testIntKeyTypePreserved()
public function testStringKeyTypePreserved()
{
$model = $this->getMockBuilder(EloquentKeyTypeModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock();
$model->id = 'string id';

$query = m::mock(Builder::class);
$query->shouldReceive('insertGetId')->once()->with([], 'id')->andReturn('string id');
$query->shouldReceive('insert')->once()->with(['id' => 'string id']);
$query->shouldReceive('getConnection')->once();
$model->expects($this->once())->method('newModelQuery')->willReturn($query);

Expand Down
36 changes: 0 additions & 36 deletions tests/Integration/Database/EloquentUlidPrimaryKeyTest.php

This file was deleted.

129 changes: 129 additions & 0 deletions tests/Integration/Database/EloquentUniqueStringPrimaryKeysTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace Illuminate\Tests\Integration\Database;

use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

class EloquentUniqueStringPrimaryKeysTest extends DatabaseTestCase
{
protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
{
Schema::create('users', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->uuid('foo');
$table->uuid('bar');
$table->timestamps();
});

Schema::create('posts', function (Blueprint $table) {
$table->ulid('id')->primary();
$table->ulid('foo');
$table->ulid('bar');
$table->timestamps();
});

Schema::create('songs', function (Blueprint $table) {
$table->id();
$table->uuid('foo');
$table->uuid('bar');
$table->timestamps();
});

Schema::create('pictures', function (Blueprint $table) {
$table->uuid('uuid')->primary();
$table->timestamps();
});
}

public function testModelWithUuidPrimaryKeyCanBeCreated()
{
$user = ModelWithUuidPrimaryKey::create();

$this->assertTrue(Str::isUuid($user->id));
$this->assertTrue(Str::isUuid($user->foo));
$this->assertTrue(Str::isUuid($user->bar));
}

public function testModelWithUlidPrimaryKeyCanBeCreated()
{
$user = ModelWithUlidPrimaryKey::create();

$this->assertTrue(Str::isUlid($user->id));
$this->assertTrue(Str::isUlid($user->foo));
$this->assertTrue(Str::isUlid($user->bar));
}

public function testModelWithoutUuidPrimaryKeyCanBeCreated()
{
$user = ModelWithoutUuidPrimaryKey::create();

$this->assertTrue(is_int($user->id));
$this->assertTrue(Str::isUuid($user->foo));
$this->assertTrue(Str::isUuid($user->bar));
}

public function testModelWithCustomUuidPrimaryKeyNameCanBeCreated()
{
$user = ModelWithCustomUuidPrimaryKeyName::create();

$this->assertTrue(Str::isUuid($user->uuid));
}
}

class ModelWithUuidPrimaryKey extends Eloquent
{
use HasUuids;

protected $table = 'users';

protected $guarded = [];

public function uniqueIds()
{
return [$this->getKeyName(), 'foo', 'bar'];
}
}

class ModelWithUlidPrimaryKey extends Eloquent
{
use HasUlids;

protected $table = 'posts';

protected $guarded = [];

public function uniqueIds()
{
return [$this->getKeyName(), 'foo', 'bar'];
}
}

class ModelWithoutUuidPrimaryKey extends Eloquent
{
use HasUuids;

protected $table = 'songs';

protected $guarded = [];

public function uniqueIds()
{
return ['foo', 'bar'];
}
}

class ModelWithCustomUuidPrimaryKeyName extends Eloquent
{
use HasUuids;

protected $table = 'pictures';

protected $guarded = [];

protected $primaryKey = 'uuid';
}
36 changes: 0 additions & 36 deletions tests/Integration/Database/EloquentUuidPrimaryKeyTest.php

This file was deleted.

0 comments on commit 9235af3

Please sign in to comment.