Skip to content

Commit 2642548

Browse files
committed
support UUIDs as primary key
1 parent e2f2e3b commit 2642548

File tree

16 files changed

+204
-42
lines changed

16 files changed

+204
-42
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ parameters:
4040
count: 1
4141
path: src/Index/AbstractIndex.php
4242

43-
-
44-
message: "#^Method Limenet\\\\LaravelElasticaBridge\\\\Index\\\\AbstractIndex\\:\\:getCreateArguments\\(\\) return type has no value type specified in iterable type array\\.$#"
45-
count: 1
46-
path: src/Index/AbstractIndex.php
47-
4843
-
4944
message: "#^Method Limenet\\\\LaravelElasticaBridge\\\\Index\\\\AbstractIndex\\:\\:getMapping\\(\\) return type has no value type specified in iterable type array\\.$#"
5045
count: 1
@@ -55,11 +50,6 @@ parameters:
5550
count: 1
5651
path: src/Index/AbstractIndex.php
5752

58-
-
59-
message: "#^Method Limenet\\\\LaravelElasticaBridge\\\\Index\\\\IndexInterface\\:\\:getCreateArguments\\(\\) return type has no value type specified in iterable type array\\.$#"
60-
count: 1
61-
path: src/Index/IndexInterface.php
62-
6353
-
6454
message: "#^Method Limenet\\\\LaravelElasticaBridge\\\\Index\\\\IndexInterface\\:\\:getMapping\\(\\) return type has no value type specified in iterable type array\\.$#"
6555
count: 1

src/Index/AbstractIndex.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ public function getSettings(): array
3636
return [];
3737
}
3838

39-
final public function hasMapping(): bool
40-
{
41-
return count($this->getMapping()) > 0;
42-
}
43-
4439
final public function getCreateArguments(): array
4540
{
41+
$mapping = $this->getMapping();
42+
$mapping['properties'] ??= [];
43+
$mapping['properties'][self::DOCUMENT_MODEL_ID] ??= ['type' => 'keyword'];
44+
$mapping['properties'][self::DOCUMENT_MODEL_CLASS] ??= ['type' => 'keyword'];
45+
4646
return array_filter([
47-
'mappings' => $this->getMapping(),
47+
'mappings' => $mapping,
4848
'settings' => $this->getSettings(),
4949
]);
5050
}

src/Index/IndexInterface.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,6 @@ public function getName(): string;
4545
*/
4646
public function getBatchSize(): int;
4747

48-
/**
49-
* @internal
50-
*/
51-
public function hasMapping(): bool;
52-
5348
/**
5449
* Defines the mapping to be used for this index.
5550
* Passed 1:1 to Elasticsearch.
@@ -67,7 +62,7 @@ public function getMapping(): array;
6762
public function getSettings(): array;
6863

6964
/**
70-
* @return array<array>
65+
* @return array{mappings:non-empty-array<mixed>,settings?:array<mixed>}
7166
*
7267
* @internal
7368
*/

src/Model/ElasticsearchableTrait.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ final public function getElasticsearchId(): string
1414
return str($this::class)
1515
->replace('\\', ' ')
1616
->snake()
17-
->append('-', $this->id)
17+
->append('-', $this->getKey())
1818
->toString();
1919
}
2020

@@ -35,7 +35,7 @@ public function toElasticaDocument(IndexInterface $indexConfig): Document
3535
[
3636
...$this->toElasticsearch($indexConfig),
3737
IndexInterface::DOCUMENT_MODEL_CLASS => $this::class,
38-
IndexInterface::DOCUMENT_MODEL_ID => $this->id,
38+
IndexInterface::DOCUMENT_MODEL_ID => $this->getKey(),
3939
]
4040
);
4141
}

tests/App/Elasticsearch/AllIndex.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Limenet\LaravelElasticaBridge\Index\AbstractIndex;
88
use Limenet\LaravelElasticaBridge\Tests\App\Models\Customer;
9+
use Limenet\LaravelElasticaBridge\Tests\App\Models\Invoice;
910
use Limenet\LaravelElasticaBridge\Tests\App\Models\Product;
1011

1112
class AllIndex extends AbstractIndex
@@ -17,6 +18,11 @@ public function getName(): string
1718

1819
public function getAllowedDocuments(): array
1920
{
20-
return [Customer::class, Order::class, Product::class];
21+
return [
22+
Customer::class,
23+
Invoice::class,
24+
Order::class,
25+
Product::class,
26+
];
2127
}
2228
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch;
6+
7+
use Limenet\LaravelElasticaBridge\Index\AbstractIndex;
8+
use Limenet\LaravelElasticaBridge\Tests\App\Models\Invoice;
9+
10+
class InvoiceIndex extends AbstractIndex
11+
{
12+
public function getName(): string
13+
{
14+
return 'testing_invoice';
15+
}
16+
17+
public function getAllowedDocuments(): array
18+
{
19+
return [Invoice::class];
20+
}
21+
}

tests/App/Models/Invoice.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Limenet\LaravelElasticaBridge\Tests\App\Models;
6+
7+
use Illuminate\Database\Eloquent\Concerns\HasUuids;
8+
use Illuminate\Database\Eloquent\Factories\Factory;
9+
use Illuminate\Database\Eloquent\Factories\HasFactory;
10+
use Illuminate\Database\Eloquent\Model;
11+
use Limenet\LaravelElasticaBridge\Model\ElasticsearchableInterface;
12+
use Limenet\LaravelElasticaBridge\Model\ElasticsearchableTrait;
13+
use Limenet\LaravelElasticaBridge\Tests\Database\Factories\InvoiceFactory;
14+
15+
class Invoice extends Model implements ElasticsearchableInterface
16+
{
17+
use ElasticsearchableTrait;
18+
use HasFactory;
19+
use HasUuids;
20+
21+
protected $primaryKey = 'uuid';
22+
23+
public $incrementing = false;
24+
25+
protected static function newFactory(): Factory
26+
{
27+
return InvoiceFactory::new();
28+
}
29+
}

tests/Feature/QueryTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Elastica\Query\BoolQuery;
88
use Elastica\Query\MatchQuery;
99
use Limenet\LaravelElasticaBridge\Index\IndexInterface;
10+
use Limenet\LaravelElasticaBridge\Tests\App\Models\Invoice;
1011

1112
class QueryTest extends TestCase
1213
{
@@ -20,6 +21,16 @@ public function test_get_by_id(): void
2021
$this->assertSame(17, $elements[0]->id);
2122
}
2223

24+
public function test_get_by_uuid(): void
25+
{
26+
$uuid = Invoice::all()->first()->uuid;
27+
$this->index($this->invoiceIndex);
28+
$elements = $this->invoiceIndex->searchForElements(new MatchQuery(IndexInterface::DOCUMENT_MODEL_ID, $uuid));
29+
30+
$this->assertCount(1, $elements);
31+
$this->assertSame($uuid, $elements[0]->getKey());
32+
}
33+
2334
public function test_size_and_from(): void
2435
{
2536
$this->index($this->productIndex);

tests/Feature/TestCase.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Limenet\LaravelElasticaBridge\Index\IndexInterface;
1111
use Limenet\LaravelElasticaBridge\Repository\IndexRepository;
1212
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\CustomerIndex;
13+
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\InvoiceIndex;
1314
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\OrderIndex;
1415
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\ProductIndex;
1516
use Limenet\LaravelElasticaBridge\Tests\TestCase as TestsTestCase;
@@ -18,6 +19,8 @@ class TestCase extends TestsTestCase
1819
{
1920
protected CustomerIndex $customerIndex;
2021

22+
protected InvoiceIndex $invoiceIndex;
23+
2124
protected OrderIndex $orderIndex;
2225

2326
protected ProductIndex $productIndex;
@@ -31,6 +34,7 @@ protected function setUp(): void
3134
parent::setUp();
3235

3336
$this->customerIndex = $this->app->make(CustomerIndex::class);
37+
$this->invoiceIndex = $this->app->make(InvoiceIndex::class);
3438
$this->orderIndex = $this->app->make(OrderIndex::class);
3539
$this->productIndex = $this->app->make(ProductIndex::class);
3640
$this->indexRepository = $this->app->make(IndexRepository::class);
@@ -48,7 +52,7 @@ protected function tearDown(): void
4852

4953
protected function cleanupIndices(): void
5054
{
51-
foreach ([$this->customerIndex, $this->orderIndex, $this->productIndex] as $index) {
55+
foreach ([$this->customerIndex, $this->invoiceIndex, $this->orderIndex, $this->productIndex] as $index) {
5256
try {
5357
if ($index->getElasticaIndex()->hasAlias($index->getName())) {
5458
$index->getElasticaIndex()->removeAlias($index->getName());

tests/TestCase.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Database\Eloquent\Factories\Factory;
88
use Limenet\LaravelElasticaBridge\LaravelElasticaBridgeServiceProvider;
99
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\CustomerIndex;
10+
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\InvoiceIndex;
1011
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\OrderIndex;
1112
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\ProductIndex;
1213
use Limenet\LaravelElasticaBridge\Tests\Database\Seeders\DatabaseSeeder;
@@ -29,7 +30,15 @@ protected function resolveApplicationConfiguration($app): void
2930
{
3031
parent::resolveApplicationConfiguration($app);
3132

32-
$app['config']->set('elastica-bridge.indices', [CustomerIndex::class, OrderIndex::class, ProductIndex::class]);
33+
$app['config']->set(
34+
'elastica-bridge.indices',
35+
[
36+
CustomerIndex::class,
37+
InvoiceIndex::class,
38+
OrderIndex::class,
39+
ProductIndex::class,
40+
]
41+
);
3342
}
3443

3544
protected function getPackageProviders($app)

tests/Unit/IndexTest.php

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,26 @@
1111
use Limenet\LaravelElasticaBridge\Exception\Index\BlueGreenIndicesIncorrectlySetupException;
1212
use Limenet\LaravelElasticaBridge\Index\IndexInterface;
1313
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\CustomerIndex;
14+
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\InvoiceIndex;
1415
use Limenet\LaravelElasticaBridge\Tests\App\Elasticsearch\ProductIndex;
1516
use Limenet\LaravelElasticaBridge\Tests\App\Models\Customer;
17+
use Limenet\LaravelElasticaBridge\Tests\App\Models\Invoice;
1618
use RuntimeException;
1719

1820
class IndexTest extends TestCase
1921
{
2022
protected CustomerIndex $customerIndex;
2123

24+
protected InvoiceIndex $invoiceIndex;
25+
2226
protected ProductIndex $productIndex;
2327

2428
protected function setUp(): void
2529
{
2630
parent::setUp();
2731

2832
$this->customerIndex = $this->app->make(CustomerIndex::class);
33+
$this->invoiceIndex = $this->app->make(InvoiceIndex::class);
2934
$this->productIndex = $this->app->make(ProductIndex::class);
3035
}
3136

@@ -39,23 +44,51 @@ public function test_raw_index(): void
3944

4045
public function test_settings_customized(): void
4146
{
42-
$settings = $this->customerIndex->getCreateArguments();
43-
$mappings = $this->customerIndex->getMapping();
44-
45-
$this->assertTrue($this->customerIndex->hasMapping());
46-
$this->assertArrayHasKey('mappings', $settings);
47-
$this->assertArrayNotHasKey('settings', $settings);
48-
$this->assertSame($settings['mappings'], $mappings);
47+
$createArguments = $this->customerIndex->getCreateArguments();
48+
49+
$this->assertArrayHasKey('mappings', $createArguments);
50+
$this->assertArrayNotHasKey('settings', $createArguments);
51+
$this->assertSame(
52+
[
53+
'mappings' => [
54+
'properties' => [
55+
'group' => [
56+
'type' => 'keyword',
57+
],
58+
'__id' => [
59+
'type' => 'keyword',
60+
],
61+
'__class' => [
62+
'type' => 'keyword',
63+
],
64+
],
65+
],
66+
],
67+
$createArguments
68+
);
4969
}
5070

51-
public function test_settings__default(): void
71+
public function test_settings_default(): void
5272
{
53-
$settings = $this->productIndex->getCreateArguments();
73+
$createArguments = $this->productIndex->getCreateArguments();
5474
$mappings = $this->productIndex->getMapping();
5575

56-
$this->assertFalse($this->productIndex->hasMapping());
5776
$this->assertEmpty($mappings);
58-
$this->assertEmpty($settings);
77+
$this->assertSame(
78+
[
79+
'mappings' => [
80+
'properties' => [
81+
'__id' => [
82+
'type' => 'keyword',
83+
],
84+
'__class' => [
85+
'type' => 'keyword',
86+
],
87+
],
88+
],
89+
],
90+
$createArguments
91+
);
5992
}
6093

6194
public function test_document_to_model(): void
@@ -69,6 +102,17 @@ public function test_document_to_model(): void
69102
});
70103
}
71104

105+
public function test_document_to_model_uuid(): void
106+
{
107+
Invoice::all()
108+
->each(function (Invoice $invoice): void {
109+
$document = $invoice->toElasticaDocument($this->invoiceIndex);
110+
$model = $this->invoiceIndex->getModelInstance($document);
111+
$this->assertInstanceOf(Invoice::class, $model);
112+
$this->assertSame($invoice->uuid, $model->uuid);
113+
});
114+
}
115+
72116
public function test_empty_document_to_model(): void
73117
{
74118
/** @var Customer $customer */

0 commit comments

Comments
 (0)