Skip to content

Commit

Permalink
Merge branch 'mostafaznv/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeldyrynda committed Jan 7, 2025
2 parents 605a37c + 75a42fa commit 8f1fad7
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 9 deletions.
59 changes: 50 additions & 9 deletions src/GeneratesUuid.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
*
* @property string $uuidVersion
*
* @method static \Illuminate\Database\Eloquent\Builder whereUuid(string $uuid)
* @method static \Illuminate\Database\Eloquent\Builder whereUuid(string|string[] $uuid, ?string $uuidColumn = null)
* @method static \Illuminate\Database\Eloquent\Builder whereNotUuid(string|string[] $uuid, ?string $uuidColumn = null)
*/
trait GeneratesUuid
{
Expand Down Expand Up @@ -121,17 +122,28 @@ public function resolveUuidVersion(): string
*/
public function scopeWhereUuid($query, $uuid, $uuidColumn = null): Builder
{
$uuidColumn = ! is_null($uuidColumn) && in_array($uuidColumn, $this->uuidColumns())
? $uuidColumn
: $this->uuidColumns()[0];
$uuidColumn = $this->getUuidColumn($uuidColumn);
$uuid = $this->prepareUuid($uuid, $uuidColumn);

$uuid = $this->normaliseUuids($uuid);
return $query->whereIn(
$this->qualifyColumn($uuidColumn),
Arr::wrap($uuid)
);
}

if ($this->isClassCastable($uuidColumn)) {
$uuid = $this->bytesFromUuid($uuid);
}
/**
* Scope queries to find by UUID.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string|array $uuid
* @param string $uuidColumn
*/
public function scopeWhereNotUuid($query, $uuid, $uuidColumn = null): Builder
{
$uuidColumn = $this->getUuidColumn($uuidColumn);
$uuid = $this->prepareUuid($uuid, $uuidColumn);

return $query->whereIn(
return $query->whereNotIn(
$this->qualifyColumn($uuidColumn),
Arr::wrap($uuid)
);
Expand Down Expand Up @@ -172,4 +184,33 @@ protected function normaliseUuids($uuid): array

return $uuid;
}

/**
* Guess UUID column based on model configurations or given uuid column
*
* @param ?string $uuidColumn
*/
protected function getUuidColumn($uuidColumn = null): string
{
return ! is_null($uuidColumn) && in_array($uuidColumn, $this->uuidColumns())
? $uuidColumn
: $this->uuidColumns()[0];
}

/**
* Prepare UUID by normalization
*
* @param string|array $uuid
* @param string $uuidColumn
*/
protected function prepareUuid($uuid, $uuidColumn): array|string
{
$uuid = $this->normaliseUuids($uuid);

if ($this->isClassCastable($uuidColumn)) {
$uuid = $this->bytesFromUuid($uuid);
}

return $uuid;
}
}
109 changes: 109 additions & 0 deletions tests/Feature/UuidTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ public function you_can_find_a_model_by_its_uuid()
$this->assertSame($uuid, $post->uuid);
}

/** @test */
public function you_can_exclude_a_model_by_its_uuid()
{
$uuid = '55635d83-10bc-424f-bf3f-395ea7a5b47f';

Post::create(['title' => 'test post', 'uuid' => $uuid]);

$this->assertNull(
Post::whereNotUuid($uuid)->first()
);
}

/** @test */
public function you_can_find_a_model_by_custom_uuid_parameter()
{
Expand Down Expand Up @@ -88,6 +100,24 @@ public function you_can_search_by_array_of_uuids()
])->count());
}

/** @test */
public function you_can_exclude_by_array_of_uuids()
{
Post::create(['title' => 'first post', 'uuid' => '8ab48e77-d9cd-4fe7-ace5-a5a428590c18']);
Post::create(['title' => 'second post', 'uuid' => 'c7c26456-ddb0-45cd-9b1c-318296cce7a3']);
Post::create(['title' => 'third post', 'uuid' => 'e99d440e-fa25-45f2-ba2f-7c4c48f6fb5d']);

$uuids = [
'8ab48e77-d9cd-4fe7-ace5-A5A428590C18',
'c7c26456-ddb0-45cd-9b1c-318296cce7a3',
];

$posts = Post::whereNotUuid($uuids)->get();

$this->assertEquals(1, $posts->count());
$this->assertEquals('e99d440e-fa25-45f2-ba2f-7c4c48f6fb5d', $posts->get(0)->uuid);
}

/** @test */
public function you_can_search_by_array_of_efficient_uuids()
{
Expand All @@ -100,6 +130,24 @@ public function you_can_search_by_array_of_efficient_uuids()
], 'efficient_uuid')->count());
}

/** @test */
public function you_can_exclude_by_array_of_efficient_uuids()
{
EfficientUuidPost::create(['title' => 'first post', 'efficient_uuid' => '8ab48e77-d9cd-4fe7-ace5-a5a428590c18']);
EfficientUuidPost::create(['title' => 'second post', 'efficient_uuid' => 'c7c26456-ddb0-45cd-9b1c-318296cce7a3']);
EfficientUuidPost::create(['title' => 'third post', 'efficient_uuid' => 'e99d440e-fa25-45f2-ba2f-7c4c48f6fb5d']);

$uuids = [
'8ab48e77-d9cd-4fe7-ace5-A5A428590C18',
'c7c26456-ddb0-45cd-9b1c-318296cce7a3',
];

$posts = EfficientUuidPost::whereNotUuid($uuids, 'efficient_uuid')->get();

$this->assertEquals(1, $posts->count());
$this->assertSame('e99d440e-fa25-45f2-ba2f-7c4c48f6fb5d', $posts->get(0)->efficient_uuid);
}

/** @test */
public function you_can_search_by_array_of_uuids_for_custom_column()
{
Expand All @@ -112,6 +160,24 @@ public function you_can_search_by_array_of_uuids_for_custom_column()
], 'custom_uuid')->count());
}

/** @test */
public function you_can_exclude_by_array_of_uuids_for_custom_column()
{
CustomCastUuidPost::create(['title' => 'first post', 'custom_uuid' => '8ab48e77-d9cd-4fe7-ace5-a5a428590c18']);
CustomCastUuidPost::create(['title' => 'second post', 'custom_uuid' => 'c7c26456-ddb0-45cd-9b1c-318296cce7a3']);
CustomCastUuidPost::create(['title' => 'third post', 'custom_uuid' => 'e99d440e-fa25-45f2-ba2f-7c4c48f6fb5d']);

$uuids = [
'8ab48e77-d9cd-4fe7-ace5-A5A428590C18',
'c7c26456-ddb0-45cd-9b1c-318296cce7a3',
];

$posts = CustomCastUuidPost::whereNotUuid($uuids, 'custom_uuid')->get();

$this->assertEquals(1, $posts->count());
$this->assertSame('e99d440e-fa25-45f2-ba2f-7c4c48f6fb5d', $posts->get(0)->custom_uuid);
}

/** @test */
public function you_can_search_by_array_of_uuids_which_contains_an_invalid_uuid()
{
Expand All @@ -125,6 +191,25 @@ public function you_can_search_by_array_of_uuids_which_contains_an_invalid_uuid(
])->count());
}

/** @test */
public function you_can_exclude_by_array_of_uuids_which_contains_an_invalid_uuid()
{
Post::create(['title' => 'first post', 'uuid' => '8ab48e77-d9cd-4fe7-ace5-a5a428590c18']);
Post::create(['title' => 'second post', 'uuid' => 'c7c26456-ddb0-45cd-9b1c-318296cce7a3']);
Post::create(['title' => 'third post', 'uuid' => 'e99d440e-fa25-45f2-ba2f-7c4c48f6fb5d']);

$uuids = [
'8ab48e77-d9cd-4fe7-ace5-A5A428590C18',
'c7c26456-ddb0-45cd-9b1c-318296cce7a3',
'this is invalid',
];

$posts = Post::whereNotUuid($uuids)->get();

$this->assertEquals(1, $posts->count());
$this->assertEquals('e99d440e-fa25-45f2-ba2f-7c4c48f6fb5d', $posts->get(0)->uuid);
}

/** @test */
public function you_can_generate_a_uuid_without_casting()
{
Expand Down Expand Up @@ -164,6 +249,18 @@ public function you_can_find_a_model_by_uuid_without_casting()
$this->assertSame($uuid, $post->uuid);
}

/** @test */
public function you_can_exclude_a_model_by_uuid_without_casting()
{
$uuid = 'b270f651-4db8-407b-aade-8666aca2750e';

UncastPost::create(['title' => 'test-post', 'uuid' => $uuid]);

$post = UncastPost::whereNotUuid($uuid)->first();

$this->assertNull($post);
}

/** @test */
public function you_can_find_a_model_by_uuid_with_casting()
{
Expand All @@ -177,6 +274,18 @@ public function you_can_find_a_model_by_uuid_with_casting()
$this->assertSame($uuid, $post->uuid);
}

/** @test */
public function you_can_exclude_a_model_by_uuid_with_casting()
{
$uuid = 'b270f651-4db8-407b-aade-8666aca2750e';

EfficientUuidPost::create(['title' => 'efficient uuid', 'uuid' => $uuid]);

$post = EfficientUuidPost::whereNotUuid($uuid)->first();

$this->assertNull($post);
}

/** @test */
public function it_handles_time_ordered_uuids()
{
Expand Down

0 comments on commit 8f1fad7

Please sign in to comment.