|
7 | 7 | use Illuminate\Database\Capsule\Manager as DB;
|
8 | 8 | use Illuminate\Database\Eloquent\Builder;
|
9 | 9 | use Illuminate\Database\Eloquent\Collection;
|
| 10 | +use Illuminate\Database\Eloquent\Concerns\HasUuids; |
10 | 11 | use Illuminate\Database\Eloquent\Model;
|
11 | 12 | use Illuminate\Database\Eloquent\Model as Eloquent;
|
12 | 13 | use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
16 | 17 | use Illuminate\Database\Eloquent\SoftDeletes;
|
17 | 18 | use Illuminate\Database\Eloquent\SoftDeletingScope;
|
18 | 19 | use Illuminate\Database\QueryException;
|
| 20 | +use Illuminate\Database\Schema\Blueprint; |
19 | 21 | use Illuminate\Database\UniqueConstraintViolationException;
|
20 | 22 | use Illuminate\Pagination\AbstractPaginator as Paginator;
|
21 | 23 | use Illuminate\Pagination\Cursor;
|
22 | 24 | use Illuminate\Pagination\CursorPaginator;
|
23 | 25 | use Illuminate\Pagination\LengthAwarePaginator;
|
24 | 26 | use Illuminate\Support\Carbon;
|
25 | 27 | use Illuminate\Support\Facades\Date;
|
| 28 | +use Illuminate\Support\Str; |
26 | 29 | use Illuminate\Tests\Integration\Database\Fixtures\Post;
|
27 | 30 | use Illuminate\Tests\Integration\Database\Fixtures\User;
|
28 | 31 | use PHPUnit\Framework\TestCase;
|
@@ -80,6 +83,14 @@ protected function createSchema()
|
80 | 83 | $table->timestamps();
|
81 | 84 | });
|
82 | 85 |
|
| 86 | + $this->schema()->create('users_having_uuids', function (Blueprint $table) { |
| 87 | + $table->id(); |
| 88 | + $table->uuid(); |
| 89 | + $table->string('name'); |
| 90 | + $table->tinyInteger('role'); |
| 91 | + $table->string('role_string'); |
| 92 | + }); |
| 93 | + |
83 | 94 | foreach (['default', 'second_connection'] as $connection) {
|
84 | 95 | $this->schema($connection)->create('users', function ($table) {
|
85 | 96 | $table->increments('id');
|
@@ -187,6 +198,8 @@ protected function tearDown(): void
|
187 | 198 | Eloquent::unsetConnectionResolver();
|
188 | 199 |
|
189 | 200 | Carbon::setTestNow(null);
|
| 201 | + Str::createUuidsNormally(); |
| 202 | + DB::flushQueryLog(); |
190 | 203 | }
|
191 | 204 |
|
192 | 205 | /**
|
@@ -2461,6 +2474,147 @@ public function testTouchingBiDirectionalChaperonedModelUpdatesAllRelatedTimesta
|
2461 | 2474 | }
|
2462 | 2475 | }
|
2463 | 2476 |
|
| 2477 | + public function testCanFillAndInsert() |
| 2478 | + { |
| 2479 | + DB::enableQueryLog(); |
| 2480 | + Carbon::setTestNow('2025-03-15T07:32:00Z'); |
| 2481 | + |
| 2482 | + $this->assertTrue(EloquentTestUser::fillAndInsert([ |
| 2483 | + [ 'email' => '[email protected]', 'birthday' => null], |
| 2484 | + [ 'email' => '[email protected]', 'birthday' => new Carbon( '1980-01-01')], |
| 2485 | + [ 'email' => '[email protected]', 'birthday' => '1987-11-01', 'created_at' => '2025-01-02T02:00:55', 'updated_at' => Carbon:: parse( '2025-02-19T11:41:13')], |
| 2486 | + ])); |
| 2487 | + |
| 2488 | + $this->assertCount(1, DB::getQueryLog()); |
| 2489 | + |
| 2490 | + $this->assertCount(3, $users = EloquentTestUser::get()); |
| 2491 | + |
| 2492 | + $users->take(2)->each(function (EloquentTestUser $user) { |
| 2493 | + $this->assertEquals(Carbon::parse('2025-03-15T07:32:00Z'), $user->created_at); |
| 2494 | + $this->assertEquals(Carbon::parse('2025-03-15T07:32:00Z'), $user->updated_at); |
| 2495 | + }); |
| 2496 | + |
| 2497 | + $tim = $users-> firstWhere( 'email', '[email protected]'); |
| 2498 | + $this->assertEquals(Carbon::parse('2025-01-02T02:00:55'), $tim->created_at); |
| 2499 | + $this->assertEquals(Carbon::parse('2025-02-19T11:41:13'), $tim->updated_at); |
| 2500 | + |
| 2501 | + $this->assertNull($users[0]->birthday); |
| 2502 | + $this->assertInstanceOf(\DateTime::class, $users[1]->birthday); |
| 2503 | + $this->assertInstanceOf(\DateTime::class, $users[2]->birthday); |
| 2504 | + $this->assertEquals('1987-11-01', $users[2]->birthday->format('Y-m-d')); |
| 2505 | + |
| 2506 | + DB::flushQueryLog(); |
| 2507 | + |
| 2508 | + $this->assertTrue(EloquentTestWithJSON::fillAndInsert([ |
| 2509 | + ['id' => 1, 'json' => ['album' => 'Keep It Like a Secret', 'release_date' => '1999-02-02']], |
| 2510 | + ['id' => 2, 'json' => (object) ['album' => 'You In Reverse', 'release_date' => '2006-04-11']], |
| 2511 | + ])); |
| 2512 | + |
| 2513 | + $this->assertCount(1, DB::getQueryLog()); |
| 2514 | + |
| 2515 | + $this->assertCount(2, $testsWithJson = EloquentTestWithJSON::get()); |
| 2516 | + |
| 2517 | + $testsWithJson->each(function (EloquentTestWithJSON $testWithJson) { |
| 2518 | + $this->assertIsArray($testWithJson->json); |
| 2519 | + $this->assertArrayHasKey('album', $testWithJson->json); |
| 2520 | + }); |
| 2521 | + } |
| 2522 | + |
| 2523 | + public function testCanFillAndInsertWithUniqueStringIds() |
| 2524 | + { |
| 2525 | + Str::createUuidsUsingSequence([ |
| 2526 | + '00000000-0000-7000-0000-000000000000', |
| 2527 | + '11111111-0000-7000-0000-000000000000', |
| 2528 | + '22222222-0000-7000-0000-000000000000', |
| 2529 | + ]); |
| 2530 | + |
| 2531 | + $this->assertTrue(ModelWithUniqueStringIds::fillAndInsert([ |
| 2532 | + [ |
| 2533 | + 'name' => 'Taylor', 'role' => IntBackedRole::Admin, 'role_string' => StringBackedRole::Admin, |
| 2534 | + ], |
| 2535 | + [ |
| 2536 | + 'name' => 'Nuno', 'role' => 3, 'role_string' => 'admin', |
| 2537 | + ], |
| 2538 | + [ |
| 2539 | + 'name' => 'Dries', 'uuid' => 'bbbb0000-0000-7000-0000-000000000000', |
| 2540 | + ], |
| 2541 | + [ |
| 2542 | + 'name' => 'Chris', |
| 2543 | + ], |
| 2544 | + ])); |
| 2545 | + |
| 2546 | + $models = ModelWithUniqueStringIds::get(); |
| 2547 | + |
| 2548 | + $taylor = $models->firstWhere('name', 'Taylor'); |
| 2549 | + $nuno = $models->firstWhere('name', 'Nuno'); |
| 2550 | + $dries = $models->firstWhere('name', 'Dries'); |
| 2551 | + $chris = $models->firstWhere('name', 'Chris'); |
| 2552 | + |
| 2553 | + $this->assertEquals(IntBackedRole::Admin, $taylor->role); |
| 2554 | + $this->assertEquals(StringBackedRole::Admin, $taylor->role_string); |
| 2555 | + $this->assertSame('00000000-0000-7000-0000-000000000000', $taylor->uuid); |
| 2556 | + |
| 2557 | + $this->assertEquals(IntBackedRole::Admin, $nuno->role); |
| 2558 | + $this->assertEquals(StringBackedRole::Admin, $nuno->role_string); |
| 2559 | + $this->assertSame('11111111-0000-7000-0000-000000000000', $nuno->uuid); |
| 2560 | + |
| 2561 | + $this->assertEquals(IntBackedRole::User, $dries->role); |
| 2562 | + $this->assertEquals(StringBackedRole::User, $dries->role_string); |
| 2563 | + $this->assertSame('bbbb0000-0000-7000-0000-000000000000', $dries->uuid); |
| 2564 | + |
| 2565 | + $this->assertEquals(IntBackedRole::User, $chris->role); |
| 2566 | + $this->assertEquals(StringBackedRole::User, $chris->role_string); |
| 2567 | + $this->assertSame('22222222-0000-7000-0000-000000000000', $chris->uuid); |
| 2568 | + } |
| 2569 | + |
| 2570 | + public function testFillAndInsertOrIgnore() |
| 2571 | + { |
| 2572 | + Str::createUuidsUsingSequence([ |
| 2573 | + '00000000-0000-7000-0000-000000000000', |
| 2574 | + '11111111-0000-7000-0000-000000000000', |
| 2575 | + '22222222-0000-7000-0000-000000000000', |
| 2576 | + ]); |
| 2577 | + |
| 2578 | + $this->assertEquals(1, ModelWithUniqueStringIds::fillAndInsertOrIgnore([ |
| 2579 | + [ |
| 2580 | + 'id' => 1, 'name' => 'Taylor', 'role' => IntBackedRole::Admin, 'role_string' => StringBackedRole::Admin, |
| 2581 | + ], |
| 2582 | + ])); |
| 2583 | + |
| 2584 | + $this->assertSame(1, ModelWithUniqueStringIds::fillAndInsertOrIgnore([ |
| 2585 | + [ |
| 2586 | + 'id' => 1, 'name' => 'Taylor', 'role' => IntBackedRole::Admin, 'role_string' => StringBackedRole::Admin, |
| 2587 | + ], |
| 2588 | + [ |
| 2589 | + 'id' => 2, 'name' => 'Nuno', |
| 2590 | + ], |
| 2591 | + ])); |
| 2592 | + |
| 2593 | + $models = ModelWithUniqueStringIds::get(); |
| 2594 | + $this->assertSame('00000000-0000-7000-0000-000000000000', $models->firstWhere('name', 'Taylor')->uuid); |
| 2595 | + $this->assertSame( |
| 2596 | + ['uuid' => '22222222-0000-7000-0000-000000000000', 'role' => IntBackedRole::User], |
| 2597 | + $models->firstWhere('name', 'Nuno')->only('uuid', 'role') |
| 2598 | + ); |
| 2599 | + } |
| 2600 | + |
| 2601 | + public function testFillAndInsertGetId() |
| 2602 | + { |
| 2603 | + Str::createUuidsUsingSequence([ |
| 2604 | + '00000000-0000-7000-0000-000000000000', |
| 2605 | + ]); |
| 2606 | + |
| 2607 | + DB::enableQueryLog(); |
| 2608 | + |
| 2609 | + $this->assertIsInt($newId = ModelWithUniqueStringIds::fillAndInsertGetId([ |
| 2610 | + 'name' => 'Taylor', |
| 2611 | + 'role' => IntBackedRole::Admin, |
| 2612 | + 'role_string' => StringBackedRole::Admin, |
| 2613 | + ])); |
| 2614 | + $this->assertCount(1, DB::getRawQueryLog()); |
| 2615 | + $this->assertSame($newId, ModelWithUniqueStringIds::sole()->id); |
| 2616 | + } |
| 2617 | + |
2464 | 2618 | /**
|
2465 | 2619 | * Helpers...
|
2466 | 2620 | */
|
@@ -2786,3 +2940,42 @@ public function children()
|
2786 | 2940 | return $this->hasMany(EloquentTouchingCategory::class, 'parent_id')->chaperone();
|
2787 | 2941 | }
|
2788 | 2942 | }
|
| 2943 | + |
| 2944 | +class ModelWithUniqueStringIds extends Eloquent |
| 2945 | +{ |
| 2946 | + use HasUuids; |
| 2947 | + |
| 2948 | + public $timestamps = false; |
| 2949 | + |
| 2950 | + protected $table = 'users_having_uuids'; |
| 2951 | + |
| 2952 | + protected function casts() |
| 2953 | + { |
| 2954 | + return [ |
| 2955 | + 'role' => IntBackedRole::class, |
| 2956 | + 'role_string' => StringBackedRole::class, |
| 2957 | + ]; |
| 2958 | + } |
| 2959 | + |
| 2960 | + protected $attributes = [ |
| 2961 | + 'role' => IntBackedRole::User, |
| 2962 | + 'role_string' => StringBackedRole::User, |
| 2963 | + ]; |
| 2964 | + |
| 2965 | + public function uniqueIds() |
| 2966 | + { |
| 2967 | + return ['uuid']; |
| 2968 | + } |
| 2969 | +} |
| 2970 | + |
| 2971 | +enum IntBackedRole: int |
| 2972 | +{ |
| 2973 | + case User = 1; |
| 2974 | + case Admin = 3; |
| 2975 | +} |
| 2976 | + |
| 2977 | +enum StringBackedRole: string |
| 2978 | +{ |
| 2979 | + case User = 'user'; |
| 2980 | + case Admin = 'admin'; |
| 2981 | +} |
0 commit comments